Migration: draft.
This commit is contained in:
parent
4ac27e2db1
commit
111adae98f
3
makefile
3
makefile
@ -49,6 +49,9 @@ validate:
|
|||||||
get-user:
|
get-user:
|
||||||
./bin/authc user get $(NAME) $(LOGIN_OPT)
|
./bin/authc user get $(NAME) $(LOGIN_OPT)
|
||||||
|
|
||||||
|
migrate-user:
|
||||||
|
./bin/authc user migrate $(NAME) $(PASSWORD_HASH) $(LOGIN_OPT)
|
||||||
|
|
||||||
SERVICE ?= 'auth'
|
SERVICE ?= 'auth'
|
||||||
RESOURCE ?= '*'
|
RESOURCE ?= '*'
|
||||||
UID ?= 1000
|
UID ?= 1000
|
||||||
|
@ -70,6 +70,17 @@ module AuthD
|
|||||||
], read
|
], read
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Migration of a user from old code base (dnsmanager v1).
|
||||||
|
def migrate_user(login : String, password_hash_brkn : String)
|
||||||
|
send_now Request::MigrateUser.new login, password_hash_brkn
|
||||||
|
parse_message [
|
||||||
|
Response::UserAdded,
|
||||||
|
Response::ErrorMustBeAuthenticated,
|
||||||
|
Response::ErrorAlreadyUsedLogin,
|
||||||
|
Response::ErrorMailRequired
|
||||||
|
], read
|
||||||
|
end
|
||||||
|
|
||||||
def bootstrap(login : String,
|
def bootstrap(login : String,
|
||||||
password : String,
|
password : String,
|
||||||
email : String,
|
email : String,
|
||||||
|
@ -38,6 +38,7 @@ class AuthD::User
|
|||||||
|
|
||||||
# Private.
|
# Private.
|
||||||
property contact : Contact
|
property contact : Contact
|
||||||
|
property password_hash_brkn : String? = nil # Old, broken algorithm.
|
||||||
property password_hash : String
|
property password_hash : String
|
||||||
property password_renew_key : String?
|
property password_renew_key : String?
|
||||||
# service => resource => permission level
|
# service => resource => permission level
|
||||||
|
@ -93,6 +93,17 @@ parser = OptionParser.new do |parser|
|
|||||||
unrecognized_args_to_context_args.call parser, 2
|
unrecognized_args_to_context_args.call parser, 2
|
||||||
end
|
end
|
||||||
|
|
||||||
|
parser.on "migrate", "Adding a user from old code base." do
|
||||||
|
parser.banner = "usage: user add login password-hash-brkn"
|
||||||
|
Baguette::Log.info "Adding a user to the DB."
|
||||||
|
Context.command = "user-migrate"
|
||||||
|
opt_authd_login.call parser
|
||||||
|
opt_profile.call parser
|
||||||
|
opt_help.call parser
|
||||||
|
# login password-hash-brkn
|
||||||
|
unrecognized_args_to_context_args.call parser, 2
|
||||||
|
end
|
||||||
|
|
||||||
parser.on "mod", "Modify a user account." do
|
parser.on "mod", "Modify a user account." do
|
||||||
parser.banner = "Usage: user mod userid [-e email|-P profile] [opt]"
|
parser.banner = "Usage: user mod userid [-e email|-P profile] [opt]"
|
||||||
Baguette::Log.info "Modify a user account."
|
Baguette::Log.info "Modify a user account."
|
||||||
|
@ -62,6 +62,7 @@ class Actions
|
|||||||
|
|
||||||
# Require admin privileges.
|
# Require admin privileges.
|
||||||
@the_call["user-add"] = ->user_add
|
@the_call["user-add"] = ->user_add
|
||||||
|
@the_call["user-migrate"] = ->user_migrate
|
||||||
@the_call["user-mod"] = ->user_mod
|
@the_call["user-mod"] = ->user_mod
|
||||||
|
|
||||||
@the_call["permission-set"] = ->permission_set
|
@the_call["permission-set"] = ->permission_set
|
||||||
@ -87,6 +88,17 @@ class Actions
|
|||||||
puts "error: #{e.message}"
|
puts "error: #{e.message}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Migrate a user from old code base (dnsmanager v1).
|
||||||
|
def user_migrate
|
||||||
|
args = Context.args.not_nil!
|
||||||
|
login, password_hash_brkn = args[0..1]
|
||||||
|
profile = Context.user_profile
|
||||||
|
|
||||||
|
pp! authd.migrate_user login, password_hash_brkn
|
||||||
|
rescue e : AuthD::Exception
|
||||||
|
puts "error: #{e.message}"
|
||||||
|
end
|
||||||
|
|
||||||
def user_registration
|
def user_registration
|
||||||
args = Context.args.not_nil!
|
args = Context.args.not_nil!
|
||||||
login, email = args[0..1]
|
login, email = args[0..1]
|
||||||
@ -143,7 +155,6 @@ class Actions
|
|||||||
puts "error: #{e.message}"
|
puts "error: #{e.message}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
def user_mod
|
def user_mod
|
||||||
args = Context.args.not_nil!
|
args = Context.args.not_nil!
|
||||||
|
@ -40,6 +40,25 @@ class AuthD::Request
|
|||||||
return Response::ErrorInvalidCredentials.new
|
return Response::ErrorInvalidCredentials.new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# MIGRATION
|
||||||
|
# The migration involves old (broken) hash algorithm.
|
||||||
|
# On first connection, the user is authenticated with the old algorithm then a new hash is generated.
|
||||||
|
if brkn_hash = user.password_hash_brkn
|
||||||
|
# Authenticates the user with its old password hash algo.
|
||||||
|
if brkn_hash != authd.obsolete_hash_password @password
|
||||||
|
Baguette::Log.error "cannot authenticate the user with his old password hash"
|
||||||
|
return Response::ErrorInvalidCredentials.new
|
||||||
|
end
|
||||||
|
|
||||||
|
# FYI: there is no need to clone the user since there are no indexes on passwords.
|
||||||
|
user.password_hash = authd.hash_password @password # Adding new password hash.
|
||||||
|
user.password_hash_brkn = nil # Removing old password hash.
|
||||||
|
Baguette::Log.info "updating password hash for #{user.login} to newer algorithm"
|
||||||
|
authd.users_per_login.update user
|
||||||
|
|
||||||
|
return AuthD::Request.perform_login authd, fd, user.not_nil!
|
||||||
|
end
|
||||||
|
|
||||||
pwhash = Sodium::Password::Hash.new
|
pwhash = Sodium::Password::Hash.new
|
||||||
hash = Base64.decode user.password_hash
|
hash = Base64.decode user.password_hash
|
||||||
|
|
||||||
|
46
src/requests/migration.cr
Normal file
46
src/requests/migration.cr
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
class AuthD::Request
|
||||||
|
# Migration involves users with a broken password hash algorithm.
|
||||||
|
IPC::JSON.message MigrateUser, 16 do
|
||||||
|
property login : String
|
||||||
|
property password_hash_brkn : String # Old, broken algorithm. Will be changed on first authentication.
|
||||||
|
property admin : Bool = false
|
||||||
|
property email : String? = nil
|
||||||
|
property profile : Hash(String, JSON::Any)? = nil
|
||||||
|
|
||||||
|
def initialize(@login, @password_hash_brkn, @admin = false, @email = nil, @profile = nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle(authd : AuthD::Service, fd : Int32)
|
||||||
|
logged_user = authd.get_logged_user_full? fd
|
||||||
|
return Response::ErrorMustBeAuthenticated.new if logged_user.nil?
|
||||||
|
|
||||||
|
logged_user.assert_permission("authd", "*", User::PermissionLevel::Admin)
|
||||||
|
|
||||||
|
if authd.users_per_login.get? @login
|
||||||
|
return Response::ErrorAlreadyUsedLogin.new
|
||||||
|
end
|
||||||
|
|
||||||
|
# No mail verification since there were no mail stored in dnsmanager v1.
|
||||||
|
|
||||||
|
uid = authd.new_uid
|
||||||
|
|
||||||
|
user = User.new uid, @login, "" # Current password is voluntarily not set.
|
||||||
|
|
||||||
|
user.password_hash_brkn = @password_hash_brkn
|
||||||
|
user.contact.email = @email unless @email.nil?
|
||||||
|
user.admin = @admin
|
||||||
|
|
||||||
|
@profile.try do |profile|
|
||||||
|
user.profile = profile
|
||||||
|
end
|
||||||
|
|
||||||
|
# We consider adding the user as a registration.
|
||||||
|
user.date_registration = Time.local
|
||||||
|
|
||||||
|
authd.users << user
|
||||||
|
authd.new_uid_commit uid
|
||||||
|
Response::UserAdded.new user.to_public
|
||||||
|
end
|
||||||
|
end
|
||||||
|
AuthD.requests << MigrateUser
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user