Skip to content
This repository has been archived by the owner on Dec 12, 2024. It is now read-only.

Commit

Permalink
[OSE-176] Operations can be cancelled (#216)
Browse files Browse the repository at this point in the history
* Initial draft of cancellation

* Linters

* Moving a constant.

* Better homes for many methods and variables.

* PR comments

* Lets make pointers.

* Rename func
  • Loading branch information
andresuribe87 authored Dec 15, 2022
1 parent f5ac154 commit 384f92e
Show file tree
Hide file tree
Showing 16 changed files with 420 additions and 274 deletions.
64 changes: 32 additions & 32 deletions doc/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ definitions:
context values.
type: string
data:
additionalProperties: true
additionalProperties: {}
type: object
expiry:
type: string
Expand Down Expand Up @@ -770,7 +770,7 @@ definitions:
description: The reason why the submission was approved or denied.
type: string
status:
description: One of {`pending`, `approved`, `denied`}.
description: One of {`pending`, `approved`, `denied`, `cancelled`}.
type: string
required:
- definition_id
Expand All @@ -790,7 +790,7 @@ definitions:
properties:
submissions:
items:
$ref: '#/definitions/presentation.Submission'
$ref: '#/definitions/model.Submission'
type: array
type: object
github.com_tbd54566975_ssi-service_pkg_server_router.Operation:
Expand Down Expand Up @@ -846,7 +846,7 @@ definitions:
description: The reason why the submission was approved or denied.
type: string
status:
description: One of {`pending`, `approved`, `denied`}.
description: One of {`pending`, `approved`, `denied`, `cancelled`}.
type: string
required:
- definition_id
Expand Down Expand Up @@ -1044,14 +1044,36 @@ definitions:
- id
- schema
type: object
model.Submission:
properties:
definition_id:
type: string
descriptor_map:
items:
$ref: '#/definitions/exchange.SubmissionDescriptor'
type: array
id:
type: string
reason:
description: The reason why the submission was approved or denied.
type: string
status:
description: One of {`pending`, `approved`, `denied`, `cancelled`}.
type: string
required:
- definition_id
- descriptor_map
- id
- status
type: object
pkg_server_router.CreateCredentialRequest:
properties:
'@context':
description: A context is optional. If not present, we'll apply default, required
context values.
type: string
data:
additionalProperties: true
additionalProperties: {}
type: object
expiry:
type: string
Expand Down Expand Up @@ -1342,7 +1364,7 @@ definitions:
description: The reason why the submission was approved or denied.
type: string
status:
description: One of {`pending`, `approved`, `denied`}.
description: One of {`pending`, `approved`, `denied`, `cancelled`}.
type: string
required:
- definition_id
Expand All @@ -1362,7 +1384,7 @@ definitions:
properties:
submissions:
items:
$ref: '#/definitions/presentation.Submission'
$ref: '#/definitions/model.Submission'
type: array
type: object
pkg_server_router.Operation:
Expand Down Expand Up @@ -1418,7 +1440,7 @@ definitions:
description: The reason why the submission was approved or denied.
type: string
status:
description: One of {`pending`, `approved`, `denied`}.
description: One of {`pending`, `approved`, `denied`, `cancelled`}.
type: string
required:
- definition_id
Expand Down Expand Up @@ -1501,28 +1523,6 @@ definitions:
verified:
type: boolean
type: object
presentation.Submission:
properties:
definition_id:
type: string
descriptor_map:
items:
$ref: '#/definitions/exchange.SubmissionDescriptor'
type: array
id:
type: string
reason:
description: The reason why the submission was approved or denied.
type: string
status:
description: One of {`pending`, `approved`, `denied`}.
type: string
required:
- definition_id
- descriptor_map
- id
- status
type: object
rendering.ColorResource:
properties:
color:
Expand Down Expand Up @@ -2411,7 +2411,7 @@ paths:
"200":
description: OK
schema:
$ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.GetOperationsResponse'
$ref: '#/definitions/pkg_server_router.Operation'
"400":
description: Bad request
schema:
Expand Down Expand Up @@ -2440,7 +2440,7 @@ paths:
"200":
description: OK
schema:
$ref: '#/definitions/github.com_tbd54566975_ssi-service_pkg_server_router.Operation'
$ref: '#/definitions/pkg_server_router.Operation'
"400":
description: Bad request
schema:
Expand Down
18 changes: 15 additions & 3 deletions pkg/server/router/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (o OperationRouter) GetOperation(ctx context.Context, w http.ResponseWriter
return framework.NewRequestError(
util.LoggingErrorMsg(err, "failed getting operation"), http.StatusInternalServerError)
}
return framework.Respond(ctx, w, routerModel(op), http.StatusOK)
return framework.Respond(ctx, w, routerModel(*op), http.StatusOK)
}

type GetOperationsRequest struct {
Expand Down Expand Up @@ -169,10 +169,22 @@ func routerModel(op operation.Operation) Operation {
// @Accept json
// @Produce json
// @Param id path string true "ID"
// @Success 200 {object} GetOperationsResponse "OK"
// @Success 200 {object} Operation "OK"
// @Failure 400 {string} string "Bad request"
// @Failure 500 {string} string "Internal server error"
// @Router /v1/operations [get]
func (o OperationRouter) CancelOperation(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
return nil
id := framework.GetParam(ctx, IDParam)
if id == nil {
return framework.NewRequestError(
util.LoggingNewError("get operation request requires id"), http.StatusBadRequest)
}

op, err := o.service.CancelOperation(operation.CancelOperationRequest{ID: *id})

if err != nil {
return framework.NewRequestError(
util.LoggingErrorMsg(err, "failed cancelling operation"), http.StatusInternalServerError)
}
return framework.Respond(ctx, w, routerModel(*op), http.StatusOK)
}
56 changes: 54 additions & 2 deletions pkg/server/server_operation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/tbd54566975/ssi-service/pkg/server/router"
"github.com/tbd54566975/ssi-service/pkg/service/operation"
"github.com/tbd54566975/ssi-service/pkg/service/operation/submission"
"github.com/tbd54566975/ssi-service/pkg/storage"
)

Expand All @@ -27,7 +28,7 @@ func TestOperationsAPI(t *testing.T) {
holderSigner, holderDID := getSigner(t)
definition := createPresentationDefinition(t, pRouter)
submissionOp := createSubmission(t, pRouter, definition.PresentationDefinition.ID, VerifiableCredential(), holderDID, holderSigner)
submission := reviewSubmission(t, pRouter, operation.SubmissionID(submissionOp.ID))
sub := reviewSubmission(t, pRouter, submission.ID(submissionOp.ID))

createdID := submissionOp.ID
req := httptest.NewRequest(
Expand All @@ -43,7 +44,7 @@ func TestOperationsAPI(t *testing.T) {
assert.NoError(t, json.NewDecoder(w.Body).Decode(&resp))
assert.True(t, resp.Done)
assert.Empty(t, resp.Result.Error)
data, err := json.Marshal(submission)
data, err := json.Marshal(sub)
assert.NoError(t, err)
var responseAsMap map[string]any
assert.NoError(t, json.Unmarshal(data, &responseAsMap))
Expand Down Expand Up @@ -220,6 +221,57 @@ func TestOperationsAPI(t *testing.T) {
})
})

t.Run("CancelOperation", func(t *testing.T) {
t.Run("Marks an operation as done", func(t *testing.T) {
s := setupTestDB(t)
pRouter := setupPresentationRouter(t, s)
opRouter := setupOperationsRouter(t, s)

holderSigner, holderDID := getSigner(t)
definition := createPresentationDefinition(t, pRouter)
submissionOp := createSubmission(t, pRouter, definition.PresentationDefinition.ID, VerifiableCredential(), holderDID, holderSigner)

createdID := submissionOp.ID
req := httptest.NewRequest(
http.MethodPut,
fmt.Sprintf("https://ssi-service.com/v1/operations/%s", createdID),
nil)
w := httptest.NewRecorder()

err := opRouter.CancelOperation(newRequestContextWithParams(map[string]string{"id": createdID}), w, req)

assert.NoError(t, err)
var resp router.Operation
assert.NoError(t, json.NewDecoder(w.Body).Decode(&resp))
assert.True(t, resp.Done)
assert.Contains(t, resp.Result.Response, "definition_id")
assert.Contains(t, resp.Result.Response, "descriptor_map")
assert.Equal(t, "cancelled", resp.Result.Response.(map[string]any)["status"])
})

t.Run("Returns error when operation is done already", func(t *testing.T) {
s := setupTestDB(t)
pRouter := setupPresentationRouter(t, s)
opRouter := setupOperationsRouter(t, s)

holderSigner, holderDID := getSigner(t)
definition := createPresentationDefinition(t, pRouter)
submissionOp := createSubmission(t, pRouter, definition.PresentationDefinition.ID, VerifiableCredential(), holderDID, holderSigner)
_ = reviewSubmission(t, pRouter, submission.ID(submissionOp.ID))

createdID := submissionOp.ID
req := httptest.NewRequest(
http.MethodPut,
fmt.Sprintf("https://ssi-service.com/v1/operations/%s", createdID),
nil)
w := httptest.NewRecorder()

err := opRouter.CancelOperation(newRequestContextWithParams(map[string]string{"id": createdID}), w, req)

assert.Error(t, err)
})
})

}

func setupTestDB(t *testing.T) storage.ServiceStorage {
Expand Down
18 changes: 9 additions & 9 deletions pkg/server/server_presentation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"github.com/tbd54566975/ssi-service/config"
"github.com/tbd54566975/ssi-service/internal/keyaccess"
"github.com/tbd54566975/ssi-service/pkg/server/router"
"github.com/tbd54566975/ssi-service/pkg/service/operation"
"github.com/tbd54566975/ssi-service/pkg/service/operation/submission"
"github.com/tbd54566975/ssi-service/pkg/service/presentation"
"github.com/tbd54566975/ssi-service/pkg/service/presentation/model"
"github.com/tbd54566975/ssi-service/pkg/storage"
Expand Down Expand Up @@ -163,14 +163,14 @@ func TestPresentationAPI(t *testing.T) {
"id": "did:web:andresuribe.com",
})), holderDID, holderSigner)

req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("https://ssi-service.com/v1/presentations/submissions/%s", operation.SubmissionID(op.ID)), nil)
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("https://ssi-service.com/v1/presentations/submissions/%s", submission.ID(op.ID)), nil)
w := httptest.NewRecorder()

assert.NoError(t, pRouter.GetSubmission(newRequestContextWithParams(map[string]string{"id": operation.SubmissionID(op.ID)}), w, req))
assert.NoError(t, pRouter.GetSubmission(newRequestContextWithParams(map[string]string{"id": submission.ID(op.ID)}), w, req))

var resp router.GetSubmissionResponse
assert.NoError(t, json.NewDecoder(w.Body).Decode(&resp))
assert.Equal(t, operation.SubmissionID(op.ID), resp.Submission.ID)
assert.Equal(t, submission.ID(op.ID), resp.Submission.ID)
assert.Equal(t, definition.PresentationDefinition.ID, resp.Submission.DefinitionID)
assert.Equal(t, "pending", resp.Submission.Status)
})
Expand Down Expand Up @@ -218,7 +218,7 @@ func TestPresentationAPI(t *testing.T) {
}

value := newRequestValue(t, request)
createdID := operation.SubmissionID(submissionOp.ID)
createdID := submission.ID(submissionOp.ID)
req := httptest.NewRequest(
http.MethodPut,
fmt.Sprintf("https://ssi-service.com/v1/presentations/submissions/%s/review", createdID),
Expand All @@ -243,7 +243,7 @@ func TestPresentationAPI(t *testing.T) {
holderSigner, holderDID := getSigner(t)
definition := createPresentationDefinition(t, pRouter)
submissionOp := createSubmission(t, pRouter, definition.PresentationDefinition.ID, VerifiableCredential(), holderDID, holderSigner)
createdID := operation.SubmissionID(submissionOp.ID)
createdID := submission.ID(submissionOp.ID)
_ = reviewSubmission(t, pRouter, createdID)

request := router.ReviewSubmissionRequest{
Expand Down Expand Up @@ -323,14 +323,14 @@ func TestPresentationAPI(t *testing.T) {
{
Status: "pending",
PresentationSubmission: &exchange.PresentationSubmission{
ID: operation.SubmissionID(op.ID),
ID: submission.ID(op.ID),
DefinitionID: definition.PresentationDefinition.ID,
},
},
{
Status: "pending",
PresentationSubmission: &exchange.PresentationSubmission{
ID: operation.SubmissionID(op2.ID),
ID: submission.ID(op2.ID),
DefinitionID: definition.PresentationDefinition.ID,
},
},
Expand Down Expand Up @@ -395,7 +395,7 @@ func TestPresentationAPI(t *testing.T) {
{
Status: "pending",
PresentationSubmission: &exchange.PresentationSubmission{
ID: operation.SubmissionID(op.ID),
ID: submission.ID(op.ID),
DefinitionID: definition.PresentationDefinition.ID,
},
},
Expand Down
Loading

0 comments on commit 384f92e

Please sign in to comment.