mirror of
https://github.com/zitadel/zitadel.git
synced 2025-07-17 23:08:36 +00:00

# Which Problems Are Solved Actions v2 is not a feature flag anymore, include functionality on executions is not used and json tags of proto messages are handled incorrectly. # How the Problems Are Solved - Remove actions from the feature flags on system and instance level - Remove include type on executions, only in the API, later maybe in the handling logic as well - Use protojson in request and response handling of actions v2 # Additional Changes - Correct integration tests for request and response handling - Use json.RawMessage for events, so that the event payload is not base64 encoded - Added separate context for async webhook calls, that executions are not cancelled when called async # Additional Context Related to #9759 Closes #9710 --------- Co-authored-by: Livio Spring <livio.a@gmail.com>
794 lines
27 KiB
Go
794 lines
27 KiB
Go
//go:build integration
|
|
|
|
package action_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/brianvoe/gofakeit/v6"
|
|
"github.com/muhlemmer/gu"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"google.golang.org/protobuf/types/known/durationpb"
|
|
|
|
"github.com/zitadel/zitadel/internal/domain"
|
|
"github.com/zitadel/zitadel/internal/integration"
|
|
action "github.com/zitadel/zitadel/pkg/grpc/action/v2beta"
|
|
filter "github.com/zitadel/zitadel/pkg/grpc/filter/v2beta"
|
|
)
|
|
|
|
func TestServer_GetTarget(t *testing.T) {
|
|
instance := integration.NewInstance(CTX)
|
|
isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner)
|
|
type args struct {
|
|
ctx context.Context
|
|
dep func(context.Context, *action.GetTargetRequest, *action.GetTargetResponse) error
|
|
req *action.GetTargetRequest
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want *action.GetTargetResponse
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "missing permission",
|
|
args: args{
|
|
ctx: instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner),
|
|
req: &action.GetTargetRequest{},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "not found",
|
|
args: args{
|
|
ctx: isolatedIAMOwnerCTX,
|
|
req: &action.GetTargetRequest{Id: "notexisting"},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "get, ok",
|
|
args: args{
|
|
ctx: isolatedIAMOwnerCTX,
|
|
dep: func(ctx context.Context, request *action.GetTargetRequest, response *action.GetTargetResponse) error {
|
|
name := gofakeit.Name()
|
|
resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeWebhook, false)
|
|
request.Id = resp.GetId()
|
|
response.Target.Id = resp.GetId()
|
|
response.Target.Name = name
|
|
response.Target.CreationDate = resp.GetCreationDate()
|
|
response.Target.ChangeDate = resp.GetCreationDate()
|
|
response.Target.SigningKey = resp.GetSigningKey()
|
|
return nil
|
|
},
|
|
req: &action.GetTargetRequest{},
|
|
},
|
|
want: &action.GetTargetResponse{
|
|
Target: &action.Target{
|
|
Endpoint: "https://example.com",
|
|
TargetType: &action.Target_RestWebhook{
|
|
RestWebhook: &action.RESTWebhook{},
|
|
},
|
|
Timeout: durationpb.New(5 * time.Second),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "get, async, ok",
|
|
args: args{
|
|
ctx: isolatedIAMOwnerCTX,
|
|
dep: func(ctx context.Context, request *action.GetTargetRequest, response *action.GetTargetResponse) error {
|
|
name := gofakeit.Name()
|
|
resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeAsync, false)
|
|
request.Id = resp.GetId()
|
|
response.Target.Id = resp.GetId()
|
|
response.Target.Name = name
|
|
response.Target.CreationDate = resp.GetCreationDate()
|
|
response.Target.ChangeDate = resp.GetCreationDate()
|
|
response.Target.SigningKey = resp.GetSigningKey()
|
|
return nil
|
|
},
|
|
req: &action.GetTargetRequest{},
|
|
},
|
|
want: &action.GetTargetResponse{
|
|
Target: &action.Target{
|
|
Endpoint: "https://example.com",
|
|
TargetType: &action.Target_RestAsync{
|
|
RestAsync: &action.RESTAsync{},
|
|
},
|
|
Timeout: durationpb.New(5 * time.Second),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "get, webhook interruptOnError, ok",
|
|
args: args{
|
|
ctx: isolatedIAMOwnerCTX,
|
|
dep: func(ctx context.Context, request *action.GetTargetRequest, response *action.GetTargetResponse) error {
|
|
name := gofakeit.Name()
|
|
resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeWebhook, true)
|
|
request.Id = resp.GetId()
|
|
response.Target.Id = resp.GetId()
|
|
response.Target.Name = name
|
|
response.Target.CreationDate = resp.GetCreationDate()
|
|
response.Target.ChangeDate = resp.GetCreationDate()
|
|
response.Target.SigningKey = resp.GetSigningKey()
|
|
return nil
|
|
},
|
|
req: &action.GetTargetRequest{},
|
|
},
|
|
want: &action.GetTargetResponse{
|
|
Target: &action.Target{
|
|
Endpoint: "https://example.com",
|
|
TargetType: &action.Target_RestWebhook{
|
|
RestWebhook: &action.RESTWebhook{
|
|
InterruptOnError: true,
|
|
},
|
|
},
|
|
Timeout: durationpb.New(5 * time.Second),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "get, call, ok",
|
|
args: args{
|
|
ctx: isolatedIAMOwnerCTX,
|
|
dep: func(ctx context.Context, request *action.GetTargetRequest, response *action.GetTargetResponse) error {
|
|
name := gofakeit.Name()
|
|
resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeCall, false)
|
|
request.Id = resp.GetId()
|
|
response.Target.Id = resp.GetId()
|
|
response.Target.Name = name
|
|
response.Target.CreationDate = resp.GetCreationDate()
|
|
response.Target.ChangeDate = resp.GetCreationDate()
|
|
response.Target.SigningKey = resp.GetSigningKey()
|
|
return nil
|
|
},
|
|
req: &action.GetTargetRequest{},
|
|
},
|
|
want: &action.GetTargetResponse{
|
|
Target: &action.Target{
|
|
Endpoint: "https://example.com",
|
|
TargetType: &action.Target_RestCall{
|
|
RestCall: &action.RESTCall{
|
|
InterruptOnError: false,
|
|
},
|
|
},
|
|
Timeout: durationpb.New(5 * time.Second),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "get, call interruptOnError, ok",
|
|
args: args{
|
|
ctx: isolatedIAMOwnerCTX,
|
|
dep: func(ctx context.Context, request *action.GetTargetRequest, response *action.GetTargetResponse) error {
|
|
name := gofakeit.Name()
|
|
resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeCall, true)
|
|
request.Id = resp.GetId()
|
|
response.Target.Id = resp.GetId()
|
|
response.Target.Name = name
|
|
response.Target.CreationDate = resp.GetCreationDate()
|
|
response.Target.ChangeDate = resp.GetCreationDate()
|
|
response.Target.SigningKey = resp.GetSigningKey()
|
|
return nil
|
|
},
|
|
req: &action.GetTargetRequest{},
|
|
},
|
|
want: &action.GetTargetResponse{
|
|
Target: &action.Target{
|
|
Endpoint: "https://example.com",
|
|
TargetType: &action.Target_RestCall{
|
|
RestCall: &action.RESTCall{
|
|
InterruptOnError: true,
|
|
},
|
|
},
|
|
Timeout: durationpb.New(5 * time.Second),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.args.dep != nil {
|
|
err := tt.args.dep(tt.args.ctx, tt.args.req, tt.want)
|
|
require.NoError(t, err)
|
|
}
|
|
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(isolatedIAMOwnerCTX, 2*time.Minute)
|
|
require.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
|
got, err := instance.Client.ActionV2beta.GetTarget(tt.args.ctx, tt.args.req)
|
|
if tt.wantErr {
|
|
assert.Error(ttt, err, "Error: "+err.Error())
|
|
return
|
|
}
|
|
assert.NoError(ttt, err)
|
|
assert.EqualExportedValues(ttt, tt.want, got)
|
|
}, retryDuration, tick, "timeout waiting for expected target result")
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestServer_ListTargets(t *testing.T) {
|
|
instance := integration.NewInstance(CTX)
|
|
isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner)
|
|
type args struct {
|
|
ctx context.Context
|
|
dep func(context.Context, *action.ListTargetsRequest, *action.ListTargetsResponse)
|
|
req *action.ListTargetsRequest
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want *action.ListTargetsResponse
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "missing permission",
|
|
args: args{
|
|
ctx: instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner),
|
|
req: &action.ListTargetsRequest{},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "list, not found",
|
|
args: args{
|
|
ctx: isolatedIAMOwnerCTX,
|
|
req: &action.ListTargetsRequest{
|
|
Filters: []*action.TargetSearchFilter{
|
|
{Filter: &action.TargetSearchFilter_InTargetIdsFilter{
|
|
InTargetIdsFilter: &action.InTargetIDsFilter{
|
|
TargetIds: []string{"notfound"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: &action.ListTargetsResponse{
|
|
Pagination: &filter.PaginationResponse{
|
|
TotalResult: 0,
|
|
AppliedLimit: 100,
|
|
},
|
|
Result: []*action.Target{},
|
|
},
|
|
},
|
|
{
|
|
name: "list single id",
|
|
args: args{
|
|
ctx: isolatedIAMOwnerCTX,
|
|
dep: func(ctx context.Context, request *action.ListTargetsRequest, response *action.ListTargetsResponse) {
|
|
name := gofakeit.Name()
|
|
resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeWebhook, false)
|
|
request.Filters[0].Filter = &action.TargetSearchFilter_InTargetIdsFilter{
|
|
InTargetIdsFilter: &action.InTargetIDsFilter{
|
|
TargetIds: []string{resp.GetId()},
|
|
},
|
|
}
|
|
|
|
response.Result[0].Id = resp.GetId()
|
|
response.Result[0].Name = name
|
|
response.Result[0].CreationDate = resp.GetCreationDate()
|
|
response.Result[0].ChangeDate = resp.GetCreationDate()
|
|
response.Result[0].SigningKey = resp.GetSigningKey()
|
|
},
|
|
req: &action.ListTargetsRequest{
|
|
Filters: []*action.TargetSearchFilter{{}},
|
|
},
|
|
},
|
|
want: &action.ListTargetsResponse{
|
|
Pagination: &filter.PaginationResponse{
|
|
TotalResult: 1,
|
|
AppliedLimit: 100,
|
|
},
|
|
Result: []*action.Target{
|
|
{
|
|
Endpoint: "https://example.com",
|
|
TargetType: &action.Target_RestWebhook{
|
|
RestWebhook: &action.RESTWebhook{
|
|
InterruptOnError: false,
|
|
},
|
|
},
|
|
Timeout: durationpb.New(5 * time.Second),
|
|
},
|
|
},
|
|
},
|
|
}, {
|
|
name: "list single name",
|
|
args: args{
|
|
ctx: isolatedIAMOwnerCTX,
|
|
dep: func(ctx context.Context, request *action.ListTargetsRequest, response *action.ListTargetsResponse) {
|
|
name := gofakeit.Name()
|
|
resp := instance.CreateTarget(ctx, t, name, "https://example.com", domain.TargetTypeWebhook, false)
|
|
request.Filters[0].Filter = &action.TargetSearchFilter_TargetNameFilter{
|
|
TargetNameFilter: &action.TargetNameFilter{
|
|
TargetName: name,
|
|
},
|
|
}
|
|
|
|
response.Result[0].Id = resp.GetId()
|
|
response.Result[0].Name = name
|
|
response.Result[0].CreationDate = resp.GetCreationDate()
|
|
response.Result[0].ChangeDate = resp.GetCreationDate()
|
|
response.Result[0].SigningKey = resp.GetSigningKey()
|
|
},
|
|
req: &action.ListTargetsRequest{
|
|
Filters: []*action.TargetSearchFilter{{}},
|
|
},
|
|
},
|
|
want: &action.ListTargetsResponse{
|
|
Pagination: &filter.PaginationResponse{
|
|
TotalResult: 1,
|
|
AppliedLimit: 100,
|
|
},
|
|
Result: []*action.Target{
|
|
{
|
|
Endpoint: "https://example.com",
|
|
TargetType: &action.Target_RestWebhook{
|
|
RestWebhook: &action.RESTWebhook{
|
|
InterruptOnError: false,
|
|
},
|
|
},
|
|
Timeout: durationpb.New(5 * time.Second),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "list multiple id",
|
|
args: args{
|
|
ctx: isolatedIAMOwnerCTX,
|
|
dep: func(ctx context.Context, request *action.ListTargetsRequest, response *action.ListTargetsResponse) {
|
|
name1 := gofakeit.Name()
|
|
name2 := gofakeit.Name()
|
|
name3 := gofakeit.Name()
|
|
resp1 := instance.CreateTarget(ctx, t, name1, "https://example.com", domain.TargetTypeWebhook, false)
|
|
resp2 := instance.CreateTarget(ctx, t, name2, "https://example.com", domain.TargetTypeCall, true)
|
|
resp3 := instance.CreateTarget(ctx, t, name3, "https://example.com", domain.TargetTypeAsync, false)
|
|
request.Filters[0].Filter = &action.TargetSearchFilter_InTargetIdsFilter{
|
|
InTargetIdsFilter: &action.InTargetIDsFilter{
|
|
TargetIds: []string{resp1.GetId(), resp2.GetId(), resp3.GetId()},
|
|
},
|
|
}
|
|
|
|
response.Result[2].Id = resp1.GetId()
|
|
response.Result[2].Name = name1
|
|
response.Result[2].CreationDate = resp1.GetCreationDate()
|
|
response.Result[2].ChangeDate = resp1.GetCreationDate()
|
|
response.Result[2].SigningKey = resp1.GetSigningKey()
|
|
|
|
response.Result[1].Id = resp2.GetId()
|
|
response.Result[1].Name = name2
|
|
response.Result[1].CreationDate = resp2.GetCreationDate()
|
|
response.Result[1].ChangeDate = resp2.GetCreationDate()
|
|
response.Result[1].SigningKey = resp2.GetSigningKey()
|
|
|
|
response.Result[0].Id = resp3.GetId()
|
|
response.Result[0].Name = name3
|
|
response.Result[0].CreationDate = resp3.GetCreationDate()
|
|
response.Result[0].ChangeDate = resp3.GetCreationDate()
|
|
response.Result[0].SigningKey = resp3.GetSigningKey()
|
|
},
|
|
req: &action.ListTargetsRequest{
|
|
Filters: []*action.TargetSearchFilter{{}},
|
|
},
|
|
},
|
|
want: &action.ListTargetsResponse{
|
|
Pagination: &filter.PaginationResponse{
|
|
TotalResult: 3,
|
|
AppliedLimit: 100,
|
|
},
|
|
Result: []*action.Target{
|
|
{
|
|
Endpoint: "https://example.com",
|
|
TargetType: &action.Target_RestAsync{
|
|
RestAsync: &action.RESTAsync{},
|
|
},
|
|
Timeout: durationpb.New(5 * time.Second),
|
|
},
|
|
{
|
|
Endpoint: "https://example.com",
|
|
TargetType: &action.Target_RestCall{
|
|
RestCall: &action.RESTCall{
|
|
InterruptOnError: true,
|
|
},
|
|
},
|
|
Timeout: durationpb.New(5 * time.Second),
|
|
},
|
|
{
|
|
Endpoint: "https://example.com",
|
|
TargetType: &action.Target_RestWebhook{
|
|
RestWebhook: &action.RESTWebhook{
|
|
InterruptOnError: false,
|
|
},
|
|
},
|
|
Timeout: durationpb.New(5 * time.Second),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.args.dep != nil {
|
|
tt.args.dep(tt.args.ctx, tt.args.req, tt.want)
|
|
}
|
|
|
|
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(isolatedIAMOwnerCTX, time.Minute)
|
|
require.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
|
got, listErr := instance.Client.ActionV2beta.ListTargets(tt.args.ctx, tt.args.req)
|
|
if tt.wantErr {
|
|
require.Error(ttt, listErr, "Error: "+listErr.Error())
|
|
return
|
|
}
|
|
require.NoError(ttt, listErr)
|
|
|
|
// always first check length, otherwise its failed anyway
|
|
if assert.Len(ttt, got.Result, len(tt.want.Result)) {
|
|
for i := range tt.want.Result {
|
|
assert.EqualExportedValues(ttt, tt.want.Result[i], got.Result[i])
|
|
}
|
|
}
|
|
assertPaginationResponse(ttt, tt.want.Pagination, got.Pagination)
|
|
}, retryDuration, tick, "timeout waiting for expected execution result")
|
|
})
|
|
}
|
|
}
|
|
|
|
func assertPaginationResponse(t *assert.CollectT, expected *filter.PaginationResponse, actual *filter.PaginationResponse) {
|
|
assert.Equal(t, expected.AppliedLimit, actual.AppliedLimit)
|
|
assert.Equal(t, expected.TotalResult, actual.TotalResult)
|
|
}
|
|
|
|
func TestServer_ListExecutions(t *testing.T) {
|
|
instance := integration.NewInstance(CTX)
|
|
isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner)
|
|
targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false)
|
|
|
|
type args struct {
|
|
ctx context.Context
|
|
dep func(context.Context, *action.ListExecutionsRequest, *action.ListExecutionsResponse)
|
|
req *action.ListExecutionsRequest
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want *action.ListExecutionsResponse
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "missing permission",
|
|
args: args{
|
|
ctx: instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner),
|
|
req: &action.ListExecutionsRequest{},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "list request single condition",
|
|
args: args{
|
|
ctx: isolatedIAMOwnerCTX,
|
|
dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) {
|
|
cond := request.Filters[0].GetInConditionsFilter().GetConditions()[0]
|
|
resp := instance.SetExecution(ctx, t, cond, []string{targetResp.GetId()})
|
|
|
|
// Set expected response with used values for SetExecution
|
|
response.Result[0].CreationDate = resp.GetSetDate()
|
|
response.Result[0].ChangeDate = resp.GetSetDate()
|
|
response.Result[0].Condition = cond
|
|
},
|
|
req: &action.ListExecutionsRequest{
|
|
Filters: []*action.ExecutionSearchFilter{{
|
|
Filter: &action.ExecutionSearchFilter_InConditionsFilter{
|
|
InConditionsFilter: &action.InConditionsFilter{
|
|
Conditions: []*action.Condition{{
|
|
ConditionType: &action.Condition_Request{
|
|
Request: &action.RequestExecution{
|
|
Condition: &action.RequestExecution_Method{
|
|
Method: "/zitadel.session.v2.SessionService/GetSession",
|
|
},
|
|
},
|
|
},
|
|
}},
|
|
},
|
|
},
|
|
}},
|
|
},
|
|
},
|
|
want: &action.ListExecutionsResponse{
|
|
Pagination: &filter.PaginationResponse{
|
|
TotalResult: 1,
|
|
AppliedLimit: 100,
|
|
},
|
|
Result: []*action.Execution{
|
|
{
|
|
Condition: &action.Condition{
|
|
ConditionType: &action.Condition_Request{
|
|
Request: &action.RequestExecution{
|
|
Condition: &action.RequestExecution_Method{
|
|
Method: "/zitadel.session.v2.SessionService/GetSession",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Targets: []string{targetResp.GetId()},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "list request single target",
|
|
args: args{
|
|
ctx: isolatedIAMOwnerCTX,
|
|
dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) {
|
|
target := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false)
|
|
// add target as Filter to the request
|
|
request.Filters[0] = &action.ExecutionSearchFilter{
|
|
Filter: &action.ExecutionSearchFilter_TargetFilter{
|
|
TargetFilter: &action.TargetFilter{
|
|
TargetId: target.GetId(),
|
|
},
|
|
},
|
|
}
|
|
cond := &action.Condition{
|
|
ConditionType: &action.Condition_Request{
|
|
Request: &action.RequestExecution{
|
|
Condition: &action.RequestExecution_Method{
|
|
Method: "/zitadel.management.v1.ManagementService/UpdateAction",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
resp := instance.SetExecution(ctx, t, cond, []string{target.GetId()})
|
|
|
|
response.Result[0].CreationDate = resp.GetSetDate()
|
|
response.Result[0].ChangeDate = resp.GetSetDate()
|
|
response.Result[0].Condition = cond
|
|
response.Result[0].Targets = []string{target.GetId()}
|
|
},
|
|
req: &action.ListExecutionsRequest{
|
|
Filters: []*action.ExecutionSearchFilter{{}},
|
|
},
|
|
},
|
|
want: &action.ListExecutionsResponse{
|
|
Pagination: &filter.PaginationResponse{
|
|
TotalResult: 1,
|
|
AppliedLimit: 100,
|
|
},
|
|
Result: []*action.Execution{
|
|
{
|
|
Condition: &action.Condition{},
|
|
Targets: []string{""},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "list multiple conditions",
|
|
args: args{
|
|
ctx: isolatedIAMOwnerCTX,
|
|
dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) {
|
|
|
|
request.Filters[0] = &action.ExecutionSearchFilter{
|
|
Filter: &action.ExecutionSearchFilter_InConditionsFilter{
|
|
InConditionsFilter: &action.InConditionsFilter{
|
|
Conditions: []*action.Condition{
|
|
{ConditionType: &action.Condition_Request{
|
|
Request: &action.RequestExecution{
|
|
Condition: &action.RequestExecution_Method{
|
|
Method: "/zitadel.session.v2.SessionService/GetSession",
|
|
},
|
|
},
|
|
}},
|
|
{ConditionType: &action.Condition_Request{
|
|
Request: &action.RequestExecution{
|
|
Condition: &action.RequestExecution_Method{
|
|
Method: "/zitadel.session.v2.SessionService/CreateSession",
|
|
},
|
|
},
|
|
}},
|
|
{ConditionType: &action.Condition_Request{
|
|
Request: &action.RequestExecution{
|
|
Condition: &action.RequestExecution_Method{
|
|
Method: "/zitadel.session.v2.SessionService/SetSession",
|
|
},
|
|
},
|
|
}},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
cond1 := request.Filters[0].GetInConditionsFilter().GetConditions()[0]
|
|
resp1 := instance.SetExecution(ctx, t, cond1, []string{targetResp.GetId()})
|
|
response.Result[2] = &action.Execution{
|
|
CreationDate: resp1.GetSetDate(),
|
|
ChangeDate: resp1.GetSetDate(),
|
|
Condition: cond1,
|
|
Targets: []string{targetResp.GetId()},
|
|
}
|
|
|
|
cond2 := request.Filters[0].GetInConditionsFilter().GetConditions()[1]
|
|
resp2 := instance.SetExecution(ctx, t, cond2, []string{targetResp.GetId()})
|
|
response.Result[1] = &action.Execution{
|
|
CreationDate: resp2.GetSetDate(),
|
|
ChangeDate: resp2.GetSetDate(),
|
|
Condition: cond2,
|
|
Targets: []string{targetResp.GetId()},
|
|
}
|
|
|
|
cond3 := request.Filters[0].GetInConditionsFilter().GetConditions()[2]
|
|
resp3 := instance.SetExecution(ctx, t, cond3, []string{targetResp.GetId()})
|
|
response.Result[0] = &action.Execution{
|
|
CreationDate: resp3.GetSetDate(),
|
|
ChangeDate: resp3.GetSetDate(),
|
|
Condition: cond3,
|
|
Targets: []string{targetResp.GetId()},
|
|
}
|
|
},
|
|
req: &action.ListExecutionsRequest{
|
|
Filters: []*action.ExecutionSearchFilter{
|
|
{},
|
|
},
|
|
},
|
|
},
|
|
want: &action.ListExecutionsResponse{
|
|
Pagination: &filter.PaginationResponse{
|
|
TotalResult: 3,
|
|
AppliedLimit: 100,
|
|
},
|
|
Result: []*action.Execution{
|
|
{}, {}, {},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "list multiple conditions all types",
|
|
args: args{
|
|
ctx: isolatedIAMOwnerCTX,
|
|
dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) {
|
|
conditions := request.Filters[0].GetInConditionsFilter().GetConditions()
|
|
for i, cond := range conditions {
|
|
resp := instance.SetExecution(ctx, t, cond, []string{targetResp.GetId()})
|
|
response.Result[(len(conditions)-1)-i] = &action.Execution{
|
|
CreationDate: resp.GetSetDate(),
|
|
ChangeDate: resp.GetSetDate(),
|
|
Condition: cond,
|
|
Targets: []string{targetResp.GetId()},
|
|
}
|
|
}
|
|
},
|
|
req: &action.ListExecutionsRequest{
|
|
Filters: []*action.ExecutionSearchFilter{{
|
|
Filter: &action.ExecutionSearchFilter_InConditionsFilter{
|
|
InConditionsFilter: &action.InConditionsFilter{
|
|
Conditions: []*action.Condition{
|
|
{ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_Method{Method: "/zitadel.session.v2.SessionService/GetSession"}}}},
|
|
{ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_Service{Service: "zitadel.session.v2.SessionService"}}}},
|
|
{ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_All{All: true}}}},
|
|
{ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_Method{Method: "/zitadel.session.v2.SessionService/GetSession"}}}},
|
|
{ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_Service{Service: "zitadel.session.v2.SessionService"}}}},
|
|
{ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_All{All: true}}}},
|
|
{ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_Event{Event: "user.added"}}}},
|
|
{ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_Group{Group: "user"}}}},
|
|
{ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_All{All: true}}}},
|
|
{ConditionType: &action.Condition_Function{Function: &action.FunctionExecution{Name: "presamlresponse"}}},
|
|
},
|
|
},
|
|
},
|
|
}},
|
|
},
|
|
},
|
|
want: &action.ListExecutionsResponse{
|
|
Pagination: &filter.PaginationResponse{
|
|
TotalResult: 10,
|
|
AppliedLimit: 100,
|
|
},
|
|
Result: []*action.Execution{
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "list multiple conditions all types, sort id",
|
|
args: args{
|
|
ctx: isolatedIAMOwnerCTX,
|
|
dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) {
|
|
conditions := request.Filters[0].GetInConditionsFilter().GetConditions()
|
|
for i, cond := range conditions {
|
|
resp := instance.SetExecution(ctx, t, cond, []string{targetResp.GetId()})
|
|
response.Result[i] = &action.Execution{
|
|
CreationDate: resp.GetSetDate(),
|
|
ChangeDate: resp.GetSetDate(),
|
|
Condition: cond,
|
|
Targets: []string{targetResp.GetId()},
|
|
}
|
|
}
|
|
},
|
|
req: &action.ListExecutionsRequest{
|
|
SortingColumn: gu.Ptr(action.ExecutionFieldName_EXECUTION_FIELD_NAME_ID),
|
|
Filters: []*action.ExecutionSearchFilter{{
|
|
Filter: &action.ExecutionSearchFilter_InConditionsFilter{
|
|
InConditionsFilter: &action.InConditionsFilter{
|
|
Conditions: []*action.Condition{
|
|
{ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_Method{Method: "/zitadel.session.v2.SessionService/GetSession"}}}},
|
|
{ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_Service{Service: "zitadel.session.v2.SessionService"}}}},
|
|
{ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_All{All: true}}}},
|
|
{ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_Method{Method: "/zitadel.session.v2.SessionService/GetSession"}}}},
|
|
{ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_Service{Service: "zitadel.session.v2.SessionService"}}}},
|
|
{ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_All{All: true}}}},
|
|
{ConditionType: &action.Condition_Function{Function: &action.FunctionExecution{Name: "presamlresponse"}}},
|
|
{ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_Event{Event: "user.added"}}}},
|
|
{ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_Group{Group: "user"}}}},
|
|
{ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_All{All: true}}}},
|
|
},
|
|
},
|
|
},
|
|
}},
|
|
},
|
|
},
|
|
want: &action.ListExecutionsResponse{
|
|
Pagination: &filter.PaginationResponse{
|
|
TotalResult: 10,
|
|
AppliedLimit: 100,
|
|
},
|
|
Result: []*action.Execution{
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.args.dep != nil {
|
|
tt.args.dep(tt.args.ctx, tt.args.req, tt.want)
|
|
}
|
|
|
|
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(isolatedIAMOwnerCTX, time.Minute)
|
|
require.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
|
got, listErr := instance.Client.ActionV2beta.ListExecutions(tt.args.ctx, tt.args.req)
|
|
if tt.wantErr {
|
|
require.Error(ttt, listErr, "Error: "+listErr.Error())
|
|
return
|
|
}
|
|
require.NoError(ttt, listErr)
|
|
// always first check length, otherwise its failed anyway
|
|
if assert.Len(ttt, got.Result, len(tt.want.Result)) {
|
|
assert.EqualExportedValues(ttt, got.Result, tt.want.Result)
|
|
}
|
|
assertPaginationResponse(ttt, tt.want.Pagination, got.Pagination)
|
|
}, retryDuration, tick, "timeout waiting for expected execution result")
|
|
})
|
|
}
|
|
}
|
|
|
|
func containExecution(t *assert.CollectT, executionList []*action.Execution, execution *action.Execution) bool {
|
|
for _, exec := range executionList {
|
|
if assert.EqualExportedValues(t, execution, exec) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|