Migration: draft.
parent
4ac27e2db1
commit
111adae98f
3
makefile
3
makefile
|
@ -49,6 +49,9 @@ validate:
|
|||
get-user:
|
||||
./bin/authc user get $(NAME) $(LOGIN_OPT)
|
||||
|
||||
migrate-user:
|
||||
./bin/authc user migrate $(NAME) $(PASSWORD_HASH) $(LOGIN_OPT)
|
||||
|
||||
SERVICE ?= 'auth'
|
||||
RESOURCE ?= '*'
|
||||
UID ?= 1000
|
||||
|
|
|
@ -70,6 +70,17 @@ module AuthD
|
|||
], read
|
||||
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,
|
||||
password : String,
|
||||
email : String,
|
||||
|
|
|
@ -38,6 +38,7 @@ class AuthD::User
|
|||
|
||||
# Private.
|
||||
property contact : Contact
|
||||
property password_hash_brkn : String? = nil # Old, broken algorithm.
|
||||
property password_hash : String
|
||||
property password_renew_key : String?
|
||||
# service => resource => permission level
|
||||
|
|
|
@ -93,6 +93,17 @@ parser = OptionParser.new do |parser|
|
|||
unrecognized_args_to_context_args.call parser, 2
|
||||
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.banner = "Usage: user mod userid [-e email|-P profile] [opt]"
|
||||
Baguette::Log.info "Modify a user account."
|
||||
|
|
|
@ -62,6 +62,7 @@ class Actions
|
|||
|
||||
# Require admin privileges.
|
||||
@the_call["user-add"] = ->user_add
|
||||
@the_call["user-migrate"] = ->user_migrate
|
||||
@the_call["user-mod"] = ->user_mod
|
||||
|
||||
@the_call["permission-set"] = ->permission_set
|
||||
|
@ -87,6 +88,17 @@ class Actions
|
|||
puts "error: #{e.message}"
|
||||
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
|
||||
args = Context.args.not_nil!
|
||||
login, email = args[0..1]
|
||||
|
@ -143,7 +155,6 @@ class Actions
|
|||
puts "error: #{e.message}"
|
||||
end
|
||||
|
||||
|
||||
# TODO
|
||||
def user_mod
|
||||
args = Context.args.not_nil!
|
||||
|
|
|
@ -40,6 +40,25 @@ class AuthD::Request
|
|||
return Response::ErrorInvalidCredentials.new
|
||||
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
|
||||
hash = Base64.decode user.password_hash
|
||||
|
||||
|
|
|
@ -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