Authd now handles authorization as well.
parent
407cfc874a
commit
a6272b3873
32
src/main.cr
32
src/main.cr
|
@ -21,6 +21,12 @@ module DNSManager
|
|||
def initialize(@domain, @rr)
|
||||
end
|
||||
end
|
||||
class CannotCheckPermissionsException < ::Exception
|
||||
property uid : UserDataID
|
||||
property resource : String
|
||||
def initialize(@uid, @resource)
|
||||
end
|
||||
end
|
||||
class AuthorizationException < ::Exception
|
||||
end
|
||||
class NoOwnershipException < ::Exception
|
||||
|
@ -31,8 +37,6 @@ module DNSManager
|
|||
end
|
||||
class TokenNotFoundException < ::Exception
|
||||
end
|
||||
class AdminAuthorizationException < ::Exception
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
@ -79,6 +83,24 @@ class DNSManager::Service < IPC
|
|||
@authd.decode_token token
|
||||
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)
|
||||
request_start = Time.utc
|
||||
|
||||
|
@ -101,15 +123,15 @@ class DNSManager::Service < IPC
|
|||
rescue e : DomainNotFoundException
|
||||
Baguette::Log.error "(fd #{"%4d" % event.fd}) #{reqname} domain not found"
|
||||
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
|
||||
Baguette::Log.error "(fd #{"%4d" % event.fd}) #{reqname} unknown user"
|
||||
Response::UnknownUser.new
|
||||
rescue e : NoOwnershipException
|
||||
Baguette::Log.error "(fd #{"%4d" % event.fd}) #{reqname} no ownership error"
|
||||
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
|
||||
Baguette::Log.error "(fd #{"%4d" % event.fd}) #{reqname} 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
|
||||
user = dnsmanagerd.get_logged_user event
|
||||
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
|
||||
DNSManager.requests << GetOrphanDomains
|
||||
|
|
|
@ -19,7 +19,8 @@ class DNSManager::Request
|
|||
|
||||
accepted_domains = dnsmanagerd.configuration.accepted_domains.not_nil!
|
||||
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
|
||||
Response::ErrorInvalidToken.new
|
||||
end
|
||||
|
@ -41,7 +42,7 @@ class DNSManager::Request
|
|||
user = dnsmanagerd.get_logged_user event
|
||||
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
|
||||
DNSManager.requests << DeleteUser
|
||||
|
|
|
@ -50,9 +50,10 @@ class DNSManager::Response
|
|||
DNSManager.responses << AcceptedDomains
|
||||
|
||||
IPC::JSON.message Logged, 16 do
|
||||
property admin : Bool
|
||||
property accepted_domains : Array(String)
|
||||
property my_domains : Array(String)
|
||||
def initialize(@accepted_domains, @my_domains)
|
||||
def initialize(@admin, @accepted_domains, @my_domains)
|
||||
end
|
||||
end
|
||||
DNSManager.responses << Logged
|
||||
|
|
|
@ -261,14 +261,14 @@ class DNSManager::Storage
|
|||
end
|
||||
|
||||
# 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
|
||||
user_must_be_admin! user_id
|
||||
def get_orphan_domains(dnsmanagerd : DNSManager::Service, user_id : UserDataID) : IPC::JSON
|
||||
user_must_be_admin! dnsmanagerd, user_id
|
||||
|
||||
Baguette::Log.debug "list all orphan domains (long computation)"
|
||||
orphans = [] of String
|
||||
user_data.each do |user|
|
||||
begin
|
||||
authd.get_user? user.uid
|
||||
dnsmanagerd.authd.get_user? user.uid
|
||||
rescue e
|
||||
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"
|
||||
|
@ -304,10 +304,10 @@ class DNSManager::Storage
|
|||
user_data_by_uid.delete user_data.uid.to_s
|
||||
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_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}."
|
||||
user_must_exist! u
|
||||
else
|
||||
|
@ -331,9 +331,9 @@ class DNSManager::Storage
|
|||
user_data
|
||||
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
|
||||
raise AdminAuthorizationException.new unless user_data.admin
|
||||
dnsmanagerd.assert_permissions! user_id, "*", AuthD::User::PermissionLevel::Admin
|
||||
user_data
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue