authd/src/requests/login.cr

74 lines
2.0 KiB
Crystal

require "sodium"
class AuthD::Request
def self.perform_login(authd : AuthD::Service, fd : Int32, user : AuthD::User)
user.date_last_connection = Time.local
token = user.to_token
# Change the date of the last connection.
authd.users_per_uid.update user.uid.to_s, user
# On successuful connection: store the authenticated user in a hash.
authd.logged_users[fd] = user.to_public
Response::Login.new (token.to_s authd.configuration.secret_key), user.uid
end
IPC::JSON.message Login, 0 do
property login : String
property password : String
def initialize(@login, @password)
end
def handle(authd : AuthD::Service, fd : Int32)
begin
user = authd.users_per_login.get @login
rescue e : DODB::MissingEntry
# This lack of proper error message is intentional.
# Let attackers try to authenticate themselves with a wrong login.
return Response::ErrorInvalidCredentials.new
end
# This line is basically just to please the Crystal's type system.
# No user means DODB::MissingEntry, so it's already covered.
return Response::ErrorInvalidCredentials.new if user.nil?
# In case the user hasn't validated his email address,
# authentication shouldn't be possible.
if user.contact.activation_key
return Response::ErrorInvalidCredentials.new
end
pwhash = Sodium::Password::Hash.new
hash = Base64.decode user.password_hash
begin
pwhash.verify hash, @password
rescue
return Response::ErrorInvalidCredentials.new
end
AuthD::Request.perform_login authd, fd, user.not_nil!
end
end
AuthD.requests << Login
IPC::JSON.message AuthByToken, 15 do
property token : String
def initialize(@token)
end
def handle(authd : AuthD::Service, fd : Int32)
token_payload = AuthD::Token.from_s authd.configuration.secret_key, token
user = authd.users_per_uid.get? token_payload.uid.to_s
return Response::ErrorUserNotFound.new if user.nil?
AuthD::Request.perform_login authd, fd, user
end
end
AuthD.requests << AuthByToken
end