diff --git a/src/client/lib/dnsmanager-client.cr b/src/client/lib/dnsmanager-client.cr index 7f5dd91..a54338c 100644 --- a/src/client/lib/dnsmanager-client.cr +++ b/src/client/lib/dnsmanager-client.cr @@ -65,6 +65,13 @@ class DNSManager::Client < IPC parse_message [ Response::Zone ], read end + # Get the generated zonefile. + def user_zonefile(domain : String) + request = Request::AskGeneratedZoneFile.new domain + send_now request + parse_message [ Response::GeneratedZone ], read + end + # # Resource Record operations # diff --git a/src/client/main.cr b/src/client/main.cr index 72dee6a..0d809d9 100644 --- a/src/client/main.cr +++ b/src/client/main.cr @@ -45,6 +45,7 @@ class Actions # Zone operations. @the_call["user-zone-add"] = ->user_zone_add @the_call["user-zone-get"] = ->user_zone_get + @the_call["user-zonefile"] = ->user_zonefile # Zone RR operations. @the_call["user-rr-add-a"] = ->user_rr_add_a @@ -153,6 +154,27 @@ class Actions end end + def user_zonefile + domains = Context.args.not_nil! + domains.each do |domain| + begin + pp! domain + response = @dnsmanagerd.user_zonefile domain + case response + when DNSManager::Response::GeneratedZone + pp! response.domain + puts response.zonefile + else + puts "Didn't get the zone" + pp! response + end + rescue e + puts "error for user_zonefile: #{e.message}" + end + end + end + + def user_domain_list response = @dnsmanagerd.user_domain_list case response diff --git a/src/client/parser.cr b/src/client/parser.cr index 197bc1e..2c65de9 100644 --- a/src/client/parser.cr +++ b/src/client/parser.cr @@ -144,6 +144,13 @@ def parsing_cli(authd_config : Baguette::Configuration::Auth) end end + parser.on("zonefile", "Get a the generated zonefile.") do + Baguette::Log.info "get a zone file." + Context.command = "user-zonefile" + parser.banner = "COMMAND: user zonefile domain [domain...]" + unrecognized_args_to_context_args.call parser, nil, 1 + end + # Zone. parser.on("zone", "Zone operations.") do parser.on("add", "Add new zone.") do diff --git a/src/requests/zone.cr b/src/requests/zone.cr index dc21804..cef395e 100644 --- a/src/requests/zone.cr +++ b/src/requests/zone.cr @@ -118,4 +118,18 @@ class DNSManager::Request end end DNSManager.requests << DeleteRR + + IPC::JSON.message AskGeneratedZoneFile, 17 do + property domain : String + + def initialize(@domain) + end + + 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_generated_zonefile user.uid, @domain + end + end + DNSManager.requests << AskGeneratedZoneFile end diff --git a/src/responses/zone.cr b/src/responses/zone.cr index 698f896..a720834 100644 --- a/src/responses/zone.cr +++ b/src/responses/zone.cr @@ -102,5 +102,13 @@ class DNSManager::Response end end DNSManager.responses << RRReadOnly + + IPC::JSON.message GeneratedZone, 23 do + property domain : String + property zonefile : String + def initialize(@domain, @zonefile) + end + end + DNSManager.responses << GeneratedZone end diff --git a/src/storage.cr b/src/storage.cr index 05108b8..e2c8576 100644 --- a/src/storage.cr +++ b/src/storage.cr @@ -85,6 +85,27 @@ class DNSManager::Storage Response::Success.new end + def get_generated_zonefile(user_id : Int32, domain : String) : IPC::JSON + zone = zones_by_domain.get? domain + return Response::DomainNotFound.new unless zone + + # User must own the zone. + user_data = user_data_by_uid.get? user_id.to_s + unless user_data + Baguette::Log.warning "unknown user #{user_id} asked a zonefile for domain #{domain}" + return Response::UnknownUser.new + end + + unless user_data.domains.includes?(zone.domain) || user_data.admin + Baguette::Log.warning "user #{user_id} doesn't own domain #{zone.domain}" + return Response::NoOwnership.new + end + + io = IO::Memory.new + zone.to_bind9 io + Response::GeneratedZone.new domain, (String.new io.buffer, io.pos) + end + def new_domain(accepted_domains : Array(String), template_directory : String, user_id : Int32,