this repo has no description
0
fork

Configure Feed

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

Improve JSON handling of identity caching

+45 -20
+9 -9
atproto/identity/identity.go
··· 13 13 14 14 // Represents an atproto identity. Could be a regular user account, or a service account (eg, feed generator) 15 15 type Identity struct { 16 - DID syntax.DID 16 + DID syntax.DID `json:"did"` 17 17 18 18 // Handle/DID mapping must be bi-directionally verified. If that fails, the Handle should be the special 'handle.invalid' value 19 - Handle syntax.Handle 19 + Handle syntax.Handle `json:"handle"` 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 - AlsoKnownAs []string 23 - Services map[string]ServiceEndpoint 24 - Keys map[string]VerificationMethod 22 + AlsoKnownAs []string `json:"alsoKnownAs"` 23 + Services map[string]ServiceEndpoint `json:"services"` 24 + Keys map[string]VerificationMethod `json:"keys"` 25 25 } 26 26 27 27 // Sub-field type for [Identity], representing a crytographic public key declared as a "verificationMethod" in the DID document. 28 28 type VerificationMethod struct { 29 - Type string 30 - PublicKeyMultibase string 29 + Type string `json:"type"` 30 + PublicKeyMultibase string `json:"publicKeyMultibase"` 31 31 } 32 32 33 33 // Sub-field type for [Identity], representing a service endpoint URL declared in the DID document. 34 34 type ServiceEndpoint struct { 35 - Type string 36 - URL string 35 + Type string `json:"type"` 36 + URL string `json:"url"` 37 37 } 38 38 39 39 // Extracts the information relevant to atproto from an arbitrary DID document.
+4 -1
cmd/butterfly/cmd_discover.go
··· 106 106 var s store.Store 107 107 switch storeMode { 108 108 case "stdout": 109 - s = &store.StdoutStore{Mode: store.StdoutStoreModeStats} 109 + s = &store.StdoutStore{Mode: store.StdoutStoreModePassthrough} 110 110 case "tarfiles": 111 111 s = store.NewTarfilesStore(storageDir) 112 112 case "duckdb": ··· 151 151 fmt.Printf("Failed to resolve %s: %v", did, err) 152 152 } 153 153 } 154 + 155 + v, err := resolver.ResolveDID(ctx, "did:plc:upo6iq6ekh66d4mbhmiy6se4") 156 + fmt.Println(v) 154 157 155 158 return nil 156 159 }
+32 -10
cmd/butterfly/identity/store_directory.go
··· 27 27 } 28 28 29 29 type handleEntry struct { 30 - Updated time.Time 31 - DID syntax.DID 32 - Err error 30 + Updated time.Time `json:"updated"` 31 + DID syntax.DID `json:"did"` 32 + Err error `json:"err"` 33 33 } 34 34 35 35 type identityEntry struct { 36 - Updated time.Time 37 - Identity *identity.Identity 38 - Err error 36 + Updated time.Time `json:"updated"` 37 + Identity *identity.Identity `json:"identity"` 38 + Err error `json:"err"` 39 39 } 40 40 41 41 // var _ identity.Directory = (*StoreDirectory)(nil) TODO is this needed? ··· 300 300 func getHandle(store store.Store, handle syntax.Handle) (*handleEntry, error) { 301 301 entryJSON, err := store.KvGet(handleCache, string(handle)) 302 302 if entryJSON != "" { 303 - // TODO - is this parse safe? do we need to be checking the output or anything? 304 303 var entry handleEntry 305 304 if err := json.Unmarshal([]byte(entryJSON), &entry); err != nil { 305 + return nil, err 306 + } 307 + if err := validateHandleEntry(&entry); err != nil { 306 308 return nil, err 307 309 } 308 310 return &entry, nil ··· 311 313 } 312 314 313 315 func putHandle(store store.Store, handle syntax.Handle, entry *handleEntry) error { 314 - // TODO - is this right? 315 316 entryJSON, err := json.Marshal(entry) 316 317 if err != nil { 317 318 return err ··· 326 327 func getIdent(store store.Store, did syntax.DID) (*identityEntry, error) { 327 328 entryJSON, err := store.KvGet(identityCache, string(did)) 328 329 if entryJSON != "" { 329 - // TODO - is this parse safe? do we need to be checking the output or anything? 330 330 var entry identityEntry 331 331 if err := json.Unmarshal([]byte(entryJSON), &entry); err != nil { 332 332 return nil, err 333 333 } 334 + if err := validateIdentityEntry(&entry); err != nil { 335 + return nil, err 336 + } 334 337 return &entry, nil 335 338 } 336 339 return nil, err 337 340 } 338 341 339 342 func putIdent(store store.Store, did syntax.DID, entry *identityEntry) error { 340 - // TODO - is this right? 341 343 entryJSON, err := json.Marshal(entry) 342 344 if err != nil { 343 345 return err ··· 348 350 func delIdent(store store.Store, did syntax.DID) error { 349 351 return store.KvDel(identityCache, string(did)) 350 352 } 353 + 354 + func validateHandleEntry(entry *handleEntry) error { 355 + _, err := syntax.ParseDID(string(entry.DID)) 356 + if err != nil { 357 + return fmt.Errorf("invalid handle entry: invalid did, %w", err) 358 + } 359 + return nil 360 + } 361 + 362 + func validateIdentityEntry(entry *identityEntry) error { 363 + _, err := syntax.ParseDID(string(entry.Identity.DID)) 364 + if err != nil { 365 + return fmt.Errorf("invalid identity entry: invalid did, %w", err) 366 + } 367 + _, err = syntax.ParseHandle(string(entry.Identity.Handle)) 368 + if err != nil { 369 + return fmt.Errorf("invalid identity entry: invalid handle, %w", err) 370 + } 371 + return nil 372 + }