1package identity
2
3import (
4 "context"
5 "encoding/json"
6 "fmt"
7 "sync"
8
9 "github.com/bluesky-social/indigo/atproto/syntax"
10)
11
12// A fake identity directory, for use in tests
13type MockDirectory struct {
14 mu *sync.RWMutex
15 Handles map[syntax.Handle]syntax.DID
16 Identities map[syntax.DID]Identity
17}
18
19var _ Directory = (*MockDirectory)(nil)
20var _ Resolver = (*MockDirectory)(nil)
21
22func NewMockDirectory() MockDirectory {
23 return MockDirectory{
24 mu: &sync.RWMutex{},
25 Handles: make(map[syntax.Handle]syntax.DID),
26 Identities: make(map[syntax.DID]Identity),
27 }
28}
29
30func (d *MockDirectory) Insert(ident Identity) {
31 d.mu.Lock()
32 defer d.mu.Unlock()
33
34 if !ident.Handle.IsInvalidHandle() {
35 d.Handles[ident.Handle.Normalize()] = ident.DID
36 }
37 d.Identities[ident.DID] = ident
38}
39
40func (d *MockDirectory) LookupHandle(ctx context.Context, h syntax.Handle) (*Identity, error) {
41 d.mu.RLock()
42 defer d.mu.RUnlock()
43
44 h = h.Normalize()
45 did, ok := d.Handles[h]
46 if !ok {
47 return nil, ErrHandleNotFound
48 }
49 ident, ok := d.Identities[did]
50 if !ok {
51 return nil, ErrDIDNotFound
52 }
53 return &ident, nil
54}
55
56func (d *MockDirectory) LookupDID(ctx context.Context, did syntax.DID) (*Identity, error) {
57 d.mu.RLock()
58 defer d.mu.RUnlock()
59
60 ident, ok := d.Identities[did]
61 if !ok {
62 return nil, ErrDIDNotFound
63 }
64 return &ident, nil
65}
66
67func (d *MockDirectory) Lookup(ctx context.Context, a syntax.AtIdentifier) (*Identity, error) {
68 d.mu.RLock()
69 defer d.mu.RUnlock()
70
71 handle, err := a.AsHandle()
72 if nil == err { // if not an error, is a Handle
73 return d.LookupHandle(ctx, handle)
74 }
75 did, err := a.AsDID()
76 if nil == err { // if not an error, is a DID
77 return d.LookupDID(ctx, did)
78 }
79 return nil, fmt.Errorf("at-identifier neither a Handle nor a DID")
80}
81
82func (d *MockDirectory) ResolveHandle(ctx context.Context, h syntax.Handle) (syntax.DID, error) {
83 d.mu.RLock()
84 defer d.mu.RUnlock()
85
86 h = h.Normalize()
87 did, ok := d.Handles[h]
88 if !ok {
89 return "", ErrHandleNotFound
90 }
91 return did, nil
92}
93
94func (d *MockDirectory) ResolveDID(ctx context.Context, did syntax.DID) (*DIDDocument, error) {
95 d.mu.RLock()
96 defer d.mu.RUnlock()
97
98 ident, ok := d.Identities[did]
99 if !ok {
100 return nil, ErrDIDNotFound
101 }
102 doc := ident.DIDDocument()
103 return &doc, nil
104}
105
106func (d *MockDirectory) ResolveDIDRaw(ctx context.Context, did syntax.DID) (json.RawMessage, error) {
107 d.mu.RLock()
108 defer d.mu.RUnlock()
109
110 ident, ok := d.Identities[did]
111 if !ok {
112 return nil, ErrDIDNotFound
113 }
114 doc := ident.DIDDocument()
115 return json.Marshal(doc)
116}
117
118func (d *MockDirectory) Purge(ctx context.Context, a syntax.AtIdentifier) error {
119 d.mu.Lock()
120 defer d.mu.Unlock()
121
122 return nil
123}