Refactoring in progress. Still a few classes to go.
parent
7958e7812e
commit
2786e2f7ff
|
@ -10,6 +10,9 @@ require "ipc"
|
|||
|
||||
require "baguette-crystal-base"
|
||||
|
||||
# In any message, a user can be referred by its Int32 uid or its login.
|
||||
alias UserID = Int32 | String
|
||||
|
||||
# Allows get configuration from a provided file.
|
||||
# See Baguette::Configuration::Base.get
|
||||
class Baguette::Configuration
|
||||
|
|
|
@ -158,13 +158,12 @@ module AuthD
|
|||
end
|
||||
end
|
||||
|
||||
def mod_user(uid_or_login : Int32 | String, password : String? = nil, email : String? = nil, phone : String? = nil, avatar : String? = nil) : Bool | Exception
|
||||
def mod_user(uid_or_login : Int32 | String, password : String? = nil, email : String? = nil, phone : String? = nil) : Bool | Exception
|
||||
request = Request::ModUser.new uid_or_login
|
||||
|
||||
request.password = password if password
|
||||
request.email = email if email
|
||||
request.phone = phone if phone
|
||||
request.avatar = avatar if avatar
|
||||
|
||||
send_now request
|
||||
|
||||
|
|
|
@ -71,5 +71,22 @@ class AuthD::User
|
|||
def to_public : Public
|
||||
Public.new @uid, @login, @admin, @profile, @date_registration
|
||||
end
|
||||
end
|
||||
|
||||
def assert_permission(service : String, resource : String, level : User::PermissionLevel)
|
||||
return if @admin # skip if admin
|
||||
|
||||
permissions = @permissions[service]?
|
||||
unless permissions
|
||||
raise AdminAuthorizationException.new "unauthorized (not admin nor in #{service} group)"
|
||||
end
|
||||
|
||||
rights = permissions[resource]?
|
||||
unless rights
|
||||
raise AdminAuthorizationException.new "unauthorized (no rights on '#{service}/#{resource}')"
|
||||
end
|
||||
|
||||
if rights < level
|
||||
raise AdminAuthorizationException.new "unauthorized (insufficient rights on '#{service}/#{resource}')"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -49,28 +49,24 @@ class AuthD::Request
|
|||
end
|
||||
AuthD.requests << AddUser
|
||||
|
||||
|
||||
IPC::JSON.message ModUser, 5 do
|
||||
property user : Int32 | String
|
||||
property user : UserID
|
||||
property admin : Bool = false
|
||||
property password : String? = nil
|
||||
property email : String? = nil
|
||||
property phone : String? = nil
|
||||
property avatar : String? = nil
|
||||
|
||||
def initialize(@user, @admin, @password, @email, @phone, @avatar)
|
||||
def initialize(@user, @admin, @password, @email, @phone)
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
logged_user = authd.get_logged_user? fd
|
||||
|
||||
return Response::Error.new "you must be logged" if logged_user.nil?
|
||||
|
||||
user = authd.user? @user
|
||||
|
||||
return Response::Error.new "user not found" if user.nil?
|
||||
|
||||
# Only an admin can create an admin.
|
||||
# Only an admin can uprank someone.
|
||||
if @admin
|
||||
return Response::Error.new "unauthorized (not admin)" unless logged_user.admin
|
||||
end
|
||||
|
|
|
@ -1,32 +1,28 @@
|
|||
class AuthD::Request
|
||||
IPC::JSON.message Delete, 17 do
|
||||
# Deletion can be triggered by either an admin or the related user.
|
||||
property user : String | Int32
|
||||
property user : UserID
|
||||
|
||||
def initialize(@user)
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
user_to_delete = authd.user? @user
|
||||
return Response::Error.new "invalid user" if user_to_delete.nil?
|
||||
|
||||
# Get currently logged user.
|
||||
logged_user = authd.get_logged_user? fd
|
||||
if logged_user.nil?
|
||||
return Response::Error.new "you must be logged"
|
||||
end
|
||||
return Response::Error.new "you must be logged" if logged_user.nil?
|
||||
|
||||
# Get the full AuthD::User instance, not just the public view.
|
||||
user_to_delete = authd.user? logged_user.uid
|
||||
return Response::Error.new "unknown user" if user_to_delete.nil?
|
||||
|
||||
unless logged_user.admin
|
||||
# Is the logged user the target?
|
||||
if logged_user.uid != user_to_delete.uid
|
||||
return Response::Error.new "invalid credentials"
|
||||
end
|
||||
return Response::Error.new "invalid credentials" if logged_user.uid != user_to_delete.uid
|
||||
end
|
||||
|
||||
# User or admin is now verified: let's proceed with the user deletion.
|
||||
authd.users_per_login.delete user_to_delete.login
|
||||
|
||||
# TODO: if the current user is deleted, unlog!
|
||||
# If the current user is deleted, unlog!
|
||||
if logged_user.uid == user_to_delete.uid
|
||||
authd.close fd
|
||||
authd.logged_users.delete fd
|
||||
|
|
|
@ -1,38 +1,17 @@
|
|||
class AuthD::Request
|
||||
IPC::JSON.message ListUsers, 8 do
|
||||
property token : String? = nil
|
||||
property key : String? = nil
|
||||
|
||||
def initialize(@token, @key)
|
||||
def initialize()
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
# FIXME: Lines too long, repeatedly (>80c with 4c tabs).
|
||||
@token.try do |token|
|
||||
user = authd.get_user_from_token token
|
||||
logged_user = authd.get_logged_user? fd
|
||||
return Response::Error.new "you must be logged" if logged_user.nil?
|
||||
|
||||
return Response::Error.new "unauthorized (user not found from token)" unless user
|
||||
user = authd.user? logged_user.uid
|
||||
return Response::Error.new "user not found" if user.nil?
|
||||
|
||||
# Test if the user is a moderator.
|
||||
if permissions = user.permissions["authd"]?
|
||||
if rights = permissions["*"]?
|
||||
if rights >= User::PermissionLevel::Read
|
||||
else
|
||||
raise AdminAuthorizationException.new "unauthorized (insufficient rights on '*')"
|
||||
end
|
||||
else
|
||||
raise AdminAuthorizationException.new "unauthorized (no rights on '*')"
|
||||
end
|
||||
else
|
||||
raise AdminAuthorizationException.new "unauthorized (user not in authd group)"
|
||||
end
|
||||
end
|
||||
|
||||
@key.try do |key|
|
||||
return Response::Error.new "unauthorized (wrong shared key)" unless key == authd.configuration.shared_key
|
||||
end
|
||||
|
||||
return Response::Error.new "unauthorized (no key nor token)" unless @key || @token
|
||||
# Test if the user is a moderator.
|
||||
user.assert_permission("authd", "*", User::PermissionLevel::Read)
|
||||
|
||||
Response::UsersList.new authd.users.to_h.map &.[1].to_public
|
||||
end
|
||||
|
|
|
@ -13,9 +13,7 @@ class AuthD::Request
|
|||
return Response::Error.new "invalid credentials"
|
||||
end
|
||||
|
||||
if user.nil?
|
||||
return Response::Error.new "invalid credentials"
|
||||
end
|
||||
return Response::Error.new "invalid credentials" if user.nil?
|
||||
|
||||
if user.password_hash != authd.hash_password @password
|
||||
return Response::Error.new "invalid credentials"
|
||||
|
|
|
@ -1,22 +1,16 @@
|
|||
class AuthD::Request
|
||||
IPC::JSON.message UpdatePassword, 7 do
|
||||
property login : String
|
||||
property old_password : String
|
||||
property new_password : String
|
||||
|
||||
def initialize(@login, @old_password, @new_password)
|
||||
def initialize(@new_password)
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
user = authd.users_per_login.get? @login
|
||||
logged_user = authd.get_logged_user? fd
|
||||
return Response::Error.new "you must be logged" if logged_user.nil?
|
||||
|
||||
unless user
|
||||
return Response::Error.new "invalid credentials"
|
||||
end
|
||||
|
||||
if authd.hash_password(@old_password) != user.password_hash
|
||||
return Response::Error.new "invalid credentials"
|
||||
end
|
||||
user = authd.user? logged_user.uid
|
||||
return Response::Error.new "user not found" if user.nil?
|
||||
|
||||
user.password_hash = authd.hash_password @new_password
|
||||
|
||||
|
@ -28,7 +22,7 @@ class AuthD::Request
|
|||
AuthD.requests << UpdatePassword
|
||||
|
||||
IPC::JSON.message PasswordRecovery, 11 do
|
||||
property user : Int32 | String
|
||||
property user : UserID
|
||||
property password_renew_key : String
|
||||
property new_password : String
|
||||
|
||||
|
@ -36,16 +30,8 @@ class AuthD::Request
|
|||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
uid_or_login = @user
|
||||
user = if uid_or_login.is_a? Int32
|
||||
authd.users_per_uid.get? uid_or_login.to_s
|
||||
else
|
||||
authd.users_per_login.get? uid_or_login
|
||||
end
|
||||
|
||||
if user.nil?
|
||||
return Response::Error.new "user not found"
|
||||
end
|
||||
user = authd.user? @user
|
||||
return Response::Error.new "user not found" if user.nil?
|
||||
|
||||
if user.password_renew_key == @password_renew_key
|
||||
user.password_hash = authd.hash_password @new_password
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class AuthD::Request
|
||||
IPC::JSON.message CheckPermission, 9 do
|
||||
property user : Int32 | String
|
||||
property user : UserID
|
||||
property service : String
|
||||
property resource : String
|
||||
|
||||
|
@ -13,16 +13,8 @@ class AuthD::Request
|
|||
return Response::Error.new "you must be logged" if logged_user.nil?
|
||||
return Response::Error.new "unauthorized (not admin)" unless logged_user.admin
|
||||
|
||||
user = case u = @user
|
||||
when .is_a? Int32
|
||||
authd.users_per_uid.get? u.to_s
|
||||
else
|
||||
authd.users_per_login.get? u
|
||||
end
|
||||
|
||||
if user.nil?
|
||||
return Response::Error.new "no such user"
|
||||
end
|
||||
user = authd.user? @user
|
||||
return Response::Error.new "no such user" if user.nil?
|
||||
|
||||
service = @service
|
||||
service_permissions = user.permissions[service]?
|
||||
|
@ -43,7 +35,7 @@ class AuthD::Request
|
|||
AuthD.requests << CheckPermission
|
||||
|
||||
IPC::JSON.message SetPermission, 10 do
|
||||
property user : Int32 | String
|
||||
property user : UserID
|
||||
property service : String
|
||||
property resource : String
|
||||
property permission : ::AuthD::User::PermissionLevel
|
||||
|
@ -57,8 +49,7 @@ class AuthD::Request
|
|||
return Response::Error.new "you must be logged" if logged_user.nil?
|
||||
return Response::Error.new "unauthorized (not admin)" unless logged_user.admin
|
||||
|
||||
user = authd.users_per_uid.get? @user.to_s
|
||||
|
||||
user = authd.user? @user
|
||||
return Response::Error.new "no such user" if user.nil?
|
||||
|
||||
service = @service
|
||||
|
|
|
@ -83,7 +83,7 @@ class AuthD::Service < IPC
|
|||
@logged_users[fd]?
|
||||
end
|
||||
|
||||
def user?(uid_or_login : Int32 | String)
|
||||
def user?(uid_or_login : UserID)
|
||||
if uid_or_login.is_a? Int32
|
||||
@users_per_uid.get? uid_or_login.to_s
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue