Use cached indexes.
parent
158d772727
commit
4923fb34f9
|
@ -15,15 +15,14 @@ class DNSManager::Request
|
|||
# "dnsmanager-last-connection" => JSON::Any.new Time.utc.to_s
|
||||
#}
|
||||
user_id = response.user.uid
|
||||
dnsmanagerd.storage.user_must_exist! user_id
|
||||
|
||||
accepted_domains = dnsmanagerd.configuration.accepted_domains.not_nil!
|
||||
|
||||
# Limit the number of domains in this message.
|
||||
# Pagination will be required beyond a hundred domains.
|
||||
user_domains = dnsmanagerd.storage.user_domains(user_id).[0..100]
|
||||
|
||||
perms = dnsmanagerd.check_permissions user_id, "*"
|
||||
|
||||
Response::Logged.new (perms == AuthD::User::PermissionLevel::Admin), accepted_domains, user_domains
|
||||
else
|
||||
Response::ErrorInvalidToken.new
|
||||
|
|
|
@ -8,16 +8,16 @@ require "dodb"
|
|||
|
||||
class DNSManager::Storage
|
||||
getter domains : DODB::CachedDataBase(Domain)
|
||||
getter domains_by_name : DODB::Index(Domain)
|
||||
getter domains_by_share_key : DODB::Index(Domain)
|
||||
getter domains_by_transfer_key : DODB::Index(Domain)
|
||||
getter domains_by_name : DODB::CachedIndex(Domain)
|
||||
getter domains_by_share_key : DODB::CachedIndex(Domain)
|
||||
getter domains_by_transfer_key : DODB::CachedIndex(Domain)
|
||||
getter domains_by_owners : DODB::Tags(Domain)
|
||||
|
||||
getter zones : DODB::CachedDataBase(Zone)
|
||||
getter zones_by_domain : DODB::Index(Zone)
|
||||
getter zones_by_domain : DODB::CachedIndex(Zone)
|
||||
|
||||
getter tokens : DODB::CachedDataBase(Token)
|
||||
getter tokens_by_uuid : DODB::Index(Token)
|
||||
getter tokens_by_uuid : DODB::CachedIndex(Token)
|
||||
getter tokens_by_domain : DODB::Partition(Token)
|
||||
|
||||
getter root : String
|
||||
|
@ -103,8 +103,6 @@ class DNSManager::Storage
|
|||
end
|
||||
|
||||
def get_generated_zonefile(user_id : UserDataID, domain : String) : IPC::JSON
|
||||
|
||||
user_must_exist! user_id
|
||||
zone = zone_must_exist! domain
|
||||
user_should_own! user_id, zone.domain
|
||||
|
||||
|
@ -118,8 +116,6 @@ class DNSManager::Storage
|
|||
user_id : UserDataID,
|
||||
domain : String) : IPC::JSON
|
||||
|
||||
user_must_exist! user_id
|
||||
|
||||
# Prevent future very confusing errors.
|
||||
domain = domain.downcase
|
||||
|
||||
|
@ -164,7 +160,6 @@ class DNSManager::Storage
|
|||
end
|
||||
|
||||
def ask_share_token(user_id : UserDataID, domain_name : String)
|
||||
user_must_exist! user_id
|
||||
user_should_own! user_id, domain_name
|
||||
|
||||
domain = @domains_by_name.get domain_name
|
||||
|
@ -178,7 +173,6 @@ class DNSManager::Storage
|
|||
end
|
||||
|
||||
def ask_transfer_token(user_id : UserDataID, domain_name : String)
|
||||
user_must_exist! user_id
|
||||
user_should_own! user_id, domain_name
|
||||
|
||||
domain = @domains_by_name.get domain_name
|
||||
|
@ -194,13 +188,12 @@ class DNSManager::Storage
|
|||
# Check the domain owners.
|
||||
# In case there's only the requesting user, allow him to gain full control.
|
||||
def ask_unshare_domain(user_id : UserDataID, domain_name : String)
|
||||
user_must_exist! user_id
|
||||
user_should_own! user_id, domain_name
|
||||
|
||||
domain = @domains_by_name.get domain_name
|
||||
if domain.owners.size == 1 && domain.owners[0] == user_id
|
||||
domain.share_key = nil
|
||||
@domains_by_name.update_or_create domain_name, domain
|
||||
@domains_by_name.update domain
|
||||
Response::DomainChanged.new domain
|
||||
else
|
||||
Response::Error.new "You are not the only owner."
|
||||
|
@ -208,14 +201,12 @@ class DNSManager::Storage
|
|||
end
|
||||
|
||||
def gain_ownership(user_id : UserDataID, uuid : String)
|
||||
user_must_exist! user_id
|
||||
|
||||
if domain = @domains_by_share_key.get? uuid
|
||||
if domain.owners.includes? user_id
|
||||
return Response::Error.new "You already own this domain."
|
||||
end
|
||||
domain.owners << user_id
|
||||
@domains_by_name.update_or_create domain.name, domain
|
||||
@domains_by_name.update domain
|
||||
Response::DomainChanged.new domain
|
||||
elsif domain = @domains_by_transfer_key.get? uuid
|
||||
if domain.owners.includes? user_id
|
||||
|
@ -223,7 +214,7 @@ class DNSManager::Storage
|
|||
end
|
||||
domain.transfer_key = nil
|
||||
domain.owners = [user_id]
|
||||
@domains_by_name.update_or_create domain.name, domain
|
||||
@domains_by_name.update domain
|
||||
Response::DomainChanged.new domain
|
||||
else
|
||||
Response::Error.new "There is no key with this UUID."
|
||||
|
@ -231,8 +222,6 @@ class DNSManager::Storage
|
|||
end
|
||||
|
||||
def add_or_update_zone(user_id : UserDataID, zone : Zone) : IPC::JSON
|
||||
user_must_exist! user_id
|
||||
|
||||
# Test zone validity.
|
||||
if errors = zone.get_errors?
|
||||
Baguette::Log.warning "zone #{zone.domain} update with errors: #{errors}"
|
||||
|
@ -254,7 +243,6 @@ class DNSManager::Storage
|
|||
end
|
||||
|
||||
def add_rr(user_id : UserDataID, domain : String, rr : Zone::ResourceRecord) : IPC::JSON
|
||||
user_must_exist! user_id
|
||||
zone = zone_must_exist! domain
|
||||
user_should_own! user_id, domain
|
||||
|
||||
|
@ -281,7 +269,6 @@ class DNSManager::Storage
|
|||
end
|
||||
|
||||
def update_rr(user_id : UserDataID, domain : String, rr : Zone::ResourceRecord) : IPC::JSON
|
||||
user_must_exist! user_id
|
||||
zone = zone_must_exist! domain
|
||||
user_should_own! user_id, domain
|
||||
|
||||
|
@ -303,8 +290,7 @@ class DNSManager::Storage
|
|||
end
|
||||
|
||||
def delete_rr(user_id : UserDataID, domain : String, rrid : UInt32) : IPC::JSON
|
||||
user_must_exist! user_id
|
||||
zone = zone_must_exist! domain
|
||||
zone = zone_must_exist! domain
|
||||
user_should_own! user_id, domain
|
||||
|
||||
rr = zone.rr_not_readonly! rrid
|
||||
|
@ -321,7 +307,6 @@ class DNSManager::Storage
|
|||
end
|
||||
|
||||
def delete_domain(user_id : UserDataID, domain_name : String) : IPC::JSON
|
||||
user_must_exist! user_id
|
||||
zone_must_exist! domain_name
|
||||
user_should_own! user_id, domain_name
|
||||
|
||||
|
@ -370,7 +355,6 @@ class DNSManager::Storage
|
|||
end
|
||||
|
||||
def get_zone(user_id : UserDataID, domain : String) : IPC::JSON
|
||||
user_must_exist! user_id
|
||||
zone = zone_must_exist! domain
|
||||
user_should_own! user_id, domain
|
||||
|
||||
|
@ -395,11 +379,9 @@ class DNSManager::Storage
|
|||
end
|
||||
|
||||
def delete_user_data(user_id : UserDataID, user_to_delete : UserDataID?) : IPC::JSON
|
||||
user_must_exist! user_id
|
||||
user_id_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
|
||||
u
|
||||
else
|
||||
Baguette::Log.info "User #{user_id} terminates his account."
|
||||
|
@ -412,8 +394,11 @@ class DNSManager::Storage
|
|||
end
|
||||
|
||||
def user_domains(user_id : UserDataID) : Array(Domain)
|
||||
user_must_exist! user_id
|
||||
domains_by_owners.get(user_id.to_s)
|
||||
if doms = domains_by_owners.get? user_id.to_s
|
||||
doms
|
||||
else
|
||||
Array(Domain).new
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: is the user known from authd?
|
||||
|
@ -434,14 +419,16 @@ class DNSManager::Storage
|
|||
# Owning a domain means to be in the owners' list of the domain.
|
||||
# TODO: accept admin users to override this test.
|
||||
def user_should_own!(user_id : UserDataID, domain : String) : Nil
|
||||
d = domains_by_name.get domain
|
||||
unless d.owners.includes? user_id
|
||||
raise NoOwnershipException.new
|
||||
if d = domains_by_name.get? domain
|
||||
unless d.owners.includes? user_id
|
||||
raise NoOwnershipException.new
|
||||
end
|
||||
else
|
||||
raise DomainNotFoundException.new
|
||||
end
|
||||
end
|
||||
|
||||
def new_token(user_id : UserDataID, domain : String, rrid : UInt32) : IPC::JSON
|
||||
user_must_exist! user_id
|
||||
zone = zone_must_exist! domain
|
||||
user_should_own! user_id, domain
|
||||
|
||||
|
|
|
@ -14,4 +14,6 @@ class DNSManager::Storage::Domain
|
|||
|
||||
def initialize(@name, share_key = nil, transfer_key = nil, owners = [] of UserDataID)
|
||||
end
|
||||
|
||||
def_clone
|
||||
end
|
||||
|
|
|
@ -7,6 +7,8 @@ class DNSManager::Storage::Token
|
|||
property domain : String
|
||||
property rrid : UInt32
|
||||
|
||||
def_clone
|
||||
|
||||
def initialize(@domain, @rrid)
|
||||
@uuid = UUID.random.to_s
|
||||
end
|
||||
|
|
|
@ -35,6 +35,8 @@ class DNSManager::Storage::Zone
|
|||
def initialize(@domain)
|
||||
end
|
||||
|
||||
def_clone
|
||||
|
||||
alias Error = String
|
||||
|
||||
# Store a Resource Record: A, AAAA, TXT, PTR, CNAME…
|
||||
|
@ -96,6 +98,8 @@ class DNSManager::Storage::Zone
|
|||
end
|
||||
|
||||
class SOA < ResourceRecord
|
||||
def_clone
|
||||
|
||||
# Start of Authority
|
||||
property mname : String # Master Name Server for the zone.
|
||||
property rname : String # admin email address john.doe@example.com => john\.doe.example.com
|
||||
|
@ -159,6 +163,8 @@ class DNSManager::Storage::Zone
|
|||
end
|
||||
|
||||
class A < ResourceRecord
|
||||
def_clone
|
||||
|
||||
def get_errors : Array(Error)
|
||||
errors = [] of Error
|
||||
|
||||
|
@ -179,6 +185,8 @@ class DNSManager::Storage::Zone
|
|||
end
|
||||
|
||||
class AAAA < ResourceRecord
|
||||
def_clone
|
||||
|
||||
def get_errors : Array(Error)
|
||||
errors = [] of Error
|
||||
|
||||
|
@ -199,6 +207,8 @@ class DNSManager::Storage::Zone
|
|||
end
|
||||
|
||||
class TXT < ResourceRecord
|
||||
def_clone
|
||||
|
||||
def get_errors : Array(Error)
|
||||
errors = [] of Error
|
||||
|
||||
|
@ -224,6 +234,8 @@ class DNSManager::Storage::Zone
|
|||
end
|
||||
|
||||
class PTR < ResourceRecord
|
||||
def_clone
|
||||
|
||||
def get_errors : Array(Error)
|
||||
errors = [] of Error
|
||||
|
||||
|
@ -252,6 +264,8 @@ class DNSManager::Storage::Zone
|
|||
end
|
||||
|
||||
class NS < ResourceRecord
|
||||
def_clone
|
||||
|
||||
def get_errors : Array(Error)
|
||||
errors = [] of Error
|
||||
|
||||
|
@ -268,6 +282,8 @@ class DNSManager::Storage::Zone
|
|||
end
|
||||
|
||||
class CNAME < ResourceRecord
|
||||
def_clone
|
||||
|
||||
def get_errors : Array(Error)
|
||||
errors = [] of Error
|
||||
|
||||
|
@ -289,7 +305,7 @@ class DNSManager::Storage::Zone
|
|||
# TODO: verifications + print.
|
||||
# baguette.netlib.re. 3600 IN TXT "v=spf1 a mx ip4:<IP> a:mail.baguette.netlib.re ~all"
|
||||
class SPF < ResourceRecord
|
||||
|
||||
def_clone
|
||||
|
||||
# SPF mechanisms are about policy, which comes with the form of a single character:
|
||||
# - '?' means no policy (neutral),
|
||||
|
@ -332,6 +348,8 @@ class DNSManager::Storage::Zone
|
|||
property t : Type # type of modifier
|
||||
property v : String # value
|
||||
|
||||
def_clone
|
||||
|
||||
def initialize(@t, @v)
|
||||
end
|
||||
|
||||
|
@ -362,6 +380,8 @@ class DNSManager::Storage::Zone
|
|||
INCLUDE # include foreign SPF policy
|
||||
end
|
||||
|
||||
def_clone
|
||||
|
||||
property q : Qualifier = Qualifier::Pass
|
||||
property t : Type # type of mechanism
|
||||
property v : String # value
|
||||
|
@ -484,6 +504,7 @@ class DNSManager::Storage::Zone
|
|||
|
||||
# TODO
|
||||
class DKIM < ResourceRecord
|
||||
def_clone
|
||||
enum Version
|
||||
DKIM1
|
||||
end
|
||||
|
@ -508,6 +529,8 @@ class DNSManager::Storage::Zone
|
|||
io << "v=#{v};h=#{h.to_s.downcase};k=#{k.to_s.downcase};p=#{p}"
|
||||
io << ";n=#{n}" unless n == ""
|
||||
end
|
||||
|
||||
def_clone
|
||||
end
|
||||
|
||||
property dkim : DKIMProperties
|
||||
|
@ -542,6 +565,7 @@ class DNSManager::Storage::Zone
|
|||
|
||||
# TODO
|
||||
class DMARC < ResourceRecord
|
||||
def_clone
|
||||
enum Version
|
||||
DMARC1
|
||||
end
|
||||
|
@ -551,6 +575,8 @@ class DNSManager::Storage::Zone
|
|||
property mail : String
|
||||
property limit : UInt32? = nil
|
||||
|
||||
def_clone
|
||||
|
||||
def to_s(io : IO)
|
||||
io << "#{mail}"
|
||||
if l = @limit
|
||||
|
@ -596,6 +622,8 @@ class DNSManager::Storage::Zone
|
|||
property rf : Array(ReportFormat)? = nil
|
||||
property ri : UInt32
|
||||
|
||||
def_clone
|
||||
|
||||
def initialize(@p, @sp, @v, @adkim, @aspf, @pct, @fo, @rua, @ruf, @rf, @ri)
|
||||
end
|
||||
|
||||
|
@ -694,6 +722,7 @@ class DNSManager::Storage::Zone
|
|||
end
|
||||
|
||||
class MX < ResourceRecord
|
||||
def_clone
|
||||
property priority : UInt32 = 10
|
||||
def initialize(@name, @ttl, @target, @priority = 10)
|
||||
@rrtype = "MX"
|
||||
|
@ -729,6 +758,7 @@ class DNSManager::Storage::Zone
|
|||
end
|
||||
|
||||
class SRV < ResourceRecord
|
||||
def_clone
|
||||
property port : UInt16
|
||||
property protocol : String = "tcp"
|
||||
property priority : UInt32 = 10
|
||||
|
|
Loading…
Reference in New Issue