Skip to content

Commit

Permalink
Restore the manual capability files
Browse files Browse the repository at this point in the history
  • Loading branch information
MaartendeKruijf committed Jan 16, 2025
1 parent 21745be commit c07e8c8
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 0 deletions.
85 changes: 85 additions & 0 deletions pkg/core/capability/manual/manual.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package manual

import (
"errors"
"reflect"
"soarca/internal/logger"
"soarca/pkg/core/capability"
"soarca/pkg/interaction"
"soarca/pkg/models/cacao"
"soarca/pkg/models/execution"
"time"
)

var (
component = reflect.TypeOf(ManualCapability{}).PkgPath()
log *logger.Log
)

const (
manualResultVariableName = "__soarca_manual_result__"
manualCapabilityName = "soarca-manual-http"
fallbackTimeout = time.Minute * 1
)

func New(controller interaction.ICapabilityInteraction,
channel chan interaction.InteractionResponse) ManualCapability {
// channel := make(chan interaction.InteractionResponse)
return ManualCapability{interaction: controller, channel: channel}
}

func init() {
log = logger.Logger(component, logger.Info, "", logger.Json)
}

type ManualCapability struct {
interaction interaction.ICapabilityInteraction
channel chan interaction.InteractionResponse
}

func (manual *ManualCapability) GetType() string {
return manualCapabilityName
}

func (manual *ManualCapability) Execute(
metadata execution.Metadata,
commandContext capability.Context) (cacao.Variables, error) {

command := interaction.InteractionCommand{Metadata: metadata, Context: commandContext}

err := manual.interaction.Queue(command, manual.channel)
if err != nil {
return cacao.NewVariables(), err
}

result, err := manual.awaitUserInput(manual.getTimeoutValue(commandContext.Step.Timeout))
if err != nil {
return cacao.NewVariables(), err
}
return result.Select(commandContext.Step.OutArgs), nil

}

func (manual *ManualCapability) awaitUserInput(timeout time.Duration) (cacao.Variables, error) {
timer := time.NewTimer(time.Duration(timeout))
for {
select {
case <-timer.C:
err := errors.New("manual response timeout, user responded not in time")
log.Error(err)
return cacao.NewVariables(), err
case response := <-manual.channel:
log.Trace("received response from api")
return response.Variables, response.ResponseError

}
}
}

func (manual *ManualCapability) getTimeoutValue(userTimeout int) time.Duration {
if userTimeout == 0 {
log.Warning("timeout is not set or set to 0 fallback timeout of 1 minute is used to complete step")
return fallbackTimeout
}
return time.Duration(userTimeout) * time.Millisecond
}
52 changes: 52 additions & 0 deletions pkg/core/capability/manual/manual_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package manual

import (
"soarca/pkg/core/capability"
"soarca/pkg/interaction"
"soarca/pkg/models/execution"
"soarca/test/unittest/mocks/mock_interaction"
"testing"
"time"

"github.com/go-playground/assert/v2"
)

func returnQueueCall(channel chan interaction.InteractionResponse) {

time.Sleep(time.Millisecond * 10)
response := interaction.InteractionResponse{}
channel <- response
}

func TestManualExecution(t *testing.T) {
interactionMock := mock_interaction.MockInteraction{}
channel := make(chan interaction.InteractionResponse)
manual := New(&interactionMock, channel)

meta := execution.Metadata{}
context := capability.Context{}

command := interaction.InteractionCommand{}
go returnQueueCall(channel)
interactionMock.On("Queue", command, channel).Return(nil)
vars, err := manual.Execute(meta, context)
assert.Equal(t, err, nil)
assert.NotEqual(t, vars, nil)

}

func TestTimetoutCalculationNotSet(t *testing.T) {
interactionMock := mock_interaction.MockInteraction{}
channel := make(chan interaction.InteractionResponse)
manual := New(&interactionMock, channel)
timeout := manual.getTimeoutValue(0)
assert.Equal(t, timeout, time.Minute)
}

func TestTimetoutCalculation(t *testing.T) {
interactionMock := mock_interaction.MockInteraction{}
channel := make(chan interaction.InteractionResponse)
manual := New(&interactionMock, channel)
timeout := manual.getTimeoutValue(1)
assert.Equal(t, timeout, time.Millisecond*1)
}

0 comments on commit c07e8c8

Please sign in to comment.