Class: DIDKit::Resolver
- Inherits:
-
Object
- Object
- DIDKit::Resolver
- Includes:
- Requests
- Defined in:
- lib/didkit/resolver.rb
Overview
A class which manages resolving of handles to DIDs and DIDs to DID documents.
Constant Summary collapse
- RESERVED_DOMAINS =
These TLDs are not allowed in ATProto handles, so the resolver returns nil for them without trying to look them up.
%w(alt arpa example internal invalid local localhost onion test)
Instance Attribute Summary collapse
-
#nameserver ⇒ String+
Custom DNS nameserver(s) to use for DNS TXT lookups.
Instance Method Summary collapse
-
#first_verified_handle(did, handles) ⇒ String?
Returns the first handle from the list that resolves back to the given DID.
-
#get_verified_handle(subject) ⇒ String?
Returns the first verified handle assigned to the given DID.
-
#initialize(options = {}) ⇒ Resolver
constructor
A new instance of Resolver.
-
#resolve_did(did) ⇒ Document
Resolve a DID to a DID document.
-
#resolve_handle(handle) ⇒ DID?
Resolve a handle into a DID.
-
#resolve_handle_by_dns(domain) ⇒ String?
Tries to resolve a handle into DID using the DNS TXT method.
-
#resolve_handle_by_well_known(domain) ⇒ String?
Tries to resolve a handle into DID using the HTTP .well-known method.
Constructor Details
#initialize(options = {}) ⇒ Resolver
Returns a new instance of Resolver.
31 32 33 34 |
# File 'lib/didkit/resolver.rb', line 31 def initialize( = {}) @nameserver = [:nameserver] @request_options = .slice(:timeout, :max_redirects) end |
Instance Attribute Details
#nameserver ⇒ String+
Returns custom DNS nameserver(s) to use for DNS TXT lookups.
24 25 26 |
# File 'lib/didkit/resolver.rb', line 24 def nameserver @nameserver end |
Instance Method Details
#first_verified_handle(did, handles) ⇒ String?
Returns the first handle from the list that resolves back to the given DID.
143 144 145 |
# File 'lib/didkit/resolver.rb', line 143 def first_verified_handle(did, handles) handles.detect { |h| resolve_handle(h) == did.to_s } end |
#get_verified_handle(subject) ⇒ String?
Returns the first verified handle assigned to the given DID.
Looks up the domain handles assigned to the DID in the DID document, checks if they are verified (i.e. assigned correctly to this DID using DNS TXT or .well-known) and returns the first handle that validates correctly, or nil if none matches.
131 132 133 134 135 |
# File 'lib/didkit/resolver.rb', line 131 def get_verified_handle(subject) document = subject.is_a?(Document) ? subject : resolve_did(subject) first_verified_handle(document.did, document.handles) end |
#resolve_did(did) ⇒ Document
Resolve a DID to a DID document.
Looks up the DID document with the DID’s identity details from an appropriate source, i.e. either [plc.directory](plc.directory) for did:plc DIDs, or the did:web’s domain for did:web DIDs.
116 117 118 119 120 |
# File 'lib/didkit/resolver.rb', line 116 def resolve_did(did) did = DID.new(did) if did.is_a?(String) did.type == :plc ? resolve_did_plc(did) : resolve_did_web(did) end |
#resolve_handle(handle) ⇒ DID?
Resolve a handle into a DID. Looks up the given ATProto domain handle using the DNS TXT method and the HTTP .well-known method and returns a DID if one is assigned using either of the methods.
If a DID string or a DID object is passed, it simply returns that DID, so you can use this method to pass it an input string from the user which can be a DID or handle, without having to check which one it is.
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/didkit/resolver.rb', line 46 def resolve_handle(handle) if handle.is_a?(DID) || handle =~ DID::GENERIC_REGEXP return DID.new(handle) end domain = handle.gsub(/^@/, '') return nil if RESERVED_DOMAINS.include?(domain.split('.').last) if dns_did = resolve_handle_by_dns(domain) DID.new(dns_did, :dns) elsif http_did = resolve_handle_by_well_known(domain) DID.new(http_did, :http) else nil end end |
#resolve_handle_by_dns(domain) ⇒ String?
Tries to resolve a handle into DID using the DNS TXT method.
Checks the DNS records for a given domain for an entry ‘_atproto.#domain` whose value is a correct DID string.
72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/didkit/resolver.rb', line 72 def resolve_handle_by_dns(domain) dns_records = Resolv::DNS.open() do |d| d.getresources("_atproto.#{domain}", Resolv::DNS::Resource::IN::TXT) end if record = dns_records.first if string = record.strings.first return parse_did_from_dns(string) end end nil end |
#resolve_handle_by_well_known(domain) ⇒ String?
Tries to resolve a handle into DID using the HTTP .well-known method.
Checks the /.well-known/atproto-did endpoint on the given domain to see if it returns a text file that contains a correct DID string.
94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/didkit/resolver.rb', line 94 def resolve_handle_by_well_known(domain) url = "https://#{domain}/.well-known/atproto-did" response = get_response(url, @request_options) if response.is_a?(Net::HTTPSuccess) && (text = response.body) return parse_did_from_well_known(text) end nil rescue StandardError => e nil end |