From e5741f5aae3a0c8d83dfc1535bd2bcac6cdb4ed0 Mon Sep 17 00:00:00 2001 From: reinkrul Date: Wed, 8 Nov 2023 12:18:04 +0100 Subject: [PATCH] Update go-did library to support DIDURL for DID URLs (#2583) --- api/ssi_types_test.go | 2 +- auth/services/irma/signer_test.go | 3 ++- auth/services/oauth/authz_server_test.go | 2 +- crypto/api/v1/api.go | 6 +++--- didman/didman_test.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- network/dag/keys_test.go | 2 +- network/network_integration_test.go | 2 +- network/network_test.go | 4 ++-- storage/mock.go | 18 +++++++++--------- vcr/ambassador_test.go | 2 +- vcr/holder/wallet_test.go | 2 +- vcr/issuer/issuer_test.go | 2 +- vcr/issuer/keyresolver_test.go | 2 +- vcr/issuer/network_publisher.go | 10 +++++----- vcr/issuer/network_publisher_test.go | 2 +- vcr/vcr.go | 2 +- vcr/vcr_test.go | 6 +++--- vcr/verifier/verifier_test.go | 2 +- vdr/didjwk/resolver.go | 6 +++--- vdr/didjwk/resolver_test.go | 2 +- vdr/didkey/resolver.go | 2 +- vdr/didnuts/ambassador_test.go | 6 ++---- vdr/didnuts/creator.go | 2 +- vdr/didnuts/creator_test.go | 2 +- vdr/didnuts/didstore/merge_test.go | 13 ++++++------- vdr/didnuts/manipulator.go | 2 +- vdr/didnuts/resolver_test.go | 4 ++-- vdr/didweb/web.go | 4 ++-- vdr/didweb/web_test.go | 19 +++++-------------- vdr/management/management.go | 2 +- vdr/management/management_mock.go | 2 +- vdr/resolver/did.go | 2 +- vdr/resolver/did_test.go | 2 +- vdr/resolver/key_test.go | 4 ++-- vdr/vdr_test.go | 2 +- 37 files changed, 71 insertions(+), 82 deletions(-) diff --git a/api/ssi_types_test.go b/api/ssi_types_test.go index 30d3ea4841..91155745c4 100644 --- a/api/ssi_types_test.go +++ b/api/ssi_types_test.go @@ -172,7 +172,7 @@ func createDidDocument() did.Document { KeyAgreement: did.VerificationRelationships{verificationRelationship}, VerificationMethod: did.VerificationMethods{verificationMethod}, Controller: []did.DID{did.MustParseDID("did:example:controller")}, - ID: verificationMethod.ID, + ID: verificationMethod.ID.DID, Service: []did.Service{ { ID: ssi.MustParseURI("example"), diff --git a/auth/services/irma/signer_test.go b/auth/services/irma/signer_test.go index 6cba581302..2f84ccb6a6 100644 --- a/auth/services/irma/signer_test.go +++ b/auth/services/irma/signer_test.go @@ -21,6 +21,7 @@ package irma import ( "context" "errors" + "github.com/nuts-foundation/go-did/did" "github.com/stretchr/testify/require" "testing" @@ -109,7 +110,7 @@ func TestService_StartSigningSession(t *testing.T) { func TestService_SigningSessionStatus(t *testing.T) { correctContractText := "EN:PractitionerLogin:v3 I hereby declare to act on behalf of verpleeghuis De nootjes located in Caretown. This declaration is valid from maandag 1 oktober 12:00:00 until maandag 1 oktober 13:00:00." holder := vdr.TestDIDA - keyID := holder + keyID := did.DIDURL{DID: holder} keyID.Fragment = keyID.ID ctx := context.Background() diff --git a/auth/services/oauth/authz_server_test.go b/auth/services/oauth/authz_server_test.go index c190f63bda..c6373b28ff 100644 --- a/auth/services/oauth/authz_server_test.go +++ b/auth/services/oauth/authz_server_test.go @@ -80,7 +80,7 @@ func getAuthorizerDIDDocument() *did.Document { doc := did.Document{ ID: id, } - signingKeyID := id + signingKeyID := did.DIDURL{DID: id} signingKeyID.Fragment = "signing-key" key, err := did.NewVerificationMethod(signingKeyID, ssi.JsonWebKey2020, id, authorizerSigningKey.Public()) if err != nil { diff --git a/crypto/api/v1/api.go b/crypto/api/v1/api.go index ca676e0887..1fe53d425d 100644 --- a/crypto/api/v1/api.go +++ b/crypto/api/v1/api.go @@ -191,8 +191,8 @@ func (w *Wrapper) EncryptJwe(ctx context.Context, request EncryptJweRequestObjec return EncryptJwe200TextResponse(jwe), err } -func (w *Wrapper) resolvePublicKey(id *did.DID) (key crypt.PublicKey, keyID ssi.URI, err error) { - if id.IsURL() { +func (w *Wrapper) resolvePublicKey(id *did.DIDURL) (key crypt.PublicKey, keyID ssi.URI, err error) { + if id.Fragment != "" { // Assume it is a keyId now := time.Now() key, err = w.K.ResolveKeyByID(id.String(), &now, resolver.KeyAgreement) @@ -202,7 +202,7 @@ func (w *Wrapper) resolvePublicKey(id *did.DID) (key crypt.PublicKey, keyID ssi. keyID = id.URI() } else { // Assume it is a DID - keyID, key, err = w.K.ResolveKey(*id, nil, resolver.KeyAgreement) + keyID, key, err = w.K.ResolveKey(id.DID, nil, resolver.KeyAgreement) if err != nil { return nil, ssi.URI{}, err } diff --git a/didman/didman_test.go b/didman/didman_test.go index d84285e850..193b2c157c 100644 --- a/didman/didman_test.go +++ b/didman/didman_test.go @@ -539,7 +539,7 @@ func TestDidman_GetContactInformation(t *testing.T) { func TestDidman_DeleteEndpointsByType(t *testing.T) { id, _ := did.ParseDID("did:nuts:123") - serviceID := *id + serviceID := did.DIDURL{DID: *id} serviceID.Fragment = "abc" endpointType := "eOverdracht" endpoints := []did.Service{{ diff --git a/go.mod b/go.mod index 338e69d4e3..f90f0af48e 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/nats-io/nats-server/v2 v2.10.4 github.com/nats-io/nats.go v1.31.0 github.com/nuts-foundation/crypto-ecies v0.0.0-20211207143025-5b84f9efce2b - github.com/nuts-foundation/go-did v0.8.0 + github.com/nuts-foundation/go-did v0.9.0 github.com/nuts-foundation/go-leia/v4 v4.0.0 github.com/nuts-foundation/go-stoabs v1.9.0 // check the oapi-codegen tool version in the makefile when upgrading the runtime diff --git a/go.sum b/go.sum index 754cb7d5fb..487e47787b 100644 --- a/go.sum +++ b/go.sum @@ -445,8 +445,8 @@ github.com/nightlyone/lockfile v1.0.0/go.mod h1:rywoIealpdNse2r832aiD9jRk8ErCatR github.com/npillmayer/nestext v0.1.3/go.mod h1:h2lrijH8jpicr25dFY+oAJLyzlya6jhnuG+zWp9L0Uk= github.com/nuts-foundation/crypto-ecies v0.0.0-20211207143025-5b84f9efce2b h1:80icUxWHwE1MrIOOEK5rxrtyKOgZeq5Iu1IjAEkggTY= github.com/nuts-foundation/crypto-ecies v0.0.0-20211207143025-5b84f9efce2b/go.mod h1:6YUioYirD6/8IahZkoS4Ypc8xbeJW76Xdk1QKcziNTM= -github.com/nuts-foundation/go-did v0.8.0 h1:L+XEaX87/P2SY762rhxIUDxj3LNrvk1LDJTtNgQ810o= -github.com/nuts-foundation/go-did v0.8.0/go.mod h1:L39mh6SBsuenqeZw2JxARx4a/bwdARwchG2x3zPMTjc= +github.com/nuts-foundation/go-did v0.9.0 h1:JBz1cYaMxplKZ31QyWierrR3Yt2RIpaxZTt8KFm4Ph4= +github.com/nuts-foundation/go-did v0.9.0/go.mod h1:L39mh6SBsuenqeZw2JxARx4a/bwdARwchG2x3zPMTjc= github.com/nuts-foundation/go-leia/v4 v4.0.0 h1:/unYCk18qGG2HWcJK4ld4CaM6k7Tdr0bR1vQd1Jwfcg= github.com/nuts-foundation/go-leia/v4 v4.0.0/go.mod h1:A246dA4nhY99OPCQpG/XbQ/iPyyfSaJchanivuPWpao= github.com/nuts-foundation/go-stoabs v1.9.0 h1:zK+ugfolaJYyBvGwsRuavLVdycXk4Yw/1gI+tz17lWQ= diff --git a/network/dag/keys_test.go b/network/dag/keys_test.go index 89d8bf56e3..ca60aea340 100644 --- a/network/dag/keys_test.go +++ b/network/dag/keys_test.go @@ -39,7 +39,7 @@ func TestNutsKeyResolver_ResolvePublicKey(t *testing.T) { doc := &did.Document{ ID: did.MustParseDID("did:nuts:123"), } - mockKID := doc.ID + mockKID := did.DIDURL{DID: doc.ID} mockKID.Fragment = "key-1" vm, err := did.NewVerificationMethod(mockKID, ssi.JsonWebKey2020, doc.ID, pk.Public()) require.NoError(t, err) diff --git a/network/network_integration_test.go b/network/network_integration_test.go index 3e463b7e73..d689dd7231 100644 --- a/network/network_integration_test.go +++ b/network/network_integration_test.go @@ -1006,7 +1006,7 @@ func resetIntegrationTest(t *testing.T) { writeDIDDocument := func(subject string) { nodeDID := did.MustParseDID(subject) document := did.Document{ID: nodeDID} - kid := nodeDID + kid := did.DIDURL{DID: nodeDID} kid.Fragment = "key-1" key, _ := keyStore.New(audit.TestContext(), func(_ crypto.PublicKey) (string, error) { return kid.String(), nil diff --git a/network/network_test.go b/network/network_test.go index 751822a7ee..fadfb31cd6 100644 --- a/network/network_test.go +++ b/network/network_test.go @@ -615,7 +615,7 @@ func TestNetwork_selfTestNutsCommAddress(t *testing.T) { func TestNetwork_validateNodeDID(t *testing.T) { ctx := context.Background() - keyID := *nodeDID + keyID := did.DIDURL{DID: *nodeDID} keyID.Fragment = "some-key" key := crypto.NewTestKey(keyID.String()).(*crypto.TestKey).PrivateKey documentWithoutNutsCommService := &did.Document{ @@ -1252,7 +1252,7 @@ func TestNetwork_checkHealth(t *testing.T) { }) t.Run("authentication", func(t *testing.T) { - keyID := *nodeDID + keyID := did.DIDURL{DID: *nodeDID} keyID.Fragment = "some-key" completeDocument := &did.Document{ KeyAgreement: []did.VerificationRelationship{ diff --git a/storage/mock.go b/storage/mock.go index de364cd577..559941d7bd 100644 --- a/storage/mock.go +++ b/storage/mock.go @@ -238,7 +238,7 @@ func (m *MockSessionDatabase) EXPECT() *MockSessionDatabaseMockRecorder { // GetStore mocks base method. func (m *MockSessionDatabase) GetStore(ttl time.Duration, keys ...string) SessionStore { m.ctrl.T.Helper() - varargs := []interface{}{ttl} + varargs := []any{ttl} for _, a := range keys { varargs = append(varargs, a) } @@ -248,9 +248,9 @@ func (m *MockSessionDatabase) GetStore(ttl time.Duration, keys ...string) Sessio } // GetStore indicates an expected call of GetStore. -func (mr *MockSessionDatabaseMockRecorder) GetStore(ttl interface{}, keys ...interface{}) *gomock.Call { +func (mr *MockSessionDatabaseMockRecorder) GetStore(ttl any, keys ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{ttl}, keys...) + varargs := append([]any{ttl}, keys...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStore", reflect.TypeOf((*MockSessionDatabase)(nil).GetStore), varargs...) } @@ -298,7 +298,7 @@ func (m *MockSessionStore) Delete(key string) error { } // Delete indicates an expected call of Delete. -func (mr *MockSessionStoreMockRecorder) Delete(key interface{}) *gomock.Call { +func (mr *MockSessionStoreMockRecorder) Delete(key any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockSessionStore)(nil).Delete), key) } @@ -312,13 +312,13 @@ func (m *MockSessionStore) Exists(key string) bool { } // Exists indicates an expected call of Exists. -func (mr *MockSessionStoreMockRecorder) Exists(key interface{}) *gomock.Call { +func (mr *MockSessionStoreMockRecorder) Exists(key any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Exists", reflect.TypeOf((*MockSessionStore)(nil).Exists), key) } // Get mocks base method. -func (m *MockSessionStore) Get(key string, target interface{}) error { +func (m *MockSessionStore) Get(key string, target any) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Get", key, target) ret0, _ := ret[0].(error) @@ -326,13 +326,13 @@ func (m *MockSessionStore) Get(key string, target interface{}) error { } // Get indicates an expected call of Get. -func (mr *MockSessionStoreMockRecorder) Get(key, target interface{}) *gomock.Call { +func (mr *MockSessionStoreMockRecorder) Get(key, target any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockSessionStore)(nil).Get), key, target) } // Put mocks base method. -func (m *MockSessionStore) Put(key string, value interface{}) error { +func (m *MockSessionStore) Put(key string, value any) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Put", key, value) ret0, _ := ret[0].(error) @@ -340,7 +340,7 @@ func (m *MockSessionStore) Put(key string, value interface{}) error { } // Put indicates an expected call of Put. -func (mr *MockSessionStoreMockRecorder) Put(key, value interface{}) *gomock.Call { +func (mr *MockSessionStoreMockRecorder) Put(key, value any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockSessionStore)(nil).Put), key, value) } diff --git a/vcr/ambassador_test.go b/vcr/ambassador_test.go index d32cf908da..11f25f5fb6 100644 --- a/vcr/ambassador_test.go +++ b/vcr/ambassador_test.go @@ -375,7 +375,7 @@ func (s stubRoundTripper) RoundTrip(request *http.Request) (*http.Response, erro func documentWithPublicKey(t *testing.T, publicKey crypt.PublicKey) *did.Document { id := did.MustParseDID("did:nuts:CuE3qeFGGLhEAS3gKzhMCeqd1dGa9at5JCbmCfyMU2Ey") - keyID := id + keyID := did.DIDURL{DID: id} keyID.Fragment = "sNGDQ3NlOe6Icv0E7_ufviOLG6Y25bSEyS5EbXBgp8Y" vm, err := did.NewVerificationMethod(keyID, ssi.JsonWebKey2020, id, publicKey) require.NoError(t, err) diff --git a/vcr/holder/wallet_test.go b/vcr/holder/wallet_test.go index a4c9d30dfc..efc4ca2adb 100644 --- a/vcr/holder/wallet_test.go +++ b/vcr/holder/wallet_test.go @@ -460,7 +460,7 @@ func createCredential(keyID string) vc.VerifiableCredential { "city": "Hengelo", "name": "De beste zorg" }, - "id": "` + did.MustParseDIDURL(keyID).WithoutURL().String() + `" + "id": "` + did.MustParseDIDURL(keyID).DID.String() + `" }, "issuanceDate": "2021-12-24T13:21:29.087205+01:00", "issuer": "did:nuts:4tzMaWfpizVKeA8fscC3JTdWBc3asUWWMj5hUFHdWX3H", diff --git a/vcr/issuer/issuer_test.go b/vcr/issuer/issuer_test.go index d978de26c7..9f3cc9e30e 100644 --- a/vcr/issuer/issuer_test.go +++ b/vcr/issuer/issuer_test.go @@ -690,7 +690,7 @@ func Test_issuer_Revoke(t *testing.T) { store: store, } revocation, err := sut.Revoke(ctx, ssi.MustParseURI("a#38E90E8C-F7E5-4333-B63A-F9DD155A0272")) - assert.EqualError(t, err, "failed to extract issuer: invalid DID") + assert.EqualError(t, err, "failed to extract issuer: invalid DID: DID must start with 'did:'") assert.Nil(t, revocation) }) diff --git a/vcr/issuer/keyresolver_test.go b/vcr/issuer/keyresolver_test.go index 2353aff38c..eae952d030 100644 --- a/vcr/issuer/keyresolver_test.go +++ b/vcr/issuer/keyresolver_test.go @@ -34,7 +34,7 @@ import ( func Test_vdrKeyResolver_ResolveAssertionKey(t *testing.T) { ctx := context.Background() issuerDID, _ := did.ParseDID("did:nuts:123") - methodID := *issuerDID + methodID := did.DIDURL{DID: *issuerDID} methodID.Fragment = "abc" publicKey := crypto.NewTestKey(issuerDID.String() + "abc").Public() newMethod, err := did.NewVerificationMethod(methodID, ssi.JsonWebKey2020, *issuerDID, publicKey) diff --git a/vcr/issuer/network_publisher.go b/vcr/issuer/network_publisher.go index 416f77f275..7eaac674cc 100644 --- a/vcr/issuer/network_publisher.go +++ b/vcr/issuer/network_publisher.go @@ -73,13 +73,13 @@ func (p networkPublisher) PublishCredential(ctx context.Context, verifiableCrede } } - key, err := p.keyResolver.ResolveAssertionKey(ctx, *issuerDID) + key, err := p.keyResolver.ResolveAssertionKey(ctx, issuerDID.DID) if err != nil { return fmt.Errorf("could not resolve an assertion key for issuer: %w", err) } // find did document/metadata for originating TXs - _, meta, err := p.didResolver.Resolve(*issuerDID, nil) + _, meta, err := p.didResolver.Resolve(issuerDID.DID, nil) if err != nil { return err } @@ -103,7 +103,7 @@ func (p networkPublisher) PublishCredential(ctx context.Context, verifiableCrede } func (p networkPublisher) generateParticipants(verifiableCredential vc.VerifiableCredential) ([]did.DID, error) { - issuer, _ := did.ParseDID(verifiableCredential.Issuer.String()) + issuer, _ := did.ParseDIDURL(verifiableCredential.Issuer.String()) participants := make([]did.DID, 0) var ( base []credential.BaseCredentialSubject @@ -118,7 +118,7 @@ func (p networkPublisher) generateParticipants(verifiableCredential vc.Verifiabl } // participants are not the issuer and the credentialSubject.id but the DID that holds the concrete endpoint for the NutsComm service - for _, vcp := range []did.DID{*issuer, *credentialSubjectID} { + for _, vcp := range []did.DID{issuer.DID, *credentialSubjectID} { serviceOwner, err := p.resolveNutsCommServiceOwner(vcp) if err != nil { return nil, fmt.Errorf("failed to resolve participating node (did=%s): %w", vcp.String(), err) @@ -149,7 +149,7 @@ func (p networkPublisher) resolveNutsCommServiceOwner(DID did.DID) (*did.DID, er } func (p networkPublisher) PublishRevocation(ctx context.Context, revocation credential.Revocation) error { - issuerDID, err := did.ParseDIDURL(revocation.Issuer.String()) + issuerDID, err := did.ParseDID(revocation.Issuer.String()) if err != nil { return fmt.Errorf("invalid revocation issuer: %w", err) } diff --git a/vcr/issuer/network_publisher_test.go b/vcr/issuer/network_publisher_test.go index e0199471c6..29b2b0612a 100644 --- a/vcr/issuer/network_publisher_test.go +++ b/vcr/issuer/network_publisher_test.go @@ -335,7 +335,7 @@ func Test_networkPublisher_PublishRevocation(t *testing.T) { publisher := NewNetworkPublisher(nil, nil, nil) revocationToPublish := credential.Revocation{} err := publisher.PublishRevocation(ctx, revocationToPublish) - assert.EqualError(t, err, "invalid revocation issuer: invalid DID") + assert.EqualError(t, err, "invalid revocation issuer: invalid DID: DID must start with 'did:'") }) }) diff --git a/vcr/vcr.go b/vcr/vcr.go index ea44364c24..a5a1a8f7b7 100644 --- a/vcr/vcr.go +++ b/vcr/vcr.go @@ -544,7 +544,7 @@ func (c *vcr) Untrusted(credentialType ssi.URI) ([]ssi.URI, error) { if err != nil { return err } - _, _, err = didResolver.Resolve(*issuerDid, nil) + _, _, err = didResolver.Resolve(issuerDid.DID, nil) if err != nil { if !(errors.Is(err, did.DeactivatedErr) || errors.Is(err, resolver.ErrNoActiveController)) { return err diff --git a/vcr/vcr_test.go b/vcr/vcr_test.go index 8290c4c4c4..ccb85482d4 100644 --- a/vcr/vcr_test.go +++ b/vcr/vcr_test.go @@ -382,19 +382,19 @@ func TestVcr_Untrusted(t *testing.T) { t.Run("Untrusted", func(t *testing.T) { confirmTrustedStatus(t, instance, testCredential.Issuer, instance.Untrusted, 0) confirmUntrustedStatus(t, func(issuer ssi.URI) ([]ssi.URI, error) { - mockDidResolver.EXPECT().Resolve(did.MustParseDIDURL(testCredential.Issuer.String()), nil).Return(nil, nil, nil) + mockDidResolver.EXPECT().Resolve(did.MustParseDID(testCredential.Issuer.String()), nil).Return(nil, nil, nil) return instance.Untrusted(issuer) }, 1) }) t.Run("Untrusted - did deactivated", func(t *testing.T) { confirmUntrustedStatus(t, func(issuer ssi.URI) ([]ssi.URI, error) { - mockDidResolver.EXPECT().Resolve(did.MustParseDIDURL(testCredential.Issuer.String()), nil).Return(nil, nil, did.DeactivatedErr) + mockDidResolver.EXPECT().Resolve(did.MustParseDID(testCredential.Issuer.String()), nil).Return(nil, nil, did.DeactivatedErr) return instance.Untrusted(issuer) }, 0) }) t.Run("Untrusted - no active controller", func(t *testing.T) { confirmUntrustedStatus(t, func(issuer ssi.URI) ([]ssi.URI, error) { - mockDidResolver.EXPECT().Resolve(did.MustParseDIDURL(testCredential.Issuer.String()), nil).Return(nil, nil, resolver.ErrNoActiveController) + mockDidResolver.EXPECT().Resolve(did.MustParseDID(testCredential.Issuer.String()), nil).Return(nil, nil, resolver.ErrNoActiveController) return instance.Untrusted(issuer) }, 0) }) diff --git a/vcr/verifier/verifier_test.go b/vcr/verifier/verifier_test.go index 8f1d647b9b..9bbffea192 100644 --- a/vcr/verifier/verifier_test.go +++ b/vcr/verifier/verifier_test.go @@ -99,7 +99,7 @@ func Test_verifier_Validate(t *testing.T) { require.NoError(t, err) template := testCredential(t) - template.Issuer = did.MustParseDIDURL(key.KID()).WithoutURL().URI() + template.Issuer = did.MustParseDIDURL(key.KID()).DID.URI() cred, err := vc.CreateJWTVerifiableCredential(audit.TestContext(), template, func(ctx context.Context, claims map[string]interface{}, headers map[string]interface{}) (string, error) { return keyStore.SignJWT(ctx, claims, headers, key) diff --git a/vdr/didjwk/resolver.go b/vdr/didjwk/resolver.go index bcb78e0493..dae339209d 100644 --- a/vdr/didjwk/resolver.go +++ b/vdr/didjwk/resolver.go @@ -82,9 +82,9 @@ func (w Resolver) Resolve(id did.DID, _ *resolver.ResolveMetadata) (*did.Documen // Create a new DID verification method. // See https://www.w3.org/TR/did-core/#verification-methods - keyID := id.WithoutURL() + keyID := did.DIDURL{DID: id} keyID.Fragment = "0" - verificationMethod, err := did.NewVerificationMethod(keyID, godid.JsonWebKey2020, id.WithoutURL(), publicRawKey) + verificationMethod, err := did.NewVerificationMethod(keyID, godid.JsonWebKey2020, id, publicRawKey) if err != nil { return nil, nil, fmt.Errorf("failed to create verification method: %w", err) } @@ -93,7 +93,7 @@ func (w Resolver) Resolve(id did.DID, _ *resolver.ResolveMetadata) (*did.Documen var document did.Document // Set the document ID - document.ID = id.WithoutURL() + document.ID = id // Add the verification method document.AddAssertionMethod(verificationMethod) diff --git a/vdr/didjwk/resolver_test.go b/vdr/didjwk/resolver_test.go index 887621d5fa..0be0e9aee1 100644 --- a/vdr/didjwk/resolver_test.go +++ b/vdr/didjwk/resolver_test.go @@ -69,7 +69,7 @@ func TestResolver_Resolve(t *testing.T) { // Generate a test function using the specified JWK JSON string return func(t *testing.T) { // Parse the DID - id := did.MustParseDIDURL("did:jwk:" + id) + id := did.MustParseDID("did:jwk:" + id) // Resolve the DID, which returns a document/error doc, md, err := resolver.Resolve(id, nil) diff --git a/vdr/didkey/resolver.go b/vdr/didkey/resolver.go index 3e01fb266a..1d84a5809c 100644 --- a/vdr/didkey/resolver.go +++ b/vdr/didkey/resolver.go @@ -121,7 +121,7 @@ func (r Resolver) Resolve(id did.DID, _ *resolver.ResolveMetadata) (*did.Documen }, ID: id, } - keyID := id + keyID := did.DIDURL{DID: id} keyID.Fragment = id.ID vm, err := did.NewVerificationMethod(keyID, ssi.JsonWebKey2020, id, key) if err != nil { diff --git a/vdr/didnuts/ambassador_test.go b/vdr/didnuts/ambassador_test.go index 7c7c630e25..c6d251aeda 100644 --- a/vdr/didnuts/ambassador_test.go +++ b/vdr/didnuts/ambassador_test.go @@ -801,13 +801,11 @@ func newDidDocWithOptions(opts management.DIDCreationOptions) (did.Document, jwk didDocument, key, err := docCreator.Create(audit.TestContext(), opts) signingKey, _ := jwk.FromRaw(key.Public()) thumbStr, _ := crypto.Thumbprint(signingKey) - didStr := fmt.Sprintf("did:nuts:%s", thumbStr) - id, _ := did.ParseDID(didStr) - didDocument.ID = *id + didDocument.ID = did.MustParseDID(fmt.Sprintf("did:nuts:%s", thumbStr)) if err != nil { return did.Document{}, nil, err } - serviceID := didDocument.ID + serviceID := did.DIDURL{DID: didDocument.ID} serviceID.Fragment = "1234" didDocument.Service = []did.Service{ { diff --git a/vdr/didnuts/creator.go b/vdr/didnuts/creator.go index fdd4c4e98a..a271b29a9a 100644 --- a/vdr/didnuts/creator.go +++ b/vdr/didnuts/creator.go @@ -113,7 +113,7 @@ func getKIDName(pKey crypto.PublicKey, idFunc func(key jwk.Key) (string, error)) } // assemble - kid := &did.DID{} + kid := &did.DIDURL{} kid.Method = MethodName kid.ID = idString kid.Fragment = jwKey.KeyID() diff --git a/vdr/didnuts/creator_test.go b/vdr/didnuts/creator_test.go index d3b30145f0..9eb4cec779 100644 --- a/vdr/didnuts/creator_test.go +++ b/vdr/didnuts/creator_test.go @@ -62,7 +62,7 @@ func TestCreator_Create(t *testing.T) { assert.NoError(t, err, "create should not return an error") assert.NotNil(t, doc, "create should return a document") assert.NotNil(t, key, "create should return a Key") - assert.Equal(t, did.MustParseDIDURL(kc.key.KID()).WithoutURL(), doc.ID, "the DID Doc should have the expected id") + assert.Equal(t, did.MustParseDIDURL(kc.key.KID()).DID, doc.ID, "the DID Doc should have the expected id") assert.Len(t, doc.VerificationMethod, 1, "it should have one verificationMethod") assert.Equal(t, kc.key.KID(), doc.VerificationMethod[0].ID.String(), "verificationMethod should have the correct id") diff --git a/vdr/didnuts/didstore/merge_test.go b/vdr/didnuts/didstore/merge_test.go index 649ded67eb..501da614ce 100644 --- a/vdr/didnuts/didstore/merge_test.go +++ b/vdr/didnuts/didstore/merge_test.go @@ -27,15 +27,14 @@ import ( func TestMerge(t *testing.T) { didA, _ := did.ParseDID("did:nuts:A") - didB, _ := did.ParseDID("did:nuts:B") - uriA := ssi.MustParseURI("did:nuts:A#A") - uriB := ssi.MustParseURI("did:nuts:A#B") - vmA := &did.VerificationMethod{ID: *didA, Type: ssi.JsonWebKey2020} - vmB := &did.VerificationMethod{ID: *didB, Type: ssi.JsonWebKey2020} + uriA := did.MustParseDIDURL("did:nuts:A#A") + uriB := did.MustParseDIDURL("did:nuts:A#B") + vmA := &did.VerificationMethod{ID: uriA, Type: ssi.JsonWebKey2020} + vmB := &did.VerificationMethod{ID: uriB, Type: ssi.JsonWebKey2020} vrA := &did.VerificationRelationship{VerificationMethod: vmA} vrB := &did.VerificationRelationship{VerificationMethod: vmB} - serviceA := did.Service{ID: uriA, Type: "type A"} - serviceB := did.Service{ID: uriB, Type: "type B"} + serviceA := did.Service{ID: uriA.URI(), Type: "type A"} + serviceB := did.Service{ID: uriB.URI(), Type: "type B"} type test struct { title string diff --git a/vdr/didnuts/manipulator.go b/vdr/didnuts/manipulator.go index 9e2f2ad0a4..4702cee121 100644 --- a/vdr/didnuts/manipulator.go +++ b/vdr/didnuts/manipulator.go @@ -73,7 +73,7 @@ func (u Manipulator) AddVerificationMethod(ctx context.Context, id did.DID, keyU } // RemoveVerificationMethod is a helper function to remove a verificationMethod from a DID Document -func (u Manipulator) RemoveVerificationMethod(ctx context.Context, id, keyID did.DID) error { +func (u Manipulator) RemoveVerificationMethod(ctx context.Context, id did.DID, keyID did.DIDURL) error { doc, meta, err := u.Resolver.Resolve(id, &resolver.ResolveMetadata{AllowDeactivated: true}) if err != nil { return err diff --git a/vdr/didnuts/resolver_test.go b/vdr/didnuts/resolver_test.go index 92bc9206c3..d4379a0f98 100644 --- a/vdr/didnuts/resolver_test.go +++ b/vdr/didnuts/resolver_test.go @@ -244,7 +244,7 @@ func TestResolveControllers(t *testing.T) { // Doc C is active docCID, _ := did.ParseDID("did:nuts:C") - docCIDCapInv := *docCID + docCIDCapInv := did.DIDURL{DID: *docCID} docCIDCapInv.Fragment = "cap-inv" docC := did.Document{ID: *docCID} docC.AddCapabilityInvocation(&did.VerificationMethod{ID: docCIDCapInv}) @@ -252,7 +252,7 @@ func TestResolveControllers(t *testing.T) { // Doc A is active docAID, _ := did.ParseDID("did:nuts:A") - docAIDCapInv := *docAID + docAIDCapInv := did.DIDURL{DID: *docAID} docAIDCapInv.Fragment = "cap-inv" docA := did.Document{ID: *docAID} docA.Controller = []did.DID{docA.ID, docB.ID, docC.ID} diff --git a/vdr/didweb/web.go b/vdr/didweb/web.go index 288aaebc94..368222f057 100644 --- a/vdr/didweb/web.go +++ b/vdr/didweb/web.go @@ -117,8 +117,8 @@ func (w Resolver) Resolve(id did.DID, _ *resolver.ResolveMetadata) (*did.Documen return nil, nil, fmt.Errorf("did:web JSON unmarshal error: %w", err) } - if !document.ID.Equals(id.WithoutURL()) { - return nil, nil, fmt.Errorf("did:web document ID mismatch: %s != %s", document.ID, id.WithoutURL()) + if !document.ID.Equals(id) { + return nil, nil, fmt.Errorf("did:web document ID mismatch: %s != %s", document.ID, id) } return &document, &resolver.DocumentMetadata{}, nil diff --git a/vdr/didweb/web_test.go b/vdr/didweb/web_test.go index 577fdca1ee..d8c7093a45 100644 --- a/vdr/didweb/web_test.go +++ b/vdr/didweb/web_test.go @@ -131,15 +131,6 @@ func TestResolver_Resolve(t *testing.T) { assert.NotNil(t, md) assert.NotNil(t, doc) }) - t.Run("resolve DID with path", func(t *testing.T) { - id := did.MustParseDIDURL(baseDID.String() + "/some/path") - doc, md, err := resolver.Resolve(id, nil) - - require.NoError(t, err) - assert.NotNil(t, md) - require.NotNil(t, doc) - assert.Equal(t, baseDID, doc.ID) - }) t.Run("resolve without port number", func(t *testing.T) { // The other tests all use a port number, since the test HTTPS server is running on a random port. @@ -163,7 +154,7 @@ func TestResolver_Resolve(t *testing.T) { assert.Equal(t, "https://example.com/.well-known/did.json", requestURL) }) t.Run("not found", func(t *testing.T) { - id := did.MustParseDIDURL(baseDID.String() + ":not-found") + id := did.MustParseDID(baseDID.String() + ":not-found") doc, md, err := resolver.Resolve(id, nil) assert.EqualError(t, err, "did:web non-ok HTTP status: 404 Not Found") @@ -171,7 +162,7 @@ func TestResolver_Resolve(t *testing.T) { assert.Nil(t, doc) }) t.Run("unsupported content-type", func(t *testing.T) { - id := did.MustParseDIDURL(baseDID.String() + ":unsupported-content-type") + id := did.MustParseDID(baseDID.String() + ":unsupported-content-type") doc, md, err := resolver.Resolve(id, nil) assert.EqualError(t, err, "did:web unsupported content-type: text/plain") @@ -179,7 +170,7 @@ func TestResolver_Resolve(t *testing.T) { assert.Nil(t, doc) }) t.Run("server returns invalid JSON", func(t *testing.T) { - id := did.MustParseDIDURL(baseDID.String() + ":invalid-json") + id := did.MustParseDID(baseDID.String() + ":invalid-json") doc, md, err := resolver.Resolve(id, nil) assert.EqualError(t, err, "did:web JSON unmarshal error: invalid character '\\x01' looking for beginning of value") @@ -187,7 +178,7 @@ func TestResolver_Resolve(t *testing.T) { assert.Nil(t, doc) }) t.Run("server returns no content-type", func(t *testing.T) { - id := did.MustParseDIDURL(baseDID.String() + ":no-content-type") + id := did.MustParseDID(baseDID.String() + ":no-content-type") doc, md, err := resolver.Resolve(id, nil) assert.EqualError(t, err, "did:web invalid content-type: mime: no media type") @@ -195,7 +186,7 @@ func TestResolver_Resolve(t *testing.T) { assert.Nil(t, doc) }) t.Run("ID in document does not match DID being resolved", func(t *testing.T) { - id := did.MustParseDIDURL(baseDID.String() + ":invalid-id-in-document") + id := did.MustParseDID(baseDID.String() + ":invalid-id-in-document") doc, md, err := resolver.Resolve(id, nil) assert.ErrorContains(t, err, "did:web document ID mismatch") diff --git a/vdr/management/management.go b/vdr/management/management.go index 2bd7846ea6..76d53eb145 100644 --- a/vdr/management/management.go +++ b/vdr/management/management.go @@ -58,7 +58,7 @@ type DocManipulator interface { // It returns an ErrNotFound when there is no VerificationMethod with the provided kid in the document. // It returns an ErrDeactivated when the DID document has the deactivated state. // It returns an ErrDIDNotManagedByThisNode if the DID document is not managed by this node. - RemoveVerificationMethod(ctx context.Context, id, keyID did.DID) error + RemoveVerificationMethod(ctx context.Context, id did.DID, keyID did.DIDURL) error // AddVerificationMethod generates a new key and adds it, wrapped as a VerificationMethod, to a DID document. // It accepts a DID as identifier for the DID document. diff --git a/vdr/management/management_mock.go b/vdr/management/management_mock.go index 29159293b4..f3d5f10cc2 100644 --- a/vdr/management/management_mock.go +++ b/vdr/management/management_mock.go @@ -146,7 +146,7 @@ func (mr *MockDocManipulatorMockRecorder) Deactivate(ctx, id any) *gomock.Call { } // RemoveVerificationMethod mocks base method. -func (m *MockDocManipulator) RemoveVerificationMethod(ctx context.Context, id, keyID did.DID) error { +func (m *MockDocManipulator) RemoveVerificationMethod(ctx context.Context, id did.DID, keyID did.DIDURL) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "RemoveVerificationMethod", ctx, id, keyID) ret0, _ := ret[0].(error) diff --git a/vdr/resolver/did.go b/vdr/resolver/did.go index 9e1a93626e..0db789b871 100644 --- a/vdr/resolver/did.go +++ b/vdr/resolver/did.go @@ -158,7 +158,7 @@ func GetDIDFromURL(didURL string) (did.DID, error) { if err != nil { return did.DID{}, err } - return parsed.WithoutURL(), nil + return parsed.DID, nil } // IsDeactivated returns true if the DID.Document has already been deactivated diff --git a/vdr/resolver/did_test.go b/vdr/resolver/did_test.go index 98cabb7a4e..f0b0cbf743 100644 --- a/vdr/resolver/did_test.go +++ b/vdr/resolver/did_test.go @@ -97,7 +97,7 @@ func Test_deactivatedError_Is(t *testing.T) { func newDidDoc() did.Document { privateKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) id := did.MustParseDID("did:example:sakjsakldjsakld") - keyID := id + keyID := did.DIDURL{DID: id} keyID.Fragment = "key-1" vm, _ := did.NewVerificationMethod(keyID, ssi.JsonWebKey2020, id, privateKey.Public()) doc := did.Document{ diff --git a/vdr/resolver/key_test.go b/vdr/resolver/key_test.go index a103ae0fdc..d9db59ea7e 100644 --- a/vdr/resolver/key_test.go +++ b/vdr/resolver/key_test.go @@ -51,7 +51,7 @@ func TestKeyResolver_ResolveKey(t *testing.T) { }) t.Run("error - key not found", func(t *testing.T) { - keyId, key, err := keyResolver.ResolveKey(did.MustParseDIDURL(doc.ID.String()), nil, CapabilityDelegation) + keyId, key, err := keyResolver.ResolveKey(did.MustParseDID(doc.ID.String()), nil, CapabilityDelegation) assert.EqualError(t, err, "key not found in DID document") assert.Empty(t, keyId) assert.Nil(t, key) @@ -86,7 +86,7 @@ func TestKeyResolver_ResolveKeyByID(t *testing.T) { }) t.Run("error - document not found", func(t *testing.T) { - unknownDID := did.MustParseDIDURL("did:example:123") + unknownDID := did.MustParseDID("did:example:123") resolver.EXPECT().Resolve(unknownDID, gomock.Any()).Return(nil, nil, ErrNotFound) key, err := keyResolver.ResolveKeyByID(unknownDID.String()+"#456", nil, AssertionMethod) assert.EqualError(t, err, "unable to find the DID document") diff --git a/vdr/vdr_test.go b/vdr/vdr_test.go index 89f17ea820..208776bd65 100644 --- a/vdr/vdr_test.go +++ b/vdr/vdr_test.go @@ -339,7 +339,7 @@ func TestVDR_ConflictingDocuments(t *testing.T) { t.Run("ok - 1 owned conflict", func(t *testing.T) { client := crypto.NewMemoryCryptoInstance() - keyID := TestDIDA + keyID := did.DIDURL{DID: TestDIDA} keyID.Fragment = "1" _, _ = client.New(audit.TestContext(), crypto.StringNamingFunc(keyID.String())) vdr := NewVDR(client, nil, didstore.NewTestStore(t), nil)