Verify accepted domains and pre-load some RRs.

master
Philippe Pittoli 2023-06-29 18:29:25 +02:00
parent d12af2047f
commit e1db03b459
4 changed files with 48 additions and 14 deletions

View File

@ -12,7 +12,10 @@ 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.new_domain dnsmanagerd.configuration.accepted_domains.not_nil!, user.uid, @domain
accepted_domains = dnsmanagerd.configuration.accepted_domains.not_nil!
template_directory = dnsmanagerd.configuration.template_directory
dnsmanagerd.storage.new_domain accepted_domains, template_directory, user.uid, @domain
end
end
DNSManager.requests << NewDomain

View File

@ -42,4 +42,10 @@ class DNSManager::Response
end
end
DNSManager.responses << UnacceptableDomain
IPC::JSON.message InvalidDomainName, 8 do
def initialize()
end
end
DNSManager.responses << InvalidDomainName
end

View File

@ -54,7 +54,11 @@ class DNSManager::Storage
Response::Success.new
end
def new_domain(accepted_domains : Array(String), user_id : Int32, domain : String) : IPC::JSON
def new_domain(accepted_domains : Array(String),
template_directory : String,
user_id : Int32,
domain : String) : IPC::JSON
# User must exist.
user_data = user_data_by_uid.get? user_id.to_s
unless user_data
@ -64,9 +68,7 @@ class DNSManager::Storage
return Response::DomainAlreadyExists.new if zones_by_domain.get? domain
# TODO: verify the domain name validity.
# TODO: verify if the domain is acceptable.
# Verify if the domain is acceptable.
matching_domains = accepted_domains.select { |adomain| domain.ends_with? adomain }
unless matching_domains
Baguette::Log.warning "trying to add an unacceptable domain: #{domain}"
@ -74,21 +76,29 @@ class DNSManager::Storage
end
matching_domains.each do |md|
Baguette::Log.info "Add new domain in #{md}: #{domain}"
Baguette::Log.info "Add new domain #{domain} (matching domain #{md})"
end
# Verify the domain name validity.
return Response::InvalidDomainName.new unless Zone.is_domain_valid? domain
# Fill a template zone.
tld = matching_domains.pop
default_zone = Zone.from_json File.read "#{template_directory}/#{tld}.json"
# Replace domain by the real domain.
default_zone.replace_domain domain
#
# Actually write data on-disk.
#
# Add the domain to the user's domain.
user_data.domains << domain
# Actually write data on-disk.
update_user_data user_data
# TODO: Fill a template zone.
## # 2 NS
## zone << rr
## # Update the zone.
## zones_by_domain.update_or_create zone.domain, zone
# Add the new zone in the database.
zones_by_domain.update_or_create default_zone.domain, default_zone
Response::Success.new
end

View File

@ -397,4 +397,19 @@ class DNSManager::Storage::Zone
false
end
# When a new domain is recorded, we load a template which contains a placeholder domain.
# `replace_domain` replaces this domain name by the real one in the different (preloaded) RR.
def replace_domain(new_domain : String)
@domain = new_domain
@resources.each do |rr|
case rr
when SOA
rr.name = domain
when NS
rr.name = domain
else
Baguette::Log.debug "new domain, rr type #{rr.class} (nothing to do)"
end
end
end
end