diff --git a/ocm/client.go b/ocm/client.go index abe0bacb2113bf4523507f009b08b7095de039c2..862b1c3fbd0ce1514988731c3fbc3d1c0aa3b34d 100644 --- a/ocm/client.go +++ b/ocm/client.go @@ -1,12 +1,17 @@ package ocm import ( - "bytes" "context" "encoding/json" "fmt" "io" "net/http" + "net/url" +) + +const ( + proofOutOfBandPath = "/proof/v1/out-of-band-proof" + proofPresentationPath = "/proof/v1/find-by-presentation-id" ) // Client is the OCM service client @@ -30,26 +35,61 @@ func New(addr string, opts ...Option) *Client { } // GetLoginProofInvitation calls the "invitation" endpoint on -// the "out-of-band" protocol in the OCM service. -func (c *Client) GetLoginProofInvitation(ctx context.Context, r *LoginProofInvitationRequest) (*LoginProofInvitationResponse, error) { - b, err := json.Marshal(r) +// the "out-of-band" protocol in the OCM. +func (c *Client) GetLoginProofInvitation(ctx context.Context, credTypes []string) (*LoginProofInvitationResponse, error) { + req, err := http.NewRequestWithContext(ctx, "POST", c.addr+proofOutOfBandPath, nil) + if err != nil { + return nil, err + } + + v := url.Values{} + for _, t := range credTypes { + v.Add("type", t) + } + req.URL.RawQuery = v.Encode() + + resp, err := c.httpClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() // nolint:errcheck + + if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("unexpected response code: %s", resp.Status) + } + + bytes, err := io.ReadAll(resp.Body) if err != nil { return nil, err } - req, err := http.NewRequestWithContext(ctx, "POST", c.addr+"/out-of-band/1.0/invitation", bytes.NewReader(b)) + var response LoginProofInvitationResponse + if err := json.Unmarshal(bytes, &response); err != nil { + return nil, err + } + + return &response, nil +} + +// GetLoginProofResult calls the "find-by-presentation-id" endpoint in the OCM. +func (c *Client) GetLoginProofResult(ctx context.Context, presentationID string) (*LoginProofResultResponse, error) { + req, err := http.NewRequestWithContext(ctx, "GET", c.addr+proofPresentationPath, nil) if err != nil { return nil, err } + v := url.Values{} + v.Add("presentationId", presentationID) + req.URL.RawQuery = v.Encode() + resp, err := c.httpClient.Do(req) if err != nil { return nil, err } defer resp.Body.Close() // nolint:errcheck - if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("unexpected response code: %d", resp.StatusCode) + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("unexpected response code: %s", resp.Status) } bytes, err := io.ReadAll(resp.Body) @@ -57,10 +97,10 @@ func (c *Client) GetLoginProofInvitation(ctx context.Context, r *LoginProofInvit return nil, err } - var response *LoginProofInvitationResponse + var response LoginProofResultResponse if err := json.Unmarshal(bytes, &response); err != nil { return nil, err } - return response, nil + return &response, nil } diff --git a/ocm/client_test.go b/ocm/client_test.go index 4a58c1ffd46b0a6a3f3698ddd1094c7caf2db6b2..909c9f5f1f2fbbf1ab7969d370c965b5e5e4478b 100644 --- a/ocm/client_test.go +++ b/ocm/client_test.go @@ -3,7 +3,6 @@ package ocm_test import ( "context" "encoding/json" - "io" "net/http" "net/http/httptest" "testing" @@ -17,29 +16,16 @@ func Test_GetLoginProofInvitationSuccess(t *testing.T) { expected := &ocm.LoginProofInvitationResponse{ StatusCode: 200, Message: "success", + Data: ocm.LoginProofInvitationResponseData{}, } ocmServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - expectedRequestBody := `{"comment":"test","attributes":null,"schemaId":"schema:1.0","participantId":"12345"}` - bodyBytes, err := io.ReadAll(r.Body) - assert.NoError(t, err) - - bodyString := string(bodyBytes) - assert.Equal(t, expectedRequestBody, bodyString) - w.WriteHeader(http.StatusOK) _ = json.NewEncoder(w).Encode(expected) })) - req := &ocm.LoginProofInvitationRequest{ - Comment: "test", - Attributes: nil, - SchemaID: "schema:1.0", - ParticipantID: "12345", - } - client := ocm.New(ocmServer.URL) - res, err := client.GetLoginProofInvitation(context.Background(), req) + res, err := client.GetLoginProofInvitation(context.Background(), []string{"principalMembershipCredential"}) assert.NoError(t, err) assert.Equal(t, expected.StatusCode, res.StatusCode) @@ -49,25 +35,45 @@ func Test_GetLoginProofInvitationSuccess(t *testing.T) { func Test_GetLoginProofInvitationErr(t *testing.T) { ocmServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - expectedRequestBody := `{"comment":"test","attributes":null,"schemaId":"schema:1.0","participantId":"12345"}` - bodyBytes, err := io.ReadAll(r.Body) - assert.NoError(t, err) - - bodyString := string(bodyBytes) - assert.Equal(t, expectedRequestBody, bodyString) - w.WriteHeader(http.StatusInternalServerError) })) - req := &ocm.LoginProofInvitationRequest{ - Comment: "test", - Attributes: nil, - SchemaID: "schema:1.0", - ParticipantID: "12345", + client := ocm.New(ocmServer.URL) + res, err := client.GetLoginProofInvitation(context.Background(), []string{"principalMembershipCredential"}) + + assert.Nil(t, res) + assert.Error(t, err) + assert.Contains(t, err.Error(), "unexpected response code") +} + +func TestClient_GetLoginProofResultSuccess(t *testing.T) { + expected := &ocm.LoginProofResultResponse{ + StatusCode: 200, + Message: "success", + Data: ocm.LoginProofResultResponseData{}, } + ocmServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + _ = json.NewEncoder(w).Encode(expected) + })) + + client := ocm.New(ocmServer.URL) + res, err := client.GetLoginProofResult(context.Background(), "2cf01406-b15f-4960-a6a7-7bc62cd37a3c") + + assert.NoError(t, err) + assert.Equal(t, expected.StatusCode, res.StatusCode) + assert.Equal(t, expected.Message, res.Message) + assert.Equal(t, expected.Data, res.Data) +} + +func Test_GetLoginProofResultErr(t *testing.T) { + ocmServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusInternalServerError) + })) + client := ocm.New(ocmServer.URL) - res, err := client.GetLoginProofInvitation(context.Background(), req) + res, err := client.GetLoginProofResult(context.Background(), "2cf01406-b15f-4960-a6a7-7bc62cd37a3c") assert.Nil(t, res) assert.Error(t, err) diff --git a/ocm/types.go b/ocm/types.go index fa12f15a01869872b1328283928592a65aa75a2b..3a002c4d7d1cf90d5359b7fa2e7496057b6cfeab 100644 --- a/ocm/types.go +++ b/ocm/types.go @@ -1,18 +1,5 @@ package ocm -type LoginProofInvitationRequest struct { - Comment string `json:"comment"` - Attributes []Attribute `json:"attributes"` - SchemaID string `json:"schemaId"` - ParticipantID string `json:"participantId"` -} - -type Attribute struct { - AttributeName string `json:"attributeName"` - Value string `json:"value"` - Condition string `json:"condition"` -} - type LoginProofInvitationResponse struct { StatusCode int `json:"statusCode"` Message string `json:"message"` @@ -23,3 +10,16 @@ type LoginProofInvitationResponseData struct { PresentationID string `json:"presentationId"` PresentationMessage string `json:"presentationMessage"` } + +type LoginProofResultResponse struct { + StatusCode int `json:"statusCode"` + Message string `json:"message"` + Data LoginProofResultResponseData `json:"data"` +} + +type LoginProofResultResponseData struct { + State string `json:"state"` + SchemaID string `json:"schemaId"` + CredDefID string `json:"credDefId"` + Claims map[string]interface{} `json:"credentialSubject"` +}