From 2e91e7faaa4ad7751daf1f7134e2547cc04b5caf Mon Sep 17 00:00:00 2001 From: gabe Date: Wed, 21 Sep 2022 14:26:24 -0700 Subject: [PATCH 01/13] utility wrappers --- internal/keyaccess/dataintegrity.go | 10 ++++- internal/keyaccess/dataintegrity_test.go | 6 +-- internal/keyaccess/jwt.go | 47 ++++++++++++++++-------- internal/keyaccess/jwt_test.go | 16 ++++---- 4 files changed, 51 insertions(+), 28 deletions(-) diff --git a/internal/keyaccess/dataintegrity.go b/internal/keyaccess/dataintegrity.go index b12073879..ecbbb2ce6 100644 --- a/internal/keyaccess/dataintegrity.go +++ b/internal/keyaccess/dataintegrity.go @@ -47,7 +47,13 @@ func NewDataIntegrityKeyAccess(kid string, key gocrypto.PrivateKey) (*DataIntegr }, nil } -func (ka DataIntegrityKeyAccess) Sign(payload cryptosuite.Provable) ([]byte, error) { +// DataIntegrityJSON represents a response from a DataIntegrityKeyAccess.Sign() call represented +// as a serialized JSON object +type DataIntegrityJSON struct { + Data []byte `json:"data" validate:"required"` +} + +func (ka DataIntegrityKeyAccess) Sign(payload cryptosuite.Provable) (*DataIntegrityJSON, error) { if payload == nil { return nil, errors.New("payload cannot be nil") } @@ -58,7 +64,7 @@ func (ka DataIntegrityKeyAccess) Sign(payload cryptosuite.Provable) ([]byte, err if err != nil { return nil, errors.Wrap(err, "could not marshal signed payload") } - return signedJSONBytes, nil + return &DataIntegrityJSON{Data: signedJSONBytes}, nil } func (ka DataIntegrityKeyAccess) Verify(payload cryptosuite.Provable) error { diff --git a/internal/keyaccess/dataintegrity_test.go b/internal/keyaccess/dataintegrity_test.go index f6a8e7907..da42819a8 100644 --- a/internal/keyaccess/dataintegrity_test.go +++ b/internal/keyaccess/dataintegrity_test.go @@ -53,7 +53,7 @@ func TestDataIntegrityKeyAccessSignVerify(t *testing.T) { assert.NotEmpty(tt, signedCred) var cred credential.VerifiableCredential - err = json.Unmarshal(signedCred, &cred) + err = json.Unmarshal(signedCred.Data, &cred) assert.NoError(tt, err) // verify @@ -104,11 +104,11 @@ func TestDataIntegrityKeyAccessSignVerify(t *testing.T) { assert.NotEmpty(tt, signedPres) var pres credential.VerifiablePresentation - err = json.Unmarshal(signedPres, &pres) + err = json.Unmarshal(signedPres.Data, &pres) assert.NoError(tt, err) // verify err = ka.Verify(&pres) assert.NoError(tt, err) }) -} \ No newline at end of file +} diff --git a/internal/keyaccess/jwt.go b/internal/keyaccess/jwt.go index 807dc9fe9..bdbaa2ec5 100644 --- a/internal/keyaccess/jwt.go +++ b/internal/keyaccess/jwt.go @@ -42,44 +42,61 @@ func NewJWKKeyAccess(kid string, key gocrypto.PrivateKey) (*JWKKeyAccess, error) }, nil } -func (ka JWKKeyAccess) Sign(payload map[string]interface{}) ([]byte, error) { +// A JWKToken is a utility that wraps a string representation of a JSON Web Token. +type JWKToken struct { + Token string `json:"token" validate:"required"` +} + +func (ka JWKKeyAccess) Sign(payload map[string]interface{}) (*JWKToken, error) { if payload == nil { return nil, errors.New("payload cannot be nil") } - return ka.SignJWT(payload) + tokenBytes, err := ka.SignJWT(payload) + if err != nil { + return nil, errors.Wrap(err, "could not sign payload") + } + return &JWKToken{Token: string(tokenBytes)}, nil } -func (ka JWKKeyAccess) Verify(token string) error { - if token == "" { +func (ka JWKKeyAccess) Verify(token JWKToken) error { + if token.Token == "" { return errors.New("token cannot be empty") } - return ka.VerifyJWT(token) + return ka.VerifyJWT(token.Token) } -func (ka JWKKeyAccess) SignVerifiableCredential(credential credential.VerifiableCredential) ([]byte, error) { +func (ka JWKKeyAccess) SignVerifiableCredential(credential credential.VerifiableCredential) (*JWKToken, error) { if err := credential.IsValid(); err != nil { return nil, errors.New("cannot sign invalid credential") } - return signing.SignVerifiableCredentialJWT(ka.JWTSigner, credential) + tokenBytes, err := signing.SignVerifiableCredentialJWT(ka.JWTSigner, credential) + if err != nil { + return nil, errors.Wrap(err, "could not sign credential") + } + return &JWKToken{Token: string(tokenBytes)}, nil } -func (ka JWKKeyAccess) VerifyVerifiableCredential(token string) (*credential.VerifiableCredential, error) { - if token == "" { +func (ka JWKKeyAccess) VerifyVerifiableCredential(token JWKToken) (*credential.VerifiableCredential, error) { + if token.Token == "" { return nil, errors.New("token cannot be empty") } - return signing.VerifyVerifiableCredentialJWT(ka.JWTVerifier, token) + return signing.VerifyVerifiableCredentialJWT(ka.JWTVerifier, token.Token) } -func (ka JWKKeyAccess) SignVerifiablePresentation(presentation credential.VerifiablePresentation) ([]byte, error) { +func (ka JWKKeyAccess) SignVerifiablePresentation(presentation credential.VerifiablePresentation) (*JWKToken, error) { if err := presentation.IsValid(); err != nil { return nil, errors.New("cannot sign invalid presentation") } - return signing.SignVerifiablePresentationJWT(ka.JWTSigner, presentation) + tokenBytes, err := signing.SignVerifiablePresentationJWT(ka.JWTSigner, presentation) + if err != nil { + return nil, errors.Wrap(err, "could not sign presentation") + } + return &JWKToken{Token: string(tokenBytes)}, nil } -func (ka JWKKeyAccess) VerifyVerifiablePresentation(token string) (*credential.VerifiablePresentation, error) { - if token == "" { +func (ka JWKKeyAccess) VerifyVerifiablePresentation(token JWKToken) (*credential.VerifiablePresentation, error) { + if token.Token == "" { return nil, errors.New("token cannot be empty") } - return signing.VerifyVerifiablePresentationJWT(ka.JWTVerifier, token) + return signing.VerifyVerifiablePresentationJWT(ka.JWTVerifier, token.Token) } diff --git a/internal/keyaccess/jwt_test.go b/internal/keyaccess/jwt_test.go index 0920e0611..c1a00730a 100644 --- a/internal/keyaccess/jwt_test.go +++ b/internal/keyaccess/jwt_test.go @@ -50,11 +50,11 @@ func TestJWKKeyAccessSignVerify(t *testing.T) { data := map[string]interface{}{ "test": "test", } - tokenBytes, err := ka.Sign(data) + token, err := ka.Sign(data) assert.NoError(tt, err) - assert.NotEmpty(tt, tokenBytes) + assert.NotEmpty(tt, token) - err = ka.Verify(string(tokenBytes)) + err = ka.Verify(*token) assert.NoError(tt, err) }) @@ -79,7 +79,7 @@ func TestJWKKeyAccessSignVerify(t *testing.T) { assert.NoError(tt, err) assert.NotEmpty(tt, ka) - err = ka.Verify("") + err = ka.Verify(JWKToken{}) assert.Error(tt, err) assert.Contains(tt, err.Error(), "token cannot be empty") }) @@ -101,7 +101,7 @@ func TestJWKKeyAccessSignVerifyCredentials(t *testing.T) { assert.NotEmpty(tt, signedCred) // verify - verifiedCred, err := ka.VerifyVerifiableCredential(string(signedCred)) + verifiedCred, err := ka.VerifyVerifiableCredential(*signedCred) assert.NoError(tt, err) assert.NotEmpty(tt, verifiedCred) @@ -136,7 +136,7 @@ func TestJWKKeyAccessSignVerifyCredentials(t *testing.T) { assert.NotEmpty(tt, ka) // verify - _, err = ka.VerifyVerifiableCredential("bad") + _, err = ka.VerifyVerifiableCredential(JWKToken{"bad"}) assert.Error(tt, err) assert.Contains(tt, err.Error(), "could not verify JWT and its signature") }) @@ -158,7 +158,7 @@ func TestJWKKeyAccessSignVerifyPresentations(t *testing.T) { assert.NotEmpty(tt, signedPres) // verify - verifiedPres, err := ka.VerifyVerifiablePresentation(string(signedPres)) + verifiedPres, err := ka.VerifyVerifiablePresentation(*signedPres) assert.NoError(tt, err) assert.NotEmpty(tt, verifiedPres) @@ -193,7 +193,7 @@ func TestJWKKeyAccessSignVerifyPresentations(t *testing.T) { assert.NotEmpty(tt, ka) // verify - _, err = ka.VerifyVerifiablePresentation("bad") + _, err = ka.VerifyVerifiablePresentation(JWKToken{"bad"}) assert.Error(tt, err) assert.Contains(tt, err.Error(), "could not verify JWT and its signature") }) From c77556743bf89212d33a09a1addbd86b7e9ac96c Mon Sep 17 00:00:00 2001 From: gabe Date: Thu, 22 Sep 2022 20:13:29 -0700 Subject: [PATCH 02/13] init --- go.mod | 2 +- go.sum | 2 ++ internal/util/crypto.go | 4 ++-- pkg/service/credential/credential.go | 1 - 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index f5bfcb762..f0197d84d 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( github.com/BurntSushi/toml v1.2.0 - github.com/TBD54566975/ssi-sdk v0.0.1-alpha.0.20220920154030-cbf6b4665a6d + github.com/TBD54566975/ssi-sdk v0.0.1-alpha.0.20220921215642-f749c4d89b8b github.com/ardanlabs/conf v1.5.0 github.com/dimfeld/httptreemux/v5 v5.4.0 github.com/go-playground/locales v0.14.0 diff --git a/go.sum b/go.sum index dece70f00..6467abe1f 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,8 @@ github.com/TBD54566975/ssi-sdk v0.0.1-alpha.0.20220919021815-57be087eca80 h1:1HB github.com/TBD54566975/ssi-sdk v0.0.1-alpha.0.20220919021815-57be087eca80/go.mod h1:ZUcjj/CHvtmz48c9GapcbavlTRsN9JZ9pKdT+co/EvY= github.com/TBD54566975/ssi-sdk v0.0.1-alpha.0.20220920154030-cbf6b4665a6d h1:NW/9Qg2Z+Yhh6PtzgV/cFwgNz7Sgng3E25IYQiUV34c= github.com/TBD54566975/ssi-sdk v0.0.1-alpha.0.20220920154030-cbf6b4665a6d/go.mod h1:jkbaZT2qU+g6weOHpjPdxuHdmfOApdT8CQg41GEyZhA= +github.com/TBD54566975/ssi-sdk v0.0.1-alpha.0.20220921215642-f749c4d89b8b h1:0IJJPN8qBGEINcNheyMN/VztIj/Wu9OLzoaEdwfKMWM= +github.com/TBD54566975/ssi-sdk v0.0.1-alpha.0.20220921215642-f749c4d89b8b/go.mod h1:jkbaZT2qU+g6weOHpjPdxuHdmfOApdT8CQg41GEyZhA= github.com/ardanlabs/conf v1.5.0 h1:5TwP6Wu9Xi07eLFEpiCUF3oQXh9UzHMDVnD3u/I5d5c= github.com/ardanlabs/conf v1.5.0/go.mod h1:ILsMo9dMqYzCxDjDXTiwMI0IgxOJd0MOiucbQY2wlJw= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= diff --git a/internal/util/crypto.go b/internal/util/crypto.go index 9ecdc2128..d53cd2b43 100644 --- a/internal/util/crypto.go +++ b/internal/util/crypto.go @@ -57,11 +57,11 @@ func XChaCha20Poly1305Decrypt(key, data []byte) ([]byte, error) { nonce, ciphertext := data[:aead.NonceSize()], data[aead.NonceSize():] // Decrypt the message and check it wasn't tampered with. - decyrpted, err := aead.Open(nil, nonce, ciphertext, nil) + decrypted, err := aead.Open(nil, nonce, ciphertext, nil) if err != nil { return nil, errors.Wrap(err, "could not decrypt data") } - return decyrpted, nil + return decrypted, nil } // Argon2KeyGen returns an encoded string generation of a key generated using the go crypto argon2 impl diff --git a/pkg/service/credential/credential.go b/pkg/service/credential/credential.go index 70c4847c6..4a6eedf37 100644 --- a/pkg/service/credential/credential.go +++ b/pkg/service/credential/credential.go @@ -63,7 +63,6 @@ func (s Service) CreateCredential(request CreateCredentialRequest) (*CreateCrede // check if there's a conflict with subject ID if id, ok := request.Data[credential.VerifiableCredentialIDProperty]; ok && id != request.Subject { errMsg := fmt.Sprintf("cannot set subject<%s>, data already contains a different ID value: %s", request.Subject, id) - logrus.Error(errMsg) return nil, util.LoggingNewError(errMsg) } From 4b7cddace83ef27d3d0b21f3d87c11005219c997 Mon Sep 17 00:00:00 2001 From: gabe Date: Fri, 23 Sep 2022 11:19:38 -0700 Subject: [PATCH 03/13] utilize key encryption --- internal/keyaccess/dataintegrity.go | 2 +- internal/keyaccess/dataintegrity_test.go | 6 ++-- internal/keyaccess/jwt.go | 4 +-- internal/keyaccess/jwt_test.go | 6 ++-- pkg/server/router/keystore.go | 4 +-- pkg/server/router/keystore_test.go | 2 +- pkg/server/server_test.go | 10 +++---- pkg/service/credential/credential.go | 3 ++ pkg/service/keystore/keystore.go | 23 ++++++++++++++ pkg/service/keystore/model.go | 12 ++++++++ pkg/service/keystore/storage/bolt.go | 38 ++++++++++++++++++++---- pkg/service/keystore/storage/storage.go | 9 +++--- 12 files changed, 93 insertions(+), 26 deletions(-) diff --git a/internal/keyaccess/dataintegrity.go b/internal/keyaccess/dataintegrity.go index ecbbb2ce6..405265207 100644 --- a/internal/keyaccess/dataintegrity.go +++ b/internal/keyaccess/dataintegrity.go @@ -20,7 +20,7 @@ type DataIntegrityKeyAccess struct { } // NewDataIntegrityKeyAccess creates a new DataIntegrityKeyAccess object from a key id and private key, generating both -// JSON Web Key Signer and Verifier objects. +// JSON Web Base58Key Signer and Verifier objects. func NewDataIntegrityKeyAccess(kid string, key gocrypto.PrivateKey) (*DataIntegrityKeyAccess, error) { if kid == "" { return nil, errors.New("kid cannot be empty") diff --git a/internal/keyaccess/dataintegrity_test.go b/internal/keyaccess/dataintegrity_test.go index da42819a8..943754562 100644 --- a/internal/keyaccess/dataintegrity_test.go +++ b/internal/keyaccess/dataintegrity_test.go @@ -10,7 +10,7 @@ import ( ) func TestCreateDataIntegrityKeyAccess(t *testing.T) { - t.Run("Create a Key Access object - Happy Path", func(tt *testing.T) { + t.Run("Create a Base58Key Access object - Happy Path", func(tt *testing.T) { _, privKey, err := crypto.GenerateEd25519Key() kid := "test-kid" assert.NoError(tt, err) @@ -19,7 +19,7 @@ func TestCreateDataIntegrityKeyAccess(t *testing.T) { assert.NotEmpty(tt, ka) }) - t.Run("Create a Key Access object - Bad Key", func(tt *testing.T) { + t.Run("Create a Base58Key Access object - Bad Base58Key", func(tt *testing.T) { kid := "test-kid" ka, err := NewDataIntegrityKeyAccess(kid, nil) assert.Error(tt, err) @@ -27,7 +27,7 @@ func TestCreateDataIntegrityKeyAccess(t *testing.T) { assert.Empty(tt, ka) }) - t.Run("Create a Key Access object - No KID", func(tt *testing.T) { + t.Run("Create a Base58Key Access object - No KID", func(tt *testing.T) { _, privKey, err := crypto.GenerateEd25519Key() assert.NoError(tt, err) ka, err := NewDataIntegrityKeyAccess("", privKey) diff --git a/internal/keyaccess/jwt.go b/internal/keyaccess/jwt.go index bdbaa2ec5..073aeb6e8 100644 --- a/internal/keyaccess/jwt.go +++ b/internal/keyaccess/jwt.go @@ -30,11 +30,11 @@ func NewJWKKeyAccess(kid string, key gocrypto.PrivateKey) (*JWKKeyAccess, error) } signer, err := crypto.NewJWTSigner(kid, gotJWK) if err != nil { - return nil, errors.Wrapf(err, "could not create JWK Key Access object for kid: %s, error creating signer", kid) + return nil, errors.Wrapf(err, "could not create JWK Base58Key Access object for kid: %s, error creating signer", kid) } verifier, err := signer.ToVerifier() if err != nil { - return nil, errors.Wrapf(err, "could not create JWK Key Access object for kid: %s, error creating verifier", kid) + return nil, errors.Wrapf(err, "could not create JWK Base58Key Access object for kid: %s, error creating verifier", kid) } return &JWKKeyAccess{ JWTSigner: *signer, diff --git a/internal/keyaccess/jwt_test.go b/internal/keyaccess/jwt_test.go index c1a00730a..70c921c05 100644 --- a/internal/keyaccess/jwt_test.go +++ b/internal/keyaccess/jwt_test.go @@ -11,7 +11,7 @@ import ( ) func TestCreateJWKKeyAccess(t *testing.T) { - t.Run("Create a Key Access object - Happy Path", func(tt *testing.T) { + t.Run("Create a Base58Key Access object - Happy Path", func(tt *testing.T) { _, privKey, err := crypto.GenerateEd25519Key() kid := "test-kid" assert.NoError(tt, err) @@ -20,7 +20,7 @@ func TestCreateJWKKeyAccess(t *testing.T) { assert.NotEmpty(tt, ka) }) - t.Run("Create a Key Access object - Bad Key", func(tt *testing.T) { + t.Run("Create a Base58Key Access object - Bad Base58Key", func(tt *testing.T) { kid := "test-kid" ka, err := NewJWKKeyAccess(kid, nil) assert.Error(tt, err) @@ -28,7 +28,7 @@ func TestCreateJWKKeyAccess(t *testing.T) { assert.Empty(tt, ka) }) - t.Run("Create a Key Access object - No KID", func(tt *testing.T) { + t.Run("Create a Base58Key Access object - No KID", func(tt *testing.T) { _, privKey, err := crypto.GenerateEd25519Key() assert.NoError(tt, err) ka, err := NewJWKKeyAccess("", privKey) diff --git a/pkg/server/router/keystore.go b/pkg/server/router/keystore.go index bb94ad377..6db8b45cc 100644 --- a/pkg/server/router/keystore.go +++ b/pkg/server/router/keystore.go @@ -51,7 +51,7 @@ func (sk StoreKeyRequest) ToServiceRequest() (*keystore.StoreKeyRequest, error) } // StoreKey godoc -// @Summary Store Key +// @Summary Store Base58Key // @Description Stores a key to be used by the service // @Tags KeyStoreAPI // @Accept json @@ -93,7 +93,7 @@ type GetKeyDetailsResponse struct { } // GetKeyDetails godoc -// @Summary Get Details For Key +// @Summary Get Details For Base58Key // @Description Get details about a stored key // @Tags KeyStoreAPI // @Accept json diff --git a/pkg/server/router/keystore_test.go b/pkg/server/router/keystore_test.go index a5bb87e36..19b942a82 100644 --- a/pkg/server/router/keystore_test.go +++ b/pkg/server/router/keystore_test.go @@ -34,7 +34,7 @@ func TestKeyStoreRouter(t *testing.T) { assert.Contains(tt, err.Error(), "could not create key store router with service type: test") }) - t.Run("Key Store Service Test", func(tt *testing.T) { + t.Run("Base58Key Store Service Test", func(tt *testing.T) { bolt, err := storage.NewBoltDB() assert.NoError(tt, err) assert.NotEmpty(tt, bolt) diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go index b9fccdde2..62d663e84 100644 --- a/pkg/server/server_test.go +++ b/pkg/server/server_test.go @@ -4,8 +4,6 @@ import ( "bytes" "context" "fmt" - "github.com/TBD54566975/ssi-sdk/credential/exchange" - "io" "net/http" "net/http/httptest" @@ -13,6 +11,8 @@ import ( "testing" "time" + "github.com/TBD54566975/ssi-sdk/credential/exchange" + credsdk "github.com/TBD54566975/ssi-sdk/credential" manifestsdk "github.com/TBD54566975/ssi-sdk/credential/manifest" "github.com/TBD54566975/ssi-sdk/crypto" @@ -121,7 +121,7 @@ func TestDIDAPI(t *testing.T) { assert.Equal(tt, resp.DIDMethods[0], did.KeyMethod) }) - t.Run("Test Create DID By Method: Key", func(tt *testing.T) { + t.Run("Test Create DID By Method: Base58Key", func(tt *testing.T) { bolt, err := storage.NewBoltDB() // remove the db file after the test @@ -1158,7 +1158,7 @@ func newManifestService(t *testing.T, bolt *storage.BoltDB) *router.ManifestRout } func TestKeyStoreAPI(t *testing.T) { - t.Run("Test Store Key", func(tt *testing.T) { + t.Run("Test Store Base58Key", func(tt *testing.T) { bolt, err := storage.NewBoltDB() // remove the db file after the test @@ -1207,7 +1207,7 @@ func TestKeyStoreAPI(t *testing.T) { assert.NoError(tt, err) }) - t.Run("Test Get Key Details", func(tt *testing.T) { + t.Run("Test Get Base58Key Details", func(tt *testing.T) { bolt, err := storage.NewBoltDB() // remove the db file after the test diff --git a/pkg/service/credential/credential.go b/pkg/service/credential/credential.go index 4a6eedf37..c30fd76ea 100644 --- a/pkg/service/credential/credential.go +++ b/pkg/service/credential/credential.go @@ -114,6 +114,9 @@ func (s Service) CreateCredential(request CreateCredentialRequest) (*CreateCrede return nil, util.LoggingErrorMsg(err, errMsg) } + // sign the credential + // keyaccess.NewJWKKeyAccess() + // store the credential storageRequest := credstorage.StoredCredential{ ID: cred.ID, diff --git a/pkg/service/keystore/keystore.go b/pkg/service/keystore/keystore.go index ac9145b24..77b7f72cd 100644 --- a/pkg/service/keystore/keystore.go +++ b/pkg/service/keystore/keystore.go @@ -85,6 +85,29 @@ func (s Service) StoreKey(request StoreKeyRequest) error { return nil } +func (s Service) GetKey(request GetKeyRequest) (*GetKeyResponse, error) { + + logrus.Debugf("getting key: %+v", request) + + id := request.ID + gotKey, err := s.storage.GetKey(id) + if err != nil { + err := errors.Wrapf(err, "could not get key for key: %s", id) + return nil, util.LoggingError(err) + } + if gotKey == nil { + err := errors.Wrapf(err, "key with id<%s> could not be found", id) + return nil, util.LoggingError(err) + } + return &GetKeyResponse{ + ID: gotKey.ID, + Type: gotKey.KeyType, + Controller: gotKey.Controller, + Key: gotKey.Key, + CreatedAt: gotKey.CreatedAt, + }, nil +} + func (s Service) GetKeyDetails(request GetKeyDetailsRequest) (*GetKeyDetailsResponse, error) { logrus.Debugf("getting key: %+v", request) diff --git a/pkg/service/keystore/model.go b/pkg/service/keystore/model.go index 2f4afac00..b031f6f42 100644 --- a/pkg/service/keystore/model.go +++ b/pkg/service/keystore/model.go @@ -11,6 +11,18 @@ type StoreKeyRequest struct { Key []byte } +type GetKeyRequest struct { + ID string +} + +type GetKeyResponse struct { + ID string + Type crypto.KeyType + Controller string + CreatedAt string + Key []byte +} + type GetKeyDetailsRequest struct { ID string } diff --git a/pkg/service/keystore/storage/bolt.go b/pkg/service/keystore/storage/bolt.go index dd4e61ca0..af6379c7f 100644 --- a/pkg/service/keystore/storage/bolt.go +++ b/pkg/service/keystore/storage/bolt.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/goccy/go-json" + "github.com/mr-tron/base58" "github.com/pkg/errors" "github.com/tbd54566975/ssi-service/internal/util" @@ -17,7 +18,8 @@ const ( ) type BoltKeyStoreStorage struct { - db *storage.BoltDB + db *storage.BoltDB + serviceKey []byte } func NewBoltKeyStoreStorage(db *storage.BoltDB, key ServiceKey) (*BoltKeyStoreStorage, error) { @@ -25,7 +27,11 @@ func NewBoltKeyStoreStorage(db *storage.BoltDB, key ServiceKey) (*BoltKeyStoreSt return nil, errors.New("bolt db reference is nil") } - bolt := &BoltKeyStoreStorage{db: db} + keyBytes, err := base58.Decode(key.Base58Key) + if err != nil { + return nil, errors.Wrap(err, "could not decode service key") + } + bolt := &BoltKeyStoreStorage{db: db, serviceKey: keyBytes} // first, store the service key if err := bolt.storeServiceKey(key); err != nil { @@ -69,10 +75,17 @@ func (b BoltKeyStoreStorage) StoreKey(key StoredKey) error { errMsg := fmt.Sprintf("could not store key: %s", id) return util.LoggingErrorMsg(err, errMsg) } - return b.db.Write(namespace, id, keyBytes) + + // encrypt key before storing + encryptedKey, err := util.XChaCha20Poly1305Encrypt(b.serviceKey, keyBytes) + if err != nil { + return errors.Wrapf(err, "could not encrypt key: %s", key.ID) + } + + return b.db.Write(namespace, id, encryptedKey) } -func (b BoltKeyStoreStorage) GetKeyDetails(id string) (*KeyDetails, error) { +func (b BoltKeyStoreStorage) GetKey(id string) (*StoredKey, error) { storedKeyBytes, err := b.db.Read(namespace, id) if err != nil { errMsg := fmt.Sprintf("could not get key details for key: %s", id) @@ -82,11 +95,26 @@ func (b BoltKeyStoreStorage) GetKeyDetails(id string) (*KeyDetails, error) { err := fmt.Errorf("could not find key details for key: %s", id) return nil, util.LoggingError(err) } + + // decrypt key before unmarshaling + decryptedKey, err := util.XChaCha20Poly1305Decrypt(b.serviceKey, storedKeyBytes) + if err != nil { + return nil, errors.Wrapf(err, "could not decrypt key: %s", id) + } + var stored StoredKey - if err := json.Unmarshal(storedKeyBytes, &stored); err != nil { + if err := json.Unmarshal(decryptedKey, &stored); err != nil { errMsg := fmt.Sprintf("could not unmarshal stored key: %s", id) return nil, util.LoggingErrorMsg(err, errMsg) } + return &stored, nil +} + +func (b BoltKeyStoreStorage) GetKeyDetails(id string) (*KeyDetails, error) { + stored, err := b.GetKey(id) + if err != nil { + return nil, errors.Wrapf(err, "could not get key details for key: %s", id) + } return &KeyDetails{ ID: stored.ID, Controller: stored.Controller, diff --git a/pkg/service/keystore/storage/storage.go b/pkg/service/keystore/storage/storage.go index 67799c13c..2ba9ff468 100644 --- a/pkg/service/keystore/storage/storage.go +++ b/pkg/service/keystore/storage/storage.go @@ -27,12 +27,13 @@ type KeyDetails struct { } type ServiceKey struct { - Key string - Salt string + Base58Key string + Base58Salt string } type Storage interface { StoreKey(key StoredKey) error + GetKey(id string) (*StoredKey, error) GetKeyDetails(id string) (*KeyDetails, error) } @@ -45,8 +46,8 @@ func NewKeyStoreStorage(s storage.ServiceStorage, serviceKey, serviceKeySalt str return nil, util.LoggingNewError(errMsg) } boltStorage, err := NewBoltKeyStoreStorage(gotBolt, ServiceKey{ - Key: serviceKey, - Salt: serviceKeySalt, + Base58Key: serviceKey, + Base58Salt: serviceKeySalt, }) if err != nil { return nil, util.LoggingErrorMsg(err, "could not instantiate key store bolt storage") From 4117baa9393e74640417170be9e1cd9b1806cc38 Mon Sep 17 00:00:00 2001 From: gabe Date: Fri, 23 Sep 2022 11:29:46 -0700 Subject: [PATCH 04/13] config updatse --- config/compose.toml | 9 ++++++++- config/config.go | 42 +++++++++++++++++++++++++++++++++--------- config/config.toml | 9 ++++++++- pkg/service/service.go | 29 ++++++++++++++++++++--------- 4 files changed, 69 insertions(+), 20 deletions(-) diff --git a/config/compose.toml b/config/compose.toml index e2e0cd0a5..63b1f7390 100644 --- a/config/compose.toml +++ b/config/compose.toml @@ -23,6 +23,10 @@ log_level = "info" storage = "bolt" # per-service configuration +[services.keystore] +name = "keystore" +password = "default-password" + [services.did] name = "did" methods = ["key"] @@ -31,4 +35,7 @@ methods = ["key"] name = "schema" [serivces.credential] -name = "credential" \ No newline at end of file +name = "credential" + +[services.manifest] +name = "manifest" \ No newline at end of file diff --git a/config/config.go b/config/config.go index d2b26fe7c..63e6cccdf 100644 --- a/config/config.go +++ b/config/config.go @@ -48,10 +48,10 @@ type ServicesConfig struct { // Embed all service-specific configs here. The order matters: from which should be instantiated first, to last + KeyStoreConfig KeyStoreServiceConfig `toml:"keystore,omitempty"` DIDConfig DIDServiceConfig `toml:"did,omitempty"` SchemaConfig SchemaServiceConfig `toml:"schema,omitempty"` CredentialConfig CredentialServiceConfig `toml:"credential,omitempty"` - KeyStoreConfig KeyStoreServiceConfig `toml:"keystore,omitempty"` ManifestConfig ManifestServiceConfig `toml:"manifest,omitempty"` } @@ -61,6 +61,20 @@ type BaseServiceConfig struct { Name string `toml:"name"` } +type KeyStoreServiceConfig struct { + *BaseServiceConfig + // Service key password. Used by a KDF whose key is used by a symmetric cypher for key encryption. + // The password is salted before usage. + ServiceKeyPassword string `toml:"password"` +} + +func (k *KeyStoreServiceConfig) IsEmpty() bool { + if k == nil { + return true + } + return reflect.DeepEqual(k, &KeyStoreServiceConfig{}) +} + type DIDServiceConfig struct { *BaseServiceConfig Methods []string `toml:"methods"` @@ -89,15 +103,22 @@ type CredentialServiceConfig struct { // TODO(gabe) supported key and signature types } +func (c *CredentialServiceConfig) IsEmpty() bool { + if c == nil { + return true + } + return reflect.DeepEqual(c, &CredentialServiceConfig{}) +} + type ManifestServiceConfig struct { *BaseServiceConfig } -type KeyStoreServiceConfig struct { - *BaseServiceConfig - // Service key password. Used by a KDF whose key is used by a symmetric cypher for key encryption. - // The password is salted before usage. - ServiceKeyPassword string +func (m *ManifestServiceConfig) IsEmpty() bool { + if m == nil { + return true + } + return reflect.DeepEqual(m, &ManifestServiceConfig{}) } // LoadConfig attempts to load a TOML config file from the given path, and coerce it into our object model. @@ -143,6 +164,10 @@ func LoadConfig(path string) (*SSIServiceConfig, error) { if defaultConfig { config.Services = ServicesConfig{ StorageProvider: "bolt", + KeyStoreConfig: KeyStoreServiceConfig{ + BaseServiceConfig: &BaseServiceConfig{Name: "keystore"}, + ServiceKeyPassword: "default-password", + }, DIDConfig: DIDServiceConfig{ BaseServiceConfig: &BaseServiceConfig{Name: "did"}, Methods: []string{"key"}, @@ -153,9 +178,8 @@ func LoadConfig(path string) (*SSIServiceConfig, error) { CredentialConfig: CredentialServiceConfig{ BaseServiceConfig: &BaseServiceConfig{Name: "credential"}, }, - KeyStoreConfig: KeyStoreServiceConfig{ - BaseServiceConfig: &BaseServiceConfig{Name: "keystore"}, - ServiceKeyPassword: "default-password", + ManifestConfig: ManifestServiceConfig{ + BaseServiceConfig: &BaseServiceConfig{Name: "manifest"}, }, } } else { diff --git a/config/config.toml b/config/config.toml index df426cb04..5c8471561 100644 --- a/config/config.toml +++ b/config/config.toml @@ -21,6 +21,10 @@ log_level = "debug" storage = "bolt" # per-service configuration +[services.keystore] +name = "keystore" +password = "default-password" + [services.did] name = "did" methods = ["key"] @@ -29,4 +33,7 @@ methods = ["key"] name = "schema" [serivces.credential] -name = "credential" \ No newline at end of file +name = "credential" + +[services.manifest] +name = "manifest" \ No newline at end of file diff --git a/pkg/service/service.go b/pkg/service/service.go index 111eb89cf..18b210a26 100644 --- a/pkg/service/service.go +++ b/pkg/service/service.go @@ -8,6 +8,7 @@ import ( "github.com/tbd54566975/ssi-service/pkg/service/credential" "github.com/tbd54566975/ssi-service/pkg/service/did" "github.com/tbd54566975/ssi-service/pkg/service/framework" + "github.com/tbd54566975/ssi-service/pkg/service/keystore" "github.com/tbd54566975/ssi-service/pkg/service/manifest" "github.com/tbd54566975/ssi-service/pkg/service/schema" "github.com/tbd54566975/ssi-service/pkg/storage" @@ -38,12 +39,21 @@ func validateServiceConfig(config config.ServicesConfig) error { if !storage.IsStorageAvailable(config.StorageProvider) { return fmt.Errorf("%s storage provider configured, but not available", config.StorageProvider) } + if config.KeyStoreConfig.IsEmpty() { + return fmt.Errorf("%s no config provided", framework.KeyStore) + } if config.DIDConfig.IsEmpty() { return fmt.Errorf("%s no config provided", framework.DID) } if config.SchemaConfig.IsEmpty() { return fmt.Errorf("%s no config provided", framework.Schema) } + if config.CredentialConfig.IsEmpty() { + return fmt.Errorf("%s no config provided", framework.Credential) + } + if config.ManifestConfig.IsEmpty() { + return fmt.Errorf("%s no config provided", framework.Manifest) + } return nil } @@ -60,29 +70,30 @@ func instantiateServices(config config.ServicesConfig) ([]framework.Service, err return nil, util.LoggingErrorMsg(err, errMsg) } + keyStoreService, err := keystore.NewKeyStoreService(config.KeyStoreConfig, storageProvider) + if err != nil { + return nil, util.LoggingErrorMsg(err, "could not instantiate keystore service") + } + didService, err := did.NewDIDService(config.DIDConfig, storageProvider) if err != nil { - errMsg := "could not instantiate the DID service" - return nil, util.LoggingErrorMsg(err, errMsg) + return nil, util.LoggingErrorMsg(err, "could not instantiate the DID service") } schemaService, err := schema.NewSchemaService(config.SchemaConfig, storageProvider) if err != nil { - errMsg := "could not instantiate the schema service" - return nil, util.LoggingErrorMsg(err, errMsg) + return nil, util.LoggingErrorMsg(err, "could not instantiate the schema service") } credentialService, err := credential.NewCredentialService(config.CredentialConfig, storageProvider) if err != nil { - errMsg := "could not instantiate the credential service" - return nil, util.LoggingErrorMsg(err, errMsg) + return nil, util.LoggingErrorMsg(err, "could not instantiate the credential service") } manifestService, err := manifest.NewManifestService(config.ManifestConfig, storageProvider) if err != nil { - errMsg := "could not instantiate the manifest service" - return nil, util.LoggingErrorMsg(err, errMsg) + return nil, util.LoggingErrorMsg(err, "could not instantiate the manifest service") } - return []framework.Service{didService, schemaService, credentialService, manifestService}, nil + return []framework.Service{keyStoreService, didService, schemaService, credentialService, manifestService}, nil } From e887a7261bb30881a5e27cfab9dddf15f04e10c8 Mon Sep 17 00:00:00 2001 From: gabe Date: Fri, 23 Sep 2022 11:33:40 -0700 Subject: [PATCH 05/13] temp --- pkg/service/did/did.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/pkg/service/did/did.go b/pkg/service/did/did.go index 0c4595122..566e6cb92 100644 --- a/pkg/service/did/did.go +++ b/pkg/service/did/did.go @@ -2,7 +2,9 @@ package did import ( "fmt" + "github.com/pkg/errors" + "github.com/tbd54566975/ssi-service/config" "github.com/tbd54566975/ssi-service/internal/util" didstorage "github.com/tbd54566975/ssi-service/pkg/service/did/storage" @@ -23,12 +25,12 @@ type Service struct { config config.DIDServiceConfig } -func (s Service) Type() framework.Type { +func (s *Service) Type() framework.Type { return framework.DID } // Status is a self-reporting status for the DID service. -func (s Service) Status() framework.Status { +func (s *Service) Status() framework.Status { if s.storage == nil || len(s.handlers) == 0 { return framework.Status{ Status: framework.StatusNotReady, @@ -38,11 +40,11 @@ func (s Service) Status() framework.Status { return framework.Status{Status: framework.StatusReady} } -func (s Service) Config() config.DIDServiceConfig { +func (s *Service) Config() config.DIDServiceConfig { return s.config } -func (s Service) GetSupportedMethods() GetSupportedMethodsResponse { +func (s *Service) GetSupportedMethods() GetSupportedMethodsResponse { var methods []Method for method := range s.handlers { methods = append(methods, method) @@ -50,7 +52,7 @@ func (s Service) GetSupportedMethods() GetSupportedMethodsResponse { return GetSupportedMethodsResponse{Methods: methods} } -func (s Service) CreateDIDByMethod(request CreateDIDRequest) (*CreateDIDResponse, error) { +func (s *Service) CreateDIDByMethod(request CreateDIDRequest) (*CreateDIDResponse, error) { handler, err := s.getHandler(request.Method) if err != nil { errMsg := fmt.Sprintf("could not get handler for method<%s>", request.Method) @@ -59,7 +61,7 @@ func (s Service) CreateDIDByMethod(request CreateDIDRequest) (*CreateDIDResponse return handler.CreateDID(request) } -func (s Service) GetDIDByMethod(request GetDIDRequest) (*GetDIDResponse, error) { +func (s *Service) GetDIDByMethod(request GetDIDRequest) (*GetDIDResponse, error) { handler, err := s.getHandler(request.Method) if err != nil { errMsg := fmt.Sprintf("could not get handler for method<%s>", request.Method) @@ -68,7 +70,7 @@ func (s Service) GetDIDByMethod(request GetDIDRequest) (*GetDIDResponse, error) return handler.GetDID(request) } -func (s Service) getHandler(method Method) (MethodHandler, error) { +func (s *Service) getHandler(method Method) (MethodHandler, error) { handler, ok := s.handlers[method] if !ok { err := fmt.Errorf("could not get handler for DID method: %s", method) From 60aba8ae43ed8d4668dea3a7c6ec44c9c7b3102c Mon Sep 17 00:00:00 2001 From: gabe Date: Fri, 23 Sep 2022 20:41:57 -0700 Subject: [PATCH 06/13] did svc uses keystore pt 1 --- pkg/server/router/did_test.go | 18 ++++++-- pkg/server/server_test.go | 62 ++++++++++++------------- pkg/service/did/did.go | 85 ++++++++++++++++++----------------- pkg/service/service.go | 2 +- 4 files changed, 92 insertions(+), 75 deletions(-) diff --git a/pkg/server/router/did_test.go b/pkg/server/router/did_test.go index 6313b465a..00e023be7 100644 --- a/pkg/server/router/did_test.go +++ b/pkg/server/router/did_test.go @@ -6,10 +6,12 @@ import ( "github.com/TBD54566975/ssi-sdk/crypto" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/tbd54566975/ssi-service/config" "github.com/tbd54566975/ssi-service/pkg/service/did" "github.com/tbd54566975/ssi-service/pkg/service/framework" + "github.com/tbd54566975/ssi-service/pkg/service/keystore" "github.com/tbd54566975/ssi-service/pkg/storage" ) @@ -35,12 +37,13 @@ func TestDIDRouter(t *testing.T) { }) t.Run("DID Service Test", func(tt *testing.T) { - bolt, err := storage.NewBoltDB() + db, err := storage.NewBoltDB() assert.NoError(tt, err) - assert.NotEmpty(tt, bolt) + assert.NotEmpty(tt, db) + keyStoreService := testKeyStoreService(tt, db) serviceConfig := config.DIDServiceConfig{Methods: []string{string(did.KeyMethod)}} - didService, err := did.NewDIDService(serviceConfig, bolt) + didService, err := did.NewDIDService(serviceConfig, db, keyStoreService) assert.NoError(tt, err) assert.NotEmpty(tt, didService) @@ -80,3 +83,12 @@ func TestDIDRouter(t *testing.T) { assert.Equal(tt, createDIDResponse.DID.ID, getDIDResponse.DID.ID) }) } + +func testKeyStoreService(t *testing.T, db *storage.BoltDB) *keystore.Service { + serviceConfig := config.KeyStoreServiceConfig{ServiceKeyPassword: "test-password"} + // create a keystore service + keystoreService, err := keystore.NewKeyStoreService(serviceConfig, db) + require.NoError(t, err) + require.NotEmpty(t, keystoreService) + return keystoreService +} diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go index 62d663e84..e95f5415f 100644 --- a/pkg/server/server_test.go +++ b/pkg/server/server_test.go @@ -60,7 +60,6 @@ func TestHealthCheckAPI(t *testing.T) { assert.NoError(t, err) assert.Equal(t, router.HealthOK, resp.Status) - } func TestReadinessAPI(t *testing.T) { @@ -103,7 +102,8 @@ func TestDIDAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - didService := newDIDService(tt, bolt) + _, keyStoreService := newKeyStore(tt, bolt) + didService := newDIDRouter(tt, bolt, keyStoreService) // get DID methods req := httptest.NewRequest(http.MethodGet, "https://ssi-service.com/v1/dids", nil) @@ -130,7 +130,8 @@ func TestDIDAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - didService := newDIDService(tt, bolt) + _, keyStoreService := newKeyStore(tt, bolt) + didService := newDIDRouter(tt, bolt, keyStoreService) // create DID by method - key - missing body req := httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/dids/key", nil) @@ -178,7 +179,8 @@ func TestDIDAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - didService := newDIDService(tt, bolt) + _, keyStore := newKeyStore(tt, bolt) + didService := newDIDRouter(tt, bolt, keyStore) // get DID by method req := httptest.NewRequest(http.MethodGet, "https://ssi-service.com/v1/dids/bad/worse", nil) @@ -237,9 +239,9 @@ func TestDIDAPI(t *testing.T) { }) } -func newDIDService(t *testing.T, bolt *storage.BoltDB) *router.DIDRouter { +func newDIDRouter(t *testing.T, bolt *storage.BoltDB, keyStore *keystore.Service) *router.DIDRouter { serviceConfig := config.DIDServiceConfig{Methods: []string{string(did.KeyMethod)}} - didService, err := did.NewDIDService(serviceConfig, bolt) + didService, err := did.NewDIDService(serviceConfig, bolt, keyStore) require.NoError(t, err) require.NotEmpty(t, didService) @@ -261,7 +263,7 @@ func TestSchemaAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - schemaService := newSchemaService(tt, bolt) + schemaService := newSchemaRouter(tt, bolt) simpleSchema := map[string]interface{}{ "type": "object", @@ -308,7 +310,7 @@ func TestSchemaAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - schemaService := newSchemaService(tt, bolt) + schemaService := newSchemaRouter(tt, bolt) // get schema that doesn't exist w := httptest.NewRecorder() @@ -394,7 +396,7 @@ func TestSchemaAPI(t *testing.T) { }) } -func newSchemaService(t *testing.T, bolt *storage.BoltDB) *router.SchemaRouter { +func newSchemaRouter(t *testing.T, bolt *storage.BoltDB) *router.SchemaRouter { schemaService, err := schema.NewSchemaService(config.SchemaServiceConfig{}, bolt) require.NoError(t, err) require.NotEmpty(t, schemaService) @@ -417,7 +419,7 @@ func TestCredentialAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - credService := newCredentialService(tt, bolt) + credService := newCredentialRouter(tt, bolt) // missing required field: data badCredRequest := router.CreateCredentialRequest{ @@ -468,7 +470,7 @@ func TestCredentialAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - credService := newCredentialService(tt, bolt) + credService := newCredentialRouter(tt, bolt) w := httptest.NewRecorder() @@ -529,7 +531,7 @@ func TestCredentialAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - credService := newCredentialService(tt, bolt) + credService := newCredentialRouter(tt, bolt) w := httptest.NewRecorder() @@ -578,7 +580,7 @@ func TestCredentialAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - credService := newCredentialService(tt, bolt) + credService := newCredentialRouter(tt, bolt) w := httptest.NewRecorder() @@ -626,7 +628,7 @@ func TestCredentialAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - credService := newCredentialService(tt, bolt) + credService := newCredentialRouter(tt, bolt) w := httptest.NewRecorder() @@ -672,7 +674,7 @@ func TestCredentialAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - credService := newCredentialService(tt, bolt) + credService := newCredentialRouter(tt, bolt) createCredRequest := router.CreateCredentialRequest{ Issuer: "did:abc:123", @@ -723,7 +725,7 @@ func TestCredentialAPI(t *testing.T) { }) } -func newCredentialService(t *testing.T, bolt *storage.BoltDB) *router.CredentialRouter { +func newCredentialRouter(t *testing.T, bolt *storage.BoltDB) *router.CredentialRouter { credentialService, err := credential.NewCredentialService(config.CredentialServiceConfig{}, bolt) require.NoError(t, err) require.NotEmpty(t, credentialService) @@ -746,7 +748,7 @@ func TestManifestAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - manifestService := newManifestService(tt, bolt) + manifestService := newManifestRouter(tt, bolt) // missing required field: Manifest badManifestRequest := router.CreateManifestRequest{} @@ -787,7 +789,7 @@ func TestManifestAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - manifestService := newManifestService(tt, bolt) + manifestService := newManifestRouter(tt, bolt) w := httptest.NewRecorder() @@ -842,7 +844,7 @@ func TestManifestAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - manifestService := newManifestService(tt, bolt) + manifestService := newManifestRouter(tt, bolt) w := httptest.NewRecorder() @@ -880,7 +882,7 @@ func TestManifestAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - manifestService := newManifestService(tt, bolt) + manifestService := newManifestRouter(tt, bolt) // good request createManifestRequest := getValidManifestRequest() @@ -933,7 +935,7 @@ func TestManifestAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - manifestService := newManifestService(tt, bolt) + manifestService := newManifestRouter(tt, bolt) // missing required field: Application badManifestRequest := router.SubmitApplicationRequest{ @@ -991,7 +993,7 @@ func TestManifestAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - manifestService := newManifestService(tt, bolt) + manifestService := newManifestRouter(tt, bolt) w := httptest.NewRecorder() @@ -1081,7 +1083,7 @@ func TestManifestAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - manifestService := newManifestService(tt, bolt) + manifestService := newManifestRouter(tt, bolt) // good manifest request createManifestRequest := getValidManifestRequest() @@ -1144,7 +1146,7 @@ func TestManifestAPI(t *testing.T) { }) } -func newManifestService(t *testing.T, bolt *storage.BoltDB) *router.ManifestRouter { +func newManifestRouter(t *testing.T, bolt *storage.BoltDB) *router.ManifestRouter { manifestService, err := manifest.NewManifestService(config.ManifestServiceConfig{}, bolt) require.NoError(t, err) require.NotEmpty(t, manifestService) @@ -1167,7 +1169,7 @@ func TestKeyStoreAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - keyStoreService := newKeyStoreService(tt, bolt) + keyStoreRouter, _ := newKeyStore(tt, bolt) w := httptest.NewRecorder() // bad key type @@ -1179,7 +1181,7 @@ func TestKeyStoreAPI(t *testing.T) { } badRequestValue := newRequestValue(tt, badKeyStoreRequest) req := httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/keys", badRequestValue) - err = keyStoreService.StoreKey(newRequestContext(), w, req) + err = keyStoreRouter.StoreKey(newRequestContext(), w, req) assert.Error(tt, err) assert.Contains(tt, err.Error(), "could not store key: test-kid, unsupported key type: bad") @@ -1203,7 +1205,7 @@ func TestKeyStoreAPI(t *testing.T) { } requestValue := newRequestValue(tt, storeKeyRequest) req = httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/keys", requestValue) - err = keyStoreService.StoreKey(newRequestContext(), w, req) + err = keyStoreRouter.StoreKey(newRequestContext(), w, req) assert.NoError(tt, err) }) @@ -1216,7 +1218,7 @@ func TestKeyStoreAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - keyStoreService := newKeyStoreService(tt, bolt) + keyStoreService, _ := newKeyStore(tt, bolt) w := httptest.NewRecorder() // store a valid key @@ -1256,7 +1258,7 @@ func TestKeyStoreAPI(t *testing.T) { }) } -func newKeyStoreService(t *testing.T, bolt *storage.BoltDB) *router.KeyStoreRouter { +func newKeyStore(t *testing.T, bolt *storage.BoltDB) (*router.KeyStoreRouter, *keystore.Service) { serviceConfig := config.KeyStoreServiceConfig{ServiceKeyPassword: "test-password"} keyStoreService, err := keystore.NewKeyStoreService(serviceConfig, bolt) require.NoError(t, err) @@ -1267,7 +1269,7 @@ func newKeyStoreService(t *testing.T, bolt *storage.BoltDB) *router.KeyStoreRout require.NoError(t, err) require.NotEmpty(t, keyStoreRouter) - return keyStoreRouter + return keyStoreRouter, keyStoreService } func newRequestValue(t *testing.T, data interface{}) io.Reader { diff --git a/pkg/service/did/did.go b/pkg/service/did/did.go index 566e6cb92..f049adf8b 100644 --- a/pkg/service/did/did.go +++ b/pkg/service/did/did.go @@ -9,6 +9,7 @@ import ( "github.com/tbd54566975/ssi-service/internal/util" didstorage "github.com/tbd54566975/ssi-service/pkg/service/did/storage" "github.com/tbd54566975/ssi-service/pkg/service/framework" + "github.com/tbd54566975/ssi-service/pkg/service/keystore" "github.com/tbd54566975/ssi-service/pkg/storage" ) @@ -23,6 +24,49 @@ type Service struct { handlers map[Method]MethodHandler storage didstorage.Storage config config.DIDServiceConfig + keyStore *keystore.Service +} + +// MethodHandler describes the functionality of *all* possible DID service, regardless of method +type MethodHandler interface { + CreateDID(request CreateDIDRequest) (*CreateDIDResponse, error) + GetDID(request GetDIDRequest) (*GetDIDResponse, error) +} + +func NewDIDService(config config.DIDServiceConfig, s storage.ServiceStorage, keyStore *keystore.Service) (*Service, error) { + didStorage, err := didstorage.NewDIDStorage(s) + if err != nil { + return nil, errors.Wrap(err, "could not instantiate DID storage for the DID service") + } + svc := Service{ + storage: didStorage, + handlers: make(map[Method]MethodHandler), + keyStore: keyStore, + } + + // instantiate all handlers for DID methods + for _, m := range config.Methods { + if err := svc.instantiateHandlerForMethod(Method(m)); err != nil { + return nil, errors.Wrap(err, "could not instantiate DID service") + } + } + return &svc, nil +} + +func (s *Service) instantiateHandlerForMethod(method Method) error { + switch method { + case KeyMethod: + handler, err := newKeyDIDHandler(s.storage) + if err != nil { + err := fmt.Errorf("could not instnatiate did:%s handler", KeyMethod) + return util.LoggingError(err) + } + s.handlers[method] = handler + default: + err := fmt.Errorf("unsupported DID method: %s", method) + return util.LoggingError(err) + } + return nil } func (s *Service) Type() framework.Type { @@ -78,44 +122,3 @@ func (s *Service) getHandler(method Method) (MethodHandler, error) { } return handler, nil } - -// MethodHandler describes the functionality of *all* possible DID service, regardless of method -type MethodHandler interface { - CreateDID(request CreateDIDRequest) (*CreateDIDResponse, error) - GetDID(request GetDIDRequest) (*GetDIDResponse, error) -} - -func NewDIDService(config config.DIDServiceConfig, s storage.ServiceStorage) (*Service, error) { - didStorage, err := didstorage.NewDIDStorage(s) - if err != nil { - return nil, errors.Wrap(err, "could not instantiate DID storage for the DID service") - } - svc := Service{ - storage: didStorage, - handlers: make(map[Method]MethodHandler), - } - - // instantiate all handlers for DID methods - for _, m := range config.Methods { - if err := svc.instantiateHandlerForMethod(Method(m)); err != nil { - return nil, errors.Wrap(err, "could not instantiate DID service") - } - } - return &svc, nil -} - -func (s *Service) instantiateHandlerForMethod(method Method) error { - switch method { - case KeyMethod: - handler, err := newKeyDIDHandler(s.storage) - if err != nil { - err := fmt.Errorf("could not instnatiate did:%s handler", KeyMethod) - return util.LoggingError(err) - } - s.handlers[method] = handler - default: - err := fmt.Errorf("unsupported DID method: %s", method) - return util.LoggingError(err) - } - return nil -} diff --git a/pkg/service/service.go b/pkg/service/service.go index 18b210a26..592fe58e8 100644 --- a/pkg/service/service.go +++ b/pkg/service/service.go @@ -75,7 +75,7 @@ func instantiateServices(config config.ServicesConfig) ([]framework.Service, err return nil, util.LoggingErrorMsg(err, "could not instantiate keystore service") } - didService, err := did.NewDIDService(config.DIDConfig, storageProvider) + didService, err := did.NewDIDService(config.DIDConfig, storageProvider, keyStoreService) if err != nil { return nil, util.LoggingErrorMsg(err, "could not instantiate the DID service") } From 8d77c814c37f03ebf8899d4ada2df013c101d94d Mon Sep 17 00:00:00 2001 From: gabe Date: Fri, 23 Sep 2022 20:54:58 -0700 Subject: [PATCH 07/13] using the keystore pt 2 --- pkg/service/did/did.go | 4 ++- pkg/service/did/key.go | 37 +++++++++++++++++-------- pkg/service/did/storage/bolt.go | 8 ++++-- pkg/service/did/storage/storage.go | 3 +- pkg/service/keystore/model.go | 6 ++-- pkg/service/keystore/storage/storage.go | 11 ++++---- 6 files changed, 45 insertions(+), 24 deletions(-) diff --git a/pkg/service/did/did.go b/pkg/service/did/did.go index f049adf8b..449732fa6 100644 --- a/pkg/service/did/did.go +++ b/pkg/service/did/did.go @@ -24,6 +24,8 @@ type Service struct { handlers map[Method]MethodHandler storage didstorage.Storage config config.DIDServiceConfig + + // external dependencies keyStore *keystore.Service } @@ -56,7 +58,7 @@ func NewDIDService(config config.DIDServiceConfig, s storage.ServiceStorage, key func (s *Service) instantiateHandlerForMethod(method Method) error { switch method { case KeyMethod: - handler, err := newKeyDIDHandler(s.storage) + handler, err := newKeyDIDHandler(s.storage, s.keyStore) if err != nil { err := fmt.Errorf("could not instnatiate did:%s handler", KeyMethod) return util.LoggingError(err) diff --git a/pkg/service/did/key.go b/pkg/service/did/key.go index 3d4a384e9..d66755005 100644 --- a/pkg/service/did/key.go +++ b/pkg/service/did/key.go @@ -10,14 +10,16 @@ import ( "github.com/sirupsen/logrus" "github.com/tbd54566975/ssi-service/pkg/service/did/storage" + "github.com/tbd54566975/ssi-service/pkg/service/keystore" ) -func newKeyDIDHandler(s storage.Storage) (MethodHandler, error) { - return &keyDIDHandler{storage: s}, nil +func newKeyDIDHandler(s storage.Storage, ks *keystore.Service) (MethodHandler, error) { + return &keyDIDHandler{storage: s, keyStore: ks}, nil } type keyDIDHandler struct { - storage storage.Storage + storage storage.Storage + keyStore *keystore.Service } func (h *keyDIDHandler) CreateDID(request CreateDIDRequest) (*CreateDIDResponse, error) { @@ -29,10 +31,6 @@ func (h *keyDIDHandler) CreateDID(request CreateDIDRequest) (*CreateDIDResponse, if err != nil { return nil, errors.Wrap(err, "could not create did:key") } - privKeyBase58, err := privateKeyToBase58(privKey) - if err != nil { - return nil, errors.Wrap(err, "could not encode private key as base58") - } // expand it to the full doc for storage expanded, err := doc.Expand() @@ -40,18 +38,35 @@ func (h *keyDIDHandler) CreateDID(request CreateDIDRequest) (*CreateDIDResponse, return nil, errors.Wrap(err, "error generating did:key document") } - // store it + // store metadata in DID storage + id := doc.ToString() storedDID := storage.StoredDID{ - DID: *expanded, - PrivateKeyBase58: privKeyBase58, + ID: id, + DID: *expanded, } if err := h.storage.StoreDID(storedDID); err != nil { return nil, errors.Wrap(err, "could not store did:key value") } + // store private key in key storage + keyStoreRequest := keystore.StoreKeyRequest{ + ID: id, + Type: request.KeyType, + Controller: id, + Key: privKey, + } + if err := h.keyStore.StoreKey(keyStoreRequest); err != nil { + return nil, errors.Wrap(err, "could not store did:key private key") + } + + privKeyBase58, err := privateKeyToBase58(privKey) + if err != nil { + return nil, errors.Wrap(err, "could not encode private key as base58") + } + return &CreateDIDResponse{ DID: storedDID.DID, - PrivateKey: storedDID.PrivateKeyBase58, + PrivateKey: privKeyBase58, }, nil } diff --git a/pkg/service/did/storage/bolt.go b/pkg/service/did/storage/bolt.go index 779cd68ac..df2b9b159 100644 --- a/pkg/service/did/storage/bolt.go +++ b/pkg/service/did/storage/bolt.go @@ -2,8 +2,10 @@ package storage import ( "fmt" + "github.com/goccy/go-json" "github.com/pkg/errors" + "github.com/tbd54566975/ssi-service/internal/util" "github.com/tbd54566975/ssi-service/pkg/storage" ) @@ -31,8 +33,8 @@ func NewBoltDIDStorage(db *storage.BoltDB) (*BoltDIDStorage, error) { } func (b BoltDIDStorage) StoreDID(did StoredDID) error { - couldNotStoreDIDErr := fmt.Sprintf("could not store DID: %s", did.DID.ID) - namespace, err := getNamespaceForDID(did.DID.ID) + couldNotStoreDIDErr := fmt.Sprintf("could not store DID: %s", did.ID) + namespace, err := getNamespaceForDID(did.ID) if err != nil { return util.LoggingErrorMsg(err, couldNotStoreDIDErr) } @@ -40,7 +42,7 @@ func (b BoltDIDStorage) StoreDID(did StoredDID) error { if err != nil { return util.LoggingErrorMsg(err, couldNotStoreDIDErr) } - return b.db.Write(namespace, did.DID.ID, didBytes) + return b.db.Write(namespace, did.ID, didBytes) } func (b BoltDIDStorage) GetDID(id string) (*StoredDID, error) { diff --git a/pkg/service/did/storage/storage.go b/pkg/service/did/storage/storage.go index 804aeae1e..038bdfcf2 100644 --- a/pkg/service/did/storage/storage.go +++ b/pkg/service/did/storage/storage.go @@ -10,9 +10,8 @@ import ( ) type StoredDID struct { + ID string `json:"id"` DID did.DIDDocument `json:"did"` - // TODO(gabe) split out key storage into a key store service encrypted with a service encryption key - PrivateKeyBase58 string `json:"privateKeyBase58"` } type Storage interface { diff --git a/pkg/service/keystore/model.go b/pkg/service/keystore/model.go index b031f6f42..25c47ff72 100644 --- a/pkg/service/keystore/model.go +++ b/pkg/service/keystore/model.go @@ -1,6 +1,8 @@ package keystore import ( + gocrypto "crypto" + "github.com/TBD54566975/ssi-sdk/crypto" ) @@ -8,7 +10,7 @@ type StoreKeyRequest struct { ID string Type crypto.KeyType Controller string - Key []byte + Key gocrypto.PrivateKey } type GetKeyRequest struct { @@ -20,7 +22,7 @@ type GetKeyResponse struct { Type crypto.KeyType Controller string CreatedAt string - Key []byte + Key gocrypto.PrivateKey } type GetKeyDetailsRequest struct { diff --git a/pkg/service/keystore/storage/storage.go b/pkg/service/keystore/storage/storage.go index 2ba9ff468..226bd0ba6 100644 --- a/pkg/service/keystore/storage/storage.go +++ b/pkg/service/keystore/storage/storage.go @@ -1,6 +1,7 @@ package storage import ( + gocrypto "crypto" "fmt" "github.com/TBD54566975/ssi-sdk/crypto" @@ -11,11 +12,11 @@ import ( // StoredKey represents a common data model to store data on all key types type StoredKey struct { - ID string `json:"id"` - Controller string `json:"controller"` - KeyType crypto.KeyType `json:"keyType"` - Key []byte `json:"key"` - CreatedAt string `json:"createdAt"` + ID string `json:"id"` + Controller string `json:"controller"` + KeyType crypto.KeyType `json:"keyType"` + Key gocrypto.PrivateKey `json:"key"` + CreatedAt string `json:"createdAt"` } // KeyDetails represents a common data model to get information about a key, without revealing the key itself From d0829129e5c60f90779f1591532b5f1b2d70fbe2 Mon Sep 17 00:00:00 2001 From: gabe Date: Tue, 27 Sep 2022 13:50:37 -0700 Subject: [PATCH 08/13] temp --- pkg/service/credential/credential.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/pkg/service/credential/credential.go b/pkg/service/credential/credential.go index c30fd76ea..f2f596a07 100644 --- a/pkg/service/credential/credential.go +++ b/pkg/service/credential/credential.go @@ -11,12 +11,16 @@ import ( "github.com/tbd54566975/ssi-service/internal/util" credstorage "github.com/tbd54566975/ssi-service/pkg/service/credential/storage" "github.com/tbd54566975/ssi-service/pkg/service/framework" + "github.com/tbd54566975/ssi-service/pkg/service/keystore" "github.com/tbd54566975/ssi-service/pkg/storage" ) type Service struct { storage credstorage.Storage config config.CredentialServiceConfig + + // external dependencies + keyStore *keystore.Service } func (s Service) Type() framework.Type { @@ -37,15 +41,16 @@ func (s Service) Config() config.CredentialServiceConfig { return s.config } -func NewCredentialService(config config.CredentialServiceConfig, s storage.ServiceStorage) (*Service, error) { +func NewCredentialService(config config.CredentialServiceConfig, s storage.ServiceStorage, keyStore *keystore.Service) (*Service, error) { credentialStorage, err := credstorage.NewCredentialStorage(s) if err != nil { errMsg := "could not instantiate storage for the credential service" return nil, util.LoggingErrorMsg(err, errMsg) } return &Service{ - storage: credentialStorage, - config: config, + storage: credentialStorage, + config: config, + keyStore: keyStore, }, nil } From b47cad6518fa42395c8e3a0caaab89df8ebfa112 Mon Sep 17 00:00:00 2001 From: gabe Date: Tue, 27 Sep 2022 17:10:01 -0700 Subject: [PATCH 09/13] add storage, update manifest with some todos --- pkg/server/router/credential_test.go | 11 +- pkg/server/router/did_test.go | 11 -- pkg/server/router/manifest.go | 6 +- pkg/server/router/manifest_test.go | 13 +- pkg/server/router/router_test.go | 2 +- pkg/server/router/schema_test.go | 9 +- pkg/server/router/testutils_test.go | 30 +++++ pkg/server/server_test.go | 143 ++++++++++++++-------- pkg/service/credential/credential.go | 3 - pkg/service/manifest/manifest.go | 151 +++++++++++------------- pkg/service/manifest/storage/storage.go | 14 ++- pkg/service/schema/schema.go | 15 ++- pkg/service/service.go | 6 +- 13 files changed, 244 insertions(+), 170 deletions(-) create mode 100644 pkg/server/router/testutils_test.go diff --git a/pkg/server/router/credential_test.go b/pkg/server/router/credential_test.go index e7aef24d3..81dc1dde7 100644 --- a/pkg/server/router/credential_test.go +++ b/pkg/server/router/credential_test.go @@ -2,16 +2,18 @@ package router import ( "fmt" + "os" + "testing" + "time" + credsdk "github.com/TBD54566975/ssi-sdk/credential" "github.com/goccy/go-json" "github.com/stretchr/testify/assert" + "github.com/tbd54566975/ssi-service/config" "github.com/tbd54566975/ssi-service/pkg/service/credential" "github.com/tbd54566975/ssi-service/pkg/service/framework" "github.com/tbd54566975/ssi-service/pkg/storage" - "os" - "testing" - "time" ) func TestCredentialRouter(t *testing.T) { @@ -40,7 +42,8 @@ func TestCredentialRouter(t *testing.T) { assert.NotEmpty(tt, bolt) serviceConfig := config.CredentialServiceConfig{BaseServiceConfig: &config.BaseServiceConfig{Name: "credential"}} - credService, err := credential.NewCredentialService(serviceConfig, bolt) + keyStoreService := testKeyStoreService(tt, bolt) + credService, err := credential.NewCredentialService(serviceConfig, bolt, keyStoreService) assert.NoError(tt, err) assert.NotEmpty(tt, credService) diff --git a/pkg/server/router/did_test.go b/pkg/server/router/did_test.go index 00e023be7..33c51220e 100644 --- a/pkg/server/router/did_test.go +++ b/pkg/server/router/did_test.go @@ -6,12 +6,10 @@ import ( "github.com/TBD54566975/ssi-sdk/crypto" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/tbd54566975/ssi-service/config" "github.com/tbd54566975/ssi-service/pkg/service/did" "github.com/tbd54566975/ssi-service/pkg/service/framework" - "github.com/tbd54566975/ssi-service/pkg/service/keystore" "github.com/tbd54566975/ssi-service/pkg/storage" ) @@ -83,12 +81,3 @@ func TestDIDRouter(t *testing.T) { assert.Equal(tt, createDIDResponse.DID.ID, getDIDResponse.DID.ID) }) } - -func testKeyStoreService(t *testing.T, db *storage.BoltDB) *keystore.Service { - serviceConfig := config.KeyStoreServiceConfig{ServiceKeyPassword: "test-password"} - // create a keystore service - keystoreService, err := keystore.NewKeyStoreService(serviceConfig, db) - require.NoError(t, err) - require.NotEmpty(t, keystoreService) - return keystoreService -} diff --git a/pkg/server/router/manifest.go b/pkg/server/router/manifest.go index c8ab63137..39ba8b4ea 100644 --- a/pkg/server/router/manifest.go +++ b/pkg/server/router/manifest.go @@ -3,10 +3,12 @@ package router import ( "context" "fmt" + "net/http" + "github.com/TBD54566975/ssi-sdk/credential" manifestsdk "github.com/TBD54566975/ssi-sdk/credential/manifest" + "github.com/tbd54566975/ssi-service/pkg/service/manifest" - "net/http" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -214,7 +216,7 @@ func (mr ManifestRouter) SubmitApplication(ctx context.Context, w http.ResponseW } req := request.ToServiceRequest() - submitApplicationResponse, err := mr.service.SubmitApplication(req) + submitApplicationResponse, err := mr.service.ProcessApplicationSubmission(req) if err != nil { errMsg := "could not submit application" logrus.WithError(err).Error(errMsg) diff --git a/pkg/server/router/manifest_test.go b/pkg/server/router/manifest_test.go index c936bde69..0ec97ddff 100644 --- a/pkg/server/router/manifest_test.go +++ b/pkg/server/router/manifest_test.go @@ -1,17 +1,19 @@ package router import ( + "os" + "testing" + "github.com/TBD54566975/ssi-sdk/credential/exchange" manifestsdk "github.com/TBD54566975/ssi-sdk/credential/manifest" "github.com/TBD54566975/ssi-sdk/crypto" "github.com/google/uuid" "github.com/stretchr/testify/assert" + "github.com/tbd54566975/ssi-service/config" "github.com/tbd54566975/ssi-service/pkg/service/framework" "github.com/tbd54566975/ssi-service/pkg/service/manifest" "github.com/tbd54566975/ssi-service/pkg/storage" - "os" - "testing" ) func TestManifestRouter(t *testing.T) { @@ -40,7 +42,9 @@ func TestManifestRouter(t *testing.T) { assert.NotEmpty(tt, bolt) serviceConfig := config.ManifestServiceConfig{BaseServiceConfig: &config.BaseServiceConfig{Name: "manifest"}} - manifestService, err := manifest.NewManifestService(serviceConfig, bolt) + keyStoreService := testKeyStoreService(tt, bolt) + testCredentialService := testCredentialService(tt, bolt, keyStoreService) + manifestService, err := manifest.NewManifestService(serviceConfig, bolt, keyStoreService, testCredentialService) assert.NoError(tt, err) assert.NotEmpty(tt, manifestService) @@ -59,7 +63,7 @@ func TestManifestRouter(t *testing.T) { // good application request createApplicationRequest := getValidApplicationRequest(createdManifest.Manifest.ID, createManifestRequest.Manifest.PresentationDefinition.InputDescriptors[0].ID) - createdApplication, err := manifestService.SubmitApplication(createApplicationRequest) + createdApplication, err := manifestService.ProcessApplicationSubmission(createApplicationRequest) assert.NoError(tt, err) assert.NotEmpty(tt, createdManifest) assert.NotEmpty(tt, createdApplication.Response.ID) @@ -111,7 +115,6 @@ func getValidManifestRequest() manifest.CreateManifestRequest { } func getValidApplicationRequest(manifestID string, submissionDescriptorId string) manifest.SubmitApplicationRequest { - createApplication := manifestsdk.CredentialApplication{ ID: uuid.New().String(), SpecVersion: "https://identity.foundation/credential-manifest/spec/v1.0.0/", diff --git a/pkg/server/router/router_test.go b/pkg/server/router/router_test.go index 7af4d714b..4bbf129a5 100644 --- a/pkg/server/router/router_test.go +++ b/pkg/server/router/router_test.go @@ -21,10 +21,10 @@ func (s *testService) Status() framework.Status { func (s *testService) Config() config.ServicesConfig { return config.ServicesConfig{ StorageProvider: "bolt", + KeyStoreConfig: config.KeyStoreServiceConfig{ServiceKeyPassword: "test-password"}, DIDConfig: config.DIDServiceConfig{Methods: []string{string(did.KeyMethod)}}, SchemaConfig: config.SchemaServiceConfig{}, CredentialConfig: config.CredentialServiceConfig{}, - KeyStoreConfig: config.KeyStoreServiceConfig{}, ManifestConfig: config.ManifestServiceConfig{}, } } diff --git a/pkg/server/router/schema_test.go b/pkg/server/router/schema_test.go index 4c7151e39..4a199492e 100644 --- a/pkg/server/router/schema_test.go +++ b/pkg/server/router/schema_test.go @@ -1,13 +1,15 @@ package router import ( + "os" + "testing" + "github.com/stretchr/testify/assert" + "github.com/tbd54566975/ssi-service/config" "github.com/tbd54566975/ssi-service/pkg/service/framework" "github.com/tbd54566975/ssi-service/pkg/service/schema" "github.com/tbd54566975/ssi-service/pkg/storage" - "os" - "testing" ) func TestSchemaRouter(t *testing.T) { @@ -37,7 +39,8 @@ func TestSchemaRouter(t *testing.T) { assert.NotEmpty(tt, bolt) serviceConfig := config.SchemaServiceConfig{BaseServiceConfig: &config.BaseServiceConfig{Name: "schema"}} - schemaService, err := schema.NewSchemaService(serviceConfig, bolt) + keyStoreService := testKeyStoreService(tt, bolt) + schemaService, err := schema.NewSchemaService(serviceConfig, bolt, keyStoreService) assert.NoError(tt, err) assert.NotEmpty(tt, schemaService) diff --git a/pkg/server/router/testutils_test.go b/pkg/server/router/testutils_test.go new file mode 100644 index 000000000..b6da1c030 --- /dev/null +++ b/pkg/server/router/testutils_test.go @@ -0,0 +1,30 @@ +package router + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/tbd54566975/ssi-service/config" + "github.com/tbd54566975/ssi-service/pkg/service/credential" + "github.com/tbd54566975/ssi-service/pkg/service/keystore" + "github.com/tbd54566975/ssi-service/pkg/storage" +) + +func testKeyStoreService(t *testing.T, db *storage.BoltDB) *keystore.Service { + serviceConfig := config.KeyStoreServiceConfig{ServiceKeyPassword: "test-password"} + // create a keystore service + keystoreService, err := keystore.NewKeyStoreService(serviceConfig, db) + require.NoError(t, err) + require.NotEmpty(t, keystoreService) + return keystoreService +} + +func testCredentialService(t *testing.T, db *storage.BoltDB, keyStore *keystore.Service) *credential.Service { + serviceConfig := config.CredentialServiceConfig{BaseServiceConfig: &config.BaseServiceConfig{Name: "credential"}} + // create a credential service + credentialService, err := credential.NewCredentialService(serviceConfig, db, keyStore) + require.NoError(t, err) + require.NotEmpty(t, credentialService) + return credentialService +} diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go index e95f5415f..a12ad09a2 100644 --- a/pkg/server/server_test.go +++ b/pkg/server/server_test.go @@ -263,7 +263,8 @@ func TestSchemaAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - schemaService := newSchemaRouter(tt, bolt) + keyStoreService := testKeyStoreService(tt, bolt) + schemaService := newSchemaRouter(tt, bolt, keyStoreService) simpleSchema := map[string]interface{}{ "type": "object", @@ -310,7 +311,8 @@ func TestSchemaAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - schemaService := newSchemaRouter(tt, bolt) + keyStoreService := testKeyStoreService(tt, bolt) + schemaService := newSchemaRouter(tt, bolt, keyStoreService) // get schema that doesn't exist w := httptest.NewRecorder() @@ -396,8 +398,8 @@ func TestSchemaAPI(t *testing.T) { }) } -func newSchemaRouter(t *testing.T, bolt *storage.BoltDB) *router.SchemaRouter { - schemaService, err := schema.NewSchemaService(config.SchemaServiceConfig{}, bolt) +func newSchemaRouter(t *testing.T, bolt *storage.BoltDB, keyStore *keystore.Service) *router.SchemaRouter { + schemaService, err := schema.NewSchemaService(config.SchemaServiceConfig{BaseServiceConfig: &config.BaseServiceConfig{Name: "test-schema"}}, bolt, keyStore) require.NoError(t, err) require.NotEmpty(t, schemaService) @@ -419,7 +421,8 @@ func TestCredentialAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - credService := newCredentialRouter(tt, bolt) + keyStoreService := testKeyStoreService(tt, bolt) + credService := newCredentialRouter(tt, bolt, keyStoreService) // missing required field: data badCredRequest := router.CreateCredentialRequest{ @@ -470,7 +473,8 @@ func TestCredentialAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - credService := newCredentialRouter(tt, bolt) + keyStoreService := testKeyStoreService(tt, bolt) + credService := newCredentialRouter(tt, bolt, keyStoreService) w := httptest.NewRecorder() @@ -531,7 +535,8 @@ func TestCredentialAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - credService := newCredentialRouter(tt, bolt) + keyStoreService := testKeyStoreService(tt, bolt) + credService := newCredentialRouter(tt, bolt, keyStoreService) w := httptest.NewRecorder() @@ -580,7 +585,8 @@ func TestCredentialAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - credService := newCredentialRouter(tt, bolt) + keyStoreService := testKeyStoreService(tt, bolt) + credService := newCredentialRouter(tt, bolt, keyStoreService) w := httptest.NewRecorder() @@ -628,7 +634,8 @@ func TestCredentialAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - credService := newCredentialRouter(tt, bolt) + keyStoreService := testKeyStoreService(tt, bolt) + credService := newCredentialRouter(tt, bolt, keyStoreService) w := httptest.NewRecorder() @@ -674,7 +681,8 @@ func TestCredentialAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - credService := newCredentialRouter(tt, bolt) + keyStoreService := testKeyStoreService(tt, bolt) + credService := newCredentialRouter(tt, bolt, keyStoreService) createCredRequest := router.CreateCredentialRequest{ Issuer: "did:abc:123", @@ -725,8 +733,8 @@ func TestCredentialAPI(t *testing.T) { }) } -func newCredentialRouter(t *testing.T, bolt *storage.BoltDB) *router.CredentialRouter { - credentialService, err := credential.NewCredentialService(config.CredentialServiceConfig{}, bolt) +func newCredentialRouter(t *testing.T, bolt *storage.BoltDB, keyStore *keystore.Service) *router.CredentialRouter { + credentialService, err := credential.NewCredentialService(config.CredentialServiceConfig{BaseServiceConfig: &config.BaseServiceConfig{Name: "test-credential"}}, bolt, keyStore) require.NoError(t, err) require.NotEmpty(t, credentialService) @@ -748,7 +756,9 @@ func TestManifestAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - manifestService := newManifestRouter(tt, bolt) + keyStoreService := testKeyStoreService(tt, bolt) + credentialService := testCredentialService(tt, bolt, keyStoreService) + manifestRouter := newManifestRouter(tt, bolt, keyStoreService, credentialService) // missing required field: Manifest badManifestRequest := router.CreateManifestRequest{} @@ -757,7 +767,7 @@ func TestManifestAPI(t *testing.T) { req := httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/manifests", badRequestValue) w := httptest.NewRecorder() - err = manifestService.CreateManifest(newRequestContext(), w, req) + err = manifestRouter.CreateManifest(newRequestContext(), w, req) assert.Error(tt, err) assert.Contains(tt, err.Error(), "invalid create manifest request") @@ -769,7 +779,7 @@ func TestManifestAPI(t *testing.T) { requestValue := newRequestValue(tt, createManifestRequest) req = httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/manifests", requestValue) - err = manifestService.CreateManifest(newRequestContext(), w, req) + err = manifestRouter.CreateManifest(newRequestContext(), w, req) assert.NoError(tt, err) var resp router.CreateManifestResponse @@ -789,13 +799,15 @@ func TestManifestAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - manifestService := newManifestRouter(tt, bolt) + keyStoreService := testKeyStoreService(tt, bolt) + credentialService := testCredentialService(tt, bolt, keyStoreService) + manifestRouter := newManifestRouter(tt, bolt, keyStoreService, credentialService) w := httptest.NewRecorder() // get a manifest that doesn't exit req := httptest.NewRequest(http.MethodGet, "https://ssi-service.com/v1/manifests/bad", nil) - err = manifestService.GetManifest(newRequestContext(), w, req) + err = manifestRouter.GetManifest(newRequestContext(), w, req) assert.Error(tt, err) assert.Contains(tt, err.Error(), "cannot get manifest without ID parameter") @@ -804,7 +816,7 @@ func TestManifestAPI(t *testing.T) { // get a manifest with an invalid id parameter req = httptest.NewRequest(http.MethodGet, "https://ssi-service.com/v1/manifests/bad", nil) - err = manifestService.GetManifest(newRequestContextWithParams(map[string]string{"id": "bad"}), w, req) + err = manifestRouter.GetManifest(newRequestContextWithParams(map[string]string{"id": "bad"}), w, req) assert.Error(tt, err) assert.Contains(tt, err.Error(), "could not get manifest with id: bad") @@ -816,7 +828,7 @@ func TestManifestAPI(t *testing.T) { requestValue := newRequestValue(tt, createManifestRequest) req = httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/manifests", requestValue) - err = manifestService.CreateManifest(newRequestContext(), w, req) + err = manifestRouter.CreateManifest(newRequestContext(), w, req) assert.NoError(tt, err) var resp router.CreateManifestResponse @@ -825,7 +837,7 @@ func TestManifestAPI(t *testing.T) { // get manifest by id req = httptest.NewRequest(http.MethodGet, fmt.Sprintf("https://ssi-service.com/v1/manifests/%s", resp.Manifest.ID), nil) - err = manifestService.GetManifest(newRequestContextWithParams(map[string]string{"id": resp.Manifest.ID}), w, req) + err = manifestRouter.GetManifest(newRequestContextWithParams(map[string]string{"id": resp.Manifest.ID}), w, req) assert.NoError(tt, err) var getManifestResp router.GetManifestResponse @@ -844,7 +856,9 @@ func TestManifestAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - manifestService := newManifestRouter(tt, bolt) + keyStoreService := testKeyStoreService(tt, bolt) + credentialService := testCredentialService(tt, bolt, keyStoreService) + manifestRouter := newManifestRouter(tt, bolt, keyStoreService, credentialService) w := httptest.NewRecorder() @@ -853,7 +867,7 @@ func TestManifestAPI(t *testing.T) { requestValue := newRequestValue(tt, createManifestRequest) req := httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/manifests", requestValue) - err = manifestService.CreateManifest(newRequestContext(), w, req) + err = manifestRouter.CreateManifest(newRequestContext(), w, req) assert.NoError(tt, err) var resp router.CreateManifestResponse @@ -862,7 +876,7 @@ func TestManifestAPI(t *testing.T) { // get manifest by id req = httptest.NewRequest(http.MethodGet, fmt.Sprintf("https://ssi-service.com/v1/manifests"), nil) - err = manifestService.GetManifests(newRequestContext(), w, req) + err = manifestRouter.GetManifests(newRequestContext(), w, req) assert.NoError(tt, err) var getManifestsResp router.GetManifestsResponse @@ -882,7 +896,9 @@ func TestManifestAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - manifestService := newManifestRouter(tt, bolt) + keyStoreService := testKeyStoreService(tt, bolt) + credentialService := testCredentialService(tt, bolt, keyStoreService) + manifestRouter := newManifestRouter(tt, bolt, keyStoreService, credentialService) // good request createManifestRequest := getValidManifestRequest() @@ -890,7 +906,7 @@ func TestManifestAPI(t *testing.T) { requestValue := newRequestValue(tt, createManifestRequest) req := httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/manifests", requestValue) w := httptest.NewRecorder() - err = manifestService.CreateManifest(newRequestContext(), w, req) + err = manifestRouter.CreateManifest(newRequestContext(), w, req) assert.NoError(tt, err) var resp router.CreateManifestResponse @@ -901,7 +917,7 @@ func TestManifestAPI(t *testing.T) { // get credential by id req = httptest.NewRequest(http.MethodGet, fmt.Sprintf("https://ssi-service.com/v1/manifests/%s", resp.Manifest.ID), nil) - err = manifestService.GetManifest(newRequestContextWithParams(map[string]string{"id": resp.Manifest.ID}), w, req) + err = manifestRouter.GetManifest(newRequestContextWithParams(map[string]string{"id": resp.Manifest.ID}), w, req) assert.NoError(tt, err) var getManifestResp router.GetCredentialResponse @@ -914,14 +930,14 @@ func TestManifestAPI(t *testing.T) { // delete it req = httptest.NewRequest(http.MethodDelete, fmt.Sprintf("https://ssi-service.com/v1/manifests/%s", resp.Manifest.ID), nil) - err = manifestService.DeleteManifest(newRequestContextWithParams(map[string]string{"id": resp.Manifest.ID}), w, req) + err = manifestRouter.DeleteManifest(newRequestContextWithParams(map[string]string{"id": resp.Manifest.ID}), w, req) assert.NoError(tt, err) w.Flush() // get it back req = httptest.NewRequest(http.MethodGet, fmt.Sprintf("https://ssi-service.com/v1/manifests/%s", resp.Manifest.ID), nil) - err = manifestService.GetManifest(newRequestContextWithParams(map[string]string{"id": resp.Manifest.ID}), w, req) + err = manifestRouter.GetManifest(newRequestContextWithParams(map[string]string{"id": resp.Manifest.ID}), w, req) assert.Error(tt, err) assert.Contains(tt, err.Error(), fmt.Sprintf("could not get manifest with id: %s", resp.Manifest.ID)) }) @@ -935,7 +951,9 @@ func TestManifestAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - manifestService := newManifestRouter(tt, bolt) + keyStoreService := testKeyStoreService(tt, bolt) + credentialService := testCredentialService(tt, bolt, keyStoreService) + manifestRouter := newManifestRouter(tt, bolt, keyStoreService, credentialService) // missing required field: Application badManifestRequest := router.SubmitApplicationRequest{ @@ -946,7 +964,7 @@ func TestManifestAPI(t *testing.T) { req := httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/manifests/applications", badRequestValue) w := httptest.NewRecorder() - err = manifestService.SubmitApplication(newRequestContext(), w, req) + err = manifestRouter.SubmitApplication(newRequestContext(), w, req) assert.Error(tt, err) assert.Contains(tt, err.Error(), "invalid submit application request") @@ -958,7 +976,7 @@ func TestManifestAPI(t *testing.T) { requestValue := newRequestValue(tt, createManifestRequest) req = httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/manifests", requestValue) - err = manifestService.CreateManifest(newRequestContext(), w, req) + err = manifestRouter.CreateManifest(newRequestContext(), w, req) assert.NoError(tt, err) var resp router.CreateManifestResponse @@ -973,7 +991,7 @@ func TestManifestAPI(t *testing.T) { applicationRequestValue := newRequestValue(tt, createApplicationRequest) req = httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/manifests/applications", applicationRequestValue) - err = manifestService.SubmitApplication(newRequestContext(), w, req) + err = manifestRouter.SubmitApplication(newRequestContext(), w, req) var appResp router.SubmitApplicationResponse err = json.NewDecoder(w.Body).Decode(&appResp) @@ -993,13 +1011,14 @@ func TestManifestAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - manifestService := newManifestRouter(tt, bolt) - + keyStoreService := testKeyStoreService(tt, bolt) + credentialService := testCredentialService(tt, bolt, keyStoreService) + manifestRouter := newManifestRouter(tt, bolt, keyStoreService, credentialService) w := httptest.NewRecorder() // get a application that doesn't exit req := httptest.NewRequest(http.MethodGet, "https://ssi-service.com/v1/manifests/applications/bad", nil) - err = manifestService.GetApplication(newRequestContext(), w, req) + err = manifestRouter.GetApplication(newRequestContext(), w, req) assert.Error(tt, err) assert.Contains(tt, err.Error(), "cannot get application without ID parameter") @@ -1011,7 +1030,7 @@ func TestManifestAPI(t *testing.T) { requestValue := newRequestValue(tt, createManifestRequest) req = httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/manifests", requestValue) - err = manifestService.CreateManifest(newRequestContext(), w, req) + err = manifestRouter.CreateManifest(newRequestContext(), w, req) assert.NoError(tt, err) var resp router.CreateManifestResponse @@ -1023,7 +1042,7 @@ func TestManifestAPI(t *testing.T) { applicationRequestValue := newRequestValue(tt, createApplicationRequest) req = httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/manifests/applications", applicationRequestValue) - err = manifestService.SubmitApplication(newRequestContext(), w, req) + err = manifestRouter.SubmitApplication(newRequestContext(), w, req) var appResp router.SubmitApplicationResponse err = json.NewDecoder(w.Body).Decode(&appResp) @@ -1031,7 +1050,7 @@ func TestManifestAPI(t *testing.T) { // get response by id req = httptest.NewRequest(http.MethodGet, fmt.Sprintf("https://ssi-service.com/v1/manifests/responses/%s", appResp.Response.ID), nil) - err = manifestService.GetResponse(newRequestContextWithParams(map[string]string{"id": appResp.Response.ID}), w, req) + err = manifestRouter.GetResponse(newRequestContextWithParams(map[string]string{"id": appResp.Response.ID}), w, req) assert.NoError(tt, err) var getResponseResponse router.GetResponseResponse @@ -1042,7 +1061,7 @@ func TestManifestAPI(t *testing.T) { // get all responses req = httptest.NewRequest(http.MethodGet, "https://ssi-service.com/v1/manifests/responses", nil) - err = manifestService.GetResponses(newRequestContext(), w, req) + err = manifestRouter.GetResponses(newRequestContext(), w, req) var getResponsesResp router.GetResponsesResponse err = json.NewDecoder(w.Body).Decode(&getResponsesResp) @@ -1053,7 +1072,7 @@ func TestManifestAPI(t *testing.T) { // get all applications req = httptest.NewRequest(http.MethodGet, "https://ssi-service.com/v1/manifests/applications", applicationRequestValue) - err = manifestService.GetApplications(newRequestContext(), w, req) + err = manifestRouter.GetApplications(newRequestContext(), w, req) var getApplicationsResp router.GetApplicationsResponse err = json.NewDecoder(w.Body).Decode(&getApplicationsResp) @@ -1064,7 +1083,7 @@ func TestManifestAPI(t *testing.T) { // get application by id req = httptest.NewRequest(http.MethodGet, fmt.Sprintf("https://ssi-service.com/v1/manifests/applications/%s", getApplicationsResp.Applications[0].ID), nil) - err = manifestService.GetApplication(newRequestContextWithParams(map[string]string{"id": getApplicationsResp.Applications[0].ID}), w, req) + err = manifestRouter.GetApplication(newRequestContextWithParams(map[string]string{"id": getApplicationsResp.Applications[0].ID}), w, req) assert.NoError(tt, err) var getApplicationResponse router.GetApplicationResponse @@ -1083,7 +1102,9 @@ func TestManifestAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - manifestService := newManifestRouter(tt, bolt) + keyStoreService := testKeyStoreService(tt, bolt) + credentialService := testCredentialService(tt, bolt, keyStoreService) + manifestRouter := newManifestRouter(tt, bolt, keyStoreService, credentialService) // good manifest request createManifestRequest := getValidManifestRequest() @@ -1091,7 +1112,7 @@ func TestManifestAPI(t *testing.T) { requestValue := newRequestValue(tt, createManifestRequest) req := httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/manifests", requestValue) w := httptest.NewRecorder() - err = manifestService.CreateManifest(newRequestContext(), w, req) + err = manifestRouter.CreateManifest(newRequestContext(), w, req) assert.NoError(tt, err) var resp router.CreateManifestResponse @@ -1103,7 +1124,7 @@ func TestManifestAPI(t *testing.T) { applicationRequestValue := newRequestValue(tt, createApplicationRequest) req = httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/manifests/applications", applicationRequestValue) - err = manifestService.SubmitApplication(newRequestContext(), w, req) + err = manifestRouter.SubmitApplication(newRequestContext(), w, req) var appResp router.SubmitApplicationResponse err = json.NewDecoder(w.Body).Decode(&appResp) @@ -1111,7 +1132,7 @@ func TestManifestAPI(t *testing.T) { // get all applications req = httptest.NewRequest(http.MethodGet, "https://ssi-service.com/v1/manifests/applications", applicationRequestValue) - err = manifestService.GetApplications(newRequestContext(), w, req) + err = manifestRouter.GetApplications(newRequestContext(), w, req) var getApplicationsResp router.GetApplicationsResponse err = json.NewDecoder(w.Body).Decode(&getApplicationsResp) @@ -1122,7 +1143,7 @@ func TestManifestAPI(t *testing.T) { // get the application req = httptest.NewRequest(http.MethodGet, fmt.Sprintf("https://ssi-service.com/v1/manifests/applications/%s", getApplicationsResp.Applications[0].ID), nil) - err = manifestService.GetApplication(newRequestContextWithParams(map[string]string{"id": getApplicationsResp.Applications[0].ID}), w, req) + err = manifestRouter.GetApplication(newRequestContextWithParams(map[string]string{"id": getApplicationsResp.Applications[0].ID}), w, req) assert.NoError(tt, err) var getApplicationResp router.GetApplicationResponse @@ -1133,21 +1154,21 @@ func TestManifestAPI(t *testing.T) { // delete the application req = httptest.NewRequest(http.MethodDelete, fmt.Sprintf("https://ssi-service.com/v1/manifests/applications/%s", getApplicationResp.Application.ID), nil) - err = manifestService.DeleteApplication(newRequestContextWithParams(map[string]string{"id": getApplicationResp.Application.ID}), w, req) + err = manifestRouter.DeleteApplication(newRequestContextWithParams(map[string]string{"id": getApplicationResp.Application.ID}), w, req) assert.NoError(tt, err) w.Flush() // get it back req = httptest.NewRequest(http.MethodGet, fmt.Sprintf("https://ssi-service.com/v1/manifests/applications/%s", appResp.Response.ID), nil) - err = manifestService.GetApplication(newRequestContextWithParams(map[string]string{"id": appResp.Response.ID}), w, req) + err = manifestRouter.GetApplication(newRequestContextWithParams(map[string]string{"id": appResp.Response.ID}), w, req) assert.Error(tt, err) assert.Contains(tt, err.Error(), fmt.Sprintf("could not get application with id: %s", appResp.Response.ID)) }) } -func newManifestRouter(t *testing.T, bolt *storage.BoltDB) *router.ManifestRouter { - manifestService, err := manifest.NewManifestService(config.ManifestServiceConfig{}, bolt) +func newManifestRouter(t *testing.T, bolt *storage.BoltDB, keyStore *keystore.Service, credential *credential.Service) *router.ManifestRouter { + manifestService, err := manifest.NewManifestService(config.ManifestServiceConfig{BaseServiceConfig: &config.BaseServiceConfig{Name: "test-manifest"}}, bolt, keyStore, credential) require.NoError(t, err) require.NotEmpty(t, manifestService) @@ -1342,7 +1363,6 @@ func getValidManifestRequest() manifest.CreateManifestRequest { } func getValidApplicationRequest(manifestID string, submissionDescriptorId string) manifest.SubmitApplicationRequest { - createApplication := manifestsdk.CredentialApplication{ ID: uuid.New().String(), SpecVersion: "https://identity.foundation/credential-manifest/spec/v1.0.0/", @@ -1370,3 +1390,24 @@ func getValidApplicationRequest(manifestID string, submissionDescriptorId string return createApplicationRequest } + +func testKeyStoreService(t *testing.T, db *storage.BoltDB) *keystore.Service { + serviceConfig := config.KeyStoreServiceConfig{ + BaseServiceConfig: &config.BaseServiceConfig{Name: "test-keystore"}, + ServiceKeyPassword: "test-password", + } + // create a keystore service + keystoreService, err := keystore.NewKeyStoreService(serviceConfig, db) + require.NoError(t, err) + require.NotEmpty(t, keystoreService) + return keystoreService +} + +func testCredentialService(t *testing.T, db *storage.BoltDB, keyStore *keystore.Service) *credential.Service { + serviceConfig := config.CredentialServiceConfig{BaseServiceConfig: &config.BaseServiceConfig{Name: "credential"}} + // create a credential service + credentialService, err := credential.NewCredentialService(serviceConfig, db, keyStore) + require.NoError(t, err) + require.NotEmpty(t, credentialService) + return credentialService +} diff --git a/pkg/service/credential/credential.go b/pkg/service/credential/credential.go index f2f596a07..9da063f6a 100644 --- a/pkg/service/credential/credential.go +++ b/pkg/service/credential/credential.go @@ -119,9 +119,6 @@ func (s Service) CreateCredential(request CreateCredentialRequest) (*CreateCrede return nil, util.LoggingErrorMsg(err, errMsg) } - // sign the credential - // keyaccess.NewJWKKeyAccess() - // store the credential storageRequest := credstorage.StoredCredential{ ID: cred.ID, diff --git a/pkg/service/manifest/manifest.go b/pkg/service/manifest/manifest.go index 5be797fba..2a65894de 100644 --- a/pkg/service/manifest/manifest.go +++ b/pkg/service/manifest/manifest.go @@ -2,22 +2,28 @@ package manifest import ( "fmt" - "github.com/TBD54566975/ssi-sdk/credential" + + credsdk "github.com/TBD54566975/ssi-sdk/credential" + "github.com/TBD54566975/ssi-sdk/credential/exchange" "github.com/TBD54566975/ssi-sdk/credential/manifest" "github.com/sirupsen/logrus" + "github.com/tbd54566975/ssi-service/config" "github.com/tbd54566975/ssi-service/internal/util" - credentialstorage "github.com/tbd54566975/ssi-service/pkg/service/credential/storage" + "github.com/tbd54566975/ssi-service/pkg/service/credential" "github.com/tbd54566975/ssi-service/pkg/service/framework" + "github.com/tbd54566975/ssi-service/pkg/service/keystore" manifeststorage "github.com/tbd54566975/ssi-service/pkg/service/manifest/storage" "github.com/tbd54566975/ssi-service/pkg/storage" - "time" ) type Service struct { - manifestStorage manifeststorage.Storage - credentialStorage credentialstorage.Storage - config config.ManifestServiceConfig + manifestStorage manifeststorage.Storage + config config.ManifestServiceConfig + + // external dependencies + credential *credential.Service + keyStore *keystore.Service } func (s Service) Type() framework.Type { @@ -28,14 +34,7 @@ func (s Service) Status() framework.Status { if s.manifestStorage == nil { return framework.Status{ Status: framework.StatusNotReady, - Message: "no manifestStorage", - } - } - - if s.credentialStorage == nil { - return framework.Status{ - Status: framework.StatusNotReady, - Message: "no credentialStorage", + Message: "no manifest storage", } } @@ -46,48 +45,42 @@ func (s Service) Config() config.ManifestServiceConfig { return s.config } -func NewManifestService(config config.ManifestServiceConfig, s storage.ServiceStorage) (*Service, error) { +func NewManifestService(config config.ManifestServiceConfig, s storage.ServiceStorage, keyStore *keystore.Service, credential *credential.Service) (*Service, error) { manifestStorage, err := manifeststorage.NewManifestStorage(s) if err != nil { errMsg := "could not instantiate manifestStorage for the manifest service" return nil, util.LoggingErrorMsg(err, errMsg) } - - credentialStorage, err := credentialstorage.NewCredentialStorage(s) - if err != nil { - errMsg := "could not instantiate credentialStorage for the manifest service" - return nil, util.LoggingErrorMsg(err, errMsg) - } return &Service{ - manifestStorage: manifestStorage, - credentialStorage: credentialStorage, - config: config, + manifestStorage: manifestStorage, + config: config, + keyStore: keyStore, + credential: credential, }, nil } func (s Service) CreateManifest(request CreateManifestRequest) (*CreateManifestResponse, error) { - logrus.Debugf("creating manifest: %+v", request) + logrus.Debugf("creating m: %+v", request) - mfst := request.Manifest - if err := mfst.IsValid(); err != nil { - errMsg := "manifest is not valid" + m := request.Manifest + if err := m.IsValid(); err != nil { + errMsg := "m is not valid" return nil, util.LoggingErrorMsg(err, errMsg) } - // store the manifest + // store the m storageRequest := manifeststorage.StoredManifest{ - ID: mfst.ID, - Manifest: mfst, - Issuer: mfst.Issuer.ID, + ID: m.ID, + Manifest: m, + Issuer: m.Issuer.ID, } if err := s.manifestStorage.StoreManifest(storageRequest); err != nil { - errMsg := "could not store manifest" - return nil, util.LoggingErrorMsg(err, errMsg) + return nil, util.LoggingErrorMsg(err, "could not store m") } // return the result - response := CreateManifestResponse{Manifest: mfst} + response := CreateManifestResponse{Manifest: m} return &response, nil } @@ -114,8 +107,8 @@ func (s Service) GetManifests() (*GetManifestsResponse, error) { } var manifests []manifest.CredentialManifest - for _, manifest := range gotManifests { - manifests = append(manifests, manifest.Manifest) + for _, m := range gotManifests { + manifests = append(manifests, m.Manifest) } response := GetManifestsResponse{Manifests: manifests} return &response, nil @@ -154,7 +147,7 @@ func isValidApplication(gotManifest *manifeststorage.StoredManifest, application return nil } -func (s Service) SubmitApplication(request SubmitApplicationRequest) (*SubmitApplicationResponse, error) { +func (s Service) ProcessApplicationSubmission(request SubmitApplicationRequest) (*SubmitApplicationResponse, error) { credApp := request.Application if err := credApp.IsValid(); err != nil { @@ -186,59 +179,57 @@ func (s Service) SubmitApplication(request SubmitApplicationRequest) (*SubmitApp } // build the credential response + // TODO(gabe) need to check if this can be fulfilled and conditionally return success/denial responseBuilder := manifest.NewCredentialResponseBuilder(request.Application.ManifestID) - responseBuilder.SetApplicationID(credApp.ID) - responseBuilder.SetFulfillment(credApp.PresentationSubmission.DescriptorMap) - - credRes, err := responseBuilder.Build() - if err != nil { - errMsg := "could not build response" - return nil, util.LoggingErrorMsg(err, errMsg) + if err := responseBuilder.SetApplicationID(credApp.ID); err != nil { + return nil, util.LoggingErrorMsg(err, "could not fulfill credential application: could not set application id") } - // store the response - responseStorageRequest := manifeststorage.StoredResponse{ - ID: credRes.ID, - Response: *credRes, - ManifestID: request.Application.ManifestID, - } - - var creds []credential.VerifiableCredential + var creds []credsdk.VerifiableCredential for _, od := range gotManifest.Manifest.OutputDescriptors { - - if err := s.manifestStorage.StoreResponse(responseStorageRequest); err != nil { - errMsg := "could not store response" - return nil, util.LoggingErrorMsg(err, errMsg) + credentialRequest := credential.CreateCredentialRequest{ + Issuer: gotManifest.Manifest.Issuer.ID, + Subject: request.RequesterDID, + JSONSchema: od.Schema, + // TODO(gabe) need to add in data here to match the request + schema + Data: map[string]interface{}{}, } - credentialBuilder := credential.NewVerifiableCredentialBuilder() - credentialBuilder.SetIssuer(gotManifest.Manifest.Issuer.ID) - credentialBuilder.SetCredentialSubject(map[string]interface{}{ - "id": request.RequesterDID, - }) - credentialBuilder.SetIssuanceDate(time.Now().Format(time.RFC3339)) - - cred, err := credentialBuilder.Build() + createdResponse, err := s.credential.CreateCredential(credentialRequest) if err != nil { - errMsg := "could not build credential" - return nil, util.LoggingErrorMsg(err, errMsg) + return nil, util.LoggingErrorMsg(err, "could not create credential") } - credentialStorageRequest := credentialstorage.StoredCredential{ - ID: cred.ID, - Credential: *cred, - Issuer: gotManifest.Manifest.Issuer.ID, - Subject: request.RequesterDID, - Schema: od.Schema, - IssuanceDate: time.Now().Format(time.RFC3339), - } + creds = append(creds, createdResponse.Credential) + } - if err := s.credentialStorage.StoreCredential(credentialStorageRequest); err != nil { - errMsg := "could not store credential" - return nil, util.LoggingErrorMsg(err, errMsg) - } + var descriptors []exchange.SubmissionDescriptor + for i, cred := range creds { + // TODO(gabe) build this correctly based on the generated credential format and envelope type + descriptors = append(descriptors, exchange.SubmissionDescriptor{ + ID: cred.ID, + Format: string(exchange.JWTVC), + Path: fmt.Sprintf("$.verifiableCredential[%d]", i), + }) + } - creds = append(creds, *cred) + // set the information for the fulfilled credentials in the response + if err := responseBuilder.SetFulfillment(descriptors); err != nil { + return nil, util.LoggingErrorMsg(err, "could not fulfill credential application: could not set fulfillment") + } + credRes, err := responseBuilder.Build() + if err != nil { + return nil, util.LoggingErrorMsg(err, "could not build response") + } + + // store the response we've generated + storeResponseRequest := manifeststorage.StoredResponse{ + ID: credRes.ID, + Response: *credRes, + ManifestID: request.Application.ManifestID, + } + if err := s.manifestStorage.StoreResponse(storeResponseRequest); err != nil { + return nil, util.LoggingErrorMsg(err, "could not store manifest response") } response := SubmitApplicationResponse{Response: *credRes, Credential: creds} diff --git a/pkg/service/manifest/storage/storage.go b/pkg/service/manifest/storage/storage.go index 9a94780df..9554f72eb 100644 --- a/pkg/service/manifest/storage/storage.go +++ b/pkg/service/manifest/storage/storage.go @@ -2,6 +2,7 @@ package storage import ( "fmt" + "github.com/TBD54566975/ssi-sdk/credential/manifest" "github.com/tbd54566975/ssi-service/internal/util" @@ -27,19 +28,26 @@ type StoredResponse struct { } type Storage interface { - // Credential Manifest + CredentialManifestStorage + CredentialApplicationStorage + CredentialResponseStorage +} + +type CredentialManifestStorage interface { StoreManifest(manifest StoredManifest) error GetManifest(id string) (*StoredManifest, error) GetManifests() ([]StoredManifest, error) DeleteManifest(id string) error +} - // Credential Application +type CredentialApplicationStorage interface { StoreApplication(application StoredApplication) error GetApplication(id string) (*StoredApplication, error) GetApplications() ([]StoredApplication, error) DeleteApplication(id string) error +} - // Credential Response +type CredentialResponseStorage interface { StoreResponse(response StoredResponse) error GetResponse(id string) (*StoredResponse, error) GetResponses() ([]StoredResponse, error) diff --git a/pkg/service/schema/schema.go b/pkg/service/schema/schema.go index 40c52c572..a67507751 100644 --- a/pkg/service/schema/schema.go +++ b/pkg/service/schema/schema.go @@ -2,22 +2,28 @@ package schema import ( "fmt" + "time" + "github.com/TBD54566975/ssi-sdk/credential/schema" schemalib "github.com/TBD54566975/ssi-sdk/schema" "github.com/goccy/go-json" "github.com/google/uuid" "github.com/pkg/errors" + "github.com/tbd54566975/ssi-service/config" "github.com/tbd54566975/ssi-service/internal/util" "github.com/tbd54566975/ssi-service/pkg/service/framework" + "github.com/tbd54566975/ssi-service/pkg/service/keystore" schemastorage "github.com/tbd54566975/ssi-service/pkg/service/schema/storage" "github.com/tbd54566975/ssi-service/pkg/storage" - "time" ) type Service struct { storage schemastorage.Storage config config.SchemaServiceConfig + + // external dependencies + keyStore *keystore.Service } func (s Service) Type() framework.Type { @@ -38,15 +44,16 @@ func (s Service) Config() config.SchemaServiceConfig { return s.config } -func NewSchemaService(config config.SchemaServiceConfig, s storage.ServiceStorage) (*Service, error) { +func NewSchemaService(config config.SchemaServiceConfig, s storage.ServiceStorage, keyStore *keystore.Service) (*Service, error) { schemaStorage, err := schemastorage.NewSchemaStorage(s) if err != nil { errMsg := "could not instantiate storage for the schema service" return nil, util.LoggingErrorMsg(err, errMsg) } return &Service{ - storage: schemaStorage, - config: config, + storage: schemaStorage, + config: config, + keyStore: keyStore, }, nil } diff --git a/pkg/service/service.go b/pkg/service/service.go index 592fe58e8..04e612d88 100644 --- a/pkg/service/service.go +++ b/pkg/service/service.go @@ -80,17 +80,17 @@ func instantiateServices(config config.ServicesConfig) ([]framework.Service, err return nil, util.LoggingErrorMsg(err, "could not instantiate the DID service") } - schemaService, err := schema.NewSchemaService(config.SchemaConfig, storageProvider) + schemaService, err := schema.NewSchemaService(config.SchemaConfig, storageProvider, keyStoreService) if err != nil { return nil, util.LoggingErrorMsg(err, "could not instantiate the schema service") } - credentialService, err := credential.NewCredentialService(config.CredentialConfig, storageProvider) + credentialService, err := credential.NewCredentialService(config.CredentialConfig, storageProvider, keyStoreService) if err != nil { return nil, util.LoggingErrorMsg(err, "could not instantiate the credential service") } - manifestService, err := manifest.NewManifestService(config.ManifestConfig, storageProvider) + manifestService, err := manifest.NewManifestService(config.ManifestConfig, storageProvider, keyStoreService, credentialService) if err != nil { return nil, util.LoggingErrorMsg(err, "could not instantiate the manifest service") } From a9ab57bf5dbf93aca6d67a0a18bc99c0e4fbf8a2 Mon Sep 17 00:00:00 2001 From: gabe Date: Tue, 27 Sep 2022 17:28:19 -0700 Subject: [PATCH 10/13] merge --- config/config.toml | 6 +- pkg/server/server_test.go | 224 ++++++++++++++++++++------------------ 2 files changed, 126 insertions(+), 104 deletions(-) diff --git a/config/config.toml b/config/config.toml index 2c5ed12f8..afd2ff38d 100644 --- a/config/config.toml +++ b/config/config.toml @@ -36,4 +36,8 @@ name = "schema" name = "credential" [services.manifest] -name = "manifest" \ No newline at end of file +name = "manifest" + +[services.dwn] +name = "dwn" +dwn_endpoint = "http://localhost:4321" \ No newline at end of file diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go index 5ee2add86..43c201b44 100644 --- a/pkg/server/server_test.go +++ b/pkg/server/server_test.go @@ -4,9 +4,6 @@ import ( "bytes" "context" "fmt" - "github.com/TBD54566975/ssi-sdk/credential/exchange" - "github.com/tbd54566975/ssi-service/pkg/service/dwn" - "io" "net/http" "net/http/httptest" @@ -16,6 +13,8 @@ import ( "github.com/TBD54566975/ssi-sdk/credential/exchange" + "github.com/tbd54566975/ssi-service/pkg/service/dwn" + credsdk "github.com/TBD54566975/ssi-sdk/credential" manifestsdk "github.com/TBD54566975/ssi-sdk/credential/manifest" "github.com/TBD54566975/ssi-sdk/crypto" @@ -106,7 +105,7 @@ func TestDIDAPI(t *testing.T) { }) _, keyStoreService := newKeyStore(tt, bolt) - didService := newDIDRouter(tt, bolt, keyStoreService) + didService := testDIDRouter(tt, bolt, keyStoreService) // get DID methods req := httptest.NewRequest(http.MethodGet, "https://ssi-service.com/v1/dids", nil) @@ -134,7 +133,7 @@ func TestDIDAPI(t *testing.T) { }) _, keyStoreService := newKeyStore(tt, bolt) - didService := newDIDRouter(tt, bolt, keyStoreService) + didService := testDIDRouter(tt, bolt, keyStoreService) // create DID by method - key - missing body req := httptest.NewRequest(http.MethodPut, "https://ssi-service.com/v1/dids/key", nil) @@ -183,7 +182,7 @@ func TestDIDAPI(t *testing.T) { }) _, keyStore := newKeyStore(tt, bolt) - didService := newDIDRouter(tt, bolt, keyStore) + didService := testDIDRouter(tt, bolt, keyStore) // get DID by method req := httptest.NewRequest(http.MethodGet, "https://ssi-service.com/v1/dids/bad/worse", nil) @@ -242,20 +241,6 @@ func TestDIDAPI(t *testing.T) { }) } -func newDIDRouter(t *testing.T, bolt *storage.BoltDB, keyStore *keystore.Service) *router.DIDRouter { - serviceConfig := config.DIDServiceConfig{Methods: []string{string(did.KeyMethod)}} - didService, err := did.NewDIDService(serviceConfig, bolt, keyStore) - require.NoError(t, err) - require.NotEmpty(t, didService) - - // create router for service - didRouter, err := router.NewDIDRouter(didService) - require.NoError(t, err) - require.NotEmpty(t, didRouter) - - return didRouter -} - func TestSchemaAPI(t *testing.T) { t.Run("Test Create Schema", func(tt *testing.T) { bolt, err := storage.NewBoltDB() @@ -267,7 +252,7 @@ func TestSchemaAPI(t *testing.T) { }) keyStoreService := testKeyStoreService(tt, bolt) - schemaService := newSchemaRouter(tt, bolt, keyStoreService) + schemaService := testSchemaRouter(tt, bolt, keyStoreService) simpleSchema := map[string]interface{}{ "type": "object", @@ -315,7 +300,7 @@ func TestSchemaAPI(t *testing.T) { }) keyStoreService := testKeyStoreService(tt, bolt) - schemaService := newSchemaRouter(tt, bolt, keyStoreService) + schemaService := testSchemaRouter(tt, bolt, keyStoreService) // get schema that doesn't exist w := httptest.NewRecorder() @@ -401,19 +386,6 @@ func TestSchemaAPI(t *testing.T) { }) } -func newSchemaRouter(t *testing.T, bolt *storage.BoltDB, keyStore *keystore.Service) *router.SchemaRouter { - schemaService, err := schema.NewSchemaService(config.SchemaServiceConfig{BaseServiceConfig: &config.BaseServiceConfig{Name: "test-schema"}}, bolt, keyStore) - require.NoError(t, err) - require.NotEmpty(t, schemaService) - - // create router for service - schemaRouter, err := router.NewSchemaRouter(schemaService) - require.NoError(t, err) - require.NotEmpty(t, schemaRouter) - - return schemaRouter -} - func TestCredentialAPI(t *testing.T) { t.Run("Test Create Credential", func(tt *testing.T) { bolt, err := storage.NewBoltDB() @@ -425,7 +397,7 @@ func TestCredentialAPI(t *testing.T) { }) keyStoreService := testKeyStoreService(tt, bolt) - credService := newCredentialRouter(tt, bolt, keyStoreService) + credService := testCredentialRouter(tt, bolt, keyStoreService) // missing required field: data badCredRequest := router.CreateCredentialRequest{ @@ -477,7 +449,7 @@ func TestCredentialAPI(t *testing.T) { }) keyStoreService := testKeyStoreService(tt, bolt) - credService := newCredentialRouter(tt, bolt, keyStoreService) + credService := testCredentialRouter(tt, bolt, keyStoreService) w := httptest.NewRecorder() @@ -539,7 +511,7 @@ func TestCredentialAPI(t *testing.T) { }) keyStoreService := testKeyStoreService(tt, bolt) - credService := newCredentialRouter(tt, bolt, keyStoreService) + credService := testCredentialRouter(tt, bolt, keyStoreService) w := httptest.NewRecorder() @@ -589,7 +561,7 @@ func TestCredentialAPI(t *testing.T) { }) keyStoreService := testKeyStoreService(tt, bolt) - credService := newCredentialRouter(tt, bolt, keyStoreService) + credService := testCredentialRouter(tt, bolt, keyStoreService) w := httptest.NewRecorder() @@ -638,7 +610,7 @@ func TestCredentialAPI(t *testing.T) { }) keyStoreService := testKeyStoreService(tt, bolt) - credService := newCredentialRouter(tt, bolt, keyStoreService) + credService := testCredentialRouter(tt, bolt, keyStoreService) w := httptest.NewRecorder() @@ -685,7 +657,7 @@ func TestCredentialAPI(t *testing.T) { }) keyStoreService := testKeyStoreService(tt, bolt) - credService := newCredentialRouter(tt, bolt, keyStoreService) + credService := testCredentialRouter(tt, bolt, keyStoreService) createCredRequest := router.CreateCredentialRequest{ Issuer: "did:abc:123", @@ -736,19 +708,6 @@ func TestCredentialAPI(t *testing.T) { }) } -func newCredentialRouter(t *testing.T, bolt *storage.BoltDB, keyStore *keystore.Service) *router.CredentialRouter { - credentialService, err := credential.NewCredentialService(config.CredentialServiceConfig{BaseServiceConfig: &config.BaseServiceConfig{Name: "test-credential"}}, bolt, keyStore) - require.NoError(t, err) - require.NotEmpty(t, credentialService) - - // create router for service - credentialRouter, err := router.NewCredentialRouter(credentialService) - require.NoError(t, err) - require.NotEmpty(t, credentialRouter) - - return credentialRouter -} - func TestManifestAPI(t *testing.T) { t.Run("Test Create Manifest", func(tt *testing.T) { bolt, err := storage.NewBoltDB() @@ -761,7 +720,7 @@ func TestManifestAPI(t *testing.T) { keyStoreService := testKeyStoreService(tt, bolt) credentialService := testCredentialService(tt, bolt, keyStoreService) - manifestRouter := newManifestRouter(tt, bolt, keyStoreService, credentialService) + manifestRouter := testManifestRouter(tt, bolt, keyStoreService, credentialService) // missing required field: Manifest badManifestRequest := router.CreateManifestRequest{} @@ -804,7 +763,7 @@ func TestManifestAPI(t *testing.T) { keyStoreService := testKeyStoreService(tt, bolt) credentialService := testCredentialService(tt, bolt, keyStoreService) - manifestRouter := newManifestRouter(tt, bolt, keyStoreService, credentialService) + manifestRouter := testManifestRouter(tt, bolt, keyStoreService, credentialService) w := httptest.NewRecorder() @@ -861,7 +820,7 @@ func TestManifestAPI(t *testing.T) { keyStoreService := testKeyStoreService(tt, bolt) credentialService := testCredentialService(tt, bolt, keyStoreService) - manifestRouter := newManifestRouter(tt, bolt, keyStoreService, credentialService) + manifestRouter := testManifestRouter(tt, bolt, keyStoreService, credentialService) w := httptest.NewRecorder() @@ -901,7 +860,7 @@ func TestManifestAPI(t *testing.T) { keyStoreService := testKeyStoreService(tt, bolt) credentialService := testCredentialService(tt, bolt, keyStoreService) - manifestRouter := newManifestRouter(tt, bolt, keyStoreService, credentialService) + manifestRouter := testManifestRouter(tt, bolt, keyStoreService, credentialService) // good request createManifestRequest := getValidManifestRequest() @@ -956,7 +915,7 @@ func TestManifestAPI(t *testing.T) { keyStoreService := testKeyStoreService(tt, bolt) credentialService := testCredentialService(tt, bolt, keyStoreService) - manifestRouter := newManifestRouter(tt, bolt, keyStoreService, credentialService) + manifestRouter := testManifestRouter(tt, bolt, keyStoreService, credentialService) // missing required field: Application badManifestRequest := router.SubmitApplicationRequest{ @@ -1016,7 +975,7 @@ func TestManifestAPI(t *testing.T) { keyStoreService := testKeyStoreService(tt, bolt) credentialService := testCredentialService(tt, bolt, keyStoreService) - manifestRouter := newManifestRouter(tt, bolt, keyStoreService, credentialService) + manifestRouter := testManifestRouter(tt, bolt, keyStoreService, credentialService) w := httptest.NewRecorder() // get a application that doesn't exit @@ -1107,7 +1066,7 @@ func TestManifestAPI(t *testing.T) { keyStoreService := testKeyStoreService(tt, bolt) credentialService := testCredentialService(tt, bolt, keyStoreService) - manifestRouter := newManifestRouter(tt, bolt, keyStoreService, credentialService) + manifestRouter := testManifestRouter(tt, bolt, keyStoreService, credentialService) // good manifest request createManifestRequest := getValidManifestRequest() @@ -1170,19 +1129,6 @@ func TestManifestAPI(t *testing.T) { }) } -func newManifestRouter(t *testing.T, bolt *storage.BoltDB, keyStore *keystore.Service, credential *credential.Service) *router.ManifestRouter { - manifestService, err := manifest.NewManifestService(config.ManifestServiceConfig{BaseServiceConfig: &config.BaseServiceConfig{Name: "test-manifest"}}, bolt, keyStore, credential) - require.NoError(t, err) - require.NotEmpty(t, manifestService) - - // create router for service - manifestRouter, err := router.NewManifestRouter(manifestService) - require.NoError(t, err) - require.NotEmpty(t, manifestRouter) - - return manifestRouter -} - func TestDWNAPI(t *testing.T) { t.Run("Test DWN Publish Manifest", func(tt *testing.T) { bolt, err := storage.NewBoltDB() @@ -1193,9 +1139,10 @@ func TestDWNAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - dwnService := newDWNService(tt, bolt) - - manifestService := newManifestService(tt, bolt) + dwnService := testDWNRouter(tt, bolt) + keyStoreService := testKeyStoreService(tt, bolt) + credentialService := testCredentialService(tt, bolt, keyStoreService) + manifestService := testManifestRouter(tt, bolt, keyStoreService, credentialService) w := httptest.NewRecorder() @@ -1222,18 +1169,6 @@ func TestDWNAPI(t *testing.T) { assert.ErrorContains(tt, err, "unsupported protocol scheme") }) } -func newDWNService(t *testing.T, bolt *storage.BoltDB) *router.DWNRouter { - dwnService, err := dwn.NewDWNService(config.DWNServiceConfig{DWNEndpoint: "test-endpoint"}, bolt) - require.NoError(t, err) - require.NotEmpty(t, dwnService) - - // create router for service - dwnRouter, err := router.NewDWNRouter(dwnService) - require.NoError(t, err) - require.NotEmpty(t, dwnRouter) - - return dwnRouter -} func TestKeyStoreAPI(t *testing.T) { t.Run("Test Store Base58Key", func(tt *testing.T) { @@ -1334,20 +1269,6 @@ func TestKeyStoreAPI(t *testing.T) { }) } -func newKeyStore(t *testing.T, bolt *storage.BoltDB) (*router.KeyStoreRouter, *keystore.Service) { - serviceConfig := config.KeyStoreServiceConfig{ServiceKeyPassword: "test-password"} - keyStoreService, err := keystore.NewKeyStoreService(serviceConfig, bolt) - require.NoError(t, err) - require.NotEmpty(t, keyStoreService) - - // create router for service - keyStoreRouter, err := router.NewKeyStoreRouter(keyStoreService) - require.NoError(t, err) - require.NotEmpty(t, keyStoreRouter) - - return keyStoreRouter, keyStoreService -} - func newRequestValue(t *testing.T, data interface{}) io.Reader { dataBytes, err := json.Marshal(data) require.NoError(t, err) @@ -1446,11 +1367,23 @@ func getValidApplicationRequest(manifestID string, submissionDescriptorId string return createApplicationRequest } +func newKeyStore(t *testing.T, bolt *storage.BoltDB) (*router.KeyStoreRouter, *keystore.Service) { + keyStoreService := testKeyStoreService(t, bolt) + + // create router for service + keyStoreRouter, err := router.NewKeyStoreRouter(keyStoreService) + require.NoError(t, err) + require.NotEmpty(t, keyStoreRouter) + + return keyStoreRouter, keyStoreService +} + func testKeyStoreService(t *testing.T, db *storage.BoltDB) *keystore.Service { serviceConfig := config.KeyStoreServiceConfig{ BaseServiceConfig: &config.BaseServiceConfig{Name: "test-keystore"}, ServiceKeyPassword: "test-password", } + // create a keystore service keystoreService, err := keystore.NewKeyStoreService(serviceConfig, db) require.NoError(t, err) @@ -1458,11 +1391,96 @@ func testKeyStoreService(t *testing.T, db *storage.BoltDB) *keystore.Service { return keystoreService } +func testDIDService(t *testing.T, bolt *storage.BoltDB, keyStore *keystore.Service) *did.Service { + serviceConfig := config.DIDServiceConfig{ + BaseServiceConfig: &config.BaseServiceConfig{Name: "test-did"}, + Methods: []string{"key"}, + } + + // create a did service + didService, err := did.NewDIDService(serviceConfig, bolt, keyStore) + require.NoError(t, err) + require.NotEmpty(t, didService) + return didService +} + +func testDIDRouter(t *testing.T, bolt *storage.BoltDB, keyStore *keystore.Service) *router.DIDRouter { + didService := testDIDService(t, bolt, keyStore) + + // create router for service + didRouter, err := router.NewDIDRouter(didService) + require.NoError(t, err) + require.NotEmpty(t, didRouter) + return didRouter +} + +func testSchemaService(t *testing.T, bolt *storage.BoltDB, keyStore *keystore.Service) *schema.Service { + schemaService, err := schema.NewSchemaService(config.SchemaServiceConfig{BaseServiceConfig: &config.BaseServiceConfig{Name: "test-schema"}}, bolt, keyStore) + require.NoError(t, err) + require.NotEmpty(t, schemaService) + return schemaService +} + +func testSchemaRouter(t *testing.T, bolt *storage.BoltDB, keyStore *keystore.Service) *router.SchemaRouter { + schemaService := testSchemaService(t, bolt, keyStore) + + // create router for service + schemaRouter, err := router.NewSchemaRouter(schemaService) + require.NoError(t, err) + require.NotEmpty(t, schemaRouter) + return schemaRouter +} + func testCredentialService(t *testing.T, db *storage.BoltDB, keyStore *keystore.Service) *credential.Service { serviceConfig := config.CredentialServiceConfig{BaseServiceConfig: &config.BaseServiceConfig{Name: "credential"}} + // create a credential service credentialService, err := credential.NewCredentialService(serviceConfig, db, keyStore) require.NoError(t, err) require.NotEmpty(t, credentialService) return credentialService } + +func testCredentialRouter(t *testing.T, bolt *storage.BoltDB, keyStore *keystore.Service) *router.CredentialRouter { + credentialService := testCredentialService(t, bolt, keyStore) + + // create router for service + credentialRouter, err := router.NewCredentialRouter(credentialService) + require.NoError(t, err) + require.NotEmpty(t, credentialRouter) + + return credentialRouter +} + +func testManifestService(t *testing.T, db *storage.BoltDB, keyStore *keystore.Service, credential *credential.Service) *manifest.Service { + serviceConfig := config.ManifestServiceConfig{BaseServiceConfig: &config.BaseServiceConfig{Name: "manifest"}} + // create a manifest service + manifestService, err := manifest.NewManifestService(serviceConfig, db, keyStore, credential) + require.NoError(t, err) + require.NotEmpty(t, manifestService) + return manifestService +} + +func testManifestRouter(t *testing.T, bolt *storage.BoltDB, keyStore *keystore.Service, credential *credential.Service) *router.ManifestRouter { + manifestService := testManifestService(t, bolt, keyStore, credential) + + // create router for service + manifestRouter, err := router.NewManifestRouter(manifestService) + require.NoError(t, err) + require.NotEmpty(t, manifestRouter) + + return manifestRouter +} + +func testDWNRouter(t *testing.T, bolt *storage.BoltDB) *router.DWNRouter { + dwnService, err := dwn.NewDWNService(config.DWNServiceConfig{BaseServiceConfig: &config.BaseServiceConfig{Name: "test-dwn"}, DWNEndpoint: "test-endpoint"}, bolt) + require.NoError(t, err) + require.NotEmpty(t, dwnService) + + // create router for service + dwnRouter, err := router.NewDWNRouter(dwnService) + require.NoError(t, err) + require.NotEmpty(t, dwnRouter) + + return dwnRouter +} From 75a9961fe773a34344810874f36f6108d98d46ea Mon Sep 17 00:00:00 2001 From: gabe Date: Tue, 27 Sep 2022 17:31:49 -0700 Subject: [PATCH 11/13] fix dwn tests --- pkg/server/router/dwn_test.go | 9 ++++++--- pkg/server/server_test.go | 6 +++--- pkg/service/dwn/dwn.go | 9 ++++++++- pkg/service/service.go | 8 +++++--- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/pkg/server/router/dwn_test.go b/pkg/server/router/dwn_test.go index 44e1ef472..95ce3e9e6 100644 --- a/pkg/server/router/dwn_test.go +++ b/pkg/server/router/dwn_test.go @@ -1,13 +1,15 @@ package router import ( + "os" + "testing" + "github.com/stretchr/testify/assert" + "github.com/tbd54566975/ssi-service/config" "github.com/tbd54566975/ssi-service/pkg/service/dwn" "github.com/tbd54566975/ssi-service/pkg/service/framework" "github.com/tbd54566975/ssi-service/pkg/storage" - "os" - "testing" ) func TestDWNRouter(t *testing.T) { @@ -36,7 +38,8 @@ func TestDWNRouter(t *testing.T) { assert.NotEmpty(tt, bolt) serviceConfig := config.DWNServiceConfig{BaseServiceConfig: &config.BaseServiceConfig{Name: "dwn"}} - dwnService, err := dwn.NewDWNService(serviceConfig, bolt) + keyStore := testKeyStoreService(t, bolt) + dwnService, err := dwn.NewDWNService(serviceConfig, bolt, keyStore) assert.NoError(tt, err) assert.NotEmpty(tt, dwnService) diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go index 43c201b44..ce807f3ab 100644 --- a/pkg/server/server_test.go +++ b/pkg/server/server_test.go @@ -1139,8 +1139,8 @@ func TestDWNAPI(t *testing.T) { _ = os.Remove(storage.DBFile) }) - dwnService := testDWNRouter(tt, bolt) keyStoreService := testKeyStoreService(tt, bolt) + dwnService := testDWNRouter(tt, bolt, keyStoreService) credentialService := testCredentialService(tt, bolt, keyStoreService) manifestService := testManifestRouter(tt, bolt, keyStoreService, credentialService) @@ -1472,8 +1472,8 @@ func testManifestRouter(t *testing.T, bolt *storage.BoltDB, keyStore *keystore.S return manifestRouter } -func testDWNRouter(t *testing.T, bolt *storage.BoltDB) *router.DWNRouter { - dwnService, err := dwn.NewDWNService(config.DWNServiceConfig{BaseServiceConfig: &config.BaseServiceConfig{Name: "test-dwn"}, DWNEndpoint: "test-endpoint"}, bolt) +func testDWNRouter(t *testing.T, bolt *storage.BoltDB, keyStore *keystore.Service) *router.DWNRouter { + dwnService, err := dwn.NewDWNService(config.DWNServiceConfig{BaseServiceConfig: &config.BaseServiceConfig{Name: "test-dwn"}, DWNEndpoint: "test-endpoint"}, bolt, keyStore) require.NoError(t, err) require.NotEmpty(t, dwnService) diff --git a/pkg/service/dwn/dwn.go b/pkg/service/dwn/dwn.go index de11e230a..f3bcec849 100644 --- a/pkg/service/dwn/dwn.go +++ b/pkg/service/dwn/dwn.go @@ -2,10 +2,13 @@ package dwn import ( "fmt" + "github.com/sirupsen/logrus" + "github.com/tbd54566975/ssi-service/config" "github.com/tbd54566975/ssi-service/internal/util" "github.com/tbd54566975/ssi-service/pkg/service/framework" + "github.com/tbd54566975/ssi-service/pkg/service/keystore" manifeststorage "github.com/tbd54566975/ssi-service/pkg/service/manifest/storage" "github.com/tbd54566975/ssi-service/pkg/storage" ) @@ -13,6 +16,9 @@ import ( type Service struct { config config.DWNServiceConfig manifestStorage manifeststorage.Storage + + // external dependencies + keyStore *keystore.Service } func (s Service) Type() framework.Type { @@ -34,7 +40,7 @@ func (s Service) Config() config.DWNServiceConfig { return s.config } -func NewDWNService(config config.DWNServiceConfig, s storage.ServiceStorage) (*Service, error) { +func NewDWNService(config config.DWNServiceConfig, s storage.ServiceStorage, keyStore *keystore.Service) (*Service, error) { manifestStorage, err := manifeststorage.NewManifestStorage(s) if err != nil { errMsg := "could not instantiate manifestStorage for the dwn service" @@ -44,6 +50,7 @@ func NewDWNService(config config.DWNServiceConfig, s storage.ServiceStorage) (*S return &Service{ config: config, manifestStorage: manifestStorage, + keyStore: keyStore, }, nil } diff --git a/pkg/service/service.go b/pkg/service/service.go index 078009b4e..6122e42d5 100644 --- a/pkg/service/service.go +++ b/pkg/service/service.go @@ -55,6 +55,9 @@ func validateServiceConfig(config config.ServicesConfig) error { if config.ManifestConfig.IsEmpty() { return fmt.Errorf("%s no config provided", framework.Manifest) } + if config.DWNConfig.IsEmpty() { + return fmt.Errorf("%s no config provided", framework.DWN) + } return nil } @@ -96,10 +99,9 @@ func instantiateServices(config config.ServicesConfig) ([]framework.Service, err return nil, util.LoggingErrorMsg(err, "could not instantiate the manifest service") } - dwnService, err := dwn.NewDWNService(config.DWNConfig, storageProvider) + dwnService, err := dwn.NewDWNService(config.DWNConfig, storageProvider, keyStoreService) if err != nil { - errMsg := "could not instantiate the dwn service" - return nil, util.LoggingErrorMsg(err, errMsg) + return nil, util.LoggingErrorMsg(err, "could not instantiate the dwn service") } return []framework.Service{keyStoreService, didService, schemaService, credentialService, manifestService, dwnService}, nil From 266bffdbb79daa03734c09c8fb952505f386d56d Mon Sep 17 00:00:00 2001 From: gabe Date: Tue, 27 Sep 2022 17:33:45 -0700 Subject: [PATCH 12/13] bad rename --- internal/keyaccess/dataintegrity.go | 2 +- internal/keyaccess/dataintegrity_test.go | 6 +++--- internal/keyaccess/jwt.go | 4 ++-- internal/keyaccess/jwt_test.go | 6 +++--- pkg/server/router/keystore.go | 4 ++-- pkg/server/router/keystore_test.go | 2 +- pkg/server/server_test.go | 6 +++--- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/internal/keyaccess/dataintegrity.go b/internal/keyaccess/dataintegrity.go index 405265207..ecbbb2ce6 100644 --- a/internal/keyaccess/dataintegrity.go +++ b/internal/keyaccess/dataintegrity.go @@ -20,7 +20,7 @@ type DataIntegrityKeyAccess struct { } // NewDataIntegrityKeyAccess creates a new DataIntegrityKeyAccess object from a key id and private key, generating both -// JSON Web Base58Key Signer and Verifier objects. +// JSON Web Key Signer and Verifier objects. func NewDataIntegrityKeyAccess(kid string, key gocrypto.PrivateKey) (*DataIntegrityKeyAccess, error) { if kid == "" { return nil, errors.New("kid cannot be empty") diff --git a/internal/keyaccess/dataintegrity_test.go b/internal/keyaccess/dataintegrity_test.go index 943754562..da42819a8 100644 --- a/internal/keyaccess/dataintegrity_test.go +++ b/internal/keyaccess/dataintegrity_test.go @@ -10,7 +10,7 @@ import ( ) func TestCreateDataIntegrityKeyAccess(t *testing.T) { - t.Run("Create a Base58Key Access object - Happy Path", func(tt *testing.T) { + t.Run("Create a Key Access object - Happy Path", func(tt *testing.T) { _, privKey, err := crypto.GenerateEd25519Key() kid := "test-kid" assert.NoError(tt, err) @@ -19,7 +19,7 @@ func TestCreateDataIntegrityKeyAccess(t *testing.T) { assert.NotEmpty(tt, ka) }) - t.Run("Create a Base58Key Access object - Bad Base58Key", func(tt *testing.T) { + t.Run("Create a Key Access object - Bad Key", func(tt *testing.T) { kid := "test-kid" ka, err := NewDataIntegrityKeyAccess(kid, nil) assert.Error(tt, err) @@ -27,7 +27,7 @@ func TestCreateDataIntegrityKeyAccess(t *testing.T) { assert.Empty(tt, ka) }) - t.Run("Create a Base58Key Access object - No KID", func(tt *testing.T) { + t.Run("Create a Key Access object - No KID", func(tt *testing.T) { _, privKey, err := crypto.GenerateEd25519Key() assert.NoError(tt, err) ka, err := NewDataIntegrityKeyAccess("", privKey) diff --git a/internal/keyaccess/jwt.go b/internal/keyaccess/jwt.go index 073aeb6e8..bdbaa2ec5 100644 --- a/internal/keyaccess/jwt.go +++ b/internal/keyaccess/jwt.go @@ -30,11 +30,11 @@ func NewJWKKeyAccess(kid string, key gocrypto.PrivateKey) (*JWKKeyAccess, error) } signer, err := crypto.NewJWTSigner(kid, gotJWK) if err != nil { - return nil, errors.Wrapf(err, "could not create JWK Base58Key Access object for kid: %s, error creating signer", kid) + return nil, errors.Wrapf(err, "could not create JWK Key Access object for kid: %s, error creating signer", kid) } verifier, err := signer.ToVerifier() if err != nil { - return nil, errors.Wrapf(err, "could not create JWK Base58Key Access object for kid: %s, error creating verifier", kid) + return nil, errors.Wrapf(err, "could not create JWK Key Access object for kid: %s, error creating verifier", kid) } return &JWKKeyAccess{ JWTSigner: *signer, diff --git a/internal/keyaccess/jwt_test.go b/internal/keyaccess/jwt_test.go index 70c921c05..c1a00730a 100644 --- a/internal/keyaccess/jwt_test.go +++ b/internal/keyaccess/jwt_test.go @@ -11,7 +11,7 @@ import ( ) func TestCreateJWKKeyAccess(t *testing.T) { - t.Run("Create a Base58Key Access object - Happy Path", func(tt *testing.T) { + t.Run("Create a Key Access object - Happy Path", func(tt *testing.T) { _, privKey, err := crypto.GenerateEd25519Key() kid := "test-kid" assert.NoError(tt, err) @@ -20,7 +20,7 @@ func TestCreateJWKKeyAccess(t *testing.T) { assert.NotEmpty(tt, ka) }) - t.Run("Create a Base58Key Access object - Bad Base58Key", func(tt *testing.T) { + t.Run("Create a Key Access object - Bad Key", func(tt *testing.T) { kid := "test-kid" ka, err := NewJWKKeyAccess(kid, nil) assert.Error(tt, err) @@ -28,7 +28,7 @@ func TestCreateJWKKeyAccess(t *testing.T) { assert.Empty(tt, ka) }) - t.Run("Create a Base58Key Access object - No KID", func(tt *testing.T) { + t.Run("Create a Key Access object - No KID", func(tt *testing.T) { _, privKey, err := crypto.GenerateEd25519Key() assert.NoError(tt, err) ka, err := NewJWKKeyAccess("", privKey) diff --git a/pkg/server/router/keystore.go b/pkg/server/router/keystore.go index 6db8b45cc..bb94ad377 100644 --- a/pkg/server/router/keystore.go +++ b/pkg/server/router/keystore.go @@ -51,7 +51,7 @@ func (sk StoreKeyRequest) ToServiceRequest() (*keystore.StoreKeyRequest, error) } // StoreKey godoc -// @Summary Store Base58Key +// @Summary Store Key // @Description Stores a key to be used by the service // @Tags KeyStoreAPI // @Accept json @@ -93,7 +93,7 @@ type GetKeyDetailsResponse struct { } // GetKeyDetails godoc -// @Summary Get Details For Base58Key +// @Summary Get Details For Key // @Description Get details about a stored key // @Tags KeyStoreAPI // @Accept json diff --git a/pkg/server/router/keystore_test.go b/pkg/server/router/keystore_test.go index 19b942a82..a5bb87e36 100644 --- a/pkg/server/router/keystore_test.go +++ b/pkg/server/router/keystore_test.go @@ -34,7 +34,7 @@ func TestKeyStoreRouter(t *testing.T) { assert.Contains(tt, err.Error(), "could not create key store router with service type: test") }) - t.Run("Base58Key Store Service Test", func(tt *testing.T) { + t.Run("Key Store Service Test", func(tt *testing.T) { bolt, err := storage.NewBoltDB() assert.NoError(tt, err) assert.NotEmpty(tt, bolt) diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go index ce807f3ab..95eee283d 100644 --- a/pkg/server/server_test.go +++ b/pkg/server/server_test.go @@ -123,7 +123,7 @@ func TestDIDAPI(t *testing.T) { assert.Equal(tt, resp.DIDMethods[0], did.KeyMethod) }) - t.Run("Test Create DID By Method: Base58Key", func(tt *testing.T) { + t.Run("Test Create DID By Method: Key", func(tt *testing.T) { bolt, err := storage.NewBoltDB() // remove the db file after the test @@ -1171,7 +1171,7 @@ func TestDWNAPI(t *testing.T) { } func TestKeyStoreAPI(t *testing.T) { - t.Run("Test Store Base58Key", func(tt *testing.T) { + t.Run("Test Store Key", func(tt *testing.T) { bolt, err := storage.NewBoltDB() // remove the db file after the test @@ -1220,7 +1220,7 @@ func TestKeyStoreAPI(t *testing.T) { assert.NoError(tt, err) }) - t.Run("Test Get Base58Key Details", func(tt *testing.T) { + t.Run("Test Get Key Details", func(tt *testing.T) { bolt, err := storage.NewBoltDB() // remove the db file after the test From 26067d8af72ce1e6bcc33255c29cdfc005a98f18 Mon Sep 17 00:00:00 2001 From: gabe Date: Wed, 28 Sep 2022 14:54:34 -0700 Subject: [PATCH 13/13] pr comments --- pkg/service/did/key.go | 12 +++++++----- pkg/service/manifest/manifest.go | 28 +++++++++++----------------- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/pkg/service/did/key.go b/pkg/service/did/key.go index d66755005..822a55774 100644 --- a/pkg/service/did/key.go +++ b/pkg/service/did/key.go @@ -48,6 +48,12 @@ func (h *keyDIDHandler) CreateDID(request CreateDIDRequest) (*CreateDIDResponse, return nil, errors.Wrap(err, "could not store did:key value") } + // convert to a serialized format for return to the client + privKeyBase58, err := privateKeyToBase58(privKey) + if err != nil { + return nil, errors.Wrap(err, "could not encode private key as base58") + } + // store private key in key storage keyStoreRequest := keystore.StoreKeyRequest{ ID: id, @@ -55,15 +61,11 @@ func (h *keyDIDHandler) CreateDID(request CreateDIDRequest) (*CreateDIDResponse, Controller: id, Key: privKey, } + if err := h.keyStore.StoreKey(keyStoreRequest); err != nil { return nil, errors.Wrap(err, "could not store did:key private key") } - privKeyBase58, err := privateKeyToBase58(privKey) - if err != nil { - return nil, errors.Wrap(err, "could not encode private key as base58") - } - return &CreateDIDResponse{ DID: storedDID.DID, PrivateKey: privKeyBase58, diff --git a/pkg/service/manifest/manifest.go b/pkg/service/manifest/manifest.go index 2a65894de..e06dfcbf5 100644 --- a/pkg/service/manifest/manifest.go +++ b/pkg/service/manifest/manifest.go @@ -60,15 +60,14 @@ func NewManifestService(config config.ManifestServiceConfig, s storage.ServiceSt } func (s Service) CreateManifest(request CreateManifestRequest) (*CreateManifestResponse, error) { - logrus.Debugf("creating m: %+v", request) + logrus.Debugf("creating manifest: %+v", request) m := request.Manifest if err := m.IsValid(); err != nil { - errMsg := "m is not valid" - return nil, util.LoggingErrorMsg(err, errMsg) + return nil, util.LoggingErrorMsg(err, "manifest is not valid") } - // store the m + // store the manifest storageRequest := manifeststorage.StoredManifest{ ID: m.ID, Manifest: m, @@ -76,7 +75,7 @@ func (s Service) CreateManifest(request CreateManifestRequest) (*CreateManifestR } if err := s.manifestStorage.StoreManifest(storageRequest); err != nil { - return nil, util.LoggingErrorMsg(err, "could not store m") + return nil, util.LoggingErrorMsg(err, "could not store manifest") } // return the result @@ -102,8 +101,7 @@ func (s Service) GetManifests() (*GetManifestsResponse, error) { gotManifests, err := s.manifestStorage.GetManifests() if err != nil { - errMsg := fmt.Sprintf("could not get manifests(s)") - return nil, util.LoggingErrorMsg(err, errMsg) + return nil, util.LoggingErrorMsg(err, "could not get manifests(s)") } var manifests []manifest.CredentialManifest @@ -151,8 +149,7 @@ func (s Service) ProcessApplicationSubmission(request SubmitApplicationRequest) credApp := request.Application if err := credApp.IsValid(); err != nil { - errMsg := "application is not valid" - return nil, util.LoggingErrorMsg(err, errMsg) + return nil, util.LoggingErrorMsg(err, "application is not valid") } gotManifest, err := s.manifestStorage.GetManifest(credApp.ManifestID) @@ -162,8 +159,7 @@ func (s Service) ProcessApplicationSubmission(request SubmitApplicationRequest) // validate if err := isValidApplication(gotManifest, credApp); err != nil { - errMsg := fmt.Sprintf("could not validate application") - return nil, util.LoggingErrorMsg(err, errMsg) + return nil, util.LoggingErrorMsg(err, "could not validate application") } // store the application @@ -195,12 +191,12 @@ func (s Service) ProcessApplicationSubmission(request SubmitApplicationRequest) Data: map[string]interface{}{}, } - createdResponse, err := s.credential.CreateCredential(credentialRequest) + credentialResponse, err := s.credential.CreateCredential(credentialRequest) if err != nil { return nil, util.LoggingErrorMsg(err, "could not create credential") } - creds = append(creds, createdResponse.Credential) + creds = append(creds, credentialResponse.Credential) } var descriptors []exchange.SubmissionDescriptor @@ -256,8 +252,7 @@ func (s Service) GetApplications() (*GetApplicationsResponse, error) { gotApps, err := s.manifestStorage.GetApplications() if err != nil { - errMsg := fmt.Sprintf("could not get application(s)") - return nil, util.LoggingErrorMsg(err, errMsg) + return nil, util.LoggingErrorMsg(err, "could not get application(s)") } var apps []manifest.CredentialApplication @@ -301,8 +296,7 @@ func (s Service) GetResponses() (*GetResponsesResponse, error) { gotResponses, err := s.manifestStorage.GetResponses() if err != nil { - errMsg := fmt.Sprintf("could not get response(s)") - return nil, util.LoggingErrorMsg(err, errMsg) + return nil, util.LoggingErrorMsg(err, "could not get response(s)") } var responses []manifest.CredentialResponse