@@ -2,12 +2,17 @@ package verifiable
22
33import (
44 "encoding/json"
5+ liberr "errors"
56 "fmt"
67
78 "github.com/iden3/go-merkletree-sql/v2"
89 "github.com/pkg/errors"
910)
1011
12+ var (
13+ ErrVerificationMethodNotFound = liberr .New ("verification method not found" )
14+ )
15+
1116// DIDDocument defines current supported did doc model.
1217type DIDDocument struct {
1318 Context interface {} `json:"@context"`
@@ -16,7 +21,78 @@ type DIDDocument struct {
1621 VerificationMethod []CommonVerificationMethod `json:"verificationMethod,omitempty"`
1722 AssertionMethod []Authentication `json:"assertionMethod,omitempty"`
1823 Authentication []Authentication `json:"authentication,omitempty"`
19- KeyAgreement []interface {} `json:"keyAgreement,omitempty"`
24+ KeyAgreement []Authentication `json:"keyAgreement,omitempty"`
25+ }
26+
27+ func (d * DIDDocument ) ResolveVerificationMethods () CommonVerificationMethods {
28+ return CommonVerificationMethods (d .VerificationMethod )
29+ }
30+
31+ func (d * DIDDocument ) resolveToVM (items []Authentication ) (CommonVerificationMethods , error ) {
32+ vms := make (CommonVerificationMethods , 0 , len (items ))
33+ for _ , auth := range items {
34+ if auth .IsDID () {
35+ vm , err := d .ResolveVerificationMethods ().FilterBy (WithID (auth .DID ()))
36+ if err != nil {
37+ return nil , err
38+ }
39+ if len (vm ) != 1 {
40+ return nil ,
41+ fmt .Errorf ("found %d verification methods for did: %s" , len (vm ), auth .DID ())
42+ }
43+ vms = append (vms , vm [0 ])
44+ continue
45+ }
46+ vms = append (vms , auth .CommonVerificationMethod )
47+ }
48+ return vms , nil
49+ }
50+
51+ func (d * DIDDocument ) ResolveAssertionVerificationMethods () (CommonVerificationMethods , error ) {
52+ return d .resolveToVM (d .AssertionMethod )
53+ }
54+
55+ func (d * DIDDocument ) ResolveAuthVerificationMethods () (CommonVerificationMethods , error ) {
56+ return d .resolveToVM (d .Authentication )
57+ }
58+
59+ func (d * DIDDocument ) ResolveKeyAgreementVerificationMethods () (CommonVerificationMethods , error ) {
60+ return d .resolveToVM (d .KeyAgreement )
61+ }
62+
63+ func (d * DIDDocument ) AllVerificationMethods () CommonVerificationMethods {
64+ alllen := len (d .VerificationMethod ) + len (d .Authentication ) +
65+ len (d .AssertionMethod ) + len (d .KeyAgreement )
66+ all := make (map [string ]CommonVerificationMethod , alllen )
67+
68+ for _ , vm := range d .VerificationMethod {
69+ all [vm .ID ] = vm
70+ }
71+
72+ appendVMs := func (auths []Authentication ) {
73+ for _ , auth := range auths {
74+ if auth .IsDID () {
75+ continue
76+ }
77+
78+ if _ , ok := all [auth .ID ]; ok {
79+ continue
80+ }
81+
82+ all [auth .ID ] = auth .CommonVerificationMethod
83+ }
84+ }
85+
86+ appendVMs (d .Authentication )
87+ appendVMs (d .AssertionMethod )
88+ appendVMs (d .KeyAgreement )
89+
90+ vms := make (CommonVerificationMethods , 0 , len (all ))
91+ for _ , vm := range all {
92+ vms = append (vms , vm )
93+ }
94+
95+ return vms
2096}
2197
2298// Service describes standard DID document service field.
@@ -55,6 +131,8 @@ type DeviceMetadata struct {
55131 PushToken string `json:"push_token"`
56132}
57133
134+ type CommonVerificationMethods []CommonVerificationMethod
135+
58136// CommonVerificationMethod DID doc verification method.
59137type CommonVerificationMethod struct {
60138 ID string `json:"id"`
@@ -182,3 +260,77 @@ type IdentityState struct {
182260 Info * StateInfo `json:"info,omitempty"`
183261 Global * GistInfo `json:"global,omitempty"`
184262}
263+
264+ type VerificationMethodFilter struct {
265+ byID string
266+ byType string
267+ byController string
268+ byJWKType string
269+ byJWKAlgorithm string
270+ }
271+
272+ type VerificationMethodFilterOpt func (* VerificationMethodFilter )
273+
274+ func WithID (id string ) VerificationMethodFilterOpt {
275+ return func (f * VerificationMethodFilter ) {
276+ f .byID = id
277+ }
278+ }
279+
280+ func WithType (typ string ) VerificationMethodFilterOpt {
281+ return func (f * VerificationMethodFilter ) {
282+ f .byType = typ
283+ }
284+ }
285+
286+ func WithController (controller string ) VerificationMethodFilterOpt {
287+ return func (f * VerificationMethodFilter ) {
288+ f .byController = controller
289+ }
290+ }
291+
292+ func WithJWKType (keyType string ) VerificationMethodFilterOpt {
293+ return func (f * VerificationMethodFilter ) {
294+ f .byJWKType = keyType
295+ }
296+ }
297+
298+ func WithJWKAlgorithm (algorithm string ) VerificationMethodFilterOpt {
299+ return func (f * VerificationMethodFilter ) {
300+ f .byJWKAlgorithm = algorithm
301+ }
302+ }
303+
304+ func (cvm CommonVerificationMethods ) FilterBy (opts ... VerificationMethodFilterOpt ) (CommonVerificationMethods , error ) {
305+ if len (opts ) == 0 {
306+ return nil , fmt .Errorf ("empty filter options" )
307+ }
308+ var filter VerificationMethodFilter
309+ for _ , opt := range opts {
310+ opt (& filter )
311+ }
312+
313+ filtered := CommonVerificationMethods {}
314+ for _ , vm := range cvm {
315+ if filter .byID != "" && vm .ID != filter .byID {
316+ continue
317+ }
318+ if filter .byType != "" && vm .Type != filter .byType {
319+ continue
320+ }
321+ if filter .byController != "" && vm .Controller != filter .byController {
322+ continue
323+ }
324+ if filter .byJWKType != "" && vm .PublicKeyJwk ["kty" ] != filter .byJWKType {
325+ continue
326+ }
327+ if filter .byJWKAlgorithm != "" && vm .PublicKeyJwk ["alg" ] != filter .byJWKAlgorithm {
328+ continue
329+ }
330+ filtered = append (filtered , vm )
331+ }
332+ if filter .byID != "" && len (filtered ) > 1 {
333+ return filtered [:1 ], nil
334+ }
335+ return filtered , nil
336+ }
0 commit comments