diff --git a/config/config.go b/config/config.go index 73c7bb0b9..546f3bbe6 100644 --- a/config/config.go +++ b/config/config.go @@ -68,6 +68,7 @@ type ServicesConfig struct { StorageProvider string `toml:"storage" conf:"default:bolt"` StorageOptions []storage.Option `toml:"storage_option"` ServiceEndpoint string `toml:"service_endpoint" conf:"default:http://localhost:8080"` + StatusEndpoint string `toml:"status_endpoint"` // Application level encryption configuration. Defines how values are encrypted before they are stored in the // configured KV store. diff --git a/config/info.go b/config/info.go index 264ddd93e..86cf42b30 100644 --- a/config/info.go +++ b/config/info.go @@ -26,12 +26,13 @@ var ( // serviceInfo is intended to be a singleton object for static service info. // WARNING: it is **NOT** currently thread safe. type serviceInfo struct { - name string - description string - version string - apiBase string - apiVersion string - servicePaths map[framework.Type]string + name string + description string + version string + apiBase string + statusBaseURL string + apiVersion string + servicePaths map[framework.Type]string } func Name() string { @@ -57,6 +58,17 @@ func GetAPIBase() string { return si.apiBase } +func SetStatusBase(url string) { + if strings.LastIndexAny(url, "/") == len(url)-1 { + url = url[:len(url)-1] + } + si.statusBaseURL = url +} + +func GetStatusBase() string { + return si.statusBaseURL +} + func SetServicePath(service framework.Type, path string) { // normalize path if strings.IndexAny(path, "/") == 0 { diff --git a/config/kitchensink.toml b/config/kitchensink.toml index 26daf1536..e56fdf549 100644 --- a/config/kitchensink.toml +++ b/config/kitchensink.toml @@ -16,6 +16,7 @@ enable_schema_caching = true [services] service_endpoint = "http://localhost:8080" +status_endpoint = "https://our-site.com/status" # Uncomment one of the following database configurations diff --git a/integration/common.go b/integration/common.go index 6de315f1e..e5ff625ad 100644 --- a/integration/common.go +++ b/integration/common.go @@ -20,12 +20,10 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" - "github.com/tbd54566975/ssi-service/config" credmodel "github.com/tbd54566975/ssi-service/internal/credential" "github.com/tbd54566975/ssi-service/internal/keyaccess" "github.com/tbd54566975/ssi-service/internal/util" "github.com/tbd54566975/ssi-service/pkg/server/router" - "github.com/tbd54566975/ssi-service/pkg/service/framework" ) const ( @@ -47,10 +45,6 @@ func init() { DisableQuote: true, ForceColors: true, }) - - config.SetAPIBase(endpoint) - config.SetServicePath(framework.Credential, "/credentials") - config.SetServicePath(framework.Schema, "/schemas") } type didConfigurationResourceParams struct { diff --git a/pkg/server/router/testutils_test.go b/pkg/server/router/testutils_test.go index dda9ae049..8078ddd7e 100644 --- a/pkg/server/router/testutils_test.go +++ b/pkg/server/router/testutils_test.go @@ -1,6 +1,7 @@ package router import ( + "fmt" "os" "testing" @@ -28,6 +29,7 @@ func TestMain(t *testing.M) { testutil.EnableSchemaCaching() config.SetAPIBase(testServerURL) config.SetServicePath(framework.Credential, "/credentials") + config.SetStatusBase(fmt.Sprintf("%s/status", config.GetServicePath(framework.Credential))) os.Exit(t.Run()) } diff --git a/pkg/server/server.go b/pkg/server/server.go index 252f89cc8..b4d7dd9b0 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -3,6 +3,7 @@ package server import ( + "fmt" "os" sdkutil "github.com/TBD54566975/ssi-sdk/util" @@ -85,7 +86,7 @@ func NewSSIServer(shutdown chan os.Signal, cfg config.SSIServiceConfig) (*SSISer if err = SchemaAPI(v1, ssi.Schema, ssi.Webhook); err != nil { return nil, sdkutil.LoggingErrorMsg(err, "unable to instantiate Schema API") } - if err = CredentialAPI(v1, ssi.Credential, ssi.Webhook); err != nil { + if err = CredentialAPI(v1, ssi.Credential, ssi.Webhook, cfg.Services.StatusEndpoint); err != nil { return nil, sdkutil.LoggingErrorMsg(err, "unable to instantiate Credential API") } if err = OperationAPI(v1, ssi.Operation); err != nil { @@ -199,7 +200,7 @@ func SchemaAPI(rg *gin.RouterGroup, service svcframework.Service, webhookService } // CredentialAPI registers all HTTP handlers for the Credentials Service -func CredentialAPI(rg *gin.RouterGroup, service svcframework.Service, webhookService *webhook.Service) (err error) { +func CredentialAPI(rg *gin.RouterGroup, service svcframework.Service, webhookService *webhook.Service, statusEndpoint string) (err error) { credRouter, err := router.NewCredentialRouter(service) if err != nil { return sdkutil.LoggingErrorMsg(err, "creating credential router") @@ -208,6 +209,13 @@ func CredentialAPI(rg *gin.RouterGroup, service svcframework.Service, webhookSer // make sure the credential service is configured to use the correct path config.SetServicePath(svcframework.Credential, CredentialsPrefix) + // allows for a custom URI to be used for status list credentials, if not set, we use the default path + if statusEndpoint != "" { + config.SetStatusBase(statusEndpoint) + } else { + config.SetStatusBase(fmt.Sprintf("%s/status", config.GetServicePath(svcframework.Credential))) + } + // Credentials credentialAPI := rg.Group(CredentialsPrefix) credentialAPI.PUT("", middleware.Webhook(webhookService, webhook.Credential, webhook.Create), credRouter.CreateCredential) diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go index f0306b397..091fe9b8e 100644 --- a/pkg/server/server_test.go +++ b/pkg/server/server_test.go @@ -2,6 +2,7 @@ package server import ( "bytes" + "fmt" "io" "net/http" "net/http/httptest" @@ -16,6 +17,7 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/tbd54566975/ssi-service/config" credmodel "github.com/tbd54566975/ssi-service/internal/credential" "github.com/tbd54566975/ssi-service/internal/util" @@ -296,6 +298,7 @@ func testCredentialRouter(t *testing.T, bolt storage.ServiceStorage, keyStore *k // set endpoint in service info config.SetServicePath(svcframework.Credential, CredentialsPrefix) + config.SetStatusBase(fmt.Sprintf("%s/status", config.GetServicePath(svcframework.Credential))) // create router for service credentialRouter, err := router.NewCredentialRouter(credentialService) diff --git a/pkg/service/credential/status.go b/pkg/service/credential/status.go index 6037b4c2d..6d5403fd6 100644 --- a/pkg/service/credential/status.go +++ b/pkg/service/credential/status.go @@ -13,7 +13,6 @@ import ( "github.com/tbd54566975/ssi-service/config" credint "github.com/tbd54566975/ssi-service/internal/credential" - "github.com/tbd54566975/ssi-service/pkg/service/framework" "github.com/tbd54566975/ssi-service/pkg/storage" ) @@ -69,8 +68,7 @@ func (s Service) createStatusListEntryForCredential(ctx context.Context, credID func (s Service) createStatusListCredential(ctx context.Context, tx storage.Tx, statusPurpose statussdk.StatusPurpose, issuerID, fullyQualifiedVerificationMethodID string, slcMetadata StatusListCredentialMetadata) (int, *credential.VerifiableCredential, error) { statusListID := uuid.NewString() - statusListURI := fmt.Sprintf("%s/status/%s", config.GetServicePath(framework.Credential), statusListID) - + statusListURI := fmt.Sprintf("%s/%s", config.GetStatusBase(), statusListID) generatedStatusListCredential, err := statussdk.GenerateStatusList2021Credential(statusListURI, issuerID, statusPurpose, []credential.VerifiableCredential{}) if err != nil { return -1, nil, sdkutil.LoggingErrorMsg(err, "could not generate status list")