diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c965ee1 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +lint: + golangci-lint run diff --git a/main.go b/main.go index 6be6e03..9752784 100644 --- a/main.go +++ b/main.go @@ -45,13 +45,14 @@ func (c *KVstring) Decode(value string) error { } type Config struct { - SupportedIssuers KVstring `envconfig:"SUPPORTED_ISSUERS" required:"true"` - IPFSURL string `envconfig:"IPFS_URL" required:"true"` - ServerHost string `envconfig:"SERVER_HOST" default:"localhost:8002"` - HTTPConfigPath string `envconfig:"HTTP_CONFIG_PATH" default:"config.yaml"` - SupportedRPC KVstring `envconfig:"SUPPORTED_RPC" required:"true"` - SupportedStateContracts KVstring `envconfig:"SUPPORTED_STATE_CONTRACTS" required:"true"` - CircuitsFolderPath string `envconfig:"CIRCUITS_FOLDER_PATH" default:"circuits"` + SupportedIssuers KVstring `envconfig:"SUPPORTED_ISSUERS" required:"true"` + IPFSURL string `envconfig:"IPFS_URL" required:"true"` + ServerHost string `envconfig:"SERVER_HOST" default:"localhost:8002"` + HTTPConfigPath string `envconfig:"HTTP_CONFIG_PATH" default:"config.yaml"` + SupportedRPC KVstring `envconfig:"SUPPORTED_RPC" required:"true"` + SupportedStateContracts KVstring `envconfig:"SUPPORTED_STATE_CONTRACTS" required:"true"` + CircuitsFolderPath string `envconfig:"CIRCUITS_FOLDER_PATH" default:"circuits"` + SupportedIssuersBasicAuth KVstring `envconfig:"ISSUERS_BASIC_AUTH"` } func main() { @@ -71,6 +72,7 @@ func main() { issuerService := service.NewIssuerService( cfg.SupportedIssuers, + cfg.SupportedIssuersBasicAuth, nil, ) diff --git a/service/agent.go b/service/agent.go index b742662..d5c6840 100644 --- a/service/agent.go +++ b/service/agent.go @@ -2,6 +2,7 @@ package service import ( "encoding/json" + "strings" "github.com/google/uuid" "github.com/iden3/iden3comm/v2" @@ -46,8 +47,11 @@ func (as *AgentService) Process(envelop []byte) ( return nil, errors.Wrapf(ErrInvalidProtocolMessage, "failed to unmarshal body: %v", err) } - refreshed, err := as.refreshService.Process(message.To, - message.From, bodyMessage.ID) + refreshed, err := as.refreshService.Process( + message.To, + message.From, + convertID(bodyMessage.ID), + ) if err != nil { return nil, err } @@ -87,3 +91,18 @@ func verifyMessageAttributes(message *iden3comm.BasicMessage) error { } return nil } + +/* +TODO(illia-korotia): temporary solution, +need to communicate with the mobile team to pass the correct ID +*/ +func convertID(id string) string { + if strings.HasPrefix(id, "urn:uuid:") { + return strings.TrimPrefix(id, "urn:uuid:") + } + parts := strings.Split(id, "/") + if len(parts) > 0 { + return parts[len(parts)-1] + } + return id +} diff --git a/service/agent_test.go b/service/agent_test.go new file mode 100644 index 0000000..39ebc4d --- /dev/null +++ b/service/agent_test.go @@ -0,0 +1,38 @@ +package service + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestConvertID(t *testing.T) { + tests := []struct { + name string + arg string + expected string + }{ + { + name: "Old id format with URL info", + arg: "https://example.com/e342def6-620e-4394-8ea1-7448ea81bb72", + expected: "e342def6-620e-4394-8ea1-7448ea81bb72", + }, + { + name: "New format with urn:uuid: prefix", + arg: "urn:uuid:e342def6-620e-4394-8ea1-7448ea81bb72", + expected: "e342def6-620e-4394-8ea1-7448ea81bb72", + }, + { + name: "Clear format", + arg: "e342def6-620e-4394-8ea1-7448ea81bb72", + expected: "e342def6-620e-4394-8ea1-7448ea81bb72", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actual := convertID(tt.arg) + require.Equal(t, tt.expected, actual) + }) + } +} diff --git a/service/issuer.go b/service/issuer.go index 2cc9c33..36a4c3b 100644 --- a/service/issuer.go +++ b/service/issuer.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "net/http" + "strings" "github.com/0xPolygonID/refresh-service/logger" "github.com/iden3/go-schema-processor/v2/verifiable" @@ -20,15 +21,21 @@ var ( // IssuerService is service for communication with issuer node type IssuerService struct { supportedIssuers map[string]string + issuerBasicAuth map[string]string do http.Client } -func NewIssuerService(supportedIssuers map[string]string, client *http.Client) *IssuerService { +func NewIssuerService( + supportedIssuers map[string]string, + issuerBasicAuth map[string]string, + client *http.Client, +) *IssuerService { if client == nil { client = http.DefaultClient } return &IssuerService{ supportedIssuers: supportedIssuers, + issuerBasicAuth: issuerBasicAuth, do: *client, } } @@ -40,9 +47,20 @@ func (is *IssuerService) GetClaimByID(issuerDID, claimID string) (*verifiable.W3 } logger.DefaultLogger.Infof("use issuer node '%s' for issuer '%s'", issuerNode, issuerDID) - resp, err := is.do.Get( - fmt.Sprintf("%s/api/v1/identities/%s/claims/%s", issuerNode, issuerDID, claimID), + getRequest, err := http.NewRequest( + http.MethodGet, + fmt.Sprintf("%s/v1/%s/claims/%s", issuerNode, issuerDID, claimID), + http.NoBody, ) + if err != nil { + return nil, errors.Wrapf(ErrGetClaim, + "failed to create http request: '%v'", err) + } + if err := is.setBasicAuth(issuerDID, getRequest); err != nil { + return nil, err + } + + resp, err := is.do.Do(getRequest) if err != nil { return nil, errors.Wrapf(ErrGetClaim, "failed http GET request: '%v'", err) @@ -77,17 +95,27 @@ func (is *IssuerService) CreateCredential(issuerDID string, credentialRequest cr return id, errors.Wrapf(ErrCreateClaim, "credential request serialization error") } - resp, err := http.DefaultClient.Post( - fmt.Sprintf("%s/api/v1/identities/%s/claims", issuerNode, issuerDID), - "application/json", + + postRequest, err := http.NewRequest( + http.MethodPost, + fmt.Sprintf("%s/v1/%s/claims", issuerNode, issuerDID), body, ) + if err != nil { + return id, errors.Wrapf(ErrCreateClaim, + "failed to create http request: '%v'", err) + } + if err := is.setBasicAuth(issuerDID, postRequest); err != nil { + return id, err + } + + resp, err := is.do.Do(postRequest) if err != nil { return id, errors.Wrapf(ErrCreateClaim, "failed http POST request: %v", err) } defer resp.Body.Close() - if resp.StatusCode != http.StatusAccepted { + if resp.StatusCode != http.StatusCreated { return id, errors.Wrap(ErrCreateClaim, "invalid status code") } @@ -112,3 +140,26 @@ func (is *IssuerService) getIssuerURL(issuerDID string) (string, error) { } return url, nil } + +func (is *IssuerService) setBasicAuth(issuerDID string, request *http.Request) error { + if is.issuerBasicAuth == nil { + return nil + } + namepass, ok := is.issuerBasicAuth[issuerDID] + if !ok { + globalNamepass, ok := is.issuerBasicAuth["*"] + if !ok { + logger.DefaultLogger.Warnf("issuer '%s' not found in basic auth map", issuerDID) + return nil + } + namepass = globalNamepass + } + + namepassPair := strings.Split(namepass, ":") + if len(namepassPair) != 2 { + return errors.Errorf("invalid basic auth: %q", namepass) + } + + request.SetBasicAuth(namepassPair[0], namepassPair[1]) + return nil +}