|
|
@ -3,6 +3,7 @@ require 'xmpp4r' |
|
|
|
require 'net/smtp' |
|
|
|
require 'json' |
|
|
|
require 'uri' |
|
|
|
require 'openssl' |
|
|
|
|
|
|
|
norxondor_gorgonax = URI::MailTo::EMAIL_REGEXP |
|
|
|
|
|
|
@ -17,11 +18,18 @@ SMTP_TLS = CONFIG["tls"] |
|
|
|
SMTP_STARTTLS = CONFIG["starttls"] |
|
|
|
SMTP_AUTH = CONFIG["auth"].to_sym |
|
|
|
JABBER_SERVER = CONFIG["jabber-server"] |
|
|
|
JABBER_HOST = CONFIG['jabber-host'] |
|
|
|
JABBER_PORT = CONFIG['jabber-port'] |
|
|
|
HTTP_SERVER_ROOT = CONFIG['http-server-root'] |
|
|
|
RATELIMIT = CONFIG['ratelimit'] |
|
|
|
HTTP_PORT = CONFIG['http-port'] |
|
|
|
|
|
|
|
Pending = {} |
|
|
|
Pending_by_username = {} |
|
|
|
|
|
|
|
Recent = {} |
|
|
|
|
|
|
|
# Get root path to redirect to |
|
|
|
def myroot(req) |
|
|
|
if req.ssl? then |
|
|
|
return "https://#{HTTP_SERVER_ROOT}" |
|
|
@ -30,9 +38,7 @@ def myroot(req) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
def register(username,password) |
|
|
|
cl = Jabber::Client.new(Jabber::JID.new( |
|
|
|
|
|
|
|
# Send email with given SMTP config |
|
|
|
def sendmail(code,email) |
|
|
|
smtp = Net::SMTP.new(SMTP_SERVER, SMTP_PORT) |
|
|
|
msg_headers = '' |
|
|
@ -47,7 +53,9 @@ def sendmail(code,email) |
|
|
|
puts(smtp.send_message msg, SMTP_USER, [email]) |
|
|
|
end |
|
|
|
|
|
|
|
server = Hyde::Server.new Port: 8001 do |
|
|
|
# Main API server |
|
|
|
server = Hyde::Server.new Port: HTTP_PORT do |
|
|
|
# Serve static shit |
|
|
|
path "register" do |
|
|
|
preprocess do |ctx| |
|
|
|
puts "#{ctx.request.remote_ip} is registering" |
|
|
@ -57,51 +65,78 @@ server = Hyde::Server.new Port: 8001 do |
|
|
|
index ['index.html'] |
|
|
|
serve "*.html" |
|
|
|
end |
|
|
|
# API itself |
|
|
|
path "api" do |
|
|
|
# First step |
|
|
|
post 'register' do |ctx| |
|
|
|
# Where to redirect to |
|
|
|
server_uri = myroot ctx.request |
|
|
|
# Add pending user |
|
|
|
# Pending user info and validation key |
|
|
|
key = (1..32).map { |x| "0123456789ABCDEF"[(rand()*15).round] }.join |
|
|
|
user = ctx.request.query['user'] |
|
|
|
password = ctx.request.query['password'] |
|
|
|
email = ctx.request.query['email'] |
|
|
|
# Expiration is 2 hours from now |
|
|
|
expires_on = Time.now+60*60*2 |
|
|
|
# Match query parameters against given rules |
|
|
|
unless user.match /^[\w_-]+$/ and |
|
|
|
email.match norxondor_gorgonax and |
|
|
|
password.match /^.{8,}$/ then |
|
|
|
redirect server_uri+"/register/error.html" |
|
|
|
end |
|
|
|
# Bounce if user is already pending registration |
|
|
|
if Pending_by_username[user] then |
|
|
|
redirect server_uri+"/register/error.html" |
|
|
|
end |
|
|
|
# Bounce if email is recent |
|
|
|
email_digest = OpenSSL::Digest.digest("sha256",email) |
|
|
|
if Recent[email_digest] then |
|
|
|
if Time.now < (Recent[email_digest]+RATELIMIT) then |
|
|
|
redirect server_uri+"/register/ratelimit.html" |
|
|
|
end |
|
|
|
end |
|
|
|
# Lock registration for pending user |
|
|
|
Pending_by_username[user] = Pending[key] = { |
|
|
|
"user" => user, |
|
|
|
"password" => password, |
|
|
|
"expires_on" => expires_on |
|
|
|
} |
|
|
|
# Record recent emails that tried registering |
|
|
|
Recent[email_digest] = Time.now |
|
|
|
begin |
|
|
|
# Send email to validate |
|
|
|
sendmail(key,email) |
|
|
|
redirect server_uri+"/register/validate.html" |
|
|
|
rescue Exception => e |
|
|
|
# Couldn't send email - delete pending account info |
|
|
|
Pending_by_username.delete (Pending.delete key)["user"] |
|
|
|
redirect server_uri+"/register/error.html" |
|
|
|
end |
|
|
|
end |
|
|
|
# Second step |
|
|
|
post 'validate' do |ctx| |
|
|
|
# Where to redirect to |
|
|
|
server_uri = myroot ctx.request |
|
|
|
# Validation key |
|
|
|
key = ctx.request.query['key'] |
|
|
|
# If validation key matches a user |
|
|
|
if Pending.has_key? key then |
|
|
|
if Pending[key].expires_on < Time.now then |
|
|
|
puts "#{Pending.delete key} expired" |
|
|
|
# ... and if it's not expired |
|
|
|
if Pending[key]["expires_on"] < Time.now then |
|
|
|
# key has expired |
|
|
|
puts "#{ctx.request.remote_ip} expired" |
|
|
|
redirect server_uri+"/register/error.html" |
|
|
|
end |
|
|
|
# register the user |
|
|
|
cl = Jabber::Client.new(Jabber::JID.new(Pending[key]["user"]+"@"+JABBER_SERVER)) |
|
|
|
cl.connect |
|
|
|
cl.connect JABBER_HOST, JABBER_PORT |
|
|
|
cl.register(Pending[key]["password"]) |
|
|
|
cl.close |
|
|
|
puts "#{Pending[key]} successfully verified" |
|
|
|
puts "#{ctx.request.remote_ip} successfully verified" |
|
|
|
redirect server_uri+"/register/success.html" |
|
|
|
else |
|
|
|
puts "#{Pending[key]} failed to verify" |
|
|
|
# key is invalid |
|
|
|
puts "#{ctx.request.remote_ip} failed to verify" |
|
|
|
redirect server_uri+"/register/error.html" |
|
|
|
end |
|
|
|
end |
|
|
|