Skip to content

Commit

Permalink
revert to postcontinue instead of patch on ids
Browse files Browse the repository at this point in the history
  • Loading branch information
lucamrgs committed Jan 10, 2025
1 parent e389d9e commit b8e9451
Show file tree
Hide file tree
Showing 7 changed files with 15 additions and 103 deletions.
4 changes: 2 additions & 2 deletions docs/content/en/docs/core-components/api-manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ We will use HTTP status codes https://en.wikipedia.org/wiki/List_of_HTTP_status_
protocol Manual {
GET /manual
GET /manual/{execution-id}/{step-id}
PATCH /manual/{execution-id}/{step-id}
POST /manual/continue
}
@enduml
```
Expand Down Expand Up @@ -154,7 +154,7 @@ None
404/Not found with payload:
General error

#### PATCH `/manual/<execution-id>/<step-id>`
#### POST `/manual/continue`
Respond to manual command pending in SOARCA, if out_args are defined they must be filled in and returned in the payload body. Only value is required in the response of the variable. You can however return the entire object. If the object does not match the original out_arg, the call we be considered as failed.

##### Call payload
Expand Down
8 changes: 4 additions & 4 deletions docs/content/en/docs/core-components/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,8 @@ class ManualStep
protocol ManualAPI {
GET /manual
GET /manual/{exec-id}/{step-id}
PATCH /manual/{exec-id}/{step-id}
GET /manual/{exec-id}/{step-id}
POST /manual/continue
}
interface ICapability{
Expand All @@ -303,7 +303,7 @@ interface ICapabilityInteraction{
interface IInteracionStorage{
GetPendingCommands() []CommandData
GetPendingCommand(execution.metadata) CommandData
Continue(execution.metadata) StatusCode
PostContinue(execution.metadata) StatusCode
}
interface IInteractionIntegrationNotifier {
Expand Down Expand Up @@ -362,7 +362,7 @@ else Native ManualAPI flow
interaction ->> interaction : async wait on integrationChannel
api -> interaction : GetPendingCommands()
api -> interaction : GetPendingCommand(execution.metadata)
api -> interaction : Continue(InteractionResponse)
api -> interaction : PostContinue(InteractionResponse)
interaction --> manual : capabilityChannel <- InteractionResponse
end
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,6 @@ func ManualRoutes(route *gin.Engine, manualHandler *manual_handler.ManualHandler
{
manualRoutes.GET("/", manualHandler.GetPendingCommands)
manualRoutes.GET(":exec_id/:step_id", manualHandler.GetPendingCommand)
manualRoutes.PATCH(":exec_id/:step_id", manualHandler.PatchContinue)
manualRoutes.POST("/continue", manualHandler.PostContinue)
}
}
20 changes: 5 additions & 15 deletions pkg/api/manual/manual_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,17 +130,15 @@ func (manualHandler *ManualHandler) GetPendingCommand(g *gin.Context) {
// @Param response_out_args body manual.ManualOutArgs true "out args"
// @Success 200 {object} api.Execution
// @failure 400 {object} api.Error
// @Router /manual/{exec_id}/{step_id} [PATCH]
func (manualHandler *ManualHandler) PatchContinue(g *gin.Context) {
paramExecutionId := g.Param("exec_id")
paramStepId := g.Param("step_id")
// @Router /manual/continue [POST]
func (manualHandler *ManualHandler) PostContinue(g *gin.Context) {

jsonData, err := io.ReadAll(g.Request.Body)
if err != nil {
log.Error("failed")
apiError.SendErrorResponse(g, http.StatusBadRequest,
"Failed to read json",
"PATCH /manual/{exec_id}/{step_id}", "")
"POST /manual/continue", "")
return
}

Expand All @@ -150,15 +148,7 @@ func (manualHandler *ManualHandler) PatchContinue(g *gin.Context) {
log.Error("failed to unmarshal JSON")
apiError.SendErrorResponse(g, http.StatusBadRequest,
"Failed to unmarshal JSON",
"PATCH /manual/{exec_id}/{step_id}", "")
return
}

if (outArgsUpdate.ExecutionId != paramExecutionId) || (outArgsUpdate.StepId != paramStepId) {
log.Error("mismatch between execution ID and step ID in url parameters vs request body")
apiError.SendErrorResponse(g, http.StatusBadRequest,
"Mismatch between execution ID and step ID between URL parameters and request body",
"PATCH /manual/{execution_id}/{step_id}", "")
"POST /manual/continue", "")
return
}

Expand All @@ -167,7 +157,7 @@ func (manualHandler *ManualHandler) PatchContinue(g *gin.Context) {
log.Error(err)
apiError.SendErrorResponse(g, http.StatusInternalServerError,
"Failed to post continue ID",
"PATCH /manual/{execution_id}/{step_id}", err.Error())
"POST /manual/continue", err.Error())
return
}
g.JSON(
Expand Down
7 changes: 0 additions & 7 deletions pkg/core/capability/manual/interaction/interaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,6 @@ func (manualController *InteractionController) PostContinue(result manual.Manual

// If it is
for varName, variable := range result.ResponseOutArgs {
// Sanity check that dictionary key matches variable name
if varName != variable.Name {
err := fmt.Errorf("provided out arg key [ %s ] does not match its name property [ %s ]", varName, variable.Name)
log.Error(err)
return http.StatusBadRequest, err
}

// first check that out args provided match the variables
if _, ok := pendingEntry.CommandData.OutVariables[varName]; !ok {
err := errors.New("provided out args do not match command-related variables")
Expand Down
71 changes: 0 additions & 71 deletions pkg/core/capability/manual/interaction/interaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,77 +391,6 @@ func TestPostContinueWarningsRaised(t *testing.T) {

}

func TestPostContinueFailOnUnmatchedOutArgsKeyName(t *testing.T) {
interaction := New([]IInteractionIntegrationNotifier{})
timeout := 500 * time.Millisecond
testCtx, testCancel := context.WithTimeout(context.Background(), timeout)

defer testCancel()

hook := NewTestLogHook()
log.Logger.AddHook(hook)

testCapComms := manualModel.ManualCapabilityCommunication{
Channel: make(chan manualModel.InteractionResponse),
TimeoutContext: testCtx,
}
defer close(testCapComms.Channel)

err := interaction.Queue(testInteractionCommand, testCapComms)
if err != nil {
t.Log(err)
t.Fail()
}

outArg := manualModel.ManualOutArg{
Type: "string",
Name: "testNotExisting",
Value: "now the value is bananas",
}

outArgsUpdate := manualModel.ManualOutArgsUpdatePayload{
Type: "test-manual-response",
ExecutionId: testMetadata.ExecutionId.String(),
PlaybookId: testMetadata.PlaybookId,
StepId: testMetadata.StepId,
ResponseStatus: true,
ResponseOutArgs: manualModel.ManualOutArgs{"asd": outArg},
}

statusCode, err := interaction.PostContinue(outArgsUpdate)

expectedStatusCode := 400
expectedErr := errors.New("provided out arg key [ asd ] does not match its name property [ testNotExisting ]")

expectedLogEntry1 := "provided out arg key [ asd ] does not match its name property [ testNotExisting ]"
expectedLogs := []string{expectedLogEntry1}

all := true
for _, expectedMessage := range expectedLogs {
containsAll := true
for _, entry := range hook.Entries {
if strings.Contains(expectedMessage, entry.Message) {
containsAll = true
break
}
if !strings.Contains(expectedMessage, entry.Message) {
containsAll = false
}
}
if !containsAll {
t.Logf("log message: '%s' not found in logged messages", expectedMessage)
all = false
break
}
}

assert.Equal(t, statusCode, expectedStatusCode)
assert.Equal(t, err, expectedErr)

assert.NotEqual(t, len(hook.Entries), 0)
assert.Equal(t, all, true)
}

func TestPostContinueFailOnNonexistingVariable(t *testing.T) {
interaction := New([]IInteractionIntegrationNotifier{})
timeout := 500 * time.Millisecond
Expand Down
6 changes: 3 additions & 3 deletions test/integration/api/routes/manual_api/manual_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func TestGetPendingCommandCalled(t *testing.T) {
mock_interaction_storage.AssertExpectations(t)
}

func TestPatchContinueCalled(t *testing.T) {
func TestPostContinueCalled(t *testing.T) {
mock_interaction_storage := mock_interaction_storage.MockInteractionStorage{}
manualApiHandler := manual_api.NewManualHandler(&mock_interaction_storage)

Expand All @@ -94,7 +94,7 @@ func TestPatchContinueCalled(t *testing.T) {
testExecId := "50b6d52c-6efc-4516-a242-dfbc5c89d421"
testStepId := "61a4d52c-6efc-4516-a242-dfbc5c89d312"
testPlaybookId := "21a4d52c-6efc-4516-a242-dfbc5c89d312"
path := "/manual/" + testExecId + "/" + testStepId
path := "/manual/continue"

testManualResponse := manual_model.ManualOutArgsUpdatePayload{
Type: "manual-step-response",
Expand All @@ -117,7 +117,7 @@ func TestPatchContinueCalled(t *testing.T) {

mock_interaction_storage.On("PostContinue", testManualResponse).Return(200, nil)

request, err := http.NewRequest("PATCH", path, bytes.NewBuffer(jsonData))
request, err := http.NewRequest("POST", path, bytes.NewBuffer(jsonData))
if err != nil {
t.Fail()
}
Expand Down

0 comments on commit b8e9451

Please sign in to comment.