Complete overhaul of ownership management: add a domain db, remove user data db.
This commit is contained in:
parent
61bace491c
commit
40fcc9c66e
@ -53,7 +53,7 @@ class DNSManager::Service < IPC
|
|||||||
|
|
||||||
def initialize(@configuration)
|
def initialize(@configuration)
|
||||||
super()
|
super()
|
||||||
@storage = DNSManager::Storage.new self, @configuration.storage_directory, @configuration.recreate_indexes
|
@storage = DNSManager::Storage.new @configuration.storage_directory, @configuration.recreate_indexes
|
||||||
|
|
||||||
@logged_users = Hash(Int32, AuthD::User::Public).new
|
@logged_users = Hash(Int32, AuthD::User::Public).new
|
||||||
|
|
||||||
@ -71,6 +71,7 @@ class DNSManager::Service < IPC
|
|||||||
raise "Cannot authenticate to authd with login #{@configuration.login}: #{response}."
|
raise "Cannot authenticate to authd with login #{@configuration.login}: #{response}."
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@storage.dnsmanagerd = self
|
||||||
self.timer @configuration.ipc_timer
|
self.timer @configuration.ipc_timer
|
||||||
self.service_init @configuration.service_name
|
self.service_init @configuration.service_name
|
||||||
end
|
end
|
||||||
|
@ -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, user.uid
|
dnsmanagerd.storage.get_orphan_domains user.uid
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
DNSManager.requests << GetOrphanDomains
|
DNSManager.requests << GetOrphanDomains
|
||||||
@ -59,8 +59,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
|
||||||
|
|
||||||
udata = dnsmanagerd.storage.get_user_data user
|
dnsmanagerd.storage.user_must_be_admin! user.uid
|
||||||
return Response::InsufficientRights.new unless udata.admin
|
|
||||||
dnsmanagerd.storage.generate_all_zonefiles
|
dnsmanagerd.storage.generate_all_zonefiles
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -77,10 +76,8 @@ 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
|
||||||
|
|
||||||
# TODO: verify user must be admin.
|
dnsmanagerd.storage.user_must_be_admin! user.uid
|
||||||
#udata = dnsmanagerd.storage.get_user_data user
|
dnsmanagerd.storage.generate_zonefile @domain
|
||||||
#return Response::InsufficientRights.new unless udata.admin
|
|
||||||
#dnsmanagerd.storage.generate_zonefile @domain
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
DNSManager.requests << GenerateZoneFile
|
DNSManager.requests << GenerateZoneFile
|
||||||
|
@ -14,12 +14,12 @@ class DNSManager::Request
|
|||||||
#dnsmanagerd.auth.edit_profile_content user.uid, {
|
#dnsmanagerd.auth.edit_profile_content user.uid, {
|
||||||
# "dnsmanager-last-connection" => JSON::Any.new Time.utc.to_s
|
# "dnsmanager-last-connection" => JSON::Any.new Time.utc.to_s
|
||||||
#}
|
#}
|
||||||
user_data = dnsmanagerd.storage.ensure_user_data response.user.uid
|
user_id = response.user.uid
|
||||||
return Response::Error.new "invalid user" unless user_data
|
dnsmanagerd.storage.user_must_exist! user_id
|
||||||
|
|
||||||
accepted_domains = dnsmanagerd.configuration.accepted_domains.not_nil!
|
accepted_domains = dnsmanagerd.configuration.accepted_domains.not_nil!
|
||||||
user_domains = user_data.domains
|
user_domains = dnsmanagerd.storage.user_domains user_id
|
||||||
perms = dnsmanagerd.check_permissions response.user.uid, "*"
|
perms = dnsmanagerd.check_permissions user_id, "*"
|
||||||
Response::Logged.new (perms == AuthD::User::PermissionLevel::Admin), accepted_domains, user_domains
|
Response::Logged.new (perms == AuthD::User::PermissionLevel::Admin), accepted_domains, user_domains
|
||||||
else
|
else
|
||||||
Response::ErrorInvalidToken.new
|
Response::ErrorInvalidToken.new
|
||||||
@ -42,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 dnsmanagerd, user.uid, user_id
|
dnsmanagerd.storage.delete_user_data user.uid, user_id
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
DNSManager.requests << DeleteUser
|
DNSManager.requests << DeleteUser
|
||||||
|
@ -69,7 +69,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.user_domains user.uid
|
Response::DomainList.new dnsmanagerd.storage.user_domains user.uid
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
DNSManager.requests << UserDomains
|
DNSManager.requests << UserDomains
|
||||||
|
@ -24,9 +24,15 @@ class DNSManager::Storage
|
|||||||
getter root : String
|
getter root : String
|
||||||
getter zonefiledir : String
|
getter zonefiledir : String
|
||||||
|
|
||||||
getter dnsmanagerd : DNSManager::Service
|
property dnsmanagerd : DNSManager::Service? = nil
|
||||||
|
|
||||||
def initialize(@dnsmanagerd, @root : String, reindex : Bool = false)
|
def dnsmanagerd() : DNSManager::Service
|
||||||
|
@dnsmanagerd.not_nil!
|
||||||
|
rescue
|
||||||
|
raise Exception.new "dnsmanagerd not defined"
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(@root : String, reindex : Bool = false)
|
||||||
@domains = DODB::CachedDataBase(Domain).new "#{@root}/domains"
|
@domains = DODB::CachedDataBase(Domain).new "#{@root}/domains"
|
||||||
@domains_by_name = @domains.new_index "name", &.name
|
@domains_by_name = @domains.new_index "name", &.name
|
||||||
@domains_by_share_key = @domains.new_nilable_index "share-key", do |d|
|
@domains_by_share_key = @domains.new_nilable_index "share-key", do |d|
|
||||||
@ -139,7 +145,7 @@ class DNSManager::Storage
|
|||||||
#
|
#
|
||||||
|
|
||||||
# Add the new domain.
|
# Add the new domain.
|
||||||
@domains << DomainInfo.new domain, owners: [user_id]
|
@domains << Domain.new domain, owners: [user_id]
|
||||||
|
|
||||||
# Add the new zone in the database.
|
# Add the new zone in the database.
|
||||||
zones_by_domain.update_or_create domain, default_zone
|
zones_by_domain.update_or_create domain, default_zone
|
||||||
@ -161,7 +167,7 @@ class DNSManager::Storage
|
|||||||
user_should_own! user_id, z.domain
|
user_should_own! user_id, z.domain
|
||||||
else
|
else
|
||||||
# Add the domain to the user's domain.
|
# Add the domain to the user's domain.
|
||||||
domains << DomainInfo.new zone.domain
|
domains << Domain.new zone.domain
|
||||||
end
|
end
|
||||||
|
|
||||||
# Add -or replace- the zone.
|
# Add -or replace- the zone.
|
||||||
@ -256,73 +262,80 @@ class DNSManager::Storage
|
|||||||
def get_orphan_domains(user_id : UserDataID) : IPC::JSON
|
def get_orphan_domains(user_id : UserDataID) : IPC::JSON
|
||||||
user_must_be_admin! user_id
|
user_must_be_admin! 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
|
||||||
@dnsmanagerd.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"
|
||||||
user.domains.each do |domain|
|
# user.domains.each do |domain|
|
||||||
orphans << domain
|
# orphans << domain
|
||||||
end
|
# end
|
||||||
wipe_user_data user
|
# wipe_user_data user
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
Baguette::Log.debug "total: #{orphans.size} orphans"
|
# Baguette::Log.debug "total: #{orphans.size} orphans"
|
||||||
|
#
|
||||||
Response::OrphanDomainList.new orphans
|
# Response::OrphanDomainList.new orphans
|
||||||
|
Response::Error.new "Not implemented."
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_zone(user_id : UserDataID, domain : String) : IPC::JSON
|
def get_zone(user_id : UserDataID, domain : String) : IPC::JSON
|
||||||
user_data = user_must_exist! user_id
|
user_must_exist! user_id
|
||||||
zone = zone_must_exist! domain
|
zone = zone_must_exist! domain
|
||||||
user_should_own! user_id, domain
|
user_should_own! user_id, domain
|
||||||
|
|
||||||
Response::Zone.new zone
|
Response::Zone.new zone
|
||||||
end
|
end
|
||||||
|
|
||||||
def wipe_user_data(user_data : UserData)
|
def wipe_user_data(user_id : UserDataID)
|
||||||
domains_by_owners.get(user_id.to_s).each do |d|
|
domains_by_owners.get(user_id.to_s).each do |domain|
|
||||||
|
domain.owners.delete user_id
|
||||||
|
|
||||||
|
# Remove the user's domain when he is the only owner.
|
||||||
|
if domain.owners.empty?
|
||||||
|
@domains_by_name.delete domain.name
|
||||||
|
@tokens_by_domain.delete domain.name
|
||||||
|
@zones_by_domain.delete domain.name
|
||||||
|
else
|
||||||
|
@domains_by_name.update_or_create domain.name, domain
|
||||||
|
end
|
||||||
end
|
end
|
||||||
# Remove the user's domains.
|
|
||||||
user_data.domains.each do |domain|
|
|
||||||
tokens_by_domain.delete domain
|
|
||||||
zones_by_domain.delete domain
|
|
||||||
rescue e
|
rescue e
|
||||||
Baguette::Log.error "while removing a domain: #{e}"
|
Baguette::Log.error "while removing a domain: #{e}"
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def delete_user_data(user_id : UserDataID, user_to_delete : UserDataID?) : IPC::JSON
|
def delete_user_data(user_id : UserDataID, user_to_delete : UserDataID?) : IPC::JSON
|
||||||
user_data = user_must_exist! user_id
|
user_must_exist! user_id
|
||||||
user_data_to_delete = if u = user_to_delete
|
user_id_to_delete = if u = user_to_delete
|
||||||
user_must_be_admin! user_id
|
user_must_be_admin! 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
|
||||||
|
u
|
||||||
else
|
else
|
||||||
Baguette::Log.info "User #{user_data.uid} terminates his account."
|
Baguette::Log.info "User #{user_id} terminates his account."
|
||||||
user_data
|
user_id
|
||||||
end
|
end
|
||||||
|
|
||||||
wipe_user_data user_data_to_delete
|
wipe_user_data user_id_to_delete
|
||||||
|
|
||||||
Response::Success.new
|
Response::Success.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def user_domains(user_id : UserDataID) : IPC::JSON
|
def user_domains(user_id : UserDataID) : Array(String)
|
||||||
user_data = user_must_exist! user_id
|
user_must_exist! user_id
|
||||||
Response::DomainList.new user_data.domains
|
domains_by_owners.get(user_id.to_s).map &.name
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: is the user known from authd?
|
# TODO: is the user known from authd?
|
||||||
def user_must_exist!(user_id : UserDataID)
|
def user_must_exist!(user_id : UserDataID)
|
||||||
@dnsmanagerd.authd.get_user? user.uid
|
dnsmanagerd().authd.get_user? user_id
|
||||||
end
|
end
|
||||||
|
|
||||||
def user_must_be_admin!(user_id : UserDataID) : Nil
|
def user_must_be_admin!(user_id : UserDataID) : Nil
|
||||||
@dnsmanagerd.assert_permissions! user_id, "*", AuthD::User::PermissionLevel::Admin
|
dnsmanagerd().assert_permissions! user_id, "*", AuthD::User::PermissionLevel::Admin
|
||||||
end
|
end
|
||||||
|
|
||||||
def zone_must_exist!(domain : String) : Zone
|
def zone_must_exist!(domain : String) : Zone
|
||||||
@ -335,13 +348,13 @@ class DNSManager::Storage
|
|||||||
# TODO: accept admin users to override this test.
|
# TODO: accept admin users to override this test.
|
||||||
def user_should_own!(user_id : UserDataID, domain : String)
|
def user_should_own!(user_id : UserDataID, domain : String)
|
||||||
d = domains_by_name.get domain
|
d = domains_by_name.get domain
|
||||||
unless d.includes? user_id
|
unless d.owners.includes? user_id
|
||||||
raise NoOwnershipException.new
|
raise NoOwnershipException.new
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def new_token(user_id : UserDataID, domain : String, rrid : UInt32) : IPC::JSON
|
def new_token(user_id : UserDataID, domain : String, rrid : UInt32) : IPC::JSON
|
||||||
user_data = user_must_exist! user_id
|
user_must_exist! user_id
|
||||||
zone = zone_must_exist! domain
|
zone = zone_must_exist! domain
|
||||||
user_should_own! user_id, domain
|
user_should_own! user_id, domain
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user