porting all github actions from bluesky-social/indigo to tangled CI
at main 4.2 kB view raw
1package identity 2 3import ( 4 "context" 5 "errors" 6 "net" 7 "net/http" 8 "time" 9 10 "github.com/bluesky-social/indigo/atproto/syntax" 11 12 "github.com/carlmjohnson/versioninfo" 13) 14 15// Ergonomic interface for atproto identity lookup, by DID or handle. 16// 17// The "Lookup" methods resolve identities (handle and DID), and return results in a compact, opinionated struct (`Identity`). They do bi-directional handle/DID verification by default. Clients and services should use these methods by default, instead of resolving handles or DIDs separately. 18// 19// Looking up a handle which fails to resolve, or don't match DID alsoKnownAs, returns an error. When looking up a DID, if the handle does not resolve back to the DID, the lookup succeeds and returns an `Identity` where the Handle is the special `handle.invalid` value. 20// 21// Some example implementations of this interface could be: 22// - basic direct resolution on every call 23// - local in-memory caching layer to reduce network hits 24// - API client, which just makes requests to PDS (or other remote service) 25// - client for shared network cache (eg, Redis) 26type Directory interface { 27 LookupHandle(ctx context.Context, handle syntax.Handle) (*Identity, error) 28 LookupDID(ctx context.Context, did syntax.DID) (*Identity, error) 29 Lookup(ctx context.Context, atid syntax.AtIdentifier) (*Identity, error) 30 31 // Flushes any cache of the indicated identifier. If directory is not using caching, can ignore this. 32 Purge(ctx context.Context, atid syntax.AtIdentifier) error 33} 34 35// Indicates that handle resolution failed. A wrapped error may provide more context. This is only returned when looking up a handle, not when looking up a DID. 36var ErrHandleResolutionFailed = errors.New("handle resolution failed") 37 38// Indicates that resolution process completed successfully, but handle does not exist. This is only returned when looking up a handle, not when looking up a DID. 39var ErrHandleNotFound = errors.New("handle not found") 40 41// Indicates that resolution process completed successfully, handle mapped to a different DID. This is only returned when looking up a handle, not when looking up a DID. 42var ErrHandleMismatch = errors.New("handle/DID mismatch") 43 44// Indicates that DID document did not include any handle ("alsoKnownAs"). This is only returned when looking up a handle, not when looking up a DID. 45var ErrHandleNotDeclared = errors.New("DID document did not declare a handle") 46 47// Handle top-level domain (TLD) is one of the special "Reserved" suffixes, and not allowed for atproto use 48var ErrHandleReservedTLD = errors.New("handle top-level domain is disallowed") 49 50// Indicates that resolution process completed successfully, but the DID does not exist. 51var ErrDIDNotFound = errors.New("DID not found") 52 53// Indicates that DID resolution process failed. A wrapped error may provide more context. 54var ErrDIDResolutionFailed = errors.New("DID resolution failed") 55 56// Indicates that DID document did not include a public key with the specified ID 57var ErrKeyNotDeclared = errors.New("DID document did not declare a relevant public key") 58 59// Handle was invalid, in a situation where a valid handle is required. 60var ErrInvalidHandle = errors.New("invalid handle") 61 62var DefaultPLCURL = "https://plc.directory" 63 64// Returns a reasonable Directory implementation for applications 65func DefaultDirectory() Directory { 66 base := BaseDirectory{ 67 PLCURL: DefaultPLCURL, 68 HTTPClient: http.Client{ 69 Timeout: time.Second * 10, 70 Transport: &http.Transport{ 71 // would want this around 100ms for services doing lots of handle resolution. Impacts PLC connections as well, but not too bad. 72 IdleConnTimeout: time.Millisecond * 1000, 73 MaxIdleConns: 100, 74 }, 75 }, 76 Resolver: net.Resolver{ 77 Dial: func(ctx context.Context, network, address string) (net.Conn, error) { 78 d := net.Dialer{Timeout: time.Second * 3} 79 return d.DialContext(ctx, network, address) 80 }, 81 }, 82 TryAuthoritativeDNS: true, 83 // primary Bluesky PDS instance only supports HTTP resolution method 84 SkipDNSDomainSuffixes: []string{".bsky.social"}, 85 UserAgent: "indigo-identity/" + versioninfo.Short(), 86 } 87 cached := NewCacheDirectory(&base, 250_000, time.Hour*24, time.Minute*2, time.Minute*5) 88 return &cached 89}