Password Recovery.
This commit is contained in:
parent
3ce1d78a50
commit
bd68148924
55
src/authd.cr
55
src/authd.cr
@ -99,6 +99,18 @@ class AuthD::Response
|
|||||||
initialize :user, :service, :resource, :permission
|
initialize :user, :service, :resource, :permission
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class PasswordRecoverySent < Response
|
||||||
|
property user : ::AuthD::User::Public
|
||||||
|
|
||||||
|
initialize :user
|
||||||
|
end
|
||||||
|
|
||||||
|
class PasswordRecovered < Response
|
||||||
|
property user : ::AuthD::User::Public
|
||||||
|
|
||||||
|
initialize :user
|
||||||
|
end
|
||||||
|
|
||||||
# This creates a Request::Type enumeration. One entry for each request type.
|
# This creates a Request::Type enumeration. One entry for each request type.
|
||||||
{% begin %}
|
{% begin %}
|
||||||
enum Type
|
enum Type
|
||||||
@ -273,6 +285,21 @@ class AuthD::Request
|
|||||||
initialize :shared_key, :user, :service, :resource, :permission
|
initialize :shared_key, :user, :service, :resource, :permission
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class PasswordRecovery < Request
|
||||||
|
property shared_key : String
|
||||||
|
property user : Int32 | String
|
||||||
|
property password_renew_key : String
|
||||||
|
property new_password : String
|
||||||
|
|
||||||
|
initialize :shared_key, :user, :password_renew_key, :new_password
|
||||||
|
end
|
||||||
|
|
||||||
|
class AskPasswordRecovery < Request
|
||||||
|
property user : Int32 | String
|
||||||
|
|
||||||
|
initialize :user
|
||||||
|
end
|
||||||
|
|
||||||
# This creates a Request::Type enumeration. One entry for each request type.
|
# This creates a Request::Type enumeration. One entry for each request type.
|
||||||
{% begin %}
|
{% begin %}
|
||||||
enum Type
|
enum Type
|
||||||
@ -309,7 +336,7 @@ class AuthD::Request
|
|||||||
|
|
||||||
requests.find(&.type.==(type)).try &.from_json(payload)
|
requests.find(&.type.==(type)).try &.from_json(payload)
|
||||||
rescue e : JSON::ParseException
|
rescue e : JSON::ParseException
|
||||||
raise Exception.new "malformed request"
|
raise Exception.new "malformed request: #{e}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -419,6 +446,32 @@ module AuthD
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ask_password_recovery(uid_or_login : String | Int32)
|
||||||
|
send Request::AskPasswordRecovery.new uid_or_login
|
||||||
|
response = Response.from_ipc read
|
||||||
|
|
||||||
|
case response
|
||||||
|
when Response::PasswordRecoverySent
|
||||||
|
when Response::Error
|
||||||
|
raise Exception.new response.reason
|
||||||
|
else
|
||||||
|
Exception.new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def change_password(uid_or_login : String | Int32, new_pass : String, renew_key : String)
|
||||||
|
send Request::PasswordRecovery.new @key, uid_or_login, renew_key, new_pass
|
||||||
|
response = Response.from_ipc read
|
||||||
|
|
||||||
|
case response
|
||||||
|
when Response::PasswordRecovered
|
||||||
|
when Response::Error
|
||||||
|
raise Exception.new response.reason
|
||||||
|
else
|
||||||
|
Exception.new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def register(login : String,
|
def register(login : String,
|
||||||
password : String,
|
password : String,
|
||||||
email : String?,
|
email : String?,
|
||||||
|
57
src/main.cr
57
src/main.cr
@ -209,6 +209,7 @@ class AuthD::Service
|
|||||||
user.profile = profile
|
user.profile = profile
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@users << user
|
@users << user
|
||||||
|
|
||||||
# Once the user is created and stored, we try to contact him
|
# Once the user is created and stored, we try to contact him
|
||||||
@ -309,6 +310,62 @@ class AuthD::Service
|
|||||||
@users_per_uid.update user.uid.to_s, user
|
@users_per_uid.update user.uid.to_s, user
|
||||||
|
|
||||||
Response::PermissionSet.new user.uid, service, request.resource, request.permission
|
Response::PermissionSet.new user.uid, service, request.resource, request.permission
|
||||||
|
when Request::AskPasswordRecovery
|
||||||
|
|
||||||
|
uid_or_login = request.user
|
||||||
|
user = if uid_or_login.is_a? Int32
|
||||||
|
@users_per_uid.get? uid_or_login.to_s
|
||||||
|
else
|
||||||
|
@users_per_login.get? uid_or_login
|
||||||
|
end
|
||||||
|
|
||||||
|
if user.nil?
|
||||||
|
return Response::Error.new "user not found"
|
||||||
|
end
|
||||||
|
|
||||||
|
user.password_renew_key = UUID.random.to_s
|
||||||
|
|
||||||
|
@users_per_uid.update user.uid.to_s, user
|
||||||
|
|
||||||
|
# Once the user is created and stored, we try to contact him
|
||||||
|
unless Process.run("password-recovery-mailer", [
|
||||||
|
"-l", user.login,
|
||||||
|
"-e", user.contact.email.not_nil!,
|
||||||
|
"-t", "Password recovery email",
|
||||||
|
"-f", "karchnu@localhost",
|
||||||
|
"-a", user.password_renew_key.not_nil!
|
||||||
|
]).success?
|
||||||
|
return Response::Error.new "cannot contact the user for password recovery"
|
||||||
|
end
|
||||||
|
|
||||||
|
Response::PasswordRecoverySent.new user.to_public
|
||||||
|
when Request::PasswordRecovery
|
||||||
|
if request.shared_key != @jwt_key
|
||||||
|
return Response::Error.new "invalid authentication key"
|
||||||
|
end
|
||||||
|
|
||||||
|
uid_or_login = request.user
|
||||||
|
user = if uid_or_login.is_a? Int32
|
||||||
|
@users_per_uid.get? uid_or_login.to_s
|
||||||
|
else
|
||||||
|
@users_per_login.get? uid_or_login
|
||||||
|
end
|
||||||
|
|
||||||
|
if user.nil?
|
||||||
|
return Response::Error.new "user not found"
|
||||||
|
end
|
||||||
|
|
||||||
|
if user.password_renew_key == request.password_renew_key
|
||||||
|
user.password_hash = hash_password request.new_password
|
||||||
|
else
|
||||||
|
return Response::Error.new "renew key not valid"
|
||||||
|
end
|
||||||
|
|
||||||
|
user.password_renew_key = nil
|
||||||
|
|
||||||
|
@users_per_uid.update user.uid.to_s, user
|
||||||
|
|
||||||
|
Response::PasswordRecoverySent.new user.to_public
|
||||||
else
|
else
|
||||||
Response::Error.new "unhandled request type"
|
Response::Error.new "unhandled request type"
|
||||||
end
|
end
|
||||||
|
@ -39,6 +39,7 @@ class AuthD::User
|
|||||||
# Private.
|
# Private.
|
||||||
property contact : Contact
|
property contact : Contact
|
||||||
property password_hash : String
|
property password_hash : String
|
||||||
|
property password_renew_key : String?
|
||||||
# service => resource => permission level
|
# service => resource => permission level
|
||||||
property permissions : Hash(String, Hash(String, PermissionLevel))
|
property permissions : Hash(String, Hash(String, PermissionLevel))
|
||||||
property configuration : Hash(String, Hash(String, JSON::Any))
|
property configuration : Hash(String, Hash(String, JSON::Any))
|
||||||
|
45
utils/authd-user-ask-for-new-password.cr
Normal file
45
utils/authd-user-ask-for-new-password.cr
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
require "option_parser"
|
||||||
|
|
||||||
|
require "../src/authd.cr"
|
||||||
|
|
||||||
|
key_file : String? = nil
|
||||||
|
cli_login : String? = nil
|
||||||
|
|
||||||
|
OptionParser.parse do |parser|
|
||||||
|
parser.unknown_args do |args|
|
||||||
|
if args.size != 1
|
||||||
|
puts "usage: #{PROGRAM_NAME} <login> [options]"
|
||||||
|
puts parser
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
|
||||||
|
cli_login = args[0]
|
||||||
|
end
|
||||||
|
|
||||||
|
parser.on "-K file", "--key-file file", "Read the authd shared key from a file." do |file|
|
||||||
|
key_file = file
|
||||||
|
end
|
||||||
|
|
||||||
|
parser.on "-h", "--help", "Prints this help message." do
|
||||||
|
puts "usage: #{PROGRAM_NAME} <login> [options]"
|
||||||
|
puts parser
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
authd = IPC::Connection.new "auth"
|
||||||
|
|
||||||
|
authd = AuthD::Client.new
|
||||||
|
authd.key = File.read(key_file.not_nil!).chomp
|
||||||
|
|
||||||
|
login = cli_login.not_nil!
|
||||||
|
|
||||||
|
# AskPasswordRecovery => PasswordRecoverySent
|
||||||
|
# PasswordRecovery =>
|
||||||
|
|
||||||
|
pp! authd.ask_password_recovery login
|
||||||
|
rescue e
|
||||||
|
puts "Error: #{e}"
|
||||||
|
exit 1
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user