+2
-2
atproto/auth/http_test.go
+2
-2
atproto/auth/http_test.go
···
86
86
dir := identity.NewMockDirectory()
87
87
dir.Insert(identity.Identity{
88
88
DID: iss,
89
-
Keys: map[string]identity.Key{
90
-
"atproto": identity.Key{
89
+
Keys: map[string]identity.VerificationMethod{
90
+
"atproto": {
91
91
Type: "Multikey",
92
92
PublicKeyMultibase: pub.Multibase(),
93
93
},
+2
-2
atproto/auth/jwt_test.go
+2
-2
atproto/auth/jwt_test.go
···
100
100
dir := identity.NewMockDirectory()
101
101
dir.Insert(identity.Identity{
102
102
DID: iss,
103
-
Keys: map[string]identity.Key{
104
-
"atproto": identity.Key{
103
+
Keys: map[string]identity.VerificationMethod{
104
+
"atproto": {
105
105
Type: "Multikey",
106
106
PublicKeyMultibase: pub.Multibase(),
107
107
},
+1
-1
atproto/client/password_auth_test.go
+1
-1
atproto/client/password_auth_test.go
···
121
121
dir.Insert(identity.Identity{
122
122
DID: "did:web:account.example.com",
123
123
Handle: "user1.example.com",
124
-
Services: map[string]identity.Service{
124
+
Services: map[string]identity.ServiceEndpoint{
125
125
"atproto_pds": {
126
126
Type: "AtprotoPersonalDataServer",
127
127
URL: srv.URL,
+25
-25
atproto/identity/cache_directory.go
+25
-25
atproto/identity/cache_directory.go
···
16
16
Inner Directory
17
17
ErrTTL time.Duration
18
18
InvalidHandleTTL time.Duration
19
-
handleCache *expirable.LRU[syntax.Handle, HandleEntry]
20
-
identityCache *expirable.LRU[syntax.DID, IdentityEntry]
19
+
handleCache *expirable.LRU[syntax.Handle, handleEntry]
20
+
identityCache *expirable.LRU[syntax.DID, identityEntry]
21
21
didLookupChans sync.Map
22
22
handleLookupChans sync.Map
23
23
}
24
24
25
-
type HandleEntry struct {
25
+
type handleEntry struct {
26
26
Updated time.Time
27
27
DID syntax.DID
28
28
Err error
29
29
}
30
30
31
-
type IdentityEntry struct {
31
+
type identityEntry struct {
32
32
Updated time.Time
33
33
Identity *Identity
34
34
Err error
···
42
42
ErrTTL: errTTL,
43
43
InvalidHandleTTL: invalidHandleTTL,
44
44
Inner: inner,
45
-
handleCache: expirable.NewLRU[syntax.Handle, HandleEntry](capacity, nil, hitTTL),
46
-
identityCache: expirable.NewLRU[syntax.DID, IdentityEntry](capacity, nil, hitTTL),
45
+
handleCache: expirable.NewLRU[syntax.Handle, handleEntry](capacity, nil, hitTTL),
46
+
identityCache: expirable.NewLRU[syntax.DID, identityEntry](capacity, nil, hitTTL),
47
47
}
48
48
}
49
49
50
-
func (d *CacheDirectory) IsHandleStale(e *HandleEntry) bool {
50
+
func (d *CacheDirectory) isHandleStale(e *handleEntry) bool {
51
51
if e.Err != nil && time.Since(e.Updated) > d.ErrTTL {
52
52
return true
53
53
}
54
54
return false
55
55
}
56
56
57
-
func (d *CacheDirectory) IsIdentityStale(e *IdentityEntry) bool {
57
+
func (d *CacheDirectory) isIdentityStale(e *identityEntry) bool {
58
58
if e.Err != nil && time.Since(e.Updated) > d.ErrTTL {
59
59
return true
60
60
}
···
64
64
return false
65
65
}
66
66
67
-
func (d *CacheDirectory) updateHandle(ctx context.Context, h syntax.Handle) HandleEntry {
67
+
func (d *CacheDirectory) updateHandle(ctx context.Context, h syntax.Handle) handleEntry {
68
68
ident, err := d.Inner.LookupHandle(ctx, h)
69
69
if err != nil {
70
-
he := HandleEntry{
70
+
he := handleEntry{
71
71
Updated: time.Now(),
72
72
DID: "",
73
73
Err: err,
···
76
76
return he
77
77
}
78
78
79
-
entry := IdentityEntry{
79
+
entry := identityEntry{
80
80
Updated: time.Now(),
81
81
Identity: ident,
82
82
Err: nil,
83
83
}
84
-
he := HandleEntry{
84
+
he := handleEntry{
85
85
Updated: time.Now(),
86
86
DID: ident.DID,
87
87
Err: nil,
···
98
98
}
99
99
start := time.Now()
100
100
entry, ok := d.handleCache.Get(h)
101
-
if ok && !d.IsHandleStale(&entry) {
101
+
if ok && !d.isHandleStale(&entry) {
102
102
handleCacheHits.Inc()
103
103
handleResolution.WithLabelValues("lru", "cached").Inc()
104
104
handleResolutionDuration.WithLabelValues("lru", "cached").Observe(time.Since(start).Seconds())
···
118
118
case <-val.(chan struct{}):
119
119
// The result should now be in the cache
120
120
entry, ok := d.handleCache.Get(h)
121
-
if ok && !d.IsHandleStale(&entry) {
121
+
if ok && !d.isHandleStale(&entry) {
122
122
return entry.DID, entry.Err
123
123
}
124
124
return "", fmt.Errorf("identity not found in cache after coalesce returned")
···
148
148
return "", fmt.Errorf("unexpected control-flow error")
149
149
}
150
150
151
-
func (d *CacheDirectory) updateDID(ctx context.Context, did syntax.DID) IdentityEntry {
151
+
func (d *CacheDirectory) updateDID(ctx context.Context, did syntax.DID) identityEntry {
152
152
ident, err := d.Inner.LookupDID(ctx, did)
153
153
// persist the identity lookup error, instead of processing it immediately
154
-
entry := IdentityEntry{
154
+
entry := identityEntry{
155
155
Updated: time.Now(),
156
156
Identity: ident,
157
157
Err: err,
158
158
}
159
-
var he *HandleEntry
159
+
var he *handleEntry
160
160
// if *not* an error, then also update the handle cache
161
161
if nil == err && !ident.Handle.IsInvalidHandle() {
162
-
he = &HandleEntry{
162
+
he = &handleEntry{
163
163
Updated: time.Now(),
164
164
DID: did,
165
165
Err: nil,
···
174
174
}
175
175
176
176
func (d *CacheDirectory) LookupDID(ctx context.Context, did syntax.DID) (*Identity, error) {
177
-
id, _, err := d.LookupDIDWithCacheState(ctx, did)
177
+
id, _, err := d.lookupDIDWithCacheState(ctx, did)
178
178
return id, err
179
179
}
180
180
181
-
func (d *CacheDirectory) LookupDIDWithCacheState(ctx context.Context, did syntax.DID) (*Identity, bool, error) {
181
+
func (d *CacheDirectory) lookupDIDWithCacheState(ctx context.Context, did syntax.DID) (*Identity, bool, error) {
182
182
start := time.Now()
183
183
entry, ok := d.identityCache.Get(did)
184
-
if ok && !d.IsIdentityStale(&entry) {
184
+
if ok && !d.isIdentityStale(&entry) {
185
185
identityCacheHits.Inc()
186
186
didResolution.WithLabelValues("lru", "cached").Inc()
187
187
didResolutionDuration.WithLabelValues("lru", "cached").Observe(time.Since(start).Seconds())
···
201
201
case <-val.(chan struct{}):
202
202
// The result should now be in the cache
203
203
entry, ok := d.identityCache.Get(did)
204
-
if ok && !d.IsIdentityStale(&entry) {
204
+
if ok && !d.isIdentityStale(&entry) {
205
205
return entry.Identity, false, entry.Err
206
206
}
207
207
return nil, false, fmt.Errorf("identity not found in cache after coalesce returned")
···
232
232
}
233
233
234
234
func (d *CacheDirectory) LookupHandle(ctx context.Context, h syntax.Handle) (*Identity, error) {
235
-
ident, _, err := d.LookupHandleWithCacheState(ctx, h)
235
+
ident, _, err := d.lookupHandleWithCacheState(ctx, h)
236
236
return ident, err
237
237
}
238
238
239
-
func (d *CacheDirectory) LookupHandleWithCacheState(ctx context.Context, h syntax.Handle) (*Identity, bool, error) {
239
+
func (d *CacheDirectory) lookupHandleWithCacheState(ctx context.Context, h syntax.Handle) (*Identity, bool, error) {
240
240
h = h.Normalize()
241
241
did, err := d.ResolveHandle(ctx, h)
242
242
if err != nil {
243
243
return nil, false, err
244
244
}
245
-
ident, hit, err := d.LookupDIDWithCacheState(ctx, did)
245
+
ident, hit, err := d.lookupDIDWithCacheState(ctx, did)
246
246
if err != nil {
247
247
return nil, hit, err
248
248
}
+10
-8
atproto/identity/identity.go
+10
-8
atproto/identity/identity.go
···
20
20
21
21
// These fields represent a parsed subset of a DID document. They are all nullable. Note that the services and keys maps do not preserve order, so they don't exactly round-trip DID documents.
22
22
AlsoKnownAs []string
23
-
Services map[string]Service
24
-
Keys map[string]Key
23
+
Services map[string]ServiceEndpoint
24
+
Keys map[string]VerificationMethod
25
25
}
26
26
27
-
type Key struct {
27
+
// Sub-field type for [Identity], representing a crytographic public key declared as a "verificationMethod" in the DID document.
28
+
type VerificationMethod struct {
28
29
Type string
29
30
PublicKeyMultibase string
30
31
}
31
32
32
-
type Service struct {
33
+
// Sub-field type for [Identity], representing a service endpoint URL declared in the DID document.
34
+
type ServiceEndpoint struct {
33
35
Type string
34
36
URL string
35
37
}
···
38
40
//
39
41
// Always returns an invalid Handle field; calling code should only populate that field if it has been bi-directionally verified.
40
42
func ParseIdentity(doc *DIDDocument) Identity {
41
-
keys := make(map[string]Key, len(doc.VerificationMethod))
43
+
keys := make(map[string]VerificationMethod, len(doc.VerificationMethod))
42
44
for _, vm := range doc.VerificationMethod {
43
45
parts := strings.SplitN(vm.ID, "#", 2)
44
46
if len(parts) < 2 {
···
53
55
continue
54
56
}
55
57
// TODO: verify that ID and type match for atproto-specific services?
56
-
keys[parts[1]] = Key{
58
+
keys[parts[1]] = VerificationMethod{
57
59
Type: vm.Type,
58
60
PublicKeyMultibase: vm.PublicKeyMultibase,
59
61
}
60
62
}
61
-
svc := make(map[string]Service, len(doc.Service))
63
+
svc := make(map[string]ServiceEndpoint, len(doc.Service))
62
64
for _, s := range doc.Service {
63
65
parts := strings.SplitN(s.ID, "#", 2)
64
66
if len(parts) < 2 {
···
69
71
continue
70
72
}
71
73
// TODO: verify that ID and type match for atproto-specific services?
72
-
svc[parts[1]] = Service{
74
+
svc[parts[1]] = ServiceEndpoint{
73
75
Type: s.Type,
74
76
URL: s.ServiceEndpoint,
75
77
}
+5
-5
atproto/identity/redisdir/redis_directory.go
+5
-5
atproto/identity/redisdir/redis_directory.go
···
273
273
}
274
274
275
275
func (d *RedisDirectory) LookupDID(ctx context.Context, did syntax.DID) (*identity.Identity, error) {
276
-
id, _, err := d.LookupDIDWithCacheState(ctx, did)
276
+
id, _, err := d.lookupDIDWithCacheState(ctx, did)
277
277
return id, err
278
278
}
279
279
280
-
func (d *RedisDirectory) LookupDIDWithCacheState(ctx context.Context, did syntax.DID) (*identity.Identity, bool, error) {
280
+
func (d *RedisDirectory) lookupDIDWithCacheState(ctx context.Context, did syntax.DID) (*identity.Identity, bool, error) {
281
281
start := time.Now()
282
282
var entry identityEntry
283
283
err := d.identityCache.Get(ctx, redisDirPrefix+did.String(), &entry)
···
340
340
}
341
341
342
342
func (d *RedisDirectory) LookupHandle(ctx context.Context, h syntax.Handle) (*identity.Identity, error) {
343
-
ident, _, err := d.LookupHandleWithCacheState(ctx, h)
343
+
ident, _, err := d.lookupHandleWithCacheState(ctx, h)
344
344
return ident, err
345
345
}
346
346
347
-
func (d *RedisDirectory) LookupHandleWithCacheState(ctx context.Context, h syntax.Handle) (*identity.Identity, bool, error) {
347
+
func (d *RedisDirectory) lookupHandleWithCacheState(ctx context.Context, h syntax.Handle) (*identity.Identity, bool, error) {
348
348
h = h.Normalize()
349
349
did, err := d.ResolveHandle(ctx, h)
350
350
if err != nil {
351
351
return nil, false, err
352
352
}
353
-
ident, hit, err := d.LookupDIDWithCacheState(ctx, did)
353
+
ident, hit, err := d.lookupDIDWithCacheState(ctx, did)
354
354
if err != nil {
355
355
return nil, hit, err
356
356
}