From 62ac51c54b72782d075884ff95fe962aad22dca0 Mon Sep 17 00:00:00 2001 From: Philippe Pittoli Date: Sat, 16 Mar 2024 07:03:04 +0100 Subject: [PATCH] UserDataID: Int32 -> UInt32. Can now wipe user data. --- src/requests/admin.cr | 1 - src/requests/{login.cr => user.cr} | 15 +++++++++ src/storage.cr | 52 ++++++++++++++++++++++-------- src/storage/user_data.cr | 4 ++- 4 files changed, 56 insertions(+), 16 deletions(-) rename src/requests/{login.cr => user.cr} (72%) diff --git a/src/requests/admin.cr b/src/requests/admin.cr index 81ac5d8..951c726 100644 --- a/src/requests/admin.cr +++ b/src/requests/admin.cr @@ -1,4 +1,3 @@ - class DNSManager::Request # Periodic actions to perform as an administrator. IPC::JSON.message Maintenance, 7 do diff --git a/src/requests/login.cr b/src/requests/user.cr similarity index 72% rename from src/requests/login.cr rename to src/requests/user.cr index 59a754a..33e961d 100644 --- a/src/requests/login.cr +++ b/src/requests/user.cr @@ -30,4 +30,19 @@ class DNSManager::Request end end DNSManager.requests << Login + + IPC::JSON.message DeleteUser, 1 do + property user_id : UserDataID? = nil + + def initialize(@user_id = nil) + end + + def handle(dnsmanagerd : DNSManager::Service, event : IPC::Event) + user = dnsmanagerd.get_logged_user event + return Response::ErrorUserNotLogged.new unless user + + dnsmanagerd.storage.delete_user_data user.uid, user_id + end + end + DNSManager.requests << DeleteUser end diff --git a/src/storage.cr b/src/storage.cr index a604b68..7ccf25c 100644 --- a/src/storage.cr +++ b/src/storage.cr @@ -44,7 +44,7 @@ class DNSManager::Storage end end - def get_user_data(uid : Int32) + def get_user_data(uid : UserDataID) user_data_by_uid.get uid.to_s rescue e : DODB::MissingEntry entry = UserData.new uid @@ -59,7 +59,7 @@ class DNSManager::Storage user_data_by_uid.update_or_create user_data.uid.to_s, user_data end - def ensure_user_data(user_id : Int32) + def ensure_user_data(user_id : UserDataID) user_data = user_data_by_uid.get? user_id.to_s unless user_data Baguette::Log.info "New user #{user_id}" @@ -94,7 +94,7 @@ class DNSManager::Storage Response::Success.new end - def get_generated_zonefile(user_id : Int32, domain : String) : IPC::JSON + def get_generated_zonefile(user_id : UserDataID, domain : String) : IPC::JSON user_data = user_must_exist! user_id zone = zone_must_exist! domain @@ -107,7 +107,7 @@ class DNSManager::Storage def new_domain(accepted_domains : Array(String), template_directory : String, - user_id : Int32, + user_id : UserDataID, domain : String) : IPC::JSON user_data = user_must_exist! user_id @@ -149,7 +149,7 @@ class DNSManager::Storage Response::DomainAdded.new domain end - def add_or_update_zone(user_id : Int32, zone : Zone) : IPC::JSON + def add_or_update_zone(user_id : UserDataID, zone : Zone) : IPC::JSON user_data = user_must_exist! user_id # Test zone validity. @@ -175,7 +175,7 @@ class DNSManager::Storage Response::Success.new end - def add_rr(user_id : Int32, domain : String, rr : Zone::ResourceRecord) : IPC::JSON + def add_rr(user_id : UserDataID, domain : String, rr : Zone::ResourceRecord) : IPC::JSON user_data = user_must_exist! user_id zone = zone_must_exist! domain user_should_own! user_data, domain @@ -202,7 +202,7 @@ class DNSManager::Storage zones_by_domain.update_or_create zone.domain, zone end - def update_rr(user_id : Int32, domain : String, rr : Zone::ResourceRecord) : IPC::JSON + def update_rr(user_id : UserDataID, domain : String, rr : Zone::ResourceRecord) : IPC::JSON user_data = user_must_exist! user_id zone = zone_must_exist! domain user_should_own! user_data, domain @@ -224,7 +224,7 @@ class DNSManager::Storage Response::RRUpdated.new domain, rr end - def delete_rr(user_id : Int32, domain : String, rrid : UInt32) : IPC::JSON + def delete_rr(user_id : UserDataID, domain : String, rrid : UInt32) : IPC::JSON user_data = user_must_exist! user_id zone = zone_must_exist! domain user_should_own! user_data, domain @@ -242,7 +242,7 @@ class DNSManager::Storage Response::RRDeleted.new rrid end - def delete_domain(user_id : Int32, domain : String) : IPC::JSON + def delete_domain(user_id : UserDataID, domain : String) : IPC::JSON user_data = user_must_exist! user_id zone_must_exist! domain user_should_own! user_data, domain @@ -260,7 +260,7 @@ class DNSManager::Storage Response::DomainDeleted.new domain end - def get_zone(user_id : Int32, domain : String) : IPC::JSON + def get_zone(user_id : UserDataID, domain : String) : IPC::JSON user_data = user_must_exist! user_id zone = zone_must_exist! domain user_should_own! user_data, domain @@ -268,18 +268,42 @@ class DNSManager::Storage Response::Zone.new zone end - def user_domains(user_id : Int32) : IPC::JSON + def delete_user_data(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 + Baguette::Log.info "Admin #{user_id} removes data of user #{u}." + user_must_exist! u + else + Baguette::Log.info "User #{user_data.uid} terminates his account." + user_data + end + + # Remove the user's domains. + user_data_to_delete.domains.each do |domain| + zones_by_domain.delete domain + rescue e + Baguette::Log.error "while removing a user: #{e}" + end + + # Remove the user. + user_data_by_uid.delete user_data_to_delete.uid.to_s + + Response::Success.new + end + + def user_domains(user_id : UserDataID) : IPC::JSON user_data = user_must_exist! user_id Response::DomainList.new user_data.domains end - def user_must_exist!(user_id : Int32) : UserData + def user_must_exist!(user_id : UserDataID) : UserData user_data = user_data_by_uid.get? user_id.to_s raise UnknownUserException.new unless user_data user_data end - def user_must_be_admin!(user_id : Int32) : UserData + def user_must_be_admin!(user_id : UserDataID) : UserData user_data = user_must_exist! user_id raise AdminAuthorizationException.new unless user_data.admin user_data @@ -297,7 +321,7 @@ class DNSManager::Storage end end - def new_token(user_id : Int32, 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 zone = zone_must_exist! domain user_should_own! user_data, domain diff --git a/src/storage/user_data.cr b/src/storage/user_data.cr index 47417f5..76bd587 100644 --- a/src/storage/user_data.cr +++ b/src/storage/user_data.cr @@ -2,10 +2,12 @@ require "json" require "uuid" require "uuid/json" +alias UserDataID = UInt32 + class DNSManager::Storage::UserData include JSON::Serializable - property uid : Int32 + property uid : UserDataID # Users may have many domains, and a domain can have many owners. property domains = [] of String