this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

break out Resolve methods to separate interface

+55 -43
+3 -2
atproto/identity/base_directory.go
··· 32 32 } 33 33 34 34 var _ Directory = (*BaseDirectory)(nil) 35 + var _ Resolver = (*BaseDirectory)(nil) 35 36 36 37 func (d *BaseDirectory) LookupHandle(ctx context.Context, h syntax.Handle) (*Identity, error) { 37 38 h = h.Normalize() ··· 39 40 if err != nil { 40 41 return nil, err 41 42 } 42 - doc, err := d.ResolveDIDDoc(ctx, did) 43 + doc, err := d.ResolveDID(ctx, did) 43 44 if err != nil { 44 45 return nil, err 45 46 } ··· 57 58 } 58 59 59 60 func (d *BaseDirectory) LookupDID(ctx context.Context, did syntax.DID) (*Identity, error) { 60 - doc, err := d.ResolveDIDDoc(ctx, did) 61 + doc, err := d.ResolveDID(ctx, did) 61 62 if err != nil { 62 63 return nil, err 63 64 }
-5
atproto/identity/cache_directory.go
··· 250 250 return nil, fmt.Errorf("at-identifier neither a Handle nor a DID") 251 251 } 252 252 253 - func (d *CacheDirectory) ResolveDID(ctx context.Context, did syntax.DID) (map[string]any, error) { 254 - // XXX: cache this kind of doc separately 255 - return d.Inner.ResolveDID(ctx, did) 256 - } 257 - 258 253 func (d *CacheDirectory) Purge(ctx context.Context, a syntax.AtIdentifier) error { 259 254 handle, err := a.AsHandle() 260 255 if nil == err { // if not an error, is a handle
+21 -14
atproto/identity/did.go
··· 14 14 "github.com/bluesky-social/indigo/atproto/syntax" 15 15 ) 16 16 17 - // This is a low-level method for resolving a DID to a raw JSON document. 18 - // 19 - // This method does not parse the DID document into an atproto-specific format, and does not bi-directionally verify handles. Most atproto-specific code should use the "Lookup*" methods, which do implement that functionality. 20 - func (d *BaseDirectory) ResolveDID(ctx context.Context, did syntax.DID) (map[string]any, error) { 21 - raw, err := d.resolveDIDBytes(ctx, did) 17 + // Variant of ResolveDID which parses in to a DIDDocument struct. 18 + func (d *BaseDirectory) ResolveDID(ctx context.Context, did syntax.DID) (*DIDDocument, error) { 19 + b, err := d.resolveDIDBytes(ctx, did) 22 20 if err != nil { 23 21 return nil, err 24 22 } 25 23 26 - var doc map[string]any 27 - if err := json.Unmarshal(raw, &doc); err != nil { 24 + var doc DIDDocument 25 + if err := json.Unmarshal(b, &doc); err != nil { 28 26 return nil, fmt.Errorf("%w: JSON DID document parse: %w", ErrDIDResolutionFailed, err) 29 27 } 30 - return doc, nil 28 + if doc.DID != did { 29 + return nil, fmt.Errorf("document ID did not match DID") 30 + } 31 + return &doc, nil 31 32 } 32 33 33 - // Variant of ResolveDID which parses in to a DIDDocument struct. 34 - func (d *BaseDirectory) ResolveDIDDoc(ctx context.Context, did syntax.DID) (*DIDDocument, error) { 35 - raw, err := d.resolveDIDBytes(ctx, did) 34 + // Low-level method for resolving a DID to a raw JSON document. 35 + // 36 + // This method does not parse the DID document into an atproto-specific format, and does not bi-directionally verify handles. Most atproto-specific code should use the "Lookup*" methods, which do implement that functionality. 37 + func (d *BaseDirectory) ResolveDIDRaw(ctx context.Context, did syntax.DID) (json.RawMessage, error) { 38 + b, err := d.resolveDIDBytes(ctx, did) 36 39 if err != nil { 37 40 return nil, err 38 41 } 39 42 43 + // parse as doc, to validate at least some syntax 40 44 var doc DIDDocument 41 - if err := json.Unmarshal(raw, &doc); err != nil { 45 + if err := json.Unmarshal(b, &doc); err != nil { 42 46 return nil, fmt.Errorf("%w: JSON DID document parse: %w", ErrDIDResolutionFailed, err) 43 47 } 44 - return &doc, nil 48 + if doc.DID != did { 49 + return nil, fmt.Errorf("document ID did not match DID") 50 + } 51 + 52 + return json.RawMessage(b), nil 45 53 } 46 54 47 - // Package-internal helper which resolves a DID document to the response bytes. 48 55 func (d *BaseDirectory) resolveDIDBytes(ctx context.Context, did syntax.DID) ([]byte, error) { 49 56 var b []byte 50 57 var err error
+3 -8
atproto/identity/directory.go
··· 10 10 "github.com/bluesky-social/indigo/atproto/syntax" 11 11 ) 12 12 13 - // Common for doing atproto identity lookups by DID or handle. 14 - // 15 - // The "Lookup" methods do bi-directional handle verification automatically, and format results in a compact atproto-specific struct ("Identity"). Clients and services should use these methods by default, instead of resolving handles or DIDs separately. 13 + // Ergonomic interface for atproto identity lookup, by DID or handle. 16 14 // 17 - // Handles which fail to resolve, or don't match DID alsoKnownAs, are an error. DIDs which resolve but the handle does not resolve back to the DID return an Identity where the Handle is the special `handle.invalid` value. 15 + // 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 16 // 19 - // The "Resolve" methods do direct resolution of just the identifier indicated. 17 + // 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 18 // 21 19 // Some example implementations of this interface could be: 22 20 // - basic direct resolution on every call ··· 27 25 LookupHandle(ctx context.Context, handle syntax.Handle) (*Identity, error) 28 26 LookupDID(ctx context.Context, did syntax.DID) (*Identity, error) 29 27 Lookup(ctx context.Context, atid syntax.AtIdentifier) (*Identity, error) 30 - 31 - ResolveDID(ctx context.Context, did syntax.DID) (map[string]any, error) 32 - ResolveHandle(ctx context.Context, handle syntax.Handle) (syntax.DID, error) 33 28 34 29 // Flushes any cache of the indicated identifier. If directory is not using caching, can ignore this. 35 30 Purge(ctx context.Context, i syntax.AtIdentifier) error
+11 -9
atproto/identity/mock_directory.go
··· 15 15 } 16 16 17 17 var _ Directory = (*MockDirectory)(nil) 18 + var _ Resolver = (*MockDirectory)(nil) 18 19 19 20 func NewMockDirectory() MockDirectory { 20 21 return MockDirectory{ ··· 72 73 return did, nil 73 74 } 74 75 75 - func (d *MockDirectory) ResolveDID(ctx context.Context, did syntax.DID) (map[string]any, error) { 76 + func (d *MockDirectory) ResolveDID(ctx context.Context, did syntax.DID) (*DIDDocument, error) { 76 77 ident, ok := d.Identities[did] 77 78 if !ok { 78 79 return nil, ErrDIDNotFound 79 80 } 80 81 doc := ident.DIDDocument() 81 - b, err := json.Marshal(doc) 82 - if err != nil { 83 - return nil, err 82 + return &doc, nil 83 + } 84 + 85 + func (d *MockDirectory) ResolveDIDRaw(ctx context.Context, did syntax.DID) (json.RawMessage, error) { 86 + ident, ok := d.Identities[did] 87 + if !ok { 88 + return nil, ErrDIDNotFound 84 89 } 85 - var m map[string]any 86 - if err := json.Unmarshal(b, &m); err != nil { 87 - return nil, err 88 - } 89 - return m, nil 90 + doc := ident.DIDDocument() 91 + return json.Marshal(doc) 90 92 } 91 93 92 94 func (d *MockDirectory) Purge(ctx context.Context, a syntax.AtIdentifier) error {
-5
atproto/identity/redisdir/redis_directory.go
··· 384 384 } 385 385 return errors.New("at-identifier neither a Handle nor a DID") 386 386 } 387 - 388 - func (d *RedisDirectory) ResolveDID(ctx context.Context, did syntax.DID) (map[string]any, error) { 389 - // XXX: cache this kind of doc separately 390 - return d.Inner.ResolveDID(ctx, did) 391 - }
+17
atproto/identity/resolver.go
··· 1 + package identity 2 + 3 + import ( 4 + "context" 5 + "encoding/json" 6 + 7 + "github.com/bluesky-social/indigo/atproto/syntax" 8 + ) 9 + 10 + // Low-level interface for resolving DIDs and atproto handles. 11 + // 12 + // Most atproto code should use the `identity.Directory` interface instead. 13 + type Resolver interface { 14 + ResolveDID(ctx context.Context, did syntax.DID) (*DIDDocument, error) 15 + ResolveDIDRaw(ctx context.Context, did syntax.DID) (json.RawMessage, error) 16 + ResolveHandle(ctx context.Context, handle syntax.Handle) (syntax.DID, error) 17 + }