Authd now handles authorization as well.
This commit is contained in:
parent
407cfc874a
commit
a6272b3873
32
src/main.cr
32
src/main.cr
@ -21,6 +21,12 @@ module DNSManager
|
|||||||
def initialize(@domain, @rr)
|
def initialize(@domain, @rr)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
class CannotCheckPermissionsException < ::Exception
|
||||||
|
property uid : UserDataID
|
||||||
|
property resource : String
|
||||||
|
def initialize(@uid, @resource)
|
||||||
|
end
|
||||||
|
end
|
||||||
class AuthorizationException < ::Exception
|
class AuthorizationException < ::Exception
|
||||||
end
|
end
|
||||||
class NoOwnershipException < ::Exception
|
class NoOwnershipException < ::Exception
|
||||||
@ -31,8 +37,6 @@ module DNSManager
|
|||||||
end
|
end
|
||||||
class TokenNotFoundException < ::Exception
|
class TokenNotFoundException < ::Exception
|
||||||
end
|
end
|
||||||
class AdminAuthorizationException < ::Exception
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -79,6 +83,24 @@ class DNSManager::Service < IPC
|
|||||||
@authd.decode_token token
|
@authd.decode_token token
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_permissions(uid : UInt32, resource : String) : AuthD::User::PermissionLevel
|
||||||
|
response = @authd.check_permission uid, "dnsmanager", resource
|
||||||
|
case response
|
||||||
|
when AuthD::Response::PermissionCheck
|
||||||
|
return response.permission
|
||||||
|
end
|
||||||
|
raise CannotCheckPermissionsException.new uid, resource
|
||||||
|
rescue e
|
||||||
|
Baguette::Log.error "error while checking permissions: #{e}"
|
||||||
|
raise CannotCheckPermissionsException.new uid, resource
|
||||||
|
end
|
||||||
|
|
||||||
|
def assert_permissions!(uid : UInt32, resource : String, perms : AuthD::User::PermissionLevel)
|
||||||
|
if check_permissions(uid, resource) < perms
|
||||||
|
raise AuthorizationException.new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def handle_request(event : IPC::Event)
|
def handle_request(event : IPC::Event)
|
||||||
request_start = Time.utc
|
request_start = Time.utc
|
||||||
|
|
||||||
@ -101,15 +123,15 @@ class DNSManager::Service < IPC
|
|||||||
rescue e : DomainNotFoundException
|
rescue e : DomainNotFoundException
|
||||||
Baguette::Log.error "(fd #{"%4d" % event.fd}) #{reqname} domain not found"
|
Baguette::Log.error "(fd #{"%4d" % event.fd}) #{reqname} domain not found"
|
||||||
Response::DomainNotFound.new
|
Response::DomainNotFound.new
|
||||||
|
rescue e : CannotCheckPermissionsException
|
||||||
|
Baguette::Log.error "(fd #{"%4d" % event.fd}) #{reqname} cannot check permissions of user '#{e.uid}' on resource '#{e.resource}'"
|
||||||
|
Response::InsufficientRights.new
|
||||||
rescue e : UnknownUserException
|
rescue e : UnknownUserException
|
||||||
Baguette::Log.error "(fd #{"%4d" % event.fd}) #{reqname} unknown user"
|
Baguette::Log.error "(fd #{"%4d" % event.fd}) #{reqname} unknown user"
|
||||||
Response::UnknownUser.new
|
Response::UnknownUser.new
|
||||||
rescue e : NoOwnershipException
|
rescue e : NoOwnershipException
|
||||||
Baguette::Log.error "(fd #{"%4d" % event.fd}) #{reqname} no ownership error"
|
Baguette::Log.error "(fd #{"%4d" % event.fd}) #{reqname} no ownership error"
|
||||||
Response::NoOwnership.new
|
Response::NoOwnership.new
|
||||||
rescue e : AdminAuthorizationException
|
|
||||||
Baguette::Log.error "(fd #{"%4d" % event.fd}) #{reqname} no admin authorization"
|
|
||||||
Response::Error.new "admin authorization error"
|
|
||||||
rescue e : NotLoggedException
|
rescue e : NotLoggedException
|
||||||
Baguette::Log.error "(fd #{"%4d" % event.fd}) #{reqname} user not logged"
|
Baguette::Log.error "(fd #{"%4d" % event.fd}) #{reqname} user not logged"
|
||||||
Response::Error.new "user not logged"
|
Response::Error.new "user not logged"
|
||||||
|
@ -7,7 +7,7 @@ class DNSManager::Request
|
|||||||
def handle(dnsmanagerd : DNSManager::Service, event : IPC::Event) : IPC::JSON
|
def handle(dnsmanagerd : DNSManager::Service, event : IPC::Event) : IPC::JSON
|
||||||
user = dnsmanagerd.get_logged_user event
|
user = dnsmanagerd.get_logged_user event
|
||||||
return Response::ErrorUserNotLogged.new unless user
|
return Response::ErrorUserNotLogged.new unless user
|
||||||
dnsmanagerd.storage.get_orphan_domains dnsmanagerd.authd, user.uid
|
dnsmanagerd.storage.get_orphan_domains dnsmanagerd, user.uid
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
DNSManager.requests << GetOrphanDomains
|
DNSManager.requests << GetOrphanDomains
|
||||||
|
@ -19,7 +19,8 @@ class DNSManager::Request
|
|||||||
|
|
||||||
accepted_domains = dnsmanagerd.configuration.accepted_domains.not_nil!
|
accepted_domains = dnsmanagerd.configuration.accepted_domains.not_nil!
|
||||||
user_domains = user_data.domains
|
user_domains = user_data.domains
|
||||||
Response::Logged.new accepted_domains, user_domains
|
perms = dnsmanagerd.check_permissions response.user.uid, "*"
|
||||||
|
Response::Logged.new (perms == AuthD::User::PermissionLevel::Admin), accepted_domains, user_domains
|
||||||
else
|
else
|
||||||
Response::ErrorInvalidToken.new
|
Response::ErrorInvalidToken.new
|
||||||
end
|
end
|
||||||
@ -41,7 +42,7 @@ class DNSManager::Request
|
|||||||
user = dnsmanagerd.get_logged_user event
|
user = dnsmanagerd.get_logged_user event
|
||||||
return Response::ErrorUserNotLogged.new unless user
|
return Response::ErrorUserNotLogged.new unless user
|
||||||
|
|
||||||
dnsmanagerd.storage.delete_user_data user.uid, user_id
|
dnsmanagerd.storage.delete_user_data dnsmanagerd, user.uid, user_id
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
DNSManager.requests << DeleteUser
|
DNSManager.requests << DeleteUser
|
||||||
|
@ -50,9 +50,10 @@ class DNSManager::Response
|
|||||||
DNSManager.responses << AcceptedDomains
|
DNSManager.responses << AcceptedDomains
|
||||||
|
|
||||||
IPC::JSON.message Logged, 16 do
|
IPC::JSON.message Logged, 16 do
|
||||||
|
property admin : Bool
|
||||||
property accepted_domains : Array(String)
|
property accepted_domains : Array(String)
|
||||||
property my_domains : Array(String)
|
property my_domains : Array(String)
|
||||||
def initialize(@accepted_domains, @my_domains)
|
def initialize(@admin, @accepted_domains, @my_domains)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
DNSManager.responses << Logged
|
DNSManager.responses << Logged
|
||||||
|
@ -261,14 +261,14 @@ class DNSManager::Storage
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Get all removed users from `authd`, list all their domains and remove their data from `dnsmanagerd`.
|
# Get all removed users from `authd`, list all their domains and remove their data from `dnsmanagerd`.
|
||||||
def get_orphan_domains(authd : AuthD::Client, user_id : UserDataID) : IPC::JSON
|
def get_orphan_domains(dnsmanagerd : DNSManager::Service, user_id : UserDataID) : IPC::JSON
|
||||||
user_must_be_admin! user_id
|
user_must_be_admin! dnsmanagerd, user_id
|
||||||
|
|
||||||
Baguette::Log.debug "list all orphan domains (long computation)"
|
Baguette::Log.debug "list all orphan domains (long computation)"
|
||||||
orphans = [] of String
|
orphans = [] of String
|
||||||
user_data.each do |user|
|
user_data.each do |user|
|
||||||
begin
|
begin
|
||||||
authd.get_user? user.uid
|
dnsmanagerd.authd.get_user? user.uid
|
||||||
rescue e
|
rescue e
|
||||||
Baguette::Log.warning "no authd info on user #{user.uid}: #{e} (removing this user)"
|
Baguette::Log.warning "no authd info on user #{user.uid}: #{e} (removing this user)"
|
||||||
Baguette::Log.debug "user #{user.uid} had #{user.domains.size} domains"
|
Baguette::Log.debug "user #{user.uid} had #{user.domains.size} domains"
|
||||||
@ -304,10 +304,10 @@ class DNSManager::Storage
|
|||||||
user_data_by_uid.delete user_data.uid.to_s
|
user_data_by_uid.delete user_data.uid.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_user_data(user_id : UserDataID, user_to_delete : UserDataID?) : IPC::JSON
|
def delete_user_data(dnsmanagerd : DNSManager::Service, user_id : UserDataID, user_to_delete : UserDataID?) : IPC::JSON
|
||||||
user_data = user_must_exist! user_id
|
user_data = user_must_exist! user_id
|
||||||
user_data_to_delete = if u = user_to_delete
|
user_data_to_delete = if u = user_to_delete
|
||||||
user_must_be_admin! user_id
|
user_must_be_admin! dnsmanagerd, user_id
|
||||||
Baguette::Log.info "Admin #{user_id} removes data of user #{u}."
|
Baguette::Log.info "Admin #{user_id} removes data of user #{u}."
|
||||||
user_must_exist! u
|
user_must_exist! u
|
||||||
else
|
else
|
||||||
@ -331,9 +331,9 @@ class DNSManager::Storage
|
|||||||
user_data
|
user_data
|
||||||
end
|
end
|
||||||
|
|
||||||
def user_must_be_admin!(user_id : UserDataID) : UserData
|
def user_must_be_admin!(dnsmanagerd : DNSManager::Service, user_id : UserDataID) : UserData
|
||||||
user_data = user_must_exist! user_id
|
user_data = user_must_exist! user_id
|
||||||
raise AdminAuthorizationException.new unless user_data.admin
|
dnsmanagerd.assert_permissions! user_id, "*", AuthD::User::PermissionLevel::Admin
|
||||||
user_data
|
user_data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user