diff --git a/go.work.sum b/go.work.sum index 446d2ac28..6d651bd1e 100644 --- a/go.work.sum +++ b/go.work.sum @@ -508,6 +508,7 @@ github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:Fecb github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/guptarohit/asciigraph v0.5.5/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag= github.com/hashicorp/consul/api v1.28.2/go.mod h1:KyzqzgMEya+IZPcD65YFoOVAgPpbfERu4I/tzG6/ueE= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -626,6 +627,7 @@ github.com/linxGnu/grocksdb v1.8.6/go.mod h1:xZCIb5Muw+nhbDK4Y5UJuOrin5MceOuiXkV github.com/linxGnu/grocksdb v1.8.12/go.mod h1:xZCIb5Muw+nhbDK4Y5UJuOrin5MceOuiXkVUR7vp4WY= github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= github.com/macabu/inamedparam v0.1.3/go.mod h1:93FLICAIk/quk7eaPPQvbzihUdn/QkGDwIZEoLtpH6I= github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= @@ -862,8 +864,6 @@ github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRci github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -953,6 +953,7 @@ go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDs go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc= go.opentelemetry.io/otel/trace v1.11.0/go.mod h1:nyYjis9jy0gytE9LXGU+/m1sHTKbRY0fX0hulNNDP1U= go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= diff --git a/x/did/types/constant_test.go b/x/did/types/constant_test.go index 99deb2bd4..1825ccf98 100644 --- a/x/did/types/constant_test.go +++ b/x/did/types/constant_test.go @@ -5,9 +5,12 @@ import ( ) var ( - ValidTestDID = "did:cheqd:testnet:zABCDEFG123456789abcd" - ValidTestDID2 = "did:cheqd:testnet:zABCDEFG987654321abcd" - InvalidTestDID = "badDid" + ValidTestDID = "did:cheqd:testnet:zABCDEFG123456789abcd" + ValidTestDID2 = "did:cheqd:testnet:zABCDEFG987654321abcd" + InvalidTestDID = "badDid" + ValidParticipantID = 123 + ValidParamsRef = "https://resolver.cheqd.net/1.0/identifiers/did:cheqd:testnet:09b20561-7339-40ea-a377-05ea35a0e82a/resources/08f35fe3-bc2a-4666-90da-972a5b05645f" + ValidCurveType = "Bls12381BBSVerificationKeyDock2023" ) type TestJWKKey struct { diff --git a/x/did/types/diddoc_assertion_method.go b/x/did/types/diddoc_assertion_method.go index 9d579da72..ac327b675 100644 --- a/x/did/types/diddoc_assertion_method.go +++ b/x/did/types/diddoc_assertion_method.go @@ -1,10 +1,17 @@ package types type AssertionMethodJSONUnescaped struct { - Id string `json:"id"` - Type string `json:"type"` - Controller string `json:"controller"` - PublicKeyBase58 *string `json:"publicKeyBase58,omitempty"` - PublicKeyMultibase *string `json:"publicKeyMultibase,omitempty"` - PublicKeyJwk *string `json:"publicKeyJwk,omitempty"` + Id string `json:"id"` + Type string `json:"type"` + Controller string `json:"controller"` + PublicKeyBase58 *string `json:"publicKeyBase58,omitempty"` + PublicKeyMultibase *string `json:"publicKeyMultibase,omitempty"` + PublicKeyJwk *string `json:"publicKeyJwk,omitempty"` + Metadata *AssertionMethodJSONUnescapedMetadata `json:"metadata,omitempty"` +} + +type AssertionMethodJSONUnescapedMetadata struct { + ParticipantId *int `json:"participantId"` + ParamsRef *string `json:"paramsRef"` + CurveType *string `json:"curveType"` } diff --git a/x/did/types/diddoc_diddoc_test.go b/x/did/types/diddoc_diddoc_test.go index e33be57a8..519db3905 100644 --- a/x/did/types/diddoc_diddoc_test.go +++ b/x/did/types/diddoc_diddoc_test.go @@ -28,7 +28,6 @@ var _ = DescribeTable("DIDDoc Validation tests", func(testCase DIDDocTestCase) { Expect(err.Error()).To(ContainSubstring(testCase.errorMsg)) } }, - Entry( "DIDDoc is valid", DIDDocTestCase{ @@ -259,7 +258,7 @@ var _ = DescribeTable("DIDDoc Validation tests", func(testCase DIDDocTestCase) { errorMsg: "", }), Entry( - "Assertion method has wrong fragment", + "Assertion method can accept arbitrary fragment", DIDDocTestCase{ didDoc: &DidDoc{ Id: ValidTestDID, @@ -282,8 +281,40 @@ var _ = DescribeTable("DIDDoc Validation tests", func(testCase DIDDocTestCase) { return strconv.Quote(string(b)) }()}, }, - isValid: false, - errorMsg: "assertionMethod should be a valid key reference within the DID document's verification method", + isValid: true, + errorMsg: "", + }), + Entry( + "Assertion method can accept metadata", + DIDDocTestCase{ + didDoc: &DidDoc{ + Id: ValidTestDID, + Controller: []string{ValidTestDID}, + VerificationMethod: []*VerificationMethod{ + { + Id: fmt.Sprintf("%s#fragment", ValidTestDID), + VerificationMethodType: "Ed25519VerificationKey2020", + Controller: ValidTestDID, + VerificationMaterial: ValidEd25519VerificationKey2020VerificationMaterial, + }, + }, + AssertionMethod: []string{fmt.Sprintf("%s#fragment", ValidTestDID), func() string { + b, _ := json.Marshal(AssertionMethodJSONUnescaped{ + Id: fmt.Sprintf("%s#fragment", ValidTestDID), + Type: "Ed25519VerificationKey2018", + Controller: ValidTestDID, + PublicKeyBase58: &ValidEd25519VerificationKey2018VerificationMaterial, // arbitrarily chosen, loosely validated + Metadata: &AssertionMethodJSONUnescapedMetadata{ + ParticipantId: &ValidParticipantID, + ParamsRef: &ValidParamsRef, + CurveType: &ValidCurveType, + }, + }) + return strconv.Quote(string(b)) + }()}, + }, + isValid: true, + errorMsg: "", }), Entry( "Assertion method has invalid protobuf value", @@ -371,6 +402,6 @@ var _ = DescribeTable("DIDDoc Validation tests", func(testCase DIDDocTestCase) { }()}, }, isValid: false, - errorMsg: "assertionMethod should be a DIDUrl or an Escaped JSON string", + errorMsg: "assertionMethod should be a valid DIDUrl or an Escaped JSON string", }), ) diff --git a/x/did/types/validate.go b/x/did/types/validate.go index 9ac3f72ae..0e5407be6 100644 --- a/x/did/types/validate.go +++ b/x/did/types/validate.go @@ -109,40 +109,40 @@ func IsDIDUrl(allowedNamespaces []string, pathRule, queryRule, fragmentRule Vali func IsAssertionMethod(allowedNamespaces []string, didDoc DidDoc) *CustomErrorRule { return NewCustomErrorRule(func(value interface{}) error { - err := validation.Validate(value, IsDIDUrl(allowedNamespaces, Empty, Empty, Required), HasPrefix(didDoc.Id)) casted, ok := value.(string) if !ok { panic("IsAssertionMethod must be only applied on string properties") } + unescapedJSON, err := strconv.Unquote(casted) if err == nil { - for _, v := range didDoc.VerificationMethod { - if v.Id == casted { - return nil - } + if err := utils.ValidateProtobufFields(unescapedJSON); err != nil { + return err } - return errors.New("assertionMethod should be a valid key reference within the DID document's verification method") - } + var result AssertionMethodJSONUnescaped + if err = json.Unmarshal([]byte(unescapedJSON), &result); err != nil { + return errors.New("assertionMethod should be a valid DIDUrl or an Escaped JSON string with id, type and controller values") + } - unescapedJSON, err := strconv.Unquote(casted) - if err != nil { - return errors.New("assertionMethod should be a DIDUrl or an Escaped JSON string") + return validation.ValidateStruct(&result, + validation.Field(&result.Id, validation.Required, IsAssertionMethod(allowedNamespaces, didDoc)), + validation.Field(&result.Controller, validation.Required, IsDID(allowedNamespaces)), + ) } - if err := utils.ValidateProtobufFields(unescapedJSON); err != nil { - return err + err = validation.Validate(value, IsDIDUrl(allowedNamespaces, Empty, Empty, Required), HasPrefix(didDoc.Id)) + if err != nil { + return errors.New("assertionMethod should be a valid DIDUrl or an Escaped JSON string with id, type and controller values") } - var result AssertionMethodJSONUnescaped - if err = json.Unmarshal([]byte(unescapedJSON), &result); err != nil { - return errors.New("assertionMethod should be a DIDUrl or an Escaped JSON string with id, type and controller values") + for _, v := range didDoc.VerificationMethod { + if v.Id == casted { + return nil + } } - return validation.ValidateStruct(&result, - validation.Field(&result.Id, validation.Required, IsAssertionMethod(allowedNamespaces, didDoc)), - validation.Field(&result.Controller, validation.Required, IsDID(allowedNamespaces)), - ) + return errors.New("assertionMethod should be a valid key reference within the DID document's verification method") }) }