diff --git a/auth/api/iam/api.go b/auth/api/iam/api.go index 53f5095ef7..1e056255a0 100644 --- a/auth/api/iam/api.go +++ b/auth/api/iam/api.go @@ -37,6 +37,7 @@ import ( "net/http" "net/url" "strings" + "sync/atomic" "time" "github.com/lestrrat-go/jwx/v2/jwt" @@ -101,8 +102,8 @@ type Wrapper struct { vdr vdr.VDR jwtSigner nutsCrypto.JWTSigner keyResolver resolver.KeyResolver - jar JAR subjectManager didsubject.SubjectManager + _jar atomic.Value } func New( @@ -114,6 +115,7 @@ func New( if err != nil { panic(err) } + keyResolver := resolver.DIDKeyResolver{Resolver: vdrInstance.Resolver()} return &Wrapper{ auth: authInstance, policyBackend: policyBackend, @@ -123,14 +125,18 @@ func New( subjectManager: subjectManager, jsonldManager: jsonldManager, jwtSigner: jwtSigner, - keyResolver: resolver.DIDKeyResolver{Resolver: vdrInstance.Resolver()}, - jar: &jar{ - auth: authInstance, - jwtSigner: jwtSigner, - keyResolver: resolver.DIDKeyResolver{Resolver: vdrInstance.Resolver()}, - resolver: vdrInstance.Resolver(), - }, + keyResolver: keyResolver, + } +} + +func (r Wrapper) jar() JAR { + // todo sync + current := r._jar.Load().(JAR) + if current == nil { + current = NewJAR(r.auth, r.jwtSigner, r.keyResolver, r.auth.IAMClient()) + r._jar.Store(current) } + return current } func (r Wrapper) Routes(router core.EchoRouter) { @@ -457,7 +463,7 @@ func (r Wrapper) HandleAuthorizeRequest(ctx context.Context, request HandleAutho // The caller must ensure ownDID is actually owned by this node. func (r Wrapper) handleAuthorizeRequest(ctx context.Context, subject string, ownMetadata oauth.AuthorizationServerMetadata, request url.URL) (HandleAuthorizeRequestResponseObject, error) { // parse and validate as JAR (RFC9101, JWT Authorization Request) - requestObject, err := r.jar.Parse(ctx, ownMetadata, request.Query()) + requestObject, err := r.jar().Parse(ctx, ownMetadata, request.Query()) if err != nil { // already an oauth.OAuth2Error return nil, err @@ -523,7 +529,7 @@ func (r Wrapper) RequestJWTByGet(ctx context.Context, request RequestJWTByGetReq } // TODO: supported signature types should be checked - token, err := r.jar.Sign(ctx, ro.Claims) + token, err := r.jar().Sign(ctx, ro.Claims) if err != nil { return nil, oauth.OAuth2Error{ Code: oauth.ServerError, @@ -577,7 +583,7 @@ func (r Wrapper) RequestJWTByPost(ctx context.Context, request RequestJWTByPostR } // TODO: supported signature types should be checked - token, err := r.jar.Sign(ctx, ro.Claims) + token, err := r.jar().Sign(ctx, ro.Claims) if err != nil { return nil, oauth.OAuth2Error{ Code: oauth.ServerError, @@ -896,7 +902,7 @@ func (r Wrapper) createAuthorizationRequest(ctx context.Context, subject string, // request_uri requestURIID := nutsCrypto.GenerateNonce() - requestObj := r.jar.Create(*clientDID, clientID.String(), audience, modifier) + requestObj := r.jar().Create(*clientDID, clientID.String(), audience, modifier) if err := r.authzRequestObjectStore().Put(requestURIID, requestObj); err != nil { return nil, err } diff --git a/auth/api/iam/api_test.go b/auth/api/iam/api_test.go index 28cbbf7378..d9bc0f4590 100644 --- a/auth/api/iam/api_test.go +++ b/auth/api/iam/api_test.go @@ -1406,6 +1406,17 @@ func newCustomTestClient(t testing.TB, publicURL *url.URL, authEndpointEnabled b subjectManager.EXPECT().Exists(gomock.Any(), verifierSubject).Return(true, nil).AnyTimes() subjectManager.EXPECT().Exists(gomock.Any(), unknownSubjectID).Return(false, nil).AnyTimes() + client := &Wrapper{ + auth: authnServices, + vdr: mockVDR, + subjectManager: subjectManager, + vcr: mockVCR, + storageEngine: storageEngine, + policyBackend: policyInstance, + keyResolver: keyResolver, + jwtSigner: jwtSigner, + } + client._jar.Store(mockJAR) return &testCtx{ ctrl: ctrl, authnServices: authnServices, @@ -1423,16 +1434,6 @@ func newCustomTestClient(t testing.TB, publicURL *url.URL, authEndpointEnabled b keyResolver: keyResolver, jwtSigner: jwtSigner, jar: mockJAR, - client: &Wrapper{ - auth: authnServices, - vdr: mockVDR, - subjectManager: subjectManager, - vcr: mockVCR, - storageEngine: storageEngine, - policyBackend: policyInstance, - keyResolver: keyResolver, - jwtSigner: jwtSigner, - jar: mockJAR, - }, + client: client, } } diff --git a/auth/api/iam/jar.go b/auth/api/iam/jar.go index 32a8f01b86..0abe49d459 100644 --- a/auth/api/iam/jar.go +++ b/auth/api/iam/jar.go @@ -19,17 +19,19 @@ package iam import ( + "bytes" "context" "crypto" - "net/url" - "slices" - + "errors" + "github.com/lestrrat-go/jwx/v2/jwk" "github.com/lestrrat-go/jwx/v2/jwt" "github.com/nuts-foundation/go-did/did" "github.com/nuts-foundation/nuts-node/auth" + "github.com/nuts-foundation/nuts-node/auth/client/iam" "github.com/nuts-foundation/nuts-node/auth/oauth" cryptoNuts "github.com/nuts-foundation/nuts-node/crypto" "github.com/nuts-foundation/nuts-node/vdr/resolver" + "net/url" ) // requestObjectModifier is a function that modifies the Claims/params of an unsigned or signed (JWT) OAuth2 request @@ -47,7 +49,7 @@ type jar struct { auth auth.AuthenticationServices jwtSigner cryptoNuts.JWTSigner keyResolver resolver.KeyResolver - resolver resolver.DIDResolver + client iam.Client } type JAR interface { @@ -69,6 +71,15 @@ type JAR interface { Parse(ctx context.Context, ownMetadata oauth.AuthorizationServerMetadata, q url.Values) (oauthParameters, error) } +func NewJAR(auth auth.AuthenticationServices, jwtSigner cryptoNuts.JWTSigner, keyResolver resolver.KeyResolver, client iam.Client) JAR { + return jar{ + auth: auth, + jwtSigner: jwtSigner, + keyResolver: keyResolver, + client: client, + } +} + func (j jar) Create(client did.DID, clientID string, audience string, modifier requestObjectModifier) jarRequest { return createJarRequest(client, clientID, audience, modifier) } @@ -147,10 +158,13 @@ func (j jar) Parse(ctx context.Context, ownMetadata oauth.AuthorizationServerMet // the client_id must match the signer of the JWT. func (j jar) validate(ctx context.Context, rawToken string, clientId string) (oauthParameters, error) { var signerKid string + var publicKey crypto.PublicKey // Parse and validate the JWT token, err := cryptoNuts.ParseJWT(rawToken, func(kid string) (crypto.PublicKey, error) { + var err error signerKid = kid - return j.keyResolver.ResolveKeyByID(kid, nil, resolver.AssertionMethod) + publicKey, err = j.keyResolver.ResolveKeyByID(kid, nil, resolver.AssertionMethod) + return publicKey, err }, jwt.WithValidate(true)) if err != nil { return nil, oauth.OAuth2Error{Code: oauth.InvalidRequestObject, Description: "request signature validation failed", InternalError: err} @@ -165,26 +179,36 @@ func (j jar) validate(ctx context.Context, rawToken string, clientId string) (oa if clientId != params.get(oauth.ClientIDParam) { return nil, oauth.OAuth2Error{Code: oauth.InvalidRequestObject, Description: "invalid client_id claim in signed authorization request"} } - // check if the signer of the JWT is the client - signer, err := did.ParseDIDURL(signerKid) + configuration, err := j.client.OpenIDConfiguration(ctx, clientId) if err != nil { - // very unlikely since the key has already been resolved - return nil, oauth.OAuth2Error{Code: oauth.InvalidRequestObject, Description: "invalid signer", InternalError: err} + return nil, oauth.OAuth2Error{Code: oauth.ServerError, Description: "failed to retrieve OpenID configuration", InternalError: err} + } + + key, exists := configuration.JWKs.LookupKeyID(signerKid) + if !exists { + return nil, oauth.OAuth2Error{Code: oauth.InvalidRequestObject, Description: "client_id does not own signer key"} + } + if err := compareThumbprint(key, publicKey); err != nil { + return nil, oauth.OAuth2Error{Code: oauth.InvalidRequestObject, Description: "key mismatch between OpenID configuration and signer key", InternalError: err} } - // resolve DID and check if clientId is in AlsoKnownAs - doc, _, err := j.resolver.Resolve(signer.DID, nil) + return params, nil +} + +func compareThumbprint(configurationKey jwk.Key, publicKey crypto.PublicKey) error { + thumbprintLeft, err := configurationKey.Thumbprint(crypto.SHA256) if err != nil { - if resolver.IsFunctionalResolveError(err) { - return nil, oauth.OAuth2Error{Code: oauth.InvalidRequestObject, Description: "invalid signer", InternalError: err} - } - return nil, oauth.OAuth2Error{Code: oauth.ServerError, Description: "server error", InternalError: err} + return err } - akaAsString := make([]string, len(doc.AlsoKnownAs)) - for i, aka := range doc.AlsoKnownAs { - akaAsString[i] = aka.String() + signerKey, err := jwk.FromRaw(publicKey) + if err != nil { + return err + } + thumbprintRight, err := signerKey.Thumbprint(crypto.SHA256) + if err != nil { + return err } - if !slices.Contains(akaAsString, clientId) { - return nil, oauth.OAuth2Error{Code: oauth.InvalidRequestObject, Description: "client_id does not match signer of authorization request"} + if bytes.Compare(thumbprintLeft, thumbprintRight) != 0 { + return errors.New("key thumbprints do not match") } - return params, nil + return nil } diff --git a/auth/api/iam/jar_test.go b/auth/api/iam/jar_test.go index 26fc05b2b3..e4a3d92738 100644 --- a/auth/api/iam/jar_test.go +++ b/auth/api/iam/jar_test.go @@ -23,7 +23,7 @@ import ( "crypto" "errors" "fmt" - ssi "github.com/nuts-foundation/go-did" + "github.com/lestrrat-go/jwx/v2/jwk" "github.com/nuts-foundation/nuts-node/crypto/storage/spi" "github.com/nuts-foundation/nuts-node/test" "testing" @@ -109,6 +109,10 @@ func TestJar_Parse(t *testing.T) { // setup did document and keys privateKey, _ := spi.GenerateKeyPair() kid := fmt.Sprintf("%s#%s", holderDID.String(), "key") + jwkKey, _ := jwk.FromRaw(privateKey.Public()) + jwkKey.Set(jwk.KeyIDKey, kid) + jwkSet := jwk.NewSet() + _ = jwkSet.AddKey(jwkKey) bytes, err := createSignedRequestObject(t, kid, privateKey, oauthParameters{ jwt.IssuerKey: holderDID.String(), @@ -118,18 +122,16 @@ func TestJar_Parse(t *testing.T) { token := string(bytes) walletIssuerURL := test.MustParseURL(holderDID.String()) verifierMetadata := authorizationServerMetadata(verifierURL, []string{"web"}) - didDocument := did.Document{ - ID: holderDID, - AlsoKnownAs: []ssi.URI{ssi.MustParseURI(holderClientID)}, + configuration := &oauth.OpenIDConfiguration{ + JWKs: jwkSet, } t.Run("request_uri_method", func(t *testing.T) { - t.Run("ok - get", func(t *testing.T) { ctx := newJarTestCtx(t) ctx.iamClient.EXPECT().RequestObjectByGet(context.Background(), "request_uri").Return(token, nil) ctx.keyResolver.EXPECT().ResolveKeyByID(kid, nil, resolver.AssertionMethod).Return(privateKey.Public(), nil) - ctx.resolver.EXPECT().Resolve(holderDID, nil).Return(&didDocument, nil, nil) + ctx.iamClient.EXPECT().OpenIDConfiguration(gomock.Any(), holderClientID).Return(configuration, nil) res, err := ctx.jar.Parse(context.Background(), verifierMetadata, map[string][]string{ @@ -145,7 +147,7 @@ func TestJar_Parse(t *testing.T) { ctx := newJarTestCtx(t) ctx.iamClient.EXPECT().RequestObjectByGet(context.Background(), "request_uri").Return(token, nil) ctx.keyResolver.EXPECT().ResolveKeyByID(kid, nil, resolver.AssertionMethod).Return(privateKey.Public(), nil) - ctx.resolver.EXPECT().Resolve(holderDID, nil).Return(&didDocument, nil, nil) + ctx.iamClient.EXPECT().OpenIDConfiguration(gomock.Any(), holderClientID).Return(configuration, nil) res, err := ctx.jar.Parse(context.Background(), verifierMetadata, map[string][]string{ @@ -162,7 +164,7 @@ func TestJar_Parse(t *testing.T) { md := authorizationServerMetadata(walletIssuerURL, []string{"web"}) ctx.iamClient.EXPECT().RequestObjectByPost(context.Background(), "request_uri", md).Return(token, nil) ctx.keyResolver.EXPECT().ResolveKeyByID(kid, nil, resolver.AssertionMethod).Return(privateKey.Public(), nil) - ctx.resolver.EXPECT().Resolve(holderDID, nil).Return(&didDocument, nil, nil) + ctx.iamClient.EXPECT().OpenIDConfiguration(gomock.Any(), holderClientID).Return(configuration, nil) res, err := ctx.jar.Parse(context.Background(), md, map[string][]string{ @@ -190,7 +192,7 @@ func TestJar_Parse(t *testing.T) { t.Run("ok - 'request'", func(t *testing.T) { ctx := newJarTestCtx(t) ctx.keyResolver.EXPECT().ResolveKeyByID(kid, nil, resolver.AssertionMethod).Return(privateKey.Public(), nil) - ctx.resolver.EXPECT().Resolve(holderDID, nil).Return(&didDocument, nil, nil) + ctx.iamClient.EXPECT().OpenIDConfiguration(gomock.Any(), holderClientID).Return(configuration, nil) res, err := ctx.jar.Parse(context.Background(), verifierMetadata, map[string][]string{ @@ -276,16 +278,52 @@ func TestJar_Parse(t *testing.T) { oauth.ClientIDParam: verifierDID.String(), }) require.NoError(t, err) - ctx.resolver.EXPECT().Resolve(holderDID, nil).Return(&did.Document{ID: holderDID}, nil, nil) ctx.keyResolver.EXPECT().ResolveKeyByID(kid, nil, resolver.AssertionMethod).Return(privateKey.Public(), nil) res, err := ctx.jar.Parse(context.Background(), verifierMetadata, map[string][]string{ - oauth.ClientIDParam: {verifierDID.String()}, + oauth.ClientIDParam: {verifierClientID}, oauth.RequestParam: {string(bytes)}, }) - requireOAuthError(t, err, oauth.InvalidRequestObject, "client_id does not match signer of authorization request") + requireOAuthError(t, err, oauth.InvalidRequestObject, "invalid client_id claim in signed authorization request") + assert.Nil(t, res) + }) + t.Run("error - retrieving OpenID configuration", func(t *testing.T) { + ctx := newJarTestCtx(t) + ctx.keyResolver.EXPECT().ResolveKeyByID(kid, nil, resolver.AssertionMethod).Return(privateKey.Public(), nil) + ctx.iamClient.EXPECT().OpenIDConfiguration(gomock.Any(), holderClientID).Return(nil, assert.AnError) + + res, err := ctx.jar.Parse(context.Background(), verifierMetadata, + map[string][]string{ + oauth.ClientIDParam: {holderClientID}, + oauth.RequestParam: {token}, + }) + + requireOAuthError(t, err, oauth.ServerError, "failed to retrieve OpenID configuration") + assert.Nil(t, res) + }) + t.Run("error - openID configuration key mismatch", func(t *testing.T) { + ctx := newJarTestCtx(t) + alternateKey, _ := spi.GenerateKeyPair() + jwkKey, _ := jwk.FromRaw(alternateKey.Public()) + jwkKey.Set(jwk.KeyIDKey, kid) + jwkSet := jwk.NewSet() + _ = jwkSet.AddKey(jwkKey) + + configuration := &oauth.OpenIDConfiguration{ + JWKs: jwkSet, + } + ctx.keyResolver.EXPECT().ResolveKeyByID(kid, nil, resolver.AssertionMethod).Return(privateKey.Public(), nil) + ctx.iamClient.EXPECT().OpenIDConfiguration(gomock.Any(), holderClientID).Return(configuration, nil) + + res, err := ctx.jar.Parse(context.Background(), verifierMetadata, + map[string][]string{ + oauth.ClientIDParam: {holderClientID}, + oauth.RequestParam: {token}, + }) + + requireOAuthError(t, err, oauth.InvalidRequestObject, "key mismatch between OpenID configuration and signer key") assert.Nil(t, res) }) } @@ -306,7 +344,6 @@ type testJarCtx struct { iamClient *iam.MockClient jwtSigner *cryptoNuts.MockJWTSigner keyResolver *resolver.MockKeyResolver - resolver *resolver.MockDIDResolver } func newJarTestCtx(t testing.TB) testJarCtx { @@ -316,18 +353,16 @@ func newJarTestCtx(t testing.TB) testJarCtx { mockAuth.EXPECT().IAMClient().Return(mockIAMClient).AnyTimes() mockSigner := cryptoNuts.NewMockJWTSigner(ctrl) mockKeyResolver := resolver.NewMockKeyResolver(ctrl) - mockResolver := resolver.NewMockDIDResolver(ctrl) return testJarCtx{ jar: &jar{ auth: mockAuth, jwtSigner: mockSigner, keyResolver: mockKeyResolver, - resolver: mockResolver, + client: mockIAMClient, }, auth: mockAuth, iamClient: mockIAMClient, keyResolver: mockKeyResolver, jwtSigner: mockSigner, - resolver: mockResolver, } } diff --git a/storage/orm/did.go b/storage/orm/did.go index c7dbd4a6a8..3773dc3abb 100644 --- a/storage/orm/did.go +++ b/storage/orm/did.go @@ -24,10 +24,9 @@ import ( // DID is the gorm representation of the DID table type DID struct { - ID string `gorm:"primaryKey"` - Subject string `gorm:"column:subject"` - Aka []DID `gorm:"foreignKey:Subject;references:Subject"` - ClientID string `gorm:"column:client_id"` + ID string `gorm:"primaryKey"` + Subject string `gorm:"column:subject"` + Aka []DID `gorm:"foreignKey:Subject;references:Subject"` } func (d DID) TableName() string { diff --git a/storage/orm/did_document.go b/storage/orm/did_document.go index 70499209dc..46089dddfa 100644 --- a/storage/orm/did_document.go +++ b/storage/orm/did_document.go @@ -72,11 +72,6 @@ func (sqlDoc DIDDocument) GenerateDIDDocument() (did.Document, error) { others = append(others, *uri) } } - clientID, err := ssi.ParseURI(sqlDoc.DID.ClientID) - if err != nil { - return did.Document{}, err - } - others = append(others, *clientID) document := did.Document{ AlsoKnownAs: others, Context: []interface{}{ diff --git a/storage/orm/did_document_test.go b/storage/orm/did_document_test.go index f8e67f39ca..947648845c 100644 --- a/storage/orm/did_document_test.go +++ b/storage/orm/did_document_test.go @@ -43,5 +43,5 @@ func TestDIDDocument_ToDIDDocument(t *testing.T) { require.Len(t, didDoc.Service, 1) assert.Equal(t, "#1", didDoc.VerificationMethod[0].ID.String()) assert.Equal(t, "#2", didDoc.Service[0].ID.String()) - assert.Len(t, didDoc.AlsoKnownAs, 2) + assert.Len(t, didDoc.AlsoKnownAs, 1) } diff --git a/storage/sql_migrations/003_did.sql b/storage/sql_migrations/003_did.sql index 0f06532421..cefff6cb8a 100644 --- a/storage/sql_migrations/003_did.sql +++ b/storage/sql_migrations/003_did.sql @@ -6,7 +6,6 @@ create table did -- id is the fully qualified DID id varchar(370) not null, subject varchar(370) not null, - client_id varchar(255) not null, primary key (id) ); diff --git a/storage/test.go b/storage/test.go index 69d242b1c2..21b348dd69 100644 --- a/storage/test.go +++ b/storage/test.go @@ -127,7 +127,7 @@ func NewTestInMemorySessionDatabase(t *testing.T) *InMemorySessionDatabase { func AddDIDtoSQLDB(t testing.TB, db *gorm.DB, dids ...did.DID) { for _, id := range dids { // use gorm EXEC since it accepts '?' as the argument placeholder for all DBs - require.NoError(t, db.Exec("INSERT INTO did (subject, id, client_id ) VALUES ( ?, ?, ? )", id.String(), id.String(), id.String()).Error) + require.NoError(t, db.Exec("INSERT INTO did (subject, id ) VALUES ( ?, ? )", id.String(), id.String(), id.String()).Error) } } diff --git a/vdr/didsubject/did_document_test.go b/vdr/didsubject/did_document_test.go index 752adccacd..105f663abc 100644 --- a/vdr/didsubject/did_document_test.go +++ b/vdr/didsubject/did_document_test.go @@ -132,6 +132,6 @@ func TestSqlDIDDocumentManager_Latest(t *testing.T) { // in did document (from Raw) didDoc, err := latest.ToDIDDocument() require.NoError(t, err) - assert.Len(t, didDoc.AlsoKnownAs, 2) + assert.Len(t, didDoc.AlsoKnownAs, 1) }) } diff --git a/vdr/didsubject/manager.go b/vdr/didsubject/manager.go index f2d3b6fe58..9a8d0ef83f 100644 --- a/vdr/didsubject/manager.go +++ b/vdr/didsubject/manager.go @@ -34,7 +34,6 @@ import ( "github.com/nuts-foundation/nuts-node/storage/orm" "github.com/nuts-foundation/nuts-node/vdr/log" "gorm.io/gorm" - "net/url" "time" ) @@ -50,7 +49,6 @@ type Manager struct { DB *gorm.DB MethodManagers map[string]MethodManager KeyStore nutsCrypto.KeyStore - PublicURL *url.URL } func (r *Manager) List(_ context.Context, subject string) ([]did.DID, error) { @@ -144,14 +142,12 @@ func (r *Manager) Create(ctx context.Context, options CreationOptions) ([]did.Do changes := make(map[string]orm.DIDChangeLog) sqlDIDDocumentManager := NewDIDDocumentManager(tx) transactionId := uuid.New().String() - clientID := r.PublicURL.String() + "/oauth2/" + subject for method, sqlDoc := range sqlDocs { // overwrite sql.DID from returned document because we have the subject and alsoKnownAs here sqlDID := orm.DID{ - ID: sqlDoc.DID.ID, - Subject: subject, - ClientID: clientID, - Aka: alsoKnownAs, + ID: sqlDoc.DID.ID, + Subject: subject, + Aka: alsoKnownAs, } createdDoc, err := sqlDIDDocumentManager.CreateOrUpdate(sqlDID, sqlDoc.VerificationMethods, nil) if err != nil { diff --git a/vdr/didsubject/manager_test.go b/vdr/didsubject/manager_test.go index 70b9cb6e51..a02ea63da9 100644 --- a/vdr/didsubject/manager_test.go +++ b/vdr/didsubject/manager_test.go @@ -22,7 +22,6 @@ import ( "context" "fmt" "github.com/nuts-foundation/nuts-node/storage/orm" - "github.com/nuts-foundation/nuts-node/test" "net/url" "strings" "testing" @@ -41,13 +40,7 @@ import ( func TestManager_Create(t *testing.T) { t.Run("ok", func(t *testing.T) { db := testDB(t) - m := Manager{ - DB: db, - MethodManagers: map[string]MethodManager{ - "example": testMethod{}, - }, - PublicURL: test.MustParseURL("https://example.com"), - } + m := Manager{DB: db, MethodManagers: map[string]MethodManager{"example": testMethod{}}} documents, _, err := m.Create(audit.TestContext(), DefaultCreationOptions()) @@ -64,14 +57,7 @@ func TestManager_Create(t *testing.T) { }) t.Run("multiple methods", func(t *testing.T) { db := testDB(t) - m := Manager{ - DB: db, - MethodManagers: map[string]MethodManager{ - "example": testMethod{}, - "test": testMethod{}, - }, - PublicURL: test.MustParseURL("https://example.com"), - } + m := Manager{DB: db, MethodManagers: map[string]MethodManager{"example": testMethod{}, "test": testMethod{}}} documents, _, err := m.Create(audit.TestContext(), DefaultCreationOptions()) require.NoError(t, err) @@ -85,17 +71,11 @@ func TestManager_Create(t *testing.T) { // test alsoKnownAs requirements document := documents[0] - assert.Len(t, document.AlsoKnownAs, 2) + assert.Len(t, document.AlsoKnownAs, 1) }) t.Run("with unknown option", func(t *testing.T) { db := testDB(t) - m := Manager{ - DB: db, - MethodManagers: map[string]MethodManager{ - "example": testMethod{}, - }, - PublicURL: test.MustParseURL("https://example.com"), - } + m := Manager{DB: db, MethodManagers: map[string]MethodManager{"example": testMethod{}}} _, _, err := m.Create(audit.TestContext(), DefaultCreationOptions().With("")) @@ -103,13 +83,7 @@ func TestManager_Create(t *testing.T) { }) t.Run("already exists", func(t *testing.T) { db := testDB(t) - m := Manager{ - DB: db, - MethodManagers: map[string]MethodManager{ - "example": testMethod{}, - }, - PublicURL: test.MustParseURL("https://example.com"), - } + m := Manager{DB: db, MethodManagers: map[string]MethodManager{"example": testMethod{}}} opts := DefaultCreationOptions().With(SubjectCreationOption{Subject: "subject"}) _, _, err := m.Create(audit.TestContext(), opts) require.NoError(t, err) @@ -123,13 +97,7 @@ func TestManager_Create(t *testing.T) { func TestManager_List(t *testing.T) { t.Run("ok", func(t *testing.T) { db := testDB(t) - m := Manager{ - DB: db, - MethodManagers: map[string]MethodManager{ - "example": testMethod{}, - }, - PublicURL: test.MustParseURL("https://example.com"), - } + m := Manager{DB: db, MethodManagers: map[string]MethodManager{"example": testMethod{}}} opts := DefaultCreationOptions().With(SubjectCreationOption{Subject: "subject"}) _, subject, err := m.Create(audit.TestContext(), opts) require.NoError(t, err) @@ -141,13 +109,7 @@ func TestManager_List(t *testing.T) { }) t.Run("unknown subject", func(t *testing.T) { db := testDB(t) - m := Manager{ - DB: db, - MethodManagers: map[string]MethodManager{ - "example": testMethod{}, - }, - PublicURL: test.MustParseURL("https://example.com"), - } + m := Manager{DB: db, MethodManagers: map[string]MethodManager{"example": testMethod{}}} _, err := m.List(audit.TestContext(), "subject") @@ -157,13 +119,7 @@ func TestManager_List(t *testing.T) { func TestManager_Services(t *testing.T) { db := testDB(t) - m := Manager{ - DB: db, - MethodManagers: map[string]MethodManager{ - "example": testMethod{}, - }, - PublicURL: test.MustParseURL("https://example.com"), - } + m := Manager{DB: db, MethodManagers: map[string]MethodManager{"example": testMethod{}}} subject := "subject" opts := DefaultCreationOptions().With(SubjectCreationOption{Subject: subject}) documents, _, err := m.Create(audit.TestContext(), opts) @@ -225,13 +181,7 @@ func TestManager_Services(t *testing.T) { func TestManager_AddVerificationMethod(t *testing.T) { db := testDB(t) - m := Manager{DB: db, - MethodManagers: map[string]MethodManager{ - "example": testMethod{}, - "test": testMethod{}, - }, - PublicURL: test.MustParseURL("https://example.com"), - } + m := Manager{DB: db, MethodManagers: map[string]MethodManager{"example": testMethod{}, "test": testMethod{}}} subject := "subject" opts := DefaultCreationOptions().With(SubjectCreationOption{Subject: subject}) documents, _, err := m.Create(audit.TestContext(), opts) @@ -253,7 +203,7 @@ func TestManager_AddVerificationMethod(t *testing.T) { didDocument, err := latest.ToDIDDocument() require.NoError(t, err) - assert.Len(t, didDocument.AlsoKnownAs, 2) + assert.Len(t, didDocument.AlsoKnownAs, 1) }) }) } @@ -265,24 +215,14 @@ func TestManager_Deactivate(t *testing.T) { t.Run("not found", func(t *testing.T) { db := testDB(t) - m := Manager{DB: db, - MethodManagers: map[string]MethodManager{ - "example": testMethod{}, - }, - PublicURL: test.MustParseURL("https://example.com"), - } + m := Manager{DB: db, MethodManagers: map[string]MethodManager{"example": testMethod{}}} err := m.Deactivate(ctx, "subject") require.ErrorIs(t, err, ErrSubjectNotFound) }) t.Run("ok", func(t *testing.T) { db := testDB(t) - m := Manager{DB: db, - MethodManagers: map[string]MethodManager{ - "example": testMethod{}, - }, - PublicURL: test.MustParseURL("https://example.com"), - } + m := Manager{DB: db, MethodManagers: map[string]MethodManager{"example": testMethod{}}} documents, subject, err := m.Create(ctx, DefaultCreationOptions()) require.NoError(t, err) require.Len(t, documents, 1) @@ -292,12 +232,7 @@ func TestManager_Deactivate(t *testing.T) { }) t.Run("error", func(t *testing.T) { db := testDB(t) - m := Manager{DB: db, - MethodManagers: map[string]MethodManager{ - "example": testMethod{}, - }, - PublicURL: test.MustParseURL("https://example.com"), - } + m := Manager{DB: db, MethodManagers: map[string]MethodManager{"example": testMethod{}}} documents, subject, err := m.Create(ctx, DefaultCreationOptions()) require.NoError(t, err) require.Len(t, documents, 1) @@ -331,12 +266,7 @@ func TestManager_rollback(t *testing.T) { t.Run("uncommited results in rollback", func(t *testing.T) { db := testDB(t) - manager := Manager{DB: db, - MethodManagers: map[string]MethodManager{ - "example": testMethod{}, - }, - PublicURL: test.MustParseURL("https://example.com"), - } + manager := Manager{DB: db, MethodManagers: map[string]MethodManager{"example": testMethod{}}} saveExamples(t, db) @@ -358,7 +288,6 @@ func TestManager_rollback(t *testing.T) { MethodManagers: map[string]MethodManager{ "example": testMethod{error: assert.AnError}, }, - PublicURL: test.MustParseURL("https://example.com"), } saveExamples(t, db) @@ -380,7 +309,6 @@ func TestManager_rollback(t *testing.T) { MethodManagers: map[string]MethodManager{ "example": testMethod{committed: true}, }, - PublicURL: test.MustParseURL("https://example.com"), } saveExamples(t, db) @@ -398,12 +326,7 @@ func TestManager_rollback(t *testing.T) { }) t.Run("rollback removes all from transaction", func(t *testing.T) { db := testDB(t) - manager := Manager{DB: db, - MethodManagers: map[string]MethodManager{ - "example": testMethod{}, - }, - PublicURL: test.MustParseURL("https://example.com"), - } + manager := Manager{DB: db, MethodManagers: map[string]MethodManager{"example": testMethod{}}} saveExamples(t, db) didId2 := orm.DID{ ID: "did:example:321", diff --git a/vdr/vdr.go b/vdr/vdr.go index 8918381573..06f6729664 100644 --- a/vdr/vdr.go +++ b/vdr/vdr.go @@ -202,7 +202,7 @@ func (r *Module) Configure(config core.ServerConfig) error { r.didResolver.(*resolver.DIDResolverRouter).Register(didweb.MethodName, webResolver) } - r.Manager = didsubject.Manager{DB: db, MethodManagers: methodManagers, KeyStore: r.keyStore, PublicURL: publicURL} + r.Manager = didsubject.Manager{DB: db, MethodManagers: methodManagers, KeyStore: r.keyStore} // Initiate the routines for auto-updating the data. return r.networkAmbassador.Configure()