| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- package api
- import (
- "context"
- "testing"
- "connectrpc.com/connect"
- "github.com/google/uuid"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- apiv1 "github.com/OliveTin/OliveTin/gen/olivetin/api/v1"
- "github.com/OliveTin/OliveTin/internal/auth"
- config "github.com/OliveTin/OliveTin/internal/config"
- "github.com/OliveTin/OliveTin/internal/executor"
- )
- func TestStartActionRequiresJustificationForGuest(t *testing.T) {
- cfg := config.DefaultConfig()
- action := &config.Action{
- Title: "Send email",
- ID: "send_email",
- Justification: config.JustificationRequiredNoTemplate,
- Shell: "echo done",
- }
- cfg.Actions = append(cfg.Actions, action)
- ex := executor.DefaultExecutor(cfg)
- ex.RebuildActionMap()
- binding := ex.FindBindingWithNoEntity(action)
- require.NotNil(t, binding)
- ts, client := getNewTestServerAndClientWithExecutor(cfg, ex)
- defer ts.Close()
- _, err := client.StartAction(context.Background(), connect.NewRequest(&apiv1.StartActionRequest{
- BindingId: binding.ID,
- UniqueTrackingId: uuid.NewString(),
- }))
- require.Error(t, err)
- assert.Equal(t, connect.CodeInvalidArgument, connect.CodeOf(err))
- resp, err := client.StartAction(context.Background(), connect.NewRequest(&apiv1.StartActionRequest{
- BindingId: binding.ID,
- UniqueTrackingId: uuid.NewString(),
- Justification: "New user registration foo@example.com",
- }))
- require.NoError(t, err)
- require.NotEmpty(t, resp.Msg.ExecutionTrackingId)
- waitForLogJustification(t, ex, resp.Msg.ExecutionTrackingId, "New user registration foo@example.com")
- }
- func TestBuildActionExposesJustificationTemplate(t *testing.T) {
- cfg := config.DefaultConfig()
- action := &config.Action{
- Title: "Audited action",
- ID: "audited",
- Justification: "{{ target }}",
- Shell: "echo hi",
- }
- cfg.Actions = append(cfg.Actions, action)
- ex := executor.DefaultExecutor(cfg)
- ex.RebuildActionMap()
- binding := ex.FindBindingWithNoEntity(action)
- require.NotNil(t, binding)
- pb := buildAction(binding, &DashboardRenderRequest{
- cfg: cfg,
- ex: ex,
- })
- require.NotNil(t, pb)
- assert.Equal(t, "{{ target }}", pb.Justification)
- }
- func TestBuildActionExposesBlankRequiredJustification(t *testing.T) {
- cfg := config.DefaultConfig()
- action := &config.Action{
- Title: "Audited action",
- ID: "audited",
- Justification: config.JustificationRequiredNoTemplate,
- Shell: "echo hi",
- }
- cfg.Actions = append(cfg.Actions, action)
- ex := executor.DefaultExecutor(cfg)
- ex.RebuildActionMap()
- binding := ex.FindBindingWithNoEntity(action)
- require.NotNil(t, binding)
- pb := buildAction(binding, &DashboardRenderRequest{
- cfg: cfg,
- ex: ex,
- })
- require.NotNil(t, pb)
- assert.Equal(t, config.JustificationRequiredNoTemplate, pb.Justification)
- }
- func TestResolveStartJustificationUsesTemplateWhenClientValueEmpty(t *testing.T) {
- action := &config.Action{
- Justification: "{{ ansible_host }}",
- }
- binding := &executor.ActionBinding{}
- got := resolveStartJustification(action, binding, "", map[string]string{
- "ansible_host": "192.168.66.8",
- })
- assert.Equal(t, "192.168.66.8", got)
- }
- func TestResolveStartJustificationPrefersClientValue(t *testing.T) {
- action := &config.Action{
- Justification: "{{ ansible_host }}",
- }
- binding := &executor.ActionBinding{}
- got := resolveStartJustification(action, binding, "manual reason", map[string]string{
- "ansible_host": "192.168.66.8",
- })
- assert.Equal(t, "manual reason", got)
- }
- func TestStartActionResolvesJustificationTemplateForGuest(t *testing.T) {
- cfg := config.DefaultConfig()
- action := &config.Action{
- Title: "Run playbook",
- ID: "run_playbook",
- Justification: "{{ ansible_host }}",
- Shell: "echo done",
- Arguments: []config.ActionArgument{
- {Name: "ansible_host", Title: "Host"},
- },
- }
- cfg.Actions = append(cfg.Actions, action)
- ex := executor.DefaultExecutor(cfg)
- ex.RebuildActionMap()
- binding := ex.FindBindingWithNoEntity(action)
- require.NotNil(t, binding)
- ts, client := getNewTestServerAndClientWithExecutor(cfg, ex)
- defer ts.Close()
- resp, err := client.StartAction(context.Background(), connect.NewRequest(&apiv1.StartActionRequest{
- BindingId: binding.ID,
- UniqueTrackingId: uuid.NewString(),
- Arguments: []*apiv1.StartActionArgument{
- {Name: "ansible_host", Value: "stuffbox"},
- },
- }))
- require.NoError(t, err)
- require.NotEmpty(t, resp.Msg.ExecutionTrackingId)
- waitForLogJustification(t, ex, resp.Msg.ExecutionTrackingId, "stuffbox")
- }
- func TestValidateJustificationRequiredAllowsSystemUser(t *testing.T) {
- cfg := config.DefaultConfig()
- action := &config.Action{Title: "Cron job", Justification: config.JustificationRequiredNoTemplate}
- err := validateJustificationRequired(action, "", auth.UserFromSystem(cfg, "cron"))
- require.NoError(t, err)
- }
|