From 6dcdef026891620ec148134033faf6890b23d712 Mon Sep 17 00:00:00 2001 From: Stefan Benz <46600784+stebenz@users.noreply.github.com> Date: Tue, 9 Apr 2024 19:21:21 +0200 Subject: [PATCH] fix: add action v2 execution to features (#7597) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: add action v2 execution to features * fix: add action v2 execution to features * fix: add action v2 execution to features * fix: update internal/command/instance_features_model.go Co-authored-by: Tim Möhlmann * fix: merge back main * fix: merge back main * fix: rename feature and service * fix: rename feature and service * fix: review changes * fix: review changes --------- Co-authored-by: Tim Möhlmann --- cmd/start/start.go | 4 +- docs/docusaurus.config.js | 6 +- docs/sidebars.js | 10 +- .../v3alpha/execution.go | 48 +- .../v3alpha/execution_integration_test.go | 642 +++++++++--------- .../{execution => action}/v3alpha/query.go | 126 ++-- .../v3alpha/query_integration_test.go | 261 +++---- .../{execution => action}/v3alpha/server.go | 28 +- .../action/v3alpha/server_integration_test.go | 69 ++ .../{execution => action}/v3alpha/target.go | 40 +- .../v3alpha/target_integration_test.go | 129 ++-- .../v3alpha/target_test.go | 44 +- .../v3alpha/server_integration_test.go | 33 - internal/api/grpc/feature/v2/converter.go | 4 + .../api/grpc/feature/v2/converter_test.go | 20 + .../feature/v2/feature_integration_test.go | 14 + .../session/v2/session_integration_test.go | 21 + .../schema/v3alpha/schema_integration_test.go | 15 +- .../repository/mock/repository.mock.go | 1 + internal/command/instance_features.go | 4 +- internal/command/instance_features_model.go | 5 + internal/command/instance_features_test.go | 23 + internal/command/system_features.go | 4 +- internal/command/system_features_model.go | 5 + internal/command/system_features_test.go | 28 + internal/domain/feature.go | 2 - .../repository/mock/repository.mock.go | 1 + internal/feature/feature.go | 2 + internal/feature/key_enumer.go | 36 +- internal/id/mock/generator.mock.go | 1 + internal/integration/client.go | 34 +- .../channels/mock/channel.mock.go | 1 + .../channels/mock/message.mock.go | 1 + .../handlers/mock/commands.mock.go | 1 + .../handlers/mock/queries.mock.go | 1 + internal/query/instance_features.go | 1 + internal/query/instance_features_model.go | 5 + internal/query/instance_features_test.go | 24 + .../query/projection/instance_features.go | 4 + internal/query/projection/system_features.go | 4 + internal/query/system_features.go | 1 + internal/query/system_features_model.go | 3 + internal/query/system_features_test.go | 24 + .../feature/feature_v2/eventstore.go | 2 + .../repository/feature/feature_v2/feature.go | 2 + internal/static/mock/storage_mock.go | 1 + .../v3alpha/action_service.proto} | 28 +- .../v3alpha/execution.proto | 4 +- .../{execution => action}/v3alpha/query.proto | 6 +- .../v3alpha/target.proto | 4 +- proto/zitadel/feature/v2beta/instance.proto | 13 + proto/zitadel/feature/v2beta/system.proto | 16 +- 52 files changed, 1069 insertions(+), 737 deletions(-) rename internal/api/grpc/{execution => action}/v3alpha/execution.go (67%) rename internal/api/grpc/{execution => action}/v3alpha/execution_integration_test.go (54%) rename internal/api/grpc/{execution => action}/v3alpha/query.go (60%) rename internal/api/grpc/{execution => action}/v3alpha/query_integration_test.go (69%) rename internal/api/grpc/{execution => action}/v3alpha/server.go (62%) create mode 100644 internal/api/grpc/action/v3alpha/server_integration_test.go rename internal/api/grpc/{execution => action}/v3alpha/target.go (64%) rename internal/api/grpc/{execution => action}/v3alpha/target_integration_test.go (68%) rename internal/api/grpc/{execution => action}/v3alpha/target_test.go (77%) delete mode 100644 internal/api/grpc/execution/v3alpha/server_integration_test.go rename proto/zitadel/{execution/v3alpha/execution_service.proto => action/v3alpha/action_service.proto} (95%) rename proto/zitadel/{execution => action}/v3alpha/execution.proto (97%) rename proto/zitadel/{execution => action}/v3alpha/query.proto (94%) rename proto/zitadel/{execution => action}/v3alpha/target.proto (94%) diff --git a/cmd/start/start.go b/cmd/start/start.go index 97f5d6a07..49de4d207 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -34,9 +34,9 @@ import ( "github.com/zitadel/zitadel/internal/api" "github.com/zitadel/zitadel/internal/api/assets" internal_authz "github.com/zitadel/zitadel/internal/api/authz" + action_v3_alpha "github.com/zitadel/zitadel/internal/api/grpc/action/v3alpha" "github.com/zitadel/zitadel/internal/api/grpc/admin" "github.com/zitadel/zitadel/internal/api/grpc/auth" - execution_v3_alpha "github.com/zitadel/zitadel/internal/api/grpc/execution/v3alpha" "github.com/zitadel/zitadel/internal/api/grpc/feature/v2" "github.com/zitadel/zitadel/internal/api/grpc/management" oidc_v2 "github.com/zitadel/zitadel/internal/api/grpc/oidc/v2" @@ -408,7 +408,7 @@ func startAPIs( if err := apis.RegisterService(ctx, feature.CreateServer(commands, queries)); err != nil { return nil, err } - if err := apis.RegisterService(ctx, execution_v3_alpha.CreateServer(commands, queries, domain.AllFunctions, apis.ListGrpcMethods, apis.ListGrpcServices)); err != nil { + if err := apis.RegisterService(ctx, action_v3_alpha.CreateServer(commands, queries, domain.AllFunctions, apis.ListGrpcMethods, apis.ListGrpcServices)); err != nil { return nil, err } if err := apis.RegisterService(ctx, user_schema_v3_alpha.CreateServer(commands, queries)); err != nil { diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 93f557792..9ccd4ae0f 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -310,9 +310,9 @@ module.exports = { groupPathsBy: "tag", }, }, - execution_v3: { - specPath: ".artifacts/openapi/zitadel/execution/v3alpha/execution_service.swagger.json", - outputDir: "docs/apis/resources/execution_service_v3", + action_v3: { + specPath: ".artifacts/openapi/zitadel/action/v3alpha/action_service.swagger.json", + outputDir: "docs/apis/resources/action_service_v3", sidebarOptions: { groupPathsBy: "tag", }, diff --git a/docs/sidebars.js b/docs/sidebars.js index 8b001971e..ddb73badd 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -732,17 +732,17 @@ module.exports = { }, { type: "category", - label: "Execution Lifecycle (Preview)", + label: "Action Lifecycle (Preview)", link: { type: "generated-index", - title: "Execution Service API (Preview)", - slug: "/apis/resources/execution_service_v3", + title: "Action Service API (Preview)", + slug: "/apis/resources/action_service_v3", description: - "This API is intended to manage custom executions (previously known as actions) in a ZITADEL instance.\n" + + "This API is intended to manage custom executions and targets (previously known as actions) in a ZITADEL instance.\n" + "\n" + "This project is in Preview state. It can AND will continue breaking until the services provide the same functionality as the current actions.", }, - items: require("./docs/apis/resources/execution_service_v3/sidebar.js"), + items: require("./docs/apis/resources/action_service_v3/sidebar.js"), }, ], }, diff --git a/internal/api/grpc/execution/v3alpha/execution.go b/internal/api/grpc/action/v3alpha/execution.go similarity index 67% rename from internal/api/grpc/execution/v3alpha/execution.go rename to internal/api/grpc/action/v3alpha/execution.go index 5aff2e109..dde4727c2 100644 --- a/internal/api/grpc/execution/v3alpha/execution.go +++ b/internal/api/grpc/action/v3alpha/execution.go @@ -1,4 +1,4 @@ -package execution +package action import ( "context" @@ -7,28 +7,32 @@ import ( "github.com/zitadel/zitadel/internal/api/grpc/object/v2" "github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/domain" - execution "github.com/zitadel/zitadel/pkg/grpc/execution/v3alpha" + action "github.com/zitadel/zitadel/pkg/grpc/action/v3alpha" ) -func (s *Server) ListExecutionFunctions(_ context.Context, _ *execution.ListExecutionFunctionsRequest) (*execution.ListExecutionFunctionsResponse, error) { - return &execution.ListExecutionFunctionsResponse{ +func (s *Server) ListExecutionFunctions(_ context.Context, _ *action.ListExecutionFunctionsRequest) (*action.ListExecutionFunctionsResponse, error) { + return &action.ListExecutionFunctionsResponse{ Functions: s.ListActionFunctions(), }, nil } -func (s *Server) ListExecutionMethods(_ context.Context, _ *execution.ListExecutionMethodsRequest) (*execution.ListExecutionMethodsResponse, error) { - return &execution.ListExecutionMethodsResponse{ +func (s *Server) ListExecutionMethods(_ context.Context, _ *action.ListExecutionMethodsRequest) (*action.ListExecutionMethodsResponse, error) { + return &action.ListExecutionMethodsResponse{ Methods: s.ListGRPCMethods(), }, nil } -func (s *Server) ListExecutionServices(_ context.Context, _ *execution.ListExecutionServicesRequest) (*execution.ListExecutionServicesResponse, error) { - return &execution.ListExecutionServicesResponse{ +func (s *Server) ListExecutionServices(_ context.Context, _ *action.ListExecutionServicesRequest) (*action.ListExecutionServicesResponse, error) { + return &action.ListExecutionServicesResponse{ Services: s.ListGRPCServices(), }, nil } -func (s *Server) SetExecution(ctx context.Context, req *execution.SetExecutionRequest) (*execution.SetExecutionResponse, error) { +func (s *Server) SetExecution(ctx context.Context, req *action.SetExecutionRequest) (*action.SetExecutionResponse, error) { + if err := checkExecutionEnabled(ctx); err != nil { + return nil, err + } + set := &command.SetExecution{ Targets: req.GetTargets(), Includes: req.GetIncludes(), @@ -37,7 +41,7 @@ func (s *Server) SetExecution(ctx context.Context, req *execution.SetExecutionRe var err error var details *domain.ObjectDetails switch t := req.GetCondition().GetConditionType().(type) { - case *execution.Condition_Request: + case *action.Condition_Request: cond := &command.ExecutionAPICondition{ Method: t.Request.GetMethod(), Service: t.Request.GetService(), @@ -47,7 +51,7 @@ func (s *Server) SetExecution(ctx context.Context, req *execution.SetExecutionRe if err != nil { return nil, err } - case *execution.Condition_Response: + case *action.Condition_Response: cond := &command.ExecutionAPICondition{ Method: t.Response.GetMethod(), Service: t.Response.GetService(), @@ -57,7 +61,7 @@ func (s *Server) SetExecution(ctx context.Context, req *execution.SetExecutionRe if err != nil { return nil, err } - case *execution.Condition_Event: + case *action.Condition_Event: cond := &command.ExecutionEventCondition{ Event: t.Event.GetEvent(), Group: t.Event.GetGroup(), @@ -67,22 +71,26 @@ func (s *Server) SetExecution(ctx context.Context, req *execution.SetExecutionRe if err != nil { return nil, err } - case *execution.Condition_Function: + case *action.Condition_Function: details, err = s.command.SetExecutionFunction(ctx, command.ExecutionFunctionCondition(t.Function), set, authz.GetInstance(ctx).InstanceID()) if err != nil { return nil, err } } - return &execution.SetExecutionResponse{ + return &action.SetExecutionResponse{ Details: object.DomainToDetailsPb(details), }, nil } -func (s *Server) DeleteExecution(ctx context.Context, req *execution.DeleteExecutionRequest) (*execution.DeleteExecutionResponse, error) { +func (s *Server) DeleteExecution(ctx context.Context, req *action.DeleteExecutionRequest) (*action.DeleteExecutionResponse, error) { + if err := checkExecutionEnabled(ctx); err != nil { + return nil, err + } + var err error var details *domain.ObjectDetails switch t := req.GetCondition().GetConditionType().(type) { - case *execution.Condition_Request: + case *action.Condition_Request: cond := &command.ExecutionAPICondition{ Method: t.Request.GetMethod(), Service: t.Request.GetService(), @@ -92,7 +100,7 @@ func (s *Server) DeleteExecution(ctx context.Context, req *execution.DeleteExecu if err != nil { return nil, err } - case *execution.Condition_Response: + case *action.Condition_Response: cond := &command.ExecutionAPICondition{ Method: t.Response.GetMethod(), Service: t.Response.GetService(), @@ -102,7 +110,7 @@ func (s *Server) DeleteExecution(ctx context.Context, req *execution.DeleteExecu if err != nil { return nil, err } - case *execution.Condition_Event: + case *action.Condition_Event: cond := &command.ExecutionEventCondition{ Event: t.Event.GetEvent(), Group: t.Event.GetGroup(), @@ -112,13 +120,13 @@ func (s *Server) DeleteExecution(ctx context.Context, req *execution.DeleteExecu if err != nil { return nil, err } - case *execution.Condition_Function: + case *action.Condition_Function: details, err = s.command.DeleteExecutionFunction(ctx, command.ExecutionFunctionCondition(t.Function), authz.GetInstance(ctx).InstanceID()) if err != nil { return nil, err } } - return &execution.DeleteExecutionResponse{ + return &action.DeleteExecutionResponse{ Details: object.DomainToDetailsPb(details), }, nil } diff --git a/internal/api/grpc/execution/v3alpha/execution_integration_test.go b/internal/api/grpc/action/v3alpha/execution_integration_test.go similarity index 54% rename from internal/api/grpc/execution/v3alpha/execution_integration_test.go rename to internal/api/grpc/action/v3alpha/execution_integration_test.go index 59f07d730..752e9b546 100644 --- a/internal/api/grpc/execution/v3alpha/execution_integration_test.go +++ b/internal/api/grpc/action/v3alpha/execution_integration_test.go @@ -1,6 +1,6 @@ //go:build integration -package execution_test +package action_test import ( "context" @@ -10,28 +10,29 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" "github.com/zitadel/zitadel/internal/integration" - execution "github.com/zitadel/zitadel/pkg/grpc/execution/v3alpha" + action "github.com/zitadel/zitadel/pkg/grpc/action/v3alpha" object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" ) func TestServer_SetExecution_Request(t *testing.T) { + ensureFeatureEnabled(t) targetResp := Tester.CreateTarget(CTX, t) tests := []struct { name string ctx context.Context - req *execution.SetExecutionRequest - want *execution.SetExecutionResponse + req *action.SetExecutionRequest + want *action.SetExecutionResponse wantErr bool }{ { name: "missing permission", ctx: Tester.WithAuthorization(context.Background(), integration.OrgOwner), - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_All{All: true}, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_All{All: true}, }, }, }, @@ -41,10 +42,10 @@ func TestServer_SetExecution_Request(t *testing.T) { { name: "no condition, error", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{}, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{}, }, }, Targets: []string{targetResp.GetId()}, @@ -54,11 +55,11 @@ func TestServer_SetExecution_Request(t *testing.T) { { name: "method, not existing", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_Method{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ Method: "/zitadel.session.v2beta.NotExistingService/List", }, }, @@ -71,11 +72,11 @@ func TestServer_SetExecution_Request(t *testing.T) { { name: "method, ok", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_Method{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ Method: "/zitadel.session.v2beta.SessionService/ListSessions", }, }, @@ -83,7 +84,7 @@ func TestServer_SetExecution_Request(t *testing.T) { }, Targets: []string{targetResp.GetId()}, }, - want: &execution.SetExecutionResponse{ + want: &action.SetExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -93,11 +94,11 @@ func TestServer_SetExecution_Request(t *testing.T) { { name: "service, not existing", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_Service{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Service{ Service: "NotExistingService", }, }, @@ -110,11 +111,11 @@ func TestServer_SetExecution_Request(t *testing.T) { { name: "service, ok", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_Service{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Service{ Service: "zitadel.session.v2beta.SessionService", }, }, @@ -122,7 +123,7 @@ func TestServer_SetExecution_Request(t *testing.T) { }, Targets: []string{targetResp.GetId()}, }, - want: &execution.SetExecutionResponse{ + want: &action.SetExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -132,11 +133,11 @@ func TestServer_SetExecution_Request(t *testing.T) { { name: "all, ok", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_All{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_All{ All: true, }, }, @@ -144,7 +145,7 @@ func TestServer_SetExecution_Request(t *testing.T) { }, Targets: []string{targetResp.GetId()}, }, - want: &execution.SetExecutionResponse{ + want: &action.SetExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -167,13 +168,15 @@ func TestServer_SetExecution_Request(t *testing.T) { } func TestServer_SetExecution_Request_Include(t *testing.T) { + ensureFeatureEnabled(t) + targetResp := Tester.CreateTarget(CTX, t) executionCond := "request" Tester.SetExecution(CTX, t, - &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_All{ + &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_All{ All: true, }, }, @@ -186,18 +189,18 @@ func TestServer_SetExecution_Request_Include(t *testing.T) { tests := []struct { name string ctx context.Context - req *execution.SetExecutionRequest - want *execution.SetExecutionResponse + req *action.SetExecutionRequest + want *action.SetExecutionResponse wantErr bool }{ { name: "method, ok", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_Method{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ Method: "/zitadel.session.v2beta.SessionService/ListSessions", }, }, @@ -205,7 +208,7 @@ func TestServer_SetExecution_Request_Include(t *testing.T) { }, Includes: []string{executionCond}, }, - want: &execution.SetExecutionResponse{ + want: &action.SetExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -215,11 +218,11 @@ func TestServer_SetExecution_Request_Include(t *testing.T) { { name: "service, ok", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_Service{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Service{ Service: "zitadel.session.v2beta.SessionService", }, }, @@ -227,7 +230,7 @@ func TestServer_SetExecution_Request_Include(t *testing.T) { }, Includes: []string{executionCond}, }, - want: &execution.SetExecutionResponse{ + want: &action.SetExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -237,11 +240,11 @@ func TestServer_SetExecution_Request_Include(t *testing.T) { { name: "all, ok", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_All{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_All{ All: true, }, }, @@ -249,7 +252,7 @@ func TestServer_SetExecution_Request_Include(t *testing.T) { }, Includes: []string{executionCond}, }, - want: &execution.SetExecutionResponse{ + want: &action.SetExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -272,24 +275,25 @@ func TestServer_SetExecution_Request_Include(t *testing.T) { } func TestServer_DeleteExecution_Request(t *testing.T) { + ensureFeatureEnabled(t) targetResp := Tester.CreateTarget(CTX, t) tests := []struct { name string ctx context.Context - dep func(ctx context.Context, request *execution.DeleteExecutionRequest) error - req *execution.DeleteExecutionRequest - want *execution.DeleteExecutionResponse + dep func(ctx context.Context, request *action.DeleteExecutionRequest) error + req *action.DeleteExecutionRequest + want *action.DeleteExecutionResponse wantErr bool }{ { name: "missing permission", ctx: Tester.WithAuthorization(context.Background(), integration.OrgOwner), - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_All{All: true}, + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_All{All: true}, }, }, }, @@ -299,10 +303,10 @@ func TestServer_DeleteExecution_Request(t *testing.T) { { name: "no condition, error", ctx: CTX, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{}, + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{}, }, }, }, @@ -311,11 +315,11 @@ func TestServer_DeleteExecution_Request(t *testing.T) { { name: "method, not existing", ctx: CTX, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_Method{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ Method: "/zitadel.session.v2beta.SessionService/NotExisting", }, }, @@ -327,22 +331,22 @@ func TestServer_DeleteExecution_Request(t *testing.T) { { name: "method, ok", ctx: CTX, - dep: func(ctx context.Context, request *execution.DeleteExecutionRequest) error { + dep: func(ctx context.Context, request *action.DeleteExecutionRequest) error { Tester.SetExecution(ctx, t, request.GetCondition(), []string{targetResp.GetId()}, []string{}) return nil }, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_Method{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ Method: "/zitadel.session.v2beta.SessionService/GetSession", }, }, }, }, }, - want: &execution.DeleteExecutionResponse{ + want: &action.DeleteExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -352,11 +356,11 @@ func TestServer_DeleteExecution_Request(t *testing.T) { { name: "service, not existing", ctx: CTX, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_Service{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Service{ Service: "NotExistingService", }, }, @@ -368,22 +372,22 @@ func TestServer_DeleteExecution_Request(t *testing.T) { { name: "service, ok", ctx: CTX, - dep: func(ctx context.Context, request *execution.DeleteExecutionRequest) error { + dep: func(ctx context.Context, request *action.DeleteExecutionRequest) error { Tester.SetExecution(ctx, t, request.GetCondition(), []string{targetResp.GetId()}, []string{}) return nil }, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_Service{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Service{ Service: "zitadel.user.v2beta.UserService", }, }, }, }, }, - want: &execution.DeleteExecutionResponse{ + want: &action.DeleteExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -393,22 +397,22 @@ func TestServer_DeleteExecution_Request(t *testing.T) { { name: "all, ok", ctx: CTX, - dep: func(ctx context.Context, request *execution.DeleteExecutionRequest) error { + dep: func(ctx context.Context, request *action.DeleteExecutionRequest) error { Tester.SetExecution(ctx, t, request.GetCondition(), []string{targetResp.GetId()}, []string{}) return nil }, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_All{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_All{ All: true, }, }, }, }, }, - want: &execution.DeleteExecutionResponse{ + want: &action.DeleteExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -436,23 +440,24 @@ func TestServer_DeleteExecution_Request(t *testing.T) { } func TestServer_SetExecution_Response(t *testing.T) { + ensureFeatureEnabled(t) targetResp := Tester.CreateTarget(CTX, t) tests := []struct { name string ctx context.Context - req *execution.SetExecutionRequest - want *execution.SetExecutionResponse + req *action.SetExecutionRequest + want *action.SetExecutionResponse wantErr bool }{ { name: "missing permission", ctx: Tester.WithAuthorization(context.Background(), integration.OrgOwner), - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Response{ - Response: &execution.ResponseExecution{ - Condition: &execution.ResponseExecution_All{All: true}, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_All{All: true}, }, }, }, @@ -462,10 +467,10 @@ func TestServer_SetExecution_Response(t *testing.T) { { name: "no condition, error", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Response{ - Response: &execution.ResponseExecution{}, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{}, }, }, Targets: []string{targetResp.GetId()}, @@ -475,11 +480,11 @@ func TestServer_SetExecution_Response(t *testing.T) { { name: "method, not existing", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Response{ - Response: &execution.ResponseExecution{ - Condition: &execution.ResponseExecution_Method{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_Method{ Method: "/zitadel.session.v2beta.NotExistingService/List", }, }, @@ -492,11 +497,11 @@ func TestServer_SetExecution_Response(t *testing.T) { { name: "method, ok", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Response{ - Response: &execution.ResponseExecution{ - Condition: &execution.ResponseExecution_Method{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_Method{ Method: "/zitadel.session.v2beta.SessionService/ListSessions", }, }, @@ -504,7 +509,7 @@ func TestServer_SetExecution_Response(t *testing.T) { }, Targets: []string{targetResp.GetId()}, }, - want: &execution.SetExecutionResponse{ + want: &action.SetExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -514,11 +519,11 @@ func TestServer_SetExecution_Response(t *testing.T) { { name: "service, not existing", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Response{ - Response: &execution.ResponseExecution{ - Condition: &execution.ResponseExecution_Service{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_Service{ Service: "NotExistingService", }, }, @@ -531,11 +536,11 @@ func TestServer_SetExecution_Response(t *testing.T) { { name: "service, ok", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Response{ - Response: &execution.ResponseExecution{ - Condition: &execution.ResponseExecution_Service{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_Service{ Service: "zitadel.session.v2beta.SessionService", }, }, @@ -543,7 +548,7 @@ func TestServer_SetExecution_Response(t *testing.T) { }, Targets: []string{targetResp.GetId()}, }, - want: &execution.SetExecutionResponse{ + want: &action.SetExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -553,11 +558,11 @@ func TestServer_SetExecution_Response(t *testing.T) { { name: "all, ok", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Response{ - Response: &execution.ResponseExecution{ - Condition: &execution.ResponseExecution_All{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_All{ All: true, }, }, @@ -565,7 +570,7 @@ func TestServer_SetExecution_Response(t *testing.T) { }, Targets: []string{targetResp.GetId()}, }, - want: &execution.SetExecutionResponse{ + want: &action.SetExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -588,24 +593,25 @@ func TestServer_SetExecution_Response(t *testing.T) { } func TestServer_DeleteExecution_Response(t *testing.T) { + ensureFeatureEnabled(t) targetResp := Tester.CreateTarget(CTX, t) tests := []struct { name string ctx context.Context - dep func(ctx context.Context, request *execution.DeleteExecutionRequest) error - req *execution.DeleteExecutionRequest - want *execution.DeleteExecutionResponse + dep func(ctx context.Context, request *action.DeleteExecutionRequest) error + req *action.DeleteExecutionRequest + want *action.DeleteExecutionResponse wantErr bool }{ { name: "missing permission", ctx: Tester.WithAuthorization(context.Background(), integration.OrgOwner), - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Response{ - Response: &execution.ResponseExecution{ - Condition: &execution.ResponseExecution_All{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_All{ All: true, }, }, @@ -617,10 +623,10 @@ func TestServer_DeleteExecution_Response(t *testing.T) { { name: "no condition, error", ctx: CTX, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Response{ - Response: &execution.ResponseExecution{}, + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{}, }, }, }, @@ -629,11 +635,11 @@ func TestServer_DeleteExecution_Response(t *testing.T) { { name: "method, not existing", ctx: CTX, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Response{ - Response: &execution.ResponseExecution{ - Condition: &execution.ResponseExecution_Method{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_Method{ Method: "/zitadel.session.v2beta.SessionService/NotExisting", }, }, @@ -645,22 +651,22 @@ func TestServer_DeleteExecution_Response(t *testing.T) { { name: "method, ok", ctx: CTX, - dep: func(ctx context.Context, request *execution.DeleteExecutionRequest) error { + dep: func(ctx context.Context, request *action.DeleteExecutionRequest) error { Tester.SetExecution(ctx, t, request.GetCondition(), []string{targetResp.GetId()}, []string{}) return nil }, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Response{ - Response: &execution.ResponseExecution{ - Condition: &execution.ResponseExecution_Method{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_Method{ Method: "/zitadel.session.v2beta.SessionService/GetSession", }, }, }, }, }, - want: &execution.DeleteExecutionResponse{ + want: &action.DeleteExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -670,11 +676,11 @@ func TestServer_DeleteExecution_Response(t *testing.T) { { name: "service, not existing", ctx: CTX, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Response{ - Response: &execution.ResponseExecution{ - Condition: &execution.ResponseExecution_Service{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_Service{ Service: "NotExistingService", }, }, @@ -686,22 +692,22 @@ func TestServer_DeleteExecution_Response(t *testing.T) { { name: "service, ok", ctx: CTX, - dep: func(ctx context.Context, request *execution.DeleteExecutionRequest) error { + dep: func(ctx context.Context, request *action.DeleteExecutionRequest) error { Tester.SetExecution(ctx, t, request.GetCondition(), []string{targetResp.GetId()}, []string{}) return nil }, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Response{ - Response: &execution.ResponseExecution{ - Condition: &execution.ResponseExecution_Service{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_Service{ Service: "zitadel.user.v2beta.UserService", }, }, }, }, }, - want: &execution.DeleteExecutionResponse{ + want: &action.DeleteExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -711,22 +717,22 @@ func TestServer_DeleteExecution_Response(t *testing.T) { { name: "all, ok", ctx: CTX, - dep: func(ctx context.Context, request *execution.DeleteExecutionRequest) error { + dep: func(ctx context.Context, request *action.DeleteExecutionRequest) error { Tester.SetExecution(ctx, t, request.GetCondition(), []string{targetResp.GetId()}, []string{}) return nil }, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Response{ - Response: &execution.ResponseExecution{ - Condition: &execution.ResponseExecution_All{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_All{ All: true, }, }, }, }, }, - want: &execution.DeleteExecutionResponse{ + want: &action.DeleteExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -754,23 +760,24 @@ func TestServer_DeleteExecution_Response(t *testing.T) { } func TestServer_SetExecution_Event(t *testing.T) { + ensureFeatureEnabled(t) targetResp := Tester.CreateTarget(CTX, t) tests := []struct { name string ctx context.Context - req *execution.SetExecutionRequest - want *execution.SetExecutionResponse + req *action.SetExecutionRequest + want *action.SetExecutionResponse wantErr bool }{ { name: "missing permission", ctx: Tester.WithAuthorization(context.Background(), integration.OrgOwner), - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Event{ - Event: &execution.EventExecution{ - Condition: &execution.EventExecution_All{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_All{ All: true, }, }, @@ -782,10 +789,10 @@ func TestServer_SetExecution_Event(t *testing.T) { { name: "no condition, error", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Event{ - Event: &execution.EventExecution{}, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{}, }, }, Targets: []string{targetResp.GetId()}, @@ -798,11 +805,11 @@ func TestServer_SetExecution_Event(t *testing.T) { { name: "event, not existing", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Event{ - Event: &execution.EventExecution{ - Condition: &execution.EventExecution_Event{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_Event{ Event: "xxx", }, }, @@ -816,11 +823,11 @@ func TestServer_SetExecution_Event(t *testing.T) { { name: "event, ok", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Event{ - Event: &execution.EventExecution{ - Condition: &execution.EventExecution_Event{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_Event{ Event: "xxx", }, }, @@ -828,7 +835,7 @@ func TestServer_SetExecution_Event(t *testing.T) { }, Targets: []string{targetResp.GetId()}, }, - want: &execution.SetExecutionResponse{ + want: &action.SetExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -841,11 +848,11 @@ func TestServer_SetExecution_Event(t *testing.T) { { name: "group, not existing", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Event{ - Event: &execution.EventExecution{ - Condition: &execution.EventExecution_Group{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_Group{ Group: "xxx", }, }, @@ -859,11 +866,11 @@ func TestServer_SetExecution_Event(t *testing.T) { { name: "group, ok", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Event{ - Event: &execution.EventExecution{ - Condition: &execution.EventExecution_Group{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_Group{ Group: "xxx", }, }, @@ -871,7 +878,7 @@ func TestServer_SetExecution_Event(t *testing.T) { }, Targets: []string{targetResp.GetId()}, }, - want: &execution.SetExecutionResponse{ + want: &action.SetExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -881,11 +888,11 @@ func TestServer_SetExecution_Event(t *testing.T) { { name: "all, ok", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Event{ - Event: &execution.EventExecution{ - Condition: &execution.EventExecution_All{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_All{ All: true, }, }, @@ -893,7 +900,7 @@ func TestServer_SetExecution_Event(t *testing.T) { }, Targets: []string{targetResp.GetId()}, }, - want: &execution.SetExecutionResponse{ + want: &action.SetExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -916,24 +923,25 @@ func TestServer_SetExecution_Event(t *testing.T) { } func TestServer_DeleteExecution_Event(t *testing.T) { + ensureFeatureEnabled(t) targetResp := Tester.CreateTarget(CTX, t) tests := []struct { name string ctx context.Context - dep func(ctx context.Context, request *execution.DeleteExecutionRequest) error - req *execution.DeleteExecutionRequest - want *execution.DeleteExecutionResponse + dep func(ctx context.Context, request *action.DeleteExecutionRequest) error + req *action.DeleteExecutionRequest + want *action.DeleteExecutionResponse wantErr bool }{ { name: "missing permission", ctx: Tester.WithAuthorization(context.Background(), integration.OrgOwner), - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Event{ - Event: &execution.EventExecution{ - Condition: &execution.EventExecution_All{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_All{ All: true, }, }, @@ -945,10 +953,10 @@ func TestServer_DeleteExecution_Event(t *testing.T) { { name: "no condition, error", ctx: CTX, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Event{ - Event: &execution.EventExecution{}, + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{}, }, }, }, @@ -959,11 +967,11 @@ func TestServer_DeleteExecution_Event(t *testing.T) { { name: "event, not existing", ctx: CTX, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Event{ - Event: &execution.EventExecution{ - Condition: &execution.EventExecution_Event{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_Event{ Event: "xxx", }, }, @@ -976,22 +984,22 @@ func TestServer_DeleteExecution_Event(t *testing.T) { { name: "event, ok", ctx: CTX, - dep: func(ctx context.Context, request *execution.DeleteExecutionRequest) error { + dep: func(ctx context.Context, request *action.DeleteExecutionRequest) error { Tester.SetExecution(ctx, t, request.GetCondition(), []string{targetResp.GetId()}, []string{}) return nil }, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Event{ - Event: &execution.EventExecution{ - Condition: &execution.EventExecution_Event{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_Event{ Event: "xxx", }, }, }, }, }, - want: &execution.DeleteExecutionResponse{ + want: &action.DeleteExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -1001,11 +1009,11 @@ func TestServer_DeleteExecution_Event(t *testing.T) { { name: "group, not existing", ctx: CTX, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Event{ - Event: &execution.EventExecution{ - Condition: &execution.EventExecution_Group{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_Group{ Group: "xxx", }, }, @@ -1017,22 +1025,22 @@ func TestServer_DeleteExecution_Event(t *testing.T) { { name: "group, ok", ctx: CTX, - dep: func(ctx context.Context, request *execution.DeleteExecutionRequest) error { + dep: func(ctx context.Context, request *action.DeleteExecutionRequest) error { Tester.SetExecution(ctx, t, request.GetCondition(), []string{targetResp.GetId()}, []string{}) return nil }, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Event{ - Event: &execution.EventExecution{ - Condition: &execution.EventExecution_Group{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_Group{ Group: "xxx", }, }, }, }, }, - want: &execution.DeleteExecutionResponse{ + want: &action.DeleteExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -1042,18 +1050,18 @@ func TestServer_DeleteExecution_Event(t *testing.T) { { name: "all, not existing", ctx: CTX, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Event{ - Event: &execution.EventExecution{ - Condition: &execution.EventExecution_All{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_All{ All: true, }, }, }, }, }, - want: &execution.DeleteExecutionResponse{ + want: &action.DeleteExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -1063,22 +1071,22 @@ func TestServer_DeleteExecution_Event(t *testing.T) { { name: "all, ok", ctx: CTX, - dep: func(ctx context.Context, request *execution.DeleteExecutionRequest) error { + dep: func(ctx context.Context, request *action.DeleteExecutionRequest) error { Tester.SetExecution(ctx, t, request.GetCondition(), []string{targetResp.GetId()}, []string{}) return nil }, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Event{ - Event: &execution.EventExecution{ - Condition: &execution.EventExecution_All{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Event{ + Event: &action.EventExecution{ + Condition: &action.EventExecution_All{ All: true, }, }, }, }, }, - want: &execution.DeleteExecutionResponse{ + want: &action.DeleteExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -1106,23 +1114,24 @@ func TestServer_DeleteExecution_Event(t *testing.T) { } func TestServer_SetExecution_Function(t *testing.T) { + ensureFeatureEnabled(t) targetResp := Tester.CreateTarget(CTX, t) tests := []struct { name string ctx context.Context - req *execution.SetExecutionRequest - want *execution.SetExecutionResponse + req *action.SetExecutionRequest + want *action.SetExecutionResponse wantErr bool }{ { name: "missing permission", ctx: Tester.WithAuthorization(context.Background(), integration.OrgOwner), - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Response{ - Response: &execution.ResponseExecution{ - Condition: &execution.ResponseExecution_All{All: true}, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_All{All: true}, }, }, }, @@ -1132,10 +1141,10 @@ func TestServer_SetExecution_Function(t *testing.T) { { name: "no condition, error", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Response{ - Response: &execution.ResponseExecution{}, + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{}, }, }, Targets: []string{targetResp.GetId()}, @@ -1145,9 +1154,9 @@ func TestServer_SetExecution_Function(t *testing.T) { { name: "function, not existing", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Function{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Function{ Function: "xxx", }, }, @@ -1158,15 +1167,15 @@ func TestServer_SetExecution_Function(t *testing.T) { { name: "function, ok", ctx: CTX, - req: &execution.SetExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Function{ + req: &action.SetExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Function{ Function: "Action.Flow.Type.ExternalAuthentication.Action.TriggerType.PostAuthentication", }, }, Targets: []string{targetResp.GetId()}, }, - want: &execution.SetExecutionResponse{ + want: &action.SetExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -1189,24 +1198,25 @@ func TestServer_SetExecution_Function(t *testing.T) { } func TestServer_DeleteExecution_Function(t *testing.T) { + ensureFeatureEnabled(t) targetResp := Tester.CreateTarget(CTX, t) tests := []struct { name string ctx context.Context - dep func(ctx context.Context, request *execution.DeleteExecutionRequest) error - req *execution.DeleteExecutionRequest - want *execution.DeleteExecutionResponse + dep func(ctx context.Context, request *action.DeleteExecutionRequest) error + req *action.DeleteExecutionRequest + want *action.DeleteExecutionResponse wantErr bool }{ { name: "missing permission", ctx: Tester.WithAuthorization(context.Background(), integration.OrgOwner), - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Response{ - Response: &execution.ResponseExecution{ - Condition: &execution.ResponseExecution_All{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{ + Condition: &action.ResponseExecution_All{ All: true, }, }, @@ -1218,10 +1228,10 @@ func TestServer_DeleteExecution_Function(t *testing.T) { { name: "no condition, error", ctx: CTX, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Response{ - Response: &execution.ResponseExecution{}, + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Response{ + Response: &action.ResponseExecution{}, }, }, }, @@ -1230,9 +1240,9 @@ func TestServer_DeleteExecution_Function(t *testing.T) { { name: "function, not existing", ctx: CTX, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Function{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Function{ Function: "xxx", }, }, @@ -1242,18 +1252,18 @@ func TestServer_DeleteExecution_Function(t *testing.T) { { name: "function, ok", ctx: CTX, - dep: func(ctx context.Context, request *execution.DeleteExecutionRequest) error { + dep: func(ctx context.Context, request *action.DeleteExecutionRequest) error { Tester.SetExecution(ctx, t, request.GetCondition(), []string{targetResp.GetId()}, []string{}) return nil }, - req: &execution.DeleteExecutionRequest{ - Condition: &execution.Condition{ - ConditionType: &execution.Condition_Function{ + req: &action.DeleteExecutionRequest{ + Condition: &action.Condition{ + ConditionType: &action.Condition_Function{ Function: "Action.Flow.Type.ExternalAuthentication.Action.TriggerType.PostAuthentication", }, }, }, - want: &execution.DeleteExecutionResponse{ + want: &action.DeleteExecutionResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), diff --git a/internal/api/grpc/execution/v3alpha/query.go b/internal/api/grpc/action/v3alpha/query.go similarity index 60% rename from internal/api/grpc/execution/v3alpha/query.go rename to internal/api/grpc/action/v3alpha/query.go index 7c47a0a3c..582510b0b 100644 --- a/internal/api/grpc/execution/v3alpha/query.go +++ b/internal/api/grpc/action/v3alpha/query.go @@ -1,4 +1,4 @@ -package execution +package action import ( "context" @@ -10,10 +10,14 @@ import ( "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/query" "github.com/zitadel/zitadel/internal/zerrors" - execution "github.com/zitadel/zitadel/pkg/grpc/execution/v3alpha" + action "github.com/zitadel/zitadel/pkg/grpc/action/v3alpha" ) -func (s *Server) ListTargets(ctx context.Context, req *execution.ListTargetsRequest) (*execution.ListTargetsResponse, error) { +func (s *Server) ListTargets(ctx context.Context, req *action.ListTargetsRequest) (*action.ListTargetsResponse, error) { + if err := checkExecutionEnabled(ctx); err != nil { + return nil, err + } + queries, err := listTargetsRequestToModel(req) if err != nil { return nil, err @@ -22,13 +26,13 @@ func (s *Server) ListTargets(ctx context.Context, req *execution.ListTargetsRequ if err != nil { return nil, err } - return &execution.ListTargetsResponse{ + return &action.ListTargetsResponse{ Result: targetsToPb(resp.Targets), Details: object.ToListDetails(resp.SearchResponse), }, nil } -func listTargetsRequestToModel(req *execution.ListTargetsRequest) (*query.TargetSearchQueries, error) { +func listTargetsRequestToModel(req *action.ListTargetsRequest) (*query.TargetSearchQueries, error) { offset, limit, asc := object.ListQueryToQuery(req.Query) queries, err := targetQueriesToQuery(req.Queries) if err != nil { @@ -45,34 +49,34 @@ func listTargetsRequestToModel(req *execution.ListTargetsRequest) (*query.Target }, nil } -func targetFieldNameToSortingColumn(field execution.TargetFieldName) query.Column { +func targetFieldNameToSortingColumn(field action.TargetFieldName) query.Column { switch field { - case execution.TargetFieldName_FIELD_NAME_UNSPECIFIED: + case action.TargetFieldName_FIELD_NAME_UNSPECIFIED: return query.TargetColumnID - case execution.TargetFieldName_FIELD_NAME_ID: + case action.TargetFieldName_FIELD_NAME_ID: return query.TargetColumnID - case execution.TargetFieldName_FIELD_NAME_CREATION_DATE: + case action.TargetFieldName_FIELD_NAME_CREATION_DATE: return query.TargetColumnCreationDate - case execution.TargetFieldName_FIELD_NAME_CHANGE_DATE: + case action.TargetFieldName_FIELD_NAME_CHANGE_DATE: return query.TargetColumnChangeDate - case execution.TargetFieldName_FIELD_NAME_NAME: + case action.TargetFieldName_FIELD_NAME_NAME: return query.TargetColumnName - case execution.TargetFieldName_FIELD_NAME_TARGET_TYPE: + case action.TargetFieldName_FIELD_NAME_TARGET_TYPE: return query.TargetColumnTargetType - case execution.TargetFieldName_FIELD_NAME_URL: + case action.TargetFieldName_FIELD_NAME_URL: return query.TargetColumnURL - case execution.TargetFieldName_FIELD_NAME_TIMEOUT: + case action.TargetFieldName_FIELD_NAME_TIMEOUT: return query.TargetColumnTimeout - case execution.TargetFieldName_FIELD_NAME_ASYNC: + case action.TargetFieldName_FIELD_NAME_ASYNC: return query.TargetColumnAsync - case execution.TargetFieldName_FIELD_NAME_INTERRUPT_ON_ERROR: + case action.TargetFieldName_FIELD_NAME_INTERRUPT_ON_ERROR: return query.TargetColumnInterruptOnError default: return query.TargetColumnID } } -func targetQueriesToQuery(queries []*execution.TargetSearchQuery) (_ []query.SearchQuery, err error) { +func targetQueriesToQuery(queries []*action.TargetSearchQuery) (_ []query.SearchQuery, err error) { q := make([]query.SearchQuery, len(queries)) for i, query := range queries { q[i], err = targetQueryToQuery(query) @@ -83,69 +87,77 @@ func targetQueriesToQuery(queries []*execution.TargetSearchQuery) (_ []query.Sea return q, nil } -func targetQueryToQuery(query *execution.TargetSearchQuery) (query.SearchQuery, error) { +func targetQueryToQuery(query *action.TargetSearchQuery) (query.SearchQuery, error) { switch q := query.Query.(type) { - case *execution.TargetSearchQuery_TargetNameQuery: + case *action.TargetSearchQuery_TargetNameQuery: return targetNameQueryToQuery(q.TargetNameQuery) - case *execution.TargetSearchQuery_InTargetIdsQuery: + case *action.TargetSearchQuery_InTargetIdsQuery: return targetInTargetIdsQueryToQuery(q.InTargetIdsQuery) default: return nil, zerrors.ThrowInvalidArgument(nil, "GRPC-vR9nC", "List.Query.Invalid") } } -func targetNameQueryToQuery(q *execution.TargetNameQuery) (query.SearchQuery, error) { +func targetNameQueryToQuery(q *action.TargetNameQuery) (query.SearchQuery, error) { return query.NewTargetNameSearchQuery(object.TextMethodToQuery(q.Method), q.GetTargetName()) } -func targetInTargetIdsQueryToQuery(q *execution.InTargetIDsQuery) (query.SearchQuery, error) { +func targetInTargetIdsQueryToQuery(q *action.InTargetIDsQuery) (query.SearchQuery, error) { return query.NewTargetInIDsSearchQuery(q.GetTargetIds()) } -func (s *Server) GetTargetByID(ctx context.Context, req *execution.GetTargetByIDRequest) (_ *execution.GetTargetByIDResponse, err error) { +func (s *Server) GetTargetByID(ctx context.Context, req *action.GetTargetByIDRequest) (_ *action.GetTargetByIDResponse, err error) { + if err := checkExecutionEnabled(ctx); err != nil { + return nil, err + } + resp, err := s.query.GetTargetByID(ctx, req.GetTargetId()) if err != nil { return nil, err } - return &execution.GetTargetByIDResponse{ + return &action.GetTargetByIDResponse{ Target: targetToPb(resp), }, nil } -func targetsToPb(targets []*query.Target) []*execution.Target { - t := make([]*execution.Target, len(targets)) +func targetsToPb(targets []*query.Target) []*action.Target { + t := make([]*action.Target, len(targets)) for i, target := range targets { t[i] = targetToPb(target) } return t } -func targetToPb(t *query.Target) *execution.Target { - target := &execution.Target{ +func targetToPb(t *query.Target) *action.Target { + target := &action.Target{ Details: object.DomainToDetailsPb(&t.ObjectDetails), TargetId: t.ID, Name: t.Name, Timeout: durationpb.New(t.Timeout), } if t.Async { - target.ExecutionType = &execution.Target_IsAsync{IsAsync: t.Async} + target.ExecutionType = &action.Target_IsAsync{IsAsync: t.Async} } if t.InterruptOnError { - target.ExecutionType = &execution.Target_InterruptOnError{InterruptOnError: t.InterruptOnError} + target.ExecutionType = &action.Target_InterruptOnError{InterruptOnError: t.InterruptOnError} } switch t.TargetType { case domain.TargetTypeWebhook: - target.TargetType = &execution.Target_RestWebhook{RestWebhook: &execution.SetRESTWebhook{Url: t.URL}} + target.TargetType = &action.Target_RestWebhook{RestWebhook: &action.SetRESTWebhook{Url: t.URL}} case domain.TargetTypeRequestResponse: - target.TargetType = &execution.Target_RestRequestResponse{RestRequestResponse: &execution.SetRESTRequestResponse{Url: t.URL}} + target.TargetType = &action.Target_RestRequestResponse{RestRequestResponse: &action.SetRESTRequestResponse{Url: t.URL}} default: target.TargetType = nil } return target } -func (s *Server) ListExecutions(ctx context.Context, req *execution.ListExecutionsRequest) (*execution.ListExecutionsResponse, error) { +func (s *Server) ListExecutions(ctx context.Context, req *action.ListExecutionsRequest) (*action.ListExecutionsResponse, error) { + if err := checkExecutionEnabled(ctx); err != nil { + return nil, err + } + queries, err := listExecutionsRequestToModel(req) if err != nil { return nil, err @@ -154,13 +166,13 @@ func (s *Server) ListExecutions(ctx context.Context, req *execution.ListExecutio if err != nil { return nil, err } - return &execution.ListExecutionsResponse{ + return &action.ListExecutionsResponse{ Result: executionsToPb(resp.Executions), Details: object.ToListDetails(resp.SearchResponse), }, nil } -func listExecutionsRequestToModel(req *execution.ListExecutionsRequest) (*query.ExecutionSearchQueries, error) { +func listExecutionsRequestToModel(req *action.ListExecutionsRequest) (*query.ExecutionSearchQueries, error) { offset, limit, asc := object.ListQueryToQuery(req.Query) queries, err := executionQueriesToQuery(req.Queries) if err != nil { @@ -176,7 +188,7 @@ func listExecutionsRequestToModel(req *execution.ListExecutionsRequest) (*query. }, nil } -func executionQueriesToQuery(queries []*execution.SearchQuery) (_ []query.SearchQuery, err error) { +func executionQueriesToQuery(queries []*action.SearchQuery) (_ []query.SearchQuery, err error) { q := make([]query.SearchQuery, len(queries)) for i, query := range queries { q[i], err = executionQueryToQuery(query) @@ -187,39 +199,39 @@ func executionQueriesToQuery(queries []*execution.SearchQuery) (_ []query.Search return q, nil } -func executionQueryToQuery(searchQuery *execution.SearchQuery) (query.SearchQuery, error) { +func executionQueryToQuery(searchQuery *action.SearchQuery) (query.SearchQuery, error) { switch q := searchQuery.Query.(type) { - case *execution.SearchQuery_InConditionsQuery: + case *action.SearchQuery_InConditionsQuery: return inConditionsQueryToQuery(q.InConditionsQuery) - case *execution.SearchQuery_ExecutionTypeQuery: + case *action.SearchQuery_ExecutionTypeQuery: return executionTypeToQuery(q.ExecutionTypeQuery) - case *execution.SearchQuery_TargetQuery: + case *action.SearchQuery_TargetQuery: return query.NewExecutionTargetSearchQuery(q.TargetQuery.GetTargetId()) - case *execution.SearchQuery_IncludeQuery: + case *action.SearchQuery_IncludeQuery: return query.NewExecutionIncludeSearchQuery(q.IncludeQuery.GetInclude()) default: return nil, zerrors.ThrowInvalidArgument(nil, "GRPC-vR9nC", "List.Query.Invalid") } } -func executionTypeToQuery(q *execution.ExecutionTypeQuery) (query.SearchQuery, error) { +func executionTypeToQuery(q *action.ExecutionTypeQuery) (query.SearchQuery, error) { switch q.ExecutionType { - case execution.ExecutionType_EXECUTION_TYPE_UNSPECIFIED: + case action.ExecutionType_EXECUTION_TYPE_UNSPECIFIED: return query.NewExecutionTypeSearchQuery(domain.ExecutionTypeUnspecified) - case execution.ExecutionType_EXECUTION_TYPE_REQUEST: + case action.ExecutionType_EXECUTION_TYPE_REQUEST: return query.NewExecutionTypeSearchQuery(domain.ExecutionTypeRequest) - case execution.ExecutionType_EXECUTION_TYPE_RESPONSE: + case action.ExecutionType_EXECUTION_TYPE_RESPONSE: return query.NewExecutionTypeSearchQuery(domain.ExecutionTypeResponse) - case execution.ExecutionType_EXECUTION_TYPE_EVENT: + case action.ExecutionType_EXECUTION_TYPE_EVENT: return query.NewExecutionTypeSearchQuery(domain.ExecutionTypeEvent) - case execution.ExecutionType_EXECUTION_TYPE_FUNCTION: + case action.ExecutionType_EXECUTION_TYPE_FUNCTION: return query.NewExecutionTypeSearchQuery(domain.ExecutionTypeFunction) default: return query.NewExecutionTypeSearchQuery(domain.ExecutionTypeUnspecified) } } -func inConditionsQueryToQuery(q *execution.InConditionsQuery) (query.SearchQuery, error) { +func inConditionsQueryToQuery(q *action.InConditionsQuery) (query.SearchQuery, error) { values := make([]string, len(q.GetConditions())) for i, condition := range q.GetConditions() { id, err := conditionToID(condition) @@ -231,45 +243,45 @@ func inConditionsQueryToQuery(q *execution.InConditionsQuery) (query.SearchQuery return query.NewExecutionInIDsSearchQuery(values) } -func conditionToID(q *execution.Condition) (string, error) { +func conditionToID(q *action.Condition) (string, error) { switch t := q.GetConditionType().(type) { - case *execution.Condition_Request: + case *action.Condition_Request: cond := &command.ExecutionAPICondition{ Method: t.Request.GetMethod(), Service: t.Request.GetService(), All: t.Request.GetAll(), } return cond.ID(domain.ExecutionTypeRequest), nil - case *execution.Condition_Response: + case *action.Condition_Response: cond := &command.ExecutionAPICondition{ Method: t.Response.GetMethod(), Service: t.Response.GetService(), All: t.Response.GetAll(), } return cond.ID(domain.ExecutionTypeResponse), nil - case *execution.Condition_Event: + case *action.Condition_Event: cond := &command.ExecutionEventCondition{ Event: t.Event.GetEvent(), Group: t.Event.GetGroup(), All: t.Event.GetAll(), } return cond.ID(), nil - case *execution.Condition_Function: + case *action.Condition_Function: return t.Function, nil default: return "", zerrors.ThrowInvalidArgument(nil, "GRPC-vR9nC", "List.Query.Invalid") } } -func executionsToPb(executions []*query.Execution) []*execution.Execution { - e := make([]*execution.Execution, len(executions)) +func executionsToPb(executions []*query.Execution) []*action.Execution { + e := make([]*action.Execution, len(executions)) for i, execution := range executions { e[i] = executionToPb(execution) } return e } -func executionToPb(e *query.Execution) *execution.Execution { +func executionToPb(e *query.Execution) *action.Execution { var targets, includes []string if len(e.Targets) > 0 { targets = e.Targets @@ -277,7 +289,7 @@ func executionToPb(e *query.Execution) *execution.Execution { if len(e.Includes) > 0 { includes = e.Includes } - return &execution.Execution{ + return &action.Execution{ Details: object.DomainToDetailsPb(&e.ObjectDetails), ExecutionId: e.ID, Targets: targets, diff --git a/internal/api/grpc/execution/v3alpha/query_integration_test.go b/internal/api/grpc/action/v3alpha/query_integration_test.go similarity index 69% rename from internal/api/grpc/execution/v3alpha/query_integration_test.go rename to internal/api/grpc/action/v3alpha/query_integration_test.go index d923a5016..31b5a8025 100644 --- a/internal/api/grpc/execution/v3alpha/query_integration_test.go +++ b/internal/api/grpc/action/v3alpha/query_integration_test.go @@ -1,6 +1,6 @@ //go:build integration -package execution_test +package action_test import ( "context" @@ -13,27 +13,28 @@ import ( "google.golang.org/protobuf/types/known/durationpb" "github.com/zitadel/zitadel/internal/integration" - execution "github.com/zitadel/zitadel/pkg/grpc/execution/v3alpha" + action "github.com/zitadel/zitadel/pkg/grpc/action/v3alpha" object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" ) func TestServer_GetTargetByID(t *testing.T) { + ensureFeatureEnabled(t) type args struct { ctx context.Context - dep func(context.Context, *execution.GetTargetByIDRequest, *execution.GetTargetByIDResponse) error - req *execution.GetTargetByIDRequest + dep func(context.Context, *action.GetTargetByIDRequest, *action.GetTargetByIDResponse) error + req *action.GetTargetByIDRequest } tests := []struct { name string args args - want *execution.GetTargetByIDResponse + want *action.GetTargetByIDResponse wantErr bool }{ { name: "missing permission", args: args{ ctx: Tester.WithAuthorization(context.Background(), integration.OrgOwner), - req: &execution.GetTargetByIDRequest{}, + req: &action.GetTargetByIDRequest{}, }, wantErr: true, }, @@ -41,7 +42,7 @@ func TestServer_GetTargetByID(t *testing.T) { name: "not found", args: args{ ctx: CTX, - req: &execution.GetTargetByIDRequest{TargetId: "notexisting"}, + req: &action.GetTargetByIDRequest{TargetId: "notexisting"}, }, wantErr: true, }, @@ -49,7 +50,7 @@ func TestServer_GetTargetByID(t *testing.T) { name: "get, ok", args: args{ ctx: CTX, - dep: func(ctx context.Context, request *execution.GetTargetByIDRequest, response *execution.GetTargetByIDResponse) error { + dep: func(ctx context.Context, request *action.GetTargetByIDRequest, response *action.GetTargetByIDResponse) error { name := fmt.Sprint(time.Now().UnixNano() + 1) resp := Tester.CreateTargetWithNameAndType(ctx, t, name, false, false) request.TargetId = resp.GetId() @@ -61,15 +62,15 @@ func TestServer_GetTargetByID(t *testing.T) { response.Target.Details.Sequence = resp.GetDetails().GetSequence() return nil }, - req: &execution.GetTargetByIDRequest{}, + req: &action.GetTargetByIDRequest{}, }, - want: &execution.GetTargetByIDResponse{ - Target: &execution.Target{ + want: &action.GetTargetByIDResponse{ + Target: &action.Target{ Details: &object.Details{ ResourceOwner: Tester.Instance.InstanceID(), }, - TargetType: &execution.Target_RestWebhook{ - RestWebhook: &execution.SetRESTWebhook{ + TargetType: &action.Target_RestWebhook{ + RestWebhook: &action.SetRESTWebhook{ Url: "https://example.com", }, }, @@ -81,7 +82,7 @@ func TestServer_GetTargetByID(t *testing.T) { name: "get, async, ok", args: args{ ctx: CTX, - dep: func(ctx context.Context, request *execution.GetTargetByIDRequest, response *execution.GetTargetByIDResponse) error { + dep: func(ctx context.Context, request *action.GetTargetByIDRequest, response *action.GetTargetByIDResponse) error { name := fmt.Sprint(time.Now().UnixNano() + 1) resp := Tester.CreateTargetWithNameAndType(ctx, t, name, true, false) request.TargetId = resp.GetId() @@ -93,20 +94,20 @@ func TestServer_GetTargetByID(t *testing.T) { response.Target.Details.Sequence = resp.GetDetails().GetSequence() return nil }, - req: &execution.GetTargetByIDRequest{}, + req: &action.GetTargetByIDRequest{}, }, - want: &execution.GetTargetByIDResponse{ - Target: &execution.Target{ + want: &action.GetTargetByIDResponse{ + Target: &action.Target{ Details: &object.Details{ ResourceOwner: Tester.Instance.InstanceID(), }, - TargetType: &execution.Target_RestWebhook{ - RestWebhook: &execution.SetRESTWebhook{ + TargetType: &action.Target_RestWebhook{ + RestWebhook: &action.SetRESTWebhook{ Url: "https://example.com", }, }, Timeout: durationpb.New(10 * time.Second), - ExecutionType: &execution.Target_IsAsync{IsAsync: true}, + ExecutionType: &action.Target_IsAsync{IsAsync: true}, }, }, }, @@ -114,7 +115,7 @@ func TestServer_GetTargetByID(t *testing.T) { name: "get, interruptOnError, ok", args: args{ ctx: CTX, - dep: func(ctx context.Context, request *execution.GetTargetByIDRequest, response *execution.GetTargetByIDResponse) error { + dep: func(ctx context.Context, request *action.GetTargetByIDRequest, response *action.GetTargetByIDResponse) error { name := fmt.Sprint(time.Now().UnixNano() + 1) resp := Tester.CreateTargetWithNameAndType(ctx, t, name, false, true) request.TargetId = resp.GetId() @@ -126,20 +127,20 @@ func TestServer_GetTargetByID(t *testing.T) { response.Target.Details.Sequence = resp.GetDetails().GetSequence() return nil }, - req: &execution.GetTargetByIDRequest{}, + req: &action.GetTargetByIDRequest{}, }, - want: &execution.GetTargetByIDResponse{ - Target: &execution.Target{ + want: &action.GetTargetByIDResponse{ + Target: &action.Target{ Details: &object.Details{ ResourceOwner: Tester.Instance.InstanceID(), }, - TargetType: &execution.Target_RestWebhook{ - RestWebhook: &execution.SetRESTWebhook{ + TargetType: &action.Target_RestWebhook{ + RestWebhook: &action.SetRESTWebhook{ Url: "https://example.com", }, }, Timeout: durationpb.New(10 * time.Second), - ExecutionType: &execution.Target_InterruptOnError{InterruptOnError: true}, + ExecutionType: &action.Target_InterruptOnError{InterruptOnError: true}, }, }, }, @@ -178,22 +179,23 @@ func TestServer_GetTargetByID(t *testing.T) { } func TestServer_ListTargets(t *testing.T) { + ensureFeatureEnabled(t) type args struct { ctx context.Context - dep func(context.Context, *execution.ListTargetsRequest, *execution.ListTargetsResponse) error - req *execution.ListTargetsRequest + dep func(context.Context, *action.ListTargetsRequest, *action.ListTargetsResponse) error + req *action.ListTargetsRequest } tests := []struct { name string args args - want *execution.ListTargetsResponse + want *action.ListTargetsResponse wantErr bool }{ { name: "missing permission", args: args{ ctx: Tester.WithAuthorization(context.Background(), integration.OrgOwner), - req: &execution.ListTargetsRequest{}, + req: &action.ListTargetsRequest{}, }, wantErr: true, }, @@ -201,10 +203,10 @@ func TestServer_ListTargets(t *testing.T) { name: "list, not found", args: args{ ctx: CTX, - req: &execution.ListTargetsRequest{ - Queries: []*execution.TargetSearchQuery{ - {Query: &execution.TargetSearchQuery_InTargetIdsQuery{ - InTargetIdsQuery: &execution.InTargetIDsQuery{ + req: &action.ListTargetsRequest{ + Queries: []*action.TargetSearchQuery{ + {Query: &action.TargetSearchQuery_InTargetIdsQuery{ + InTargetIdsQuery: &action.InTargetIDsQuery{ TargetIds: []string{"notfound"}, }, }, @@ -212,22 +214,22 @@ func TestServer_ListTargets(t *testing.T) { }, }, }, - want: &execution.ListTargetsResponse{ + want: &action.ListTargetsResponse{ Details: &object.ListDetails{ TotalResult: 0, }, - Result: []*execution.Target{}, + Result: []*action.Target{}, }, }, { name: "list single id", args: args{ ctx: CTX, - dep: func(ctx context.Context, request *execution.ListTargetsRequest, response *execution.ListTargetsResponse) error { + dep: func(ctx context.Context, request *action.ListTargetsRequest, response *action.ListTargetsResponse) error { name := fmt.Sprint(time.Now().UnixNano() + 1) resp := Tester.CreateTargetWithNameAndType(ctx, t, name, false, false) - request.Queries[0].Query = &execution.TargetSearchQuery_InTargetIdsQuery{ - InTargetIdsQuery: &execution.InTargetIDsQuery{ + request.Queries[0].Query = &action.TargetSearchQuery_InTargetIdsQuery{ + InTargetIdsQuery: &action.InTargetIDsQuery{ TargetIds: []string{resp.GetId()}, }, } @@ -240,21 +242,21 @@ func TestServer_ListTargets(t *testing.T) { response.Result[0].Name = name return nil }, - req: &execution.ListTargetsRequest{ - Queries: []*execution.TargetSearchQuery{{}}, + req: &action.ListTargetsRequest{ + Queries: []*action.TargetSearchQuery{{}}, }, }, - want: &execution.ListTargetsResponse{ + want: &action.ListTargetsResponse{ Details: &object.ListDetails{ TotalResult: 1, }, - Result: []*execution.Target{ + Result: []*action.Target{ { Details: &object.Details{ ResourceOwner: Tester.Instance.InstanceID(), }, - TargetType: &execution.Target_RestWebhook{ - RestWebhook: &execution.SetRESTWebhook{ + TargetType: &action.Target_RestWebhook{ + RestWebhook: &action.SetRESTWebhook{ Url: "https://example.com", }, }, @@ -266,11 +268,11 @@ func TestServer_ListTargets(t *testing.T) { name: "list single name", args: args{ ctx: CTX, - dep: func(ctx context.Context, request *execution.ListTargetsRequest, response *execution.ListTargetsResponse) error { + dep: func(ctx context.Context, request *action.ListTargetsRequest, response *action.ListTargetsResponse) error { name := fmt.Sprint(time.Now().UnixNano() + 1) resp := Tester.CreateTargetWithNameAndType(ctx, t, name, false, false) - request.Queries[0].Query = &execution.TargetSearchQuery_TargetNameQuery{ - TargetNameQuery: &execution.TargetNameQuery{ + request.Queries[0].Query = &action.TargetSearchQuery_TargetNameQuery{ + TargetNameQuery: &action.TargetNameQuery{ TargetName: name, }, } @@ -283,21 +285,21 @@ func TestServer_ListTargets(t *testing.T) { response.Result[0].Name = name return nil }, - req: &execution.ListTargetsRequest{ - Queries: []*execution.TargetSearchQuery{{}}, + req: &action.ListTargetsRequest{ + Queries: []*action.TargetSearchQuery{{}}, }, }, - want: &execution.ListTargetsResponse{ + want: &action.ListTargetsResponse{ Details: &object.ListDetails{ TotalResult: 1, }, - Result: []*execution.Target{ + Result: []*action.Target{ { Details: &object.Details{ ResourceOwner: Tester.Instance.InstanceID(), }, - TargetType: &execution.Target_RestWebhook{ - RestWebhook: &execution.SetRESTWebhook{ + TargetType: &action.Target_RestWebhook{ + RestWebhook: &action.SetRESTWebhook{ Url: "https://example.com", }, }, @@ -310,15 +312,15 @@ func TestServer_ListTargets(t *testing.T) { name: "list multiple id", args: args{ ctx: CTX, - dep: func(ctx context.Context, request *execution.ListTargetsRequest, response *execution.ListTargetsResponse) error { + dep: func(ctx context.Context, request *action.ListTargetsRequest, response *action.ListTargetsResponse) error { name1 := fmt.Sprint(time.Now().UnixNano() + 1) name2 := fmt.Sprint(time.Now().UnixNano() + 3) name3 := fmt.Sprint(time.Now().UnixNano() + 5) resp1 := Tester.CreateTargetWithNameAndType(ctx, t, name1, false, false) resp2 := Tester.CreateTargetWithNameAndType(ctx, t, name2, true, false) resp3 := Tester.CreateTargetWithNameAndType(ctx, t, name3, false, true) - request.Queries[0].Query = &execution.TargetSearchQuery_InTargetIdsQuery{ - InTargetIdsQuery: &execution.InTargetIDsQuery{ + request.Queries[0].Query = &action.TargetSearchQuery_InTargetIdsQuery{ + InTargetIdsQuery: &action.InTargetIDsQuery{ TargetIds: []string{resp1.GetId(), resp2.GetId(), resp3.GetId()}, }, } @@ -339,21 +341,21 @@ func TestServer_ListTargets(t *testing.T) { response.Result[2].Name = name3 return nil }, - req: &execution.ListTargetsRequest{ - Queries: []*execution.TargetSearchQuery{{}}, + req: &action.ListTargetsRequest{ + Queries: []*action.TargetSearchQuery{{}}, }, }, - want: &execution.ListTargetsResponse{ + want: &action.ListTargetsResponse{ Details: &object.ListDetails{ TotalResult: 3, }, - Result: []*execution.Target{ + Result: []*action.Target{ { Details: &object.Details{ ResourceOwner: Tester.Instance.InstanceID(), }, - TargetType: &execution.Target_RestWebhook{ - RestWebhook: &execution.SetRESTWebhook{ + TargetType: &action.Target_RestWebhook{ + RestWebhook: &action.SetRESTWebhook{ Url: "https://example.com", }, }, @@ -363,25 +365,25 @@ func TestServer_ListTargets(t *testing.T) { Details: &object.Details{ ResourceOwner: Tester.Instance.InstanceID(), }, - TargetType: &execution.Target_RestWebhook{ - RestWebhook: &execution.SetRESTWebhook{ + TargetType: &action.Target_RestWebhook{ + RestWebhook: &action.SetRESTWebhook{ Url: "https://example.com", }, }, Timeout: durationpb.New(10 * time.Second), - ExecutionType: &execution.Target_IsAsync{IsAsync: true}, + ExecutionType: &action.Target_IsAsync{IsAsync: true}, }, { Details: &object.Details{ ResourceOwner: Tester.Instance.InstanceID(), }, - TargetType: &execution.Target_RestWebhook{ - RestWebhook: &execution.SetRESTWebhook{ + TargetType: &action.Target_RestWebhook{ + RestWebhook: &action.SetRESTWebhook{ Url: "https://example.com", }, }, Timeout: durationpb.New(10 * time.Second), - ExecutionType: &execution.Target_InterruptOnError{InterruptOnError: true}, + ExecutionType: &action.Target_InterruptOnError{InterruptOnError: true}, }, }, }, @@ -421,24 +423,25 @@ func TestServer_ListTargets(t *testing.T) { } func TestServer_ListExecutions_Request(t *testing.T) { + ensureFeatureEnabled(t) targetResp := Tester.CreateTarget(CTX, t) type args struct { ctx context.Context - dep func(context.Context, *execution.ListExecutionsRequest, *execution.ListExecutionsResponse) error - req *execution.ListExecutionsRequest + dep func(context.Context, *action.ListExecutionsRequest, *action.ListExecutionsResponse) error + req *action.ListExecutionsRequest } tests := []struct { name string args args - want *execution.ListExecutionsResponse + want *action.ListExecutionsResponse wantErr bool }{ { name: "missing permission", args: args{ ctx: Tester.WithAuthorization(context.Background(), integration.OrgOwner), - req: &execution.ListExecutionsRequest{}, + req: &action.ListExecutionsRequest{}, }, wantErr: true, }, @@ -446,7 +449,7 @@ func TestServer_ListExecutions_Request(t *testing.T) { name: "list single condition", args: args{ ctx: CTX, - dep: func(ctx context.Context, request *execution.ListExecutionsRequest, response *execution.ListExecutionsResponse) error { + dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) error { resp := Tester.SetExecution(ctx, t, request.Queries[0].GetInConditionsQuery().GetConditions()[0], []string{targetResp.GetId()}, []string{}) response.Details.Timestamp = resp.GetDetails().GetChangeDate() @@ -456,14 +459,14 @@ func TestServer_ListExecutions_Request(t *testing.T) { response.Result[0].Details.Sequence = resp.GetDetails().GetSequence() return nil }, - req: &execution.ListExecutionsRequest{ - Queries: []*execution.SearchQuery{{ - Query: &execution.SearchQuery_InConditionsQuery{ - InConditionsQuery: &execution.InConditionsQuery{ - Conditions: []*execution.Condition{{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_Method{ + req: &action.ListExecutionsRequest{ + Queries: []*action.SearchQuery{{ + Query: &action.SearchQuery_InConditionsQuery{ + InConditionsQuery: &action.InConditionsQuery{ + Conditions: []*action.Condition{{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ Method: "/zitadel.session.v2beta.SessionService/GetSession", }, }, @@ -475,11 +478,11 @@ func TestServer_ListExecutions_Request(t *testing.T) { }}, }, }, - want: &execution.ListExecutionsResponse{ + want: &action.ListExecutionsResponse{ Details: &object.ListDetails{ TotalResult: 1, }, - Result: []*execution.Execution{ + Result: []*action.Execution{ { Details: &object.Details{ ResourceOwner: Tester.Instance.InstanceID(), @@ -494,20 +497,20 @@ func TestServer_ListExecutions_Request(t *testing.T) { name: "list single target", args: args{ ctx: CTX, - dep: func(ctx context.Context, request *execution.ListExecutionsRequest, response *execution.ListExecutionsResponse) error { + dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) error { target := Tester.CreateTarget(ctx, t) // add target as query to the request - request.Queries[0] = &execution.SearchQuery{ - Query: &execution.SearchQuery_TargetQuery{ - TargetQuery: &execution.TargetQuery{ + request.Queries[0] = &action.SearchQuery{ + Query: &action.SearchQuery_TargetQuery{ + TargetQuery: &action.TargetQuery{ TargetId: target.GetId(), }, }, } - resp := Tester.SetExecution(ctx, t, &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_Method{ + resp := Tester.SetExecution(ctx, t, &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ Method: "/zitadel.management.v1.ManagementService/UpdateAction", }, }, @@ -522,15 +525,15 @@ func TestServer_ListExecutions_Request(t *testing.T) { response.Result[0].Targets[0] = target.GetId() return nil }, - req: &execution.ListExecutionsRequest{ - Queries: []*execution.SearchQuery{{}}, + req: &action.ListExecutionsRequest{ + Queries: []*action.SearchQuery{{}}, }, }, - want: &execution.ListExecutionsResponse{ + want: &action.ListExecutionsResponse{ Details: &object.ListDetails{ TotalResult: 1, }, - Result: []*execution.Execution{ + Result: []*action.Execution{ { Details: &object.Details{ ResourceOwner: Tester.Instance.InstanceID(), @@ -544,20 +547,20 @@ func TestServer_ListExecutions_Request(t *testing.T) { name: "list single include", args: args{ ctx: CTX, - dep: func(ctx context.Context, request *execution.ListExecutionsRequest, response *execution.ListExecutionsResponse) error { - Tester.SetExecution(ctx, t, &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_Method{ + dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) error { + Tester.SetExecution(ctx, t, &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ Method: "/zitadel.management.v1.ManagementService/GetAction", }, }, }, }, []string{targetResp.GetId()}, []string{}) - resp2 := Tester.SetExecution(ctx, t, &execution.Condition{ - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_Method{ + resp2 := Tester.SetExecution(ctx, t, &action.Condition{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ Method: "/zitadel.management.v1.ManagementService/ListActions", }, }, @@ -571,19 +574,19 @@ func TestServer_ListExecutions_Request(t *testing.T) { response.Result[0].Details.Sequence = resp2.GetDetails().GetSequence() return nil }, - req: &execution.ListExecutionsRequest{ - Queries: []*execution.SearchQuery{{ - Query: &execution.SearchQuery_IncludeQuery{ - IncludeQuery: &execution.IncludeQuery{Include: "request./zitadel.management.v1.ManagementService/GetAction"}, + req: &action.ListExecutionsRequest{ + Queries: []*action.SearchQuery{{ + Query: &action.SearchQuery_IncludeQuery{ + IncludeQuery: &action.IncludeQuery{Include: "request./zitadel.management.v1.ManagementService/GetAction"}, }, }}, }, }, - want: &execution.ListExecutionsResponse{ + want: &action.ListExecutionsResponse{ Details: &object.ListDetails{ TotalResult: 1, }, - Result: []*execution.Execution{ + Result: []*action.Execution{ { Details: &object.Details{ ResourceOwner: Tester.Instance.InstanceID(), @@ -598,7 +601,7 @@ func TestServer_ListExecutions_Request(t *testing.T) { name: "list multiple conditions", args: args{ ctx: CTX, - dep: func(ctx context.Context, request *execution.ListExecutionsRequest, response *execution.ListExecutionsResponse) error { + dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) error { resp1 := Tester.SetExecution(ctx, t, request.Queries[0].GetInConditionsQuery().GetConditions()[0], []string{targetResp.GetId()}, []string{}) response.Result[0].Details.ChangeDate = resp1.GetDetails().GetChangeDate() @@ -615,33 +618,33 @@ func TestServer_ListExecutions_Request(t *testing.T) { response.Result[2].Details.Sequence = resp3.GetDetails().GetSequence() return nil }, - req: &execution.ListExecutionsRequest{ - Queries: []*execution.SearchQuery{{ - Query: &execution.SearchQuery_InConditionsQuery{ - InConditionsQuery: &execution.InConditionsQuery{ - Conditions: []*execution.Condition{ + req: &action.ListExecutionsRequest{ + Queries: []*action.SearchQuery{{ + Query: &action.SearchQuery_InConditionsQuery{ + InConditionsQuery: &action.InConditionsQuery{ + Conditions: []*action.Condition{ { - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_Method{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ Method: "/zitadel.session.v2beta.SessionService/GetSession", }, }, }, }, { - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_Method{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ Method: "/zitadel.session.v2beta.SessionService/CreateSession", }, }, }, }, { - ConditionType: &execution.Condition_Request{ - Request: &execution.RequestExecution{ - Condition: &execution.RequestExecution_Method{ + ConditionType: &action.Condition_Request{ + Request: &action.RequestExecution{ + Condition: &action.RequestExecution_Method{ Method: "/zitadel.session.v2beta.SessionService/SetSession", }, }, @@ -653,11 +656,11 @@ func TestServer_ListExecutions_Request(t *testing.T) { }}, }, }, - want: &execution.ListExecutionsResponse{ + want: &action.ListExecutionsResponse{ Details: &object.ListDetails{ TotalResult: 3, }, - Result: []*execution.Execution{ + Result: []*action.Execution{ { Details: &object.Details{ ResourceOwner: Tester.Instance.InstanceID(), diff --git a/internal/api/grpc/execution/v3alpha/server.go b/internal/api/grpc/action/v3alpha/server.go similarity index 62% rename from internal/api/grpc/execution/v3alpha/server.go rename to internal/api/grpc/action/v3alpha/server.go index b1a1b5cb4..dfd813a5a 100644 --- a/internal/api/grpc/execution/v3alpha/server.go +++ b/internal/api/grpc/action/v3alpha/server.go @@ -1,19 +1,22 @@ -package execution +package action import ( + "context" + "google.golang.org/grpc" "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/api/grpc/server" "github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/query" - execution "github.com/zitadel/zitadel/pkg/grpc/execution/v3alpha" + "github.com/zitadel/zitadel/internal/zerrors" + action "github.com/zitadel/zitadel/pkg/grpc/action/v3alpha" ) -var _ execution.ExecutionServiceServer = (*Server)(nil) +var _ action.ActionServiceServer = (*Server)(nil) type Server struct { - execution.UnimplementedExecutionServiceServer + action.UnimplementedActionServiceServer command *command.Commands query *query.Queries ListActionFunctions func() []string @@ -40,21 +43,28 @@ func CreateServer( } func (s *Server) RegisterServer(grpcServer *grpc.Server) { - execution.RegisterExecutionServiceServer(grpcServer, s) + action.RegisterActionServiceServer(grpcServer, s) } func (s *Server) AppName() string { - return execution.ExecutionService_ServiceDesc.ServiceName + return action.ActionService_ServiceDesc.ServiceName } func (s *Server) MethodPrefix() string { - return execution.ExecutionService_ServiceDesc.ServiceName + return action.ActionService_ServiceDesc.ServiceName } func (s *Server) AuthMethods() authz.MethodMapping { - return execution.ExecutionService_AuthMethods + return action.ActionService_AuthMethods } func (s *Server) RegisterGateway() server.RegisterGatewayFunc { - return execution.RegisterExecutionServiceHandler + return action.RegisterActionServiceHandler +} + +func checkExecutionEnabled(ctx context.Context) error { + if authz.GetInstance(ctx).Features().Actions { + return nil + } + return zerrors.ThrowPreconditionFailed(nil, "SCHEMA-141bwx3lef", "Errors.action.NotEnabled") } diff --git a/internal/api/grpc/action/v3alpha/server_integration_test.go b/internal/api/grpc/action/v3alpha/server_integration_test.go new file mode 100644 index 000000000..d27105fc4 --- /dev/null +++ b/internal/api/grpc/action/v3alpha/server_integration_test.go @@ -0,0 +1,69 @@ +//go:build integration + +package action_test + +import ( + "context" + "os" + "testing" + "time" + + "github.com/muhlemmer/gu" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/zitadel/zitadel/internal/integration" + action "github.com/zitadel/zitadel/pkg/grpc/action/v3alpha" + feature "github.com/zitadel/zitadel/pkg/grpc/feature/v2beta" +) + +var ( + CTX context.Context + Tester *integration.Tester + Client action.ActionServiceClient +) + +func TestMain(m *testing.M) { + os.Exit(func() int { + ctx, errCtx, cancel := integration.Contexts(5 * time.Minute) + defer cancel() + + Tester = integration.NewTester(ctx) + defer Tester.Done() + Client = Tester.Client.ActionV3 + + CTX, _ = Tester.WithAuthorization(ctx, integration.IAMOwner), errCtx + return m.Run() + }()) +} + +func ensureFeatureEnabled(t *testing.T) { + f, err := Tester.Client.FeatureV2.GetInstanceFeatures(CTX, &feature.GetInstanceFeaturesRequest{ + Inheritance: true, + }) + require.NoError(t, err) + if f.Actions.GetEnabled() { + return + } + _, err = Tester.Client.FeatureV2.SetInstanceFeatures(CTX, &feature.SetInstanceFeaturesRequest{ + Actions: gu.Ptr(true), + }) + require.NoError(t, err) + retryDuration := time.Minute + if ctxDeadline, ok := CTX.Deadline(); ok { + retryDuration = time.Until(ctxDeadline) + } + require.EventuallyWithT(t, + func(ttt *assert.CollectT) { + f, err := Tester.Client.FeatureV2.GetInstanceFeatures(CTX, &feature.GetInstanceFeaturesRequest{ + Inheritance: true, + }) + require.NoError(ttt, err) + if f.Actions.GetEnabled() { + return + } + }, + retryDuration, + 100*time.Millisecond, + "timed out waiting for ensuring instance feature") +} diff --git a/internal/api/grpc/execution/v3alpha/target.go b/internal/api/grpc/action/v3alpha/target.go similarity index 64% rename from internal/api/grpc/execution/v3alpha/target.go rename to internal/api/grpc/action/v3alpha/target.go index 23e23dd5f..1a01ad226 100644 --- a/internal/api/grpc/execution/v3alpha/target.go +++ b/internal/api/grpc/action/v3alpha/target.go @@ -1,4 +1,4 @@ -package execution +package action import ( "context" @@ -10,49 +10,61 @@ import ( "github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/eventstore/v1/models" - execution "github.com/zitadel/zitadel/pkg/grpc/execution/v3alpha" + action "github.com/zitadel/zitadel/pkg/grpc/action/v3alpha" ) -func (s *Server) CreateTarget(ctx context.Context, req *execution.CreateTargetRequest) (*execution.CreateTargetResponse, error) { +func (s *Server) CreateTarget(ctx context.Context, req *action.CreateTargetRequest) (*action.CreateTargetResponse, error) { + if err := checkExecutionEnabled(ctx); err != nil { + return nil, err + } + add := createTargetToCommand(req) details, err := s.command.AddTarget(ctx, add, authz.GetInstance(ctx).InstanceID()) if err != nil { return nil, err } - return &execution.CreateTargetResponse{ + return &action.CreateTargetResponse{ Id: add.AggregateID, Details: object.DomainToDetailsPb(details), }, nil } -func (s *Server) UpdateTarget(ctx context.Context, req *execution.UpdateTargetRequest) (*execution.UpdateTargetResponse, error) { +func (s *Server) UpdateTarget(ctx context.Context, req *action.UpdateTargetRequest) (*action.UpdateTargetResponse, error) { + if err := checkExecutionEnabled(ctx); err != nil { + return nil, err + } + details, err := s.command.ChangeTarget(ctx, updateTargetToCommand(req), authz.GetInstance(ctx).InstanceID()) if err != nil { return nil, err } - return &execution.UpdateTargetResponse{ + return &action.UpdateTargetResponse{ Details: object.DomainToDetailsPb(details), }, nil } -func (s *Server) DeleteTarget(ctx context.Context, req *execution.DeleteTargetRequest) (*execution.DeleteTargetResponse, error) { +func (s *Server) DeleteTarget(ctx context.Context, req *action.DeleteTargetRequest) (*action.DeleteTargetResponse, error) { + if err := checkExecutionEnabled(ctx); err != nil { + return nil, err + } + details, err := s.command.DeleteTarget(ctx, req.GetTargetId(), authz.GetInstance(ctx).InstanceID()) if err != nil { return nil, err } - return &execution.DeleteTargetResponse{ + return &action.DeleteTargetResponse{ Details: object.DomainToDetailsPb(details), }, nil } -func createTargetToCommand(req *execution.CreateTargetRequest) *command.AddTarget { +func createTargetToCommand(req *action.CreateTargetRequest) *command.AddTarget { var targetType domain.TargetType var url string switch t := req.GetTargetType().(type) { - case *execution.CreateTargetRequest_RestWebhook: + case *action.CreateTargetRequest_RestWebhook: targetType = domain.TargetTypeWebhook url = t.RestWebhook.GetUrl() - case *execution.CreateTargetRequest_RestRequestResponse: + case *action.CreateTargetRequest_RestRequestResponse: targetType = domain.TargetTypeRequestResponse url = t.RestRequestResponse.GetUrl() } @@ -66,7 +78,7 @@ func createTargetToCommand(req *execution.CreateTargetRequest) *command.AddTarge } } -func updateTargetToCommand(req *execution.UpdateTargetRequest) *command.ChangeTarget { +func updateTargetToCommand(req *action.UpdateTargetRequest) *command.ChangeTarget { if req == nil { return nil } @@ -77,10 +89,10 @@ func updateTargetToCommand(req *execution.UpdateTargetRequest) *command.ChangeTa Name: req.Name, } switch t := req.GetTargetType().(type) { - case *execution.UpdateTargetRequest_RestWebhook: + case *action.UpdateTargetRequest_RestWebhook: target.TargetType = gu.Ptr(domain.TargetTypeWebhook) target.URL = gu.Ptr(t.RestWebhook.GetUrl()) - case *execution.UpdateTargetRequest_RestRequestResponse: + case *action.UpdateTargetRequest_RestRequestResponse: target.TargetType = gu.Ptr(domain.TargetTypeRequestResponse) target.URL = gu.Ptr(t.RestRequestResponse.GetUrl()) } diff --git a/internal/api/grpc/execution/v3alpha/target_integration_test.go b/internal/api/grpc/action/v3alpha/target_integration_test.go similarity index 68% rename from internal/api/grpc/execution/v3alpha/target_integration_test.go rename to internal/api/grpc/action/v3alpha/target_integration_test.go index e45476a1e..2d45bed6d 100644 --- a/internal/api/grpc/execution/v3alpha/target_integration_test.go +++ b/internal/api/grpc/action/v3alpha/target_integration_test.go @@ -1,6 +1,6 @@ //go:build integration -package execution_test +package action_test import ( "context" @@ -15,22 +15,23 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" "github.com/zitadel/zitadel/internal/integration" - execution "github.com/zitadel/zitadel/pkg/grpc/execution/v3alpha" + action "github.com/zitadel/zitadel/pkg/grpc/action/v3alpha" object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" ) func TestServer_CreateTarget(t *testing.T) { + ensureFeatureEnabled(t) tests := []struct { name string ctx context.Context - req *execution.CreateTargetRequest - want *execution.CreateTargetResponse + req *action.CreateTargetRequest + want *action.CreateTargetResponse wantErr bool }{ { name: "missing permission", ctx: Tester.WithAuthorization(context.Background(), integration.OrgOwner), - req: &execution.CreateTargetRequest{ + req: &action.CreateTargetRequest{ Name: fmt.Sprint(time.Now().UnixNano() + 1), }, wantErr: true, @@ -38,7 +39,7 @@ func TestServer_CreateTarget(t *testing.T) { { name: "empty name", ctx: CTX, - req: &execution.CreateTargetRequest{ + req: &action.CreateTargetRequest{ Name: "", }, wantErr: true, @@ -46,7 +47,7 @@ func TestServer_CreateTarget(t *testing.T) { { name: "empty type", ctx: CTX, - req: &execution.CreateTargetRequest{ + req: &action.CreateTargetRequest{ Name: fmt.Sprint(time.Now().UnixNano() + 1), TargetType: nil, }, @@ -55,10 +56,10 @@ func TestServer_CreateTarget(t *testing.T) { { name: "empty webhook url", ctx: CTX, - req: &execution.CreateTargetRequest{ + req: &action.CreateTargetRequest{ Name: fmt.Sprint(time.Now().UnixNano() + 1), - TargetType: &execution.CreateTargetRequest_RestWebhook{ - RestWebhook: &execution.SetRESTWebhook{}, + TargetType: &action.CreateTargetRequest_RestWebhook{ + RestWebhook: &action.SetRESTWebhook{}, }, }, wantErr: true, @@ -66,10 +67,10 @@ func TestServer_CreateTarget(t *testing.T) { { name: "empty request response url", ctx: CTX, - req: &execution.CreateTargetRequest{ + req: &action.CreateTargetRequest{ Name: fmt.Sprint(time.Now().UnixNano() + 1), - TargetType: &execution.CreateTargetRequest_RestRequestResponse{ - RestRequestResponse: &execution.SetRESTRequestResponse{}, + TargetType: &action.CreateTargetRequest_RestRequestResponse{ + RestRequestResponse: &action.SetRESTRequestResponse{}, }, }, wantErr: true, @@ -77,10 +78,10 @@ func TestServer_CreateTarget(t *testing.T) { { name: "empty timeout", ctx: CTX, - req: &execution.CreateTargetRequest{ + req: &action.CreateTargetRequest{ Name: fmt.Sprint(time.Now().UnixNano() + 1), - TargetType: &execution.CreateTargetRequest_RestWebhook{ - RestWebhook: &execution.SetRESTWebhook{ + TargetType: &action.CreateTargetRequest_RestWebhook{ + RestWebhook: &action.SetRESTWebhook{ Url: "https://example.com", }, }, @@ -92,17 +93,17 @@ func TestServer_CreateTarget(t *testing.T) { { name: "empty execution type, ok", ctx: CTX, - req: &execution.CreateTargetRequest{ + req: &action.CreateTargetRequest{ Name: fmt.Sprint(time.Now().UnixNano() + 1), - TargetType: &execution.CreateTargetRequest_RestWebhook{ - RestWebhook: &execution.SetRESTWebhook{ + TargetType: &action.CreateTargetRequest_RestWebhook{ + RestWebhook: &action.SetRESTWebhook{ Url: "https://example.com", }, }, Timeout: durationpb.New(10 * time.Second), ExecutionType: nil, }, - want: &execution.CreateTargetResponse{ + want: &action.CreateTargetResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -112,19 +113,19 @@ func TestServer_CreateTarget(t *testing.T) { { name: "async execution, ok", ctx: CTX, - req: &execution.CreateTargetRequest{ + req: &action.CreateTargetRequest{ Name: fmt.Sprint(time.Now().UnixNano() + 1), - TargetType: &execution.CreateTargetRequest_RestWebhook{ - RestWebhook: &execution.SetRESTWebhook{ + TargetType: &action.CreateTargetRequest_RestWebhook{ + RestWebhook: &action.SetRESTWebhook{ Url: "https://example.com", }, }, Timeout: durationpb.New(10 * time.Second), - ExecutionType: &execution.CreateTargetRequest_IsAsync{ + ExecutionType: &action.CreateTargetRequest_IsAsync{ IsAsync: true, }, }, - want: &execution.CreateTargetResponse{ + want: &action.CreateTargetResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -134,19 +135,19 @@ func TestServer_CreateTarget(t *testing.T) { { name: "interrupt on error execution, ok", ctx: CTX, - req: &execution.CreateTargetRequest{ + req: &action.CreateTargetRequest{ Name: fmt.Sprint(time.Now().UnixNano() + 1), - TargetType: &execution.CreateTargetRequest_RestWebhook{ - RestWebhook: &execution.SetRESTWebhook{ + TargetType: &action.CreateTargetRequest_RestWebhook{ + RestWebhook: &action.SetRESTWebhook{ Url: "https://example.com", }, }, Timeout: durationpb.New(10 * time.Second), - ExecutionType: &execution.CreateTargetRequest_InterruptOnError{ + ExecutionType: &action.CreateTargetRequest_InterruptOnError{ InterruptOnError: true, }, }, - want: &execution.CreateTargetResponse{ + want: &action.CreateTargetResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -170,27 +171,28 @@ func TestServer_CreateTarget(t *testing.T) { } func TestServer_UpdateTarget(t *testing.T) { + ensureFeatureEnabled(t) type args struct { ctx context.Context - req *execution.UpdateTargetRequest + req *action.UpdateTargetRequest } tests := []struct { name string - prepare func(request *execution.UpdateTargetRequest) error + prepare func(request *action.UpdateTargetRequest) error args args - want *execution.UpdateTargetResponse + want *action.UpdateTargetResponse wantErr bool }{ { name: "missing permission", - prepare: func(request *execution.UpdateTargetRequest) error { + prepare: func(request *action.UpdateTargetRequest) error { targetID := Tester.CreateTarget(CTX, t).GetId() request.TargetId = targetID return nil }, args: args{ ctx: Tester.WithAuthorization(context.Background(), integration.OrgOwner), - req: &execution.UpdateTargetRequest{ + req: &action.UpdateTargetRequest{ Name: gu.Ptr(fmt.Sprint(time.Now().UnixNano() + 1)), }, }, @@ -198,13 +200,13 @@ func TestServer_UpdateTarget(t *testing.T) { }, { name: "not existing", - prepare: func(request *execution.UpdateTargetRequest) error { + prepare: func(request *action.UpdateTargetRequest) error { request.TargetId = "notexisting" return nil }, args: args{ ctx: CTX, - req: &execution.UpdateTargetRequest{ + req: &action.UpdateTargetRequest{ Name: gu.Ptr(fmt.Sprint(time.Now().UnixNano() + 1)), }, }, @@ -212,18 +214,18 @@ func TestServer_UpdateTarget(t *testing.T) { }, { name: "change name, ok", - prepare: func(request *execution.UpdateTargetRequest) error { + prepare: func(request *action.UpdateTargetRequest) error { targetID := Tester.CreateTarget(CTX, t).GetId() request.TargetId = targetID return nil }, args: args{ ctx: CTX, - req: &execution.UpdateTargetRequest{ + req: &action.UpdateTargetRequest{ Name: gu.Ptr(fmt.Sprint(time.Now().UnixNano() + 1)), }, }, - want: &execution.UpdateTargetResponse{ + want: &action.UpdateTargetResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -232,22 +234,22 @@ func TestServer_UpdateTarget(t *testing.T) { }, { name: "change type, ok", - prepare: func(request *execution.UpdateTargetRequest) error { + prepare: func(request *action.UpdateTargetRequest) error { targetID := Tester.CreateTarget(CTX, t).GetId() request.TargetId = targetID return nil }, args: args{ ctx: CTX, - req: &execution.UpdateTargetRequest{ - TargetType: &execution.UpdateTargetRequest_RestRequestResponse{ - RestRequestResponse: &execution.SetRESTRequestResponse{ + req: &action.UpdateTargetRequest{ + TargetType: &action.UpdateTargetRequest_RestRequestResponse{ + RestRequestResponse: &action.SetRESTRequestResponse{ Url: "https://example.com", }, }, }, }, - want: &execution.UpdateTargetResponse{ + want: &action.UpdateTargetResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -256,22 +258,22 @@ func TestServer_UpdateTarget(t *testing.T) { }, { name: "change url, ok", - prepare: func(request *execution.UpdateTargetRequest) error { + prepare: func(request *action.UpdateTargetRequest) error { targetID := Tester.CreateTarget(CTX, t).GetId() request.TargetId = targetID return nil }, args: args{ ctx: CTX, - req: &execution.UpdateTargetRequest{ - TargetType: &execution.UpdateTargetRequest_RestWebhook{ - RestWebhook: &execution.SetRESTWebhook{ + req: &action.UpdateTargetRequest{ + TargetType: &action.UpdateTargetRequest_RestWebhook{ + RestWebhook: &action.SetRESTWebhook{ Url: "https://example.com/hooks/new", }, }, }, }, - want: &execution.UpdateTargetResponse{ + want: &action.UpdateTargetResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -280,18 +282,18 @@ func TestServer_UpdateTarget(t *testing.T) { }, { name: "change timeout, ok", - prepare: func(request *execution.UpdateTargetRequest) error { + prepare: func(request *action.UpdateTargetRequest) error { targetID := Tester.CreateTarget(CTX, t).GetId() request.TargetId = targetID return nil }, args: args{ ctx: CTX, - req: &execution.UpdateTargetRequest{ + req: &action.UpdateTargetRequest{ Timeout: durationpb.New(20 * time.Second), }, }, - want: &execution.UpdateTargetResponse{ + want: &action.UpdateTargetResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -300,20 +302,20 @@ func TestServer_UpdateTarget(t *testing.T) { }, { name: "change execution type, ok", - prepare: func(request *execution.UpdateTargetRequest) error { + prepare: func(request *action.UpdateTargetRequest) error { targetID := Tester.CreateTarget(CTX, t).GetId() request.TargetId = targetID return nil }, args: args{ ctx: CTX, - req: &execution.UpdateTargetRequest{ - ExecutionType: &execution.UpdateTargetRequest_IsAsync{ + req: &action.UpdateTargetRequest{ + ExecutionType: &action.UpdateTargetRequest_IsAsync{ IsAsync: true, }, }, }, - want: &execution.UpdateTargetResponse{ + want: &action.UpdateTargetResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), @@ -338,18 +340,19 @@ func TestServer_UpdateTarget(t *testing.T) { } func TestServer_DeleteTarget(t *testing.T) { + ensureFeatureEnabled(t) target := Tester.CreateTarget(CTX, t) tests := []struct { name string ctx context.Context - req *execution.DeleteTargetRequest - want *execution.DeleteTargetResponse + req *action.DeleteTargetRequest + want *action.DeleteTargetResponse wantErr bool }{ { name: "missing permission", ctx: Tester.WithAuthorization(context.Background(), integration.OrgOwner), - req: &execution.DeleteTargetRequest{ + req: &action.DeleteTargetRequest{ TargetId: target.GetId(), }, wantErr: true, @@ -357,7 +360,7 @@ func TestServer_DeleteTarget(t *testing.T) { { name: "empty id", ctx: CTX, - req: &execution.DeleteTargetRequest{ + req: &action.DeleteTargetRequest{ TargetId: "", }, wantErr: true, @@ -365,10 +368,10 @@ func TestServer_DeleteTarget(t *testing.T) { { name: "delete target", ctx: CTX, - req: &execution.DeleteTargetRequest{ + req: &action.DeleteTargetRequest{ TargetId: target.GetId(), }, - want: &execution.DeleteTargetResponse{ + want: &action.DeleteTargetResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Instance.InstanceID(), diff --git a/internal/api/grpc/execution/v3alpha/target_test.go b/internal/api/grpc/action/v3alpha/target_test.go similarity index 77% rename from internal/api/grpc/execution/v3alpha/target_test.go rename to internal/api/grpc/action/v3alpha/target_test.go index 02939e515..f630a6c71 100644 --- a/internal/api/grpc/execution/v3alpha/target_test.go +++ b/internal/api/grpc/action/v3alpha/target_test.go @@ -1,4 +1,4 @@ -package execution +package action import ( "testing" @@ -10,12 +10,12 @@ import ( "github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/domain" - execution "github.com/zitadel/zitadel/pkg/grpc/execution/v3alpha" + action "github.com/zitadel/zitadel/pkg/grpc/action/v3alpha" ) func Test_createTargetToCommand(t *testing.T) { type args struct { - req *execution.CreateTargetRequest + req *action.CreateTargetRequest } tests := []struct { name string @@ -35,15 +35,15 @@ func Test_createTargetToCommand(t *testing.T) { }, { name: "all fields (async webhook)", - args: args{&execution.CreateTargetRequest{ + args: args{&action.CreateTargetRequest{ Name: "target 1", - TargetType: &execution.CreateTargetRequest_RestWebhook{ - RestWebhook: &execution.SetRESTWebhook{ + TargetType: &action.CreateTargetRequest_RestWebhook{ + RestWebhook: &action.SetRESTWebhook{ Url: "https://example.com/hooks/1", }, }, Timeout: durationpb.New(10 * time.Second), - ExecutionType: &execution.CreateTargetRequest_IsAsync{ + ExecutionType: &action.CreateTargetRequest_IsAsync{ IsAsync: true, }, }}, @@ -58,15 +58,15 @@ func Test_createTargetToCommand(t *testing.T) { }, { name: "all fields (interrupting response)", - args: args{&execution.CreateTargetRequest{ + args: args{&action.CreateTargetRequest{ Name: "target 1", - TargetType: &execution.CreateTargetRequest_RestRequestResponse{ - RestRequestResponse: &execution.SetRESTRequestResponse{ + TargetType: &action.CreateTargetRequest_RestRequestResponse{ + RestRequestResponse: &action.SetRESTRequestResponse{ Url: "https://example.com/hooks/1", }, }, Timeout: durationpb.New(10 * time.Second), - ExecutionType: &execution.CreateTargetRequest_InterruptOnError{ + ExecutionType: &action.CreateTargetRequest_InterruptOnError{ InterruptOnError: true, }, }}, @@ -90,7 +90,7 @@ func Test_createTargetToCommand(t *testing.T) { func Test_updateTargetToCommand(t *testing.T) { type args struct { - req *execution.UpdateTargetRequest + req *action.UpdateTargetRequest } tests := []struct { name string @@ -104,7 +104,7 @@ func Test_updateTargetToCommand(t *testing.T) { }, { name: "all fields nil", - args: args{&execution.UpdateTargetRequest{ + args: args{&action.UpdateTargetRequest{ Name: nil, TargetType: nil, Timeout: nil, @@ -121,7 +121,7 @@ func Test_updateTargetToCommand(t *testing.T) { }, { name: "all fields empty", - args: args{&execution.UpdateTargetRequest{ + args: args{&action.UpdateTargetRequest{ Name: gu.Ptr(""), TargetType: nil, Timeout: durationpb.New(0), @@ -138,15 +138,15 @@ func Test_updateTargetToCommand(t *testing.T) { }, { name: "all fields (async webhook)", - args: args{&execution.UpdateTargetRequest{ + args: args{&action.UpdateTargetRequest{ Name: gu.Ptr("target 1"), - TargetType: &execution.UpdateTargetRequest_RestWebhook{ - RestWebhook: &execution.SetRESTWebhook{ + TargetType: &action.UpdateTargetRequest_RestWebhook{ + RestWebhook: &action.SetRESTWebhook{ Url: "https://example.com/hooks/1", }, }, Timeout: durationpb.New(10 * time.Second), - ExecutionType: &execution.UpdateTargetRequest_IsAsync{ + ExecutionType: &action.UpdateTargetRequest_IsAsync{ IsAsync: true, }, }}, @@ -161,15 +161,15 @@ func Test_updateTargetToCommand(t *testing.T) { }, { name: "all fields (interrupting response)", - args: args{&execution.UpdateTargetRequest{ + args: args{&action.UpdateTargetRequest{ Name: gu.Ptr("target 1"), - TargetType: &execution.UpdateTargetRequest_RestRequestResponse{ - RestRequestResponse: &execution.SetRESTRequestResponse{ + TargetType: &action.UpdateTargetRequest_RestRequestResponse{ + RestRequestResponse: &action.SetRESTRequestResponse{ Url: "https://example.com/hooks/1", }, }, Timeout: durationpb.New(10 * time.Second), - ExecutionType: &execution.UpdateTargetRequest_InterruptOnError{ + ExecutionType: &action.UpdateTargetRequest_InterruptOnError{ InterruptOnError: true, }, }}, diff --git a/internal/api/grpc/execution/v3alpha/server_integration_test.go b/internal/api/grpc/execution/v3alpha/server_integration_test.go deleted file mode 100644 index 41cdf3f8d..000000000 --- a/internal/api/grpc/execution/v3alpha/server_integration_test.go +++ /dev/null @@ -1,33 +0,0 @@ -//go:build integration - -package execution_test - -import ( - "context" - "os" - "testing" - "time" - - "github.com/zitadel/zitadel/internal/integration" - execution "github.com/zitadel/zitadel/pkg/grpc/execution/v3alpha" -) - -var ( - CTX context.Context - Tester *integration.Tester - Client execution.ExecutionServiceClient -) - -func TestMain(m *testing.M) { - os.Exit(func() int { - ctx, errCtx, cancel := integration.Contexts(5 * time.Minute) - defer cancel() - - Tester = integration.NewTester(ctx) - defer Tester.Done() - Client = Tester.Client.ExecutionV3 - - CTX, _ = Tester.WithAuthorization(ctx, integration.IAMOwner), errCtx - return m.Run() - }()) -} diff --git a/internal/api/grpc/feature/v2/converter.go b/internal/api/grpc/feature/v2/converter.go index 55ab38978..aa8b1287f 100644 --- a/internal/api/grpc/feature/v2/converter.go +++ b/internal/api/grpc/feature/v2/converter.go @@ -14,6 +14,7 @@ func systemFeaturesToCommand(req *feature_pb.SetSystemFeaturesRequest) *command. TriggerIntrospectionProjections: req.OidcTriggerIntrospectionProjections, LegacyIntrospection: req.OidcLegacyIntrospection, UserSchema: req.UserSchema, + Actions: req.Actions, TokenExchange: req.OidcTokenExchange, } } @@ -26,6 +27,7 @@ func systemFeaturesToPb(f *query.SystemFeatures) *feature_pb.GetSystemFeaturesRe OidcLegacyIntrospection: featureSourceToFlagPb(&f.LegacyIntrospection), UserSchema: featureSourceToFlagPb(&f.UserSchema), OidcTokenExchange: featureSourceToFlagPb(&f.TokenExchange), + Actions: featureSourceToFlagPb(&f.Actions), } } @@ -36,6 +38,7 @@ func instanceFeaturesToCommand(req *feature_pb.SetInstanceFeaturesRequest) *comm LegacyIntrospection: req.OidcLegacyIntrospection, UserSchema: req.UserSchema, TokenExchange: req.OidcTokenExchange, + Actions: req.Actions, } } @@ -47,6 +50,7 @@ func instanceFeaturesToPb(f *query.InstanceFeatures) *feature_pb.GetInstanceFeat OidcLegacyIntrospection: featureSourceToFlagPb(&f.LegacyIntrospection), UserSchema: featureSourceToFlagPb(&f.UserSchema), OidcTokenExchange: featureSourceToFlagPb(&f.TokenExchange), + Actions: featureSourceToFlagPb(&f.Actions), } } diff --git a/internal/api/grpc/feature/v2/converter_test.go b/internal/api/grpc/feature/v2/converter_test.go index baac093b6..78aea5eb1 100644 --- a/internal/api/grpc/feature/v2/converter_test.go +++ b/internal/api/grpc/feature/v2/converter_test.go @@ -22,6 +22,7 @@ func Test_systemFeaturesToCommand(t *testing.T) { OidcTriggerIntrospectionProjections: gu.Ptr(false), OidcLegacyIntrospection: nil, UserSchema: gu.Ptr(true), + Actions: gu.Ptr(true), OidcTokenExchange: gu.Ptr(true), } want := &command.SystemFeatures{ @@ -29,6 +30,7 @@ func Test_systemFeaturesToCommand(t *testing.T) { TriggerIntrospectionProjections: gu.Ptr(false), LegacyIntrospection: nil, UserSchema: gu.Ptr(true), + Actions: gu.Ptr(true), TokenExchange: gu.Ptr(true), } got := systemFeaturesToCommand(arg) @@ -58,6 +60,10 @@ func Test_systemFeaturesToPb(t *testing.T) { Level: feature.LevelSystem, Value: true, }, + Actions: query.FeatureSource[bool]{ + Level: feature.LevelSystem, + Value: true, + }, TokenExchange: query.FeatureSource[bool]{ Level: feature.LevelSystem, Value: false, @@ -89,6 +95,10 @@ func Test_systemFeaturesToPb(t *testing.T) { Enabled: false, Source: feature_pb.Source_SOURCE_SYSTEM, }, + Actions: &feature_pb.FeatureFlag{ + Enabled: true, + Source: feature_pb.Source_SOURCE_SYSTEM, + }, } got := systemFeaturesToPb(arg) assert.Equal(t, want, got) @@ -101,6 +111,7 @@ func Test_instanceFeaturesToCommand(t *testing.T) { OidcLegacyIntrospection: nil, UserSchema: gu.Ptr(true), OidcTokenExchange: gu.Ptr(true), + Actions: gu.Ptr(true), } want := &command.InstanceFeatures{ LoginDefaultOrg: gu.Ptr(true), @@ -108,6 +119,7 @@ func Test_instanceFeaturesToCommand(t *testing.T) { LegacyIntrospection: nil, UserSchema: gu.Ptr(true), TokenExchange: gu.Ptr(true), + Actions: gu.Ptr(true), } got := instanceFeaturesToCommand(arg) assert.Equal(t, want, got) @@ -136,6 +148,10 @@ func Test_instanceFeaturesToPb(t *testing.T) { Level: feature.LevelInstance, Value: true, }, + Actions: query.FeatureSource[bool]{ + Level: feature.LevelInstance, + Value: true, + }, TokenExchange: query.FeatureSource[bool]{ Level: feature.LevelSystem, Value: false, @@ -163,6 +179,10 @@ func Test_instanceFeaturesToPb(t *testing.T) { Enabled: true, Source: feature_pb.Source_SOURCE_INSTANCE, }, + Actions: &feature_pb.FeatureFlag{ + Enabled: true, + Source: feature_pb.Source_SOURCE_INSTANCE, + }, OidcTokenExchange: &feature_pb.FeatureFlag{ Enabled: false, Source: feature_pb.Source_SOURCE_SYSTEM, diff --git a/internal/api/grpc/feature/v2/feature_integration_test.go b/internal/api/grpc/feature/v2/feature_integration_test.go index 5413936b2..5dcd0c37f 100644 --- a/internal/api/grpc/feature/v2/feature_integration_test.go +++ b/internal/api/grpc/feature/v2/feature_integration_test.go @@ -219,6 +219,7 @@ func TestServer_GetSystemFeatures(t *testing.T) { assertFeatureFlag(t, tt.want.OidcTriggerIntrospectionProjections, got.OidcTriggerIntrospectionProjections) assertFeatureFlag(t, tt.want.OidcLegacyIntrospection, got.OidcLegacyIntrospection) assertFeatureFlag(t, tt.want.UserSchema, got.UserSchema) + assertFeatureFlag(t, tt.want.Actions, got.Actions) }) } } @@ -389,6 +390,10 @@ func TestServer_GetInstanceFeatures(t *testing.T) { Enabled: false, Source: feature.Source_SOURCE_UNSPECIFIED, }, + Actions: &feature.FeatureFlag{ + Enabled: false, + Source: feature.Source_SOURCE_UNSPECIFIED, + }, }, }, { @@ -398,6 +403,7 @@ func TestServer_GetInstanceFeatures(t *testing.T) { LoginDefaultOrg: gu.Ptr(true), OidcTriggerIntrospectionProjections: gu.Ptr(false), UserSchema: gu.Ptr(true), + Actions: gu.Ptr(true), }) require.NoError(t, err) }, @@ -418,6 +424,10 @@ func TestServer_GetInstanceFeatures(t *testing.T) { Enabled: true, Source: feature.Source_SOURCE_INSTANCE, }, + Actions: &feature.FeatureFlag{ + Enabled: true, + Source: feature.Source_SOURCE_INSTANCE, + }, }, }, { @@ -451,6 +461,10 @@ func TestServer_GetInstanceFeatures(t *testing.T) { Enabled: false, Source: feature.Source_SOURCE_UNSPECIFIED, }, + Actions: &feature.FeatureFlag{ + Enabled: false, + Source: feature.Source_SOURCE_UNSPECIFIED, + }, }, }, } diff --git a/internal/api/grpc/session/v2/session_integration_test.go b/internal/api/grpc/session/v2/session_integration_test.go index 3b2ceebbf..cc70c75ea 100644 --- a/internal/api/grpc/session/v2/session_integration_test.go +++ b/internal/api/grpc/session/v2/session_integration_test.go @@ -390,6 +390,27 @@ func TestServer_CreateSession_successfulIntent(t *testing.T) { verifyCurrentSession(t, createResp.GetSessionId(), updateResp.GetSessionToken(), updateResp.GetDetails().GetSequence(), time.Minute, nil, nil, 0, wantUserFactor, wantIntentFactor) } +func TestServer_CreateSession_successfulIntent_instant(t *testing.T) { + idpID := Tester.AddGenericOAuthProvider(t) + + intentID, token, _, _ := Tester.CreateSuccessfulOAuthIntent(t, idpID, User.GetUserId(), "id") + createResp, err := Client.CreateSession(CTX, &session.CreateSessionRequest{ + Checks: &session.Checks{ + User: &session.CheckUser{ + Search: &session.CheckUser_UserId{ + UserId: User.GetUserId(), + }, + }, + IdpIntent: &session.CheckIDPIntent{ + IdpIntentId: intentID, + IdpIntentToken: token, + }, + }, + }) + require.NoError(t, err) + verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil, nil, 0, wantUserFactor, wantIntentFactor) +} + func TestServer_CreateSession_successfulIntentUnknownUserID(t *testing.T) { idpID := Tester.AddGenericOAuthProvider(t) diff --git a/internal/api/grpc/user/schema/v3alpha/schema_integration_test.go b/internal/api/grpc/user/schema/v3alpha/schema_integration_test.go index bbd320065..f84c338ab 100644 --- a/internal/api/grpc/user/schema/v3alpha/schema_integration_test.go +++ b/internal/api/grpc/user/schema/v3alpha/schema_integration_test.go @@ -75,6 +75,8 @@ func ensureFeatureEnabled(t *testing.T) { } func TestServer_CreateUserSchema(t *testing.T) { + ensureFeatureEnabled(t) + tests := []struct { name string ctx context.Context @@ -315,7 +317,6 @@ func TestServer_CreateUserSchema(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ensureFeatureEnabled(t) got, err := Client.CreateUserSchema(tt.ctx, tt.req) if tt.wantErr { require.Error(t, err) @@ -330,6 +331,8 @@ func TestServer_CreateUserSchema(t *testing.T) { } func TestServer_UpdateUserSchema(t *testing.T) { + ensureFeatureEnabled(t) + type args struct { ctx context.Context req *schema.UpdateUserSchemaRequest @@ -572,7 +575,6 @@ func TestServer_UpdateUserSchema(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ensureFeatureEnabled(t) err := tt.prepare(tt.args.req) require.NoError(t, err) @@ -588,6 +590,8 @@ func TestServer_UpdateUserSchema(t *testing.T) { } func TestServer_DeactivateUserSchema(t *testing.T) { + ensureFeatureEnabled(t) + type args struct { ctx context.Context req *schema.DeactivateUserSchemaRequest @@ -647,7 +651,6 @@ func TestServer_DeactivateUserSchema(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ensureFeatureEnabled(t) err := tt.args.prepare(tt.args.req) require.NoError(t, err) @@ -663,6 +666,8 @@ func TestServer_DeactivateUserSchema(t *testing.T) { } func TestServer_ReactivateUserSchema(t *testing.T) { + ensureFeatureEnabled(t) + type args struct { ctx context.Context req *schema.ReactivateUserSchemaRequest @@ -722,7 +727,6 @@ func TestServer_ReactivateUserSchema(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ensureFeatureEnabled(t) err := tt.args.prepare(tt.args.req) require.NoError(t, err) @@ -738,6 +742,8 @@ func TestServer_ReactivateUserSchema(t *testing.T) { } func TestServer_DeleteUserSchema(t *testing.T) { + ensureFeatureEnabled(t) + type args struct { ctx context.Context req *schema.DeleteUserSchemaRequest @@ -797,7 +803,6 @@ func TestServer_DeleteUserSchema(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ensureFeatureEnabled(t) err := tt.args.prepare(tt.args.req) require.NoError(t, err) diff --git a/internal/auth_request/repository/mock/repository.mock.go b/internal/auth_request/repository/mock/repository.mock.go index 9dd297728..773018b21 100644 --- a/internal/auth_request/repository/mock/repository.mock.go +++ b/internal/auth_request/repository/mock/repository.mock.go @@ -5,6 +5,7 @@ // // mockgen -package mock -destination ./mock/repository.mock.go github.com/zitadel/zitadel/internal/auth_request/repository AuthRequestCache // + // Package mock is a generated GoMock package. package mock diff --git a/internal/command/instance_features.go b/internal/command/instance_features.go index abcdb439b..35ef57da3 100644 --- a/internal/command/instance_features.go +++ b/internal/command/instance_features.go @@ -17,6 +17,7 @@ type InstanceFeatures struct { LegacyIntrospection *bool UserSchema *bool TokenExchange *bool + Actions *bool } func (m *InstanceFeatures) isEmpty() bool { @@ -24,7 +25,8 @@ func (m *InstanceFeatures) isEmpty() bool { m.TriggerIntrospectionProjections == nil && m.LegacyIntrospection == nil && m.UserSchema == nil && - m.TokenExchange == nil + m.TokenExchange == nil && + m.Actions == nil } func (c *Commands) SetInstanceFeatures(ctx context.Context, f *InstanceFeatures) (*domain.ObjectDetails, error) { diff --git a/internal/command/instance_features_model.go b/internal/command/instance_features_model.go index 02c9266c6..55ce5ea3d 100644 --- a/internal/command/instance_features_model.go +++ b/internal/command/instance_features_model.go @@ -56,6 +56,7 @@ func (m *InstanceFeaturesWriteModel) Query() *eventstore.SearchQueryBuilder { feature_v2.InstanceLegacyIntrospectionEventType, feature_v2.InstanceUserSchemaEventType, feature_v2.InstanceTokenExchangeEventType, + feature_v2.InstanceActionsEventType, ). Builder().ResourceOwner(m.ResourceOwner) } @@ -66,6 +67,7 @@ func (m *InstanceFeaturesWriteModel) reduceReset() { m.LegacyIntrospection = nil m.UserSchema = nil m.TokenExchange = nil + m.Actions = nil } func (m *InstanceFeaturesWriteModel) reduceBoolFeature(event *feature_v2.SetEvent[bool]) error { @@ -86,6 +88,8 @@ func (m *InstanceFeaturesWriteModel) reduceBoolFeature(event *feature_v2.SetEven m.TokenExchange = &event.Value case feature.KeyUserSchema: m.UserSchema = &event.Value + case feature.KeyActions: + m.Actions = &event.Value } return nil } @@ -98,5 +102,6 @@ func (wm *InstanceFeaturesWriteModel) setCommands(ctx context.Context, f *Instan cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.LegacyIntrospection, f.LegacyIntrospection, feature_v2.InstanceLegacyIntrospectionEventType) cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.TokenExchange, f.TokenExchange, feature_v2.InstanceTokenExchangeEventType) cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.UserSchema, f.UserSchema, feature_v2.InstanceUserSchemaEventType) + cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.Actions, f.Actions, feature_v2.InstanceActionsEventType) return cmds } diff --git a/internal/command/instance_features_test.go b/internal/command/instance_features_test.go index 0130d91de..4765fc283 100644 --- a/internal/command/instance_features_test.go +++ b/internal/command/instance_features_test.go @@ -149,6 +149,24 @@ func TestCommands_SetInstanceFeatures(t *testing.T) { ResourceOwner: "instance1", }, }, + { + name: "set Actions", + eventstore: expectEventstore( + expectFilter(), + expectPush( + feature_v2.NewSetEvent[bool]( + ctx, aggregate, + feature_v2.InstanceActionsEventType, true, + ), + ), + ), + args: args{ctx, &InstanceFeatures{ + Actions: gu.Ptr(true), + }}, + want: &domain.ObjectDetails{ + ResourceOwner: "instance1", + }, + }, { name: "push error", eventstore: expectEventstore( @@ -186,6 +204,10 @@ func TestCommands_SetInstanceFeatures(t *testing.T) { ctx, aggregate, feature_v2.InstanceUserSchemaEventType, true, ), + feature_v2.NewSetEvent[bool]( + ctx, aggregate, + feature_v2.InstanceActionsEventType, true, + ), ), ), args: args{ctx, &InstanceFeatures{ @@ -193,6 +215,7 @@ func TestCommands_SetInstanceFeatures(t *testing.T) { TriggerIntrospectionProjections: gu.Ptr(false), LegacyIntrospection: gu.Ptr(true), UserSchema: gu.Ptr(true), + Actions: gu.Ptr(true), }}, want: &domain.ObjectDetails{ ResourceOwner: "instance1", diff --git a/internal/command/system_features.go b/internal/command/system_features.go index 70ec66dbe..838fef5b9 100644 --- a/internal/command/system_features.go +++ b/internal/command/system_features.go @@ -14,6 +14,7 @@ type SystemFeatures struct { LegacyIntrospection *bool TokenExchange *bool UserSchema *bool + Actions *bool } func (m *SystemFeatures) isEmpty() bool { @@ -21,7 +22,8 @@ func (m *SystemFeatures) isEmpty() bool { m.TriggerIntrospectionProjections == nil && m.LegacyIntrospection == nil && m.UserSchema == nil && - m.TokenExchange == nil + m.TokenExchange == nil && + m.Actions == nil } func (c *Commands) SetSystemFeatures(ctx context.Context, f *SystemFeatures) (*domain.ObjectDetails, error) { diff --git a/internal/command/system_features_model.go b/internal/command/system_features_model.go index 9b223d7f0..d21aa85cb 100644 --- a/internal/command/system_features_model.go +++ b/internal/command/system_features_model.go @@ -51,6 +51,7 @@ func (m *SystemFeaturesWriteModel) Query() *eventstore.SearchQueryBuilder { feature_v2.SystemLegacyIntrospectionEventType, feature_v2.SystemUserSchemaEventType, feature_v2.SystemTokenExchangeEventType, + feature_v2.SystemActionsEventType, ). Builder().ResourceOwner(m.ResourceOwner) } @@ -61,6 +62,7 @@ func (m *SystemFeaturesWriteModel) reduceReset() { m.LegacyIntrospection = nil m.TokenExchange = nil m.UserSchema = nil + m.Actions = nil } func (m *SystemFeaturesWriteModel) reduceBoolFeature(event *feature_v2.SetEvent[bool]) error { @@ -81,6 +83,8 @@ func (m *SystemFeaturesWriteModel) reduceBoolFeature(event *feature_v2.SetEvent[ m.UserSchema = &event.Value case feature.KeyTokenExchange: m.TokenExchange = &event.Value + case feature.KeyActions: + m.Actions = &event.Value } return nil } @@ -93,6 +97,7 @@ func (wm *SystemFeaturesWriteModel) setCommands(ctx context.Context, f *SystemFe cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.LegacyIntrospection, f.LegacyIntrospection, feature_v2.SystemLegacyIntrospectionEventType) cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.UserSchema, f.UserSchema, feature_v2.SystemUserSchemaEventType) cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.TokenExchange, f.TokenExchange, feature_v2.SystemTokenExchangeEventType) + cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.Actions, f.Actions, feature_v2.SystemActionsEventType) return cmds } diff --git a/internal/command/system_features_test.go b/internal/command/system_features_test.go index e426721e3..83d8c8550 100644 --- a/internal/command/system_features_test.go +++ b/internal/command/system_features_test.go @@ -117,6 +117,24 @@ func TestCommands_SetSystemFeatures(t *testing.T) { ResourceOwner: "SYSTEM", }, }, + { + name: "set Actions", + eventstore: expectEventstore( + expectFilter(), + expectPush( + feature_v2.NewSetEvent[bool]( + context.Background(), aggregate, + feature_v2.SystemActionsEventType, true, + ), + ), + ), + args: args{context.Background(), &SystemFeatures{ + Actions: gu.Ptr(true), + }}, + want: &domain.ObjectDetails{ + ResourceOwner: "SYSTEM", + }, + }, { name: "push error", eventstore: expectEventstore( @@ -154,6 +172,10 @@ func TestCommands_SetSystemFeatures(t *testing.T) { context.Background(), aggregate, feature_v2.SystemUserSchemaEventType, true, ), + feature_v2.NewSetEvent[bool]( + context.Background(), aggregate, + feature_v2.SystemActionsEventType, true, + ), ), ), args: args{context.Background(), &SystemFeatures{ @@ -161,6 +183,7 @@ func TestCommands_SetSystemFeatures(t *testing.T) { TriggerIntrospectionProjections: gu.Ptr(false), LegacyIntrospection: gu.Ptr(true), UserSchema: gu.Ptr(true), + Actions: gu.Ptr(true), }}, want: &domain.ObjectDetails{ ResourceOwner: "SYSTEM", @@ -205,6 +228,10 @@ func TestCommands_SetSystemFeatures(t *testing.T) { context.Background(), aggregate, feature_v2.SystemUserSchemaEventType, true, ), + feature_v2.NewSetEvent[bool]( + context.Background(), aggregate, + feature_v2.SystemActionsEventType, false, + ), ), ), args: args{context.Background(), &SystemFeatures{ @@ -212,6 +239,7 @@ func TestCommands_SetSystemFeatures(t *testing.T) { TriggerIntrospectionProjections: gu.Ptr(false), LegacyIntrospection: gu.Ptr(true), UserSchema: gu.Ptr(true), + Actions: gu.Ptr(false), }}, want: &domain.ObjectDetails{ ResourceOwner: "SYSTEM", diff --git a/internal/domain/feature.go b/internal/domain/feature.go index 47f58c991..ffd4e8e68 100644 --- a/internal/domain/feature.go +++ b/internal/domain/feature.go @@ -1,5 +1,3 @@ -//go:generate enumer -type Feature - package domain type Feature int diff --git a/internal/eventstore/repository/mock/repository.mock.go b/internal/eventstore/repository/mock/repository.mock.go index 8fef0ceac..a854de299 100644 --- a/internal/eventstore/repository/mock/repository.mock.go +++ b/internal/eventstore/repository/mock/repository.mock.go @@ -5,6 +5,7 @@ // // mockgen -package mock -destination ./repository.mock.go github.com/zitadel/zitadel/internal/eventstore Querier,Pusher // + // Package mock is a generated GoMock package. package mock diff --git a/internal/feature/feature.go b/internal/feature/feature.go index d497f626b..5edab4a8b 100644 --- a/internal/feature/feature.go +++ b/internal/feature/feature.go @@ -10,6 +10,7 @@ const ( KeyLegacyIntrospection KeyUserSchema KeyTokenExchange + KeyActions ) //go:generate enumer -type Level -transform snake -trimprefix Level @@ -31,4 +32,5 @@ type Features struct { LegacyIntrospection bool `json:"legacy_introspection,omitempty"` UserSchema bool `json:"user_schema,omitempty"` TokenExchange bool `json:"token_exchange,omitempty"` + Actions bool `json:"actions,omitempty"` } diff --git a/internal/feature/key_enumer.go b/internal/feature/key_enumer.go index 06a052ee8..172d5f9d0 100644 --- a/internal/feature/key_enumer.go +++ b/internal/feature/key_enumer.go @@ -7,11 +7,11 @@ import ( "strings" ) -const _KeyName = "unspecifiedlogin_default_orgtrigger_introspection_projectionslegacy_introspectionuser_schematoken_exchange" +const _KeyName = "unspecifiedlogin_default_orgtrigger_introspection_projectionslegacy_introspectionuser_schematoken_exchangeactions" -var _KeyIndex = [...]uint8{0, 11, 28, 61, 81, 92, 106} +var _KeyIndex = [...]uint8{0, 11, 28, 61, 81, 92, 106, 113} -const _KeyLowerName = "unspecifiedlogin_default_orgtrigger_introspection_projectionslegacy_introspectionuser_schematoken_exchange" +const _KeyLowerName = "unspecifiedlogin_default_orgtrigger_introspection_projectionslegacy_introspectionuser_schematoken_exchangeactions" func (i Key) String() string { if i < 0 || i >= Key(len(_KeyIndex)-1) { @@ -30,23 +30,26 @@ func _KeyNoOp() { _ = x[KeyLegacyIntrospection-(3)] _ = x[KeyUserSchema-(4)] _ = x[KeyTokenExchange-(5)] + _ = x[KeyActions-(6)] } -var _KeyValues = []Key{KeyUnspecified, KeyLoginDefaultOrg, KeyTriggerIntrospectionProjections, KeyLegacyIntrospection, KeyUserSchema, KeyTokenExchange} +var _KeyValues = []Key{KeyUnspecified, KeyLoginDefaultOrg, KeyTriggerIntrospectionProjections, KeyLegacyIntrospection, KeyUserSchema, KeyTokenExchange, KeyActions} var _KeyNameToValueMap = map[string]Key{ - _KeyName[0:11]: KeyUnspecified, - _KeyLowerName[0:11]: KeyUnspecified, - _KeyName[11:28]: KeyLoginDefaultOrg, - _KeyLowerName[11:28]: KeyLoginDefaultOrg, - _KeyName[28:61]: KeyTriggerIntrospectionProjections, - _KeyLowerName[28:61]: KeyTriggerIntrospectionProjections, - _KeyName[61:81]: KeyLegacyIntrospection, - _KeyLowerName[61:81]: KeyLegacyIntrospection, - _KeyName[81:92]: KeyUserSchema, - _KeyLowerName[81:92]: KeyUserSchema, - _KeyName[92:106]: KeyTokenExchange, - _KeyLowerName[92:106]: KeyTokenExchange, + _KeyName[0:11]: KeyUnspecified, + _KeyLowerName[0:11]: KeyUnspecified, + _KeyName[11:28]: KeyLoginDefaultOrg, + _KeyLowerName[11:28]: KeyLoginDefaultOrg, + _KeyName[28:61]: KeyTriggerIntrospectionProjections, + _KeyLowerName[28:61]: KeyTriggerIntrospectionProjections, + _KeyName[61:81]: KeyLegacyIntrospection, + _KeyLowerName[61:81]: KeyLegacyIntrospection, + _KeyName[81:92]: KeyUserSchema, + _KeyLowerName[81:92]: KeyUserSchema, + _KeyName[92:106]: KeyTokenExchange, + _KeyLowerName[92:106]: KeyTokenExchange, + _KeyName[106:113]: KeyActions, + _KeyLowerName[106:113]: KeyActions, } var _KeyNames = []string{ @@ -56,6 +59,7 @@ var _KeyNames = []string{ _KeyName[61:81], _KeyName[81:92], _KeyName[92:106], + _KeyName[106:113], } // KeyString retrieves an enum value from the enum constants string name. diff --git a/internal/id/mock/generator.mock.go b/internal/id/mock/generator.mock.go index 898d3a1e8..9fce9d958 100644 --- a/internal/id/mock/generator.mock.go +++ b/internal/id/mock/generator.mock.go @@ -5,6 +5,7 @@ // // mockgen -package mock -destination ./mock/generator.mock.go github.com/zitadel/zitadel/internal/id Generator // + // Package mock is a generated GoMock package. package mock diff --git a/internal/integration/client.go b/internal/integration/client.go index 48e7dc4a1..eb95134bc 100644 --- a/internal/integration/client.go +++ b/internal/integration/client.go @@ -25,9 +25,9 @@ import ( openid "github.com/zitadel/zitadel/internal/idp/providers/oidc" "github.com/zitadel/zitadel/internal/idp/providers/saml" "github.com/zitadel/zitadel/internal/repository/idp" + action "github.com/zitadel/zitadel/pkg/grpc/action/v3alpha" "github.com/zitadel/zitadel/pkg/grpc/admin" "github.com/zitadel/zitadel/pkg/grpc/auth" - execution "github.com/zitadel/zitadel/pkg/grpc/execution/v3alpha" feature "github.com/zitadel/zitadel/pkg/grpc/feature/v2beta" mgmt "github.com/zitadel/zitadel/pkg/grpc/management" object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" @@ -53,7 +53,7 @@ type Client struct { OIDCv2 oidc_pb.OIDCServiceClient OrgV2 organisation.OrganizationServiceClient System system.SystemServiceClient - ExecutionV3 execution.ExecutionServiceClient + ActionV3 action.ActionServiceClient FeatureV2 feature.FeatureServiceClient UserSchemaV3 schema.UserSchemaServiceClient } @@ -70,7 +70,7 @@ func newClient(cc *grpc.ClientConn) Client { OIDCv2: oidc_pb.NewOIDCServiceClient(cc), OrgV2: organisation.NewOrganizationServiceClient(cc), System: system.NewSystemServiceClient(cc), - ExecutionV3: execution.NewExecutionServiceClient(cc), + ActionV3: action.NewActionServiceClient(cc), FeatureV2: feature.NewFeatureServiceClient(cc), UserSchemaV3: schema.NewUserSchemaServiceClient(cc), } @@ -522,48 +522,48 @@ func (s *Tester) CreateProjectMembership(t *testing.T, ctx context.Context, proj require.NoError(t, err) } -func (s *Tester) CreateTarget(ctx context.Context, t *testing.T) *execution.CreateTargetResponse { - req := &execution.CreateTargetRequest{ +func (s *Tester) CreateTarget(ctx context.Context, t *testing.T) *action.CreateTargetResponse { + req := &action.CreateTargetRequest{ Name: fmt.Sprint(time.Now().UnixNano() + 1), - TargetType: &execution.CreateTargetRequest_RestWebhook{ - RestWebhook: &execution.SetRESTWebhook{ + TargetType: &action.CreateTargetRequest_RestWebhook{ + RestWebhook: &action.SetRESTWebhook{ Url: "https://example.com", }, }, Timeout: durationpb.New(10 * time.Second), } - target, err := s.Client.ExecutionV3.CreateTarget(ctx, req) + target, err := s.Client.ActionV3.CreateTarget(ctx, req) require.NoError(t, err) return target } -func (s *Tester) CreateTargetWithNameAndType(ctx context.Context, t *testing.T, name string, async bool, interrupt bool) *execution.CreateTargetResponse { - req := &execution.CreateTargetRequest{ +func (s *Tester) CreateTargetWithNameAndType(ctx context.Context, t *testing.T, name string, async bool, interrupt bool) *action.CreateTargetResponse { + req := &action.CreateTargetRequest{ Name: name, - TargetType: &execution.CreateTargetRequest_RestWebhook{ - RestWebhook: &execution.SetRESTWebhook{ + TargetType: &action.CreateTargetRequest_RestWebhook{ + RestWebhook: &action.SetRESTWebhook{ Url: "https://example.com", }, }, Timeout: durationpb.New(10 * time.Second), } if async { - req.ExecutionType = &execution.CreateTargetRequest_IsAsync{ + req.ExecutionType = &action.CreateTargetRequest_IsAsync{ IsAsync: true, } } if interrupt { - req.ExecutionType = &execution.CreateTargetRequest_InterruptOnError{ + req.ExecutionType = &action.CreateTargetRequest_InterruptOnError{ InterruptOnError: true, } } - target, err := s.Client.ExecutionV3.CreateTarget(ctx, req) + target, err := s.Client.ActionV3.CreateTarget(ctx, req) require.NoError(t, err) return target } -func (s *Tester) SetExecution(ctx context.Context, t *testing.T, cond *execution.Condition, targets []string, includes []string) *execution.SetExecutionResponse { - target, err := s.Client.ExecutionV3.SetExecution(ctx, &execution.SetExecutionRequest{ +func (s *Tester) SetExecution(ctx context.Context, t *testing.T, cond *action.Condition, targets []string, includes []string) *action.SetExecutionResponse { + target, err := s.Client.ActionV3.SetExecution(ctx, &action.SetExecutionRequest{ Condition: cond, Targets: targets, Includes: includes, diff --git a/internal/notification/channels/mock/channel.mock.go b/internal/notification/channels/mock/channel.mock.go index f00b61119..3594178a4 100644 --- a/internal/notification/channels/mock/channel.mock.go +++ b/internal/notification/channels/mock/channel.mock.go @@ -5,6 +5,7 @@ // // mockgen -package mock -destination ./mock/channel.mock.go github.com/zitadel/zitadel/internal/notification/channels NotificationChannel // + // Package mock is a generated GoMock package. package mock diff --git a/internal/notification/channels/mock/message.mock.go b/internal/notification/channels/mock/message.mock.go index 4a498b269..1e8ea0067 100644 --- a/internal/notification/channels/mock/message.mock.go +++ b/internal/notification/channels/mock/message.mock.go @@ -5,6 +5,7 @@ // // mockgen -package mock -destination ./mock/message.mock.go github.com/zitadel/zitadel/internal/notification/channels Message // + // Package mock is a generated GoMock package. package mock diff --git a/internal/notification/handlers/mock/commands.mock.go b/internal/notification/handlers/mock/commands.mock.go index 845ab264e..3105dcdf6 100644 --- a/internal/notification/handlers/mock/commands.mock.go +++ b/internal/notification/handlers/mock/commands.mock.go @@ -5,6 +5,7 @@ // // mockgen -package mock -destination ./mock/commands.mock.go github.com/zitadel/zitadel/internal/notification/handlers Commands // + // Package mock is a generated GoMock package. package mock diff --git a/internal/notification/handlers/mock/queries.mock.go b/internal/notification/handlers/mock/queries.mock.go index 620e8ccd5..18a1dd416 100644 --- a/internal/notification/handlers/mock/queries.mock.go +++ b/internal/notification/handlers/mock/queries.mock.go @@ -5,6 +5,7 @@ // // mockgen -package mock -destination ./mock/queries.mock.go github.com/zitadel/zitadel/internal/notification/handlers Queries // + // Package mock is a generated GoMock package. package mock diff --git a/internal/query/instance_features.go b/internal/query/instance_features.go index ed806f355..a362b6a5a 100644 --- a/internal/query/instance_features.go +++ b/internal/query/instance_features.go @@ -13,6 +13,7 @@ type InstanceFeatures struct { LegacyIntrospection FeatureSource[bool] UserSchema FeatureSource[bool] TokenExchange FeatureSource[bool] + Actions FeatureSource[bool] } func (q *Queries) GetInstanceFeatures(ctx context.Context, cascade bool) (_ *InstanceFeatures, err error) { diff --git a/internal/query/instance_features_model.go b/internal/query/instance_features_model.go index 50beb1e36..068e56a23 100644 --- a/internal/query/instance_features_model.go +++ b/internal/query/instance_features_model.go @@ -62,6 +62,7 @@ func (m *InstanceFeaturesReadModel) Query() *eventstore.SearchQueryBuilder { feature_v2.InstanceLegacyIntrospectionEventType, feature_v2.InstanceUserSchemaEventType, feature_v2.InstanceTokenExchangeEventType, + feature_v2.InstanceActionsEventType, ). Builder().ResourceOwner(m.ResourceOwner) } @@ -75,6 +76,7 @@ func (m *InstanceFeaturesReadModel) reduceReset() { m.instance.LegacyIntrospection = FeatureSource[bool]{} m.instance.UserSchema = FeatureSource[bool]{} m.instance.TokenExchange = FeatureSource[bool]{} + m.instance.Actions = FeatureSource[bool]{} } func (m *InstanceFeaturesReadModel) populateFromSystem() bool { @@ -86,6 +88,7 @@ func (m *InstanceFeaturesReadModel) populateFromSystem() bool { m.instance.LegacyIntrospection = m.system.LegacyIntrospection m.instance.UserSchema = m.system.UserSchema m.instance.TokenExchange = m.system.TokenExchange + m.instance.Actions = m.system.Actions return true } @@ -109,6 +112,8 @@ func (m *InstanceFeaturesReadModel) reduceBoolFeature(event *feature_v2.SetEvent dst = &m.instance.UserSchema case feature.KeyTokenExchange: dst = &m.instance.TokenExchange + case feature.KeyActions: + dst = &m.instance.Actions } *dst = FeatureSource[bool]{ Level: level, diff --git a/internal/query/instance_features_test.go b/internal/query/instance_features_test.go index 010a4d42e..e182f4002 100644 --- a/internal/query/instance_features_test.go +++ b/internal/query/instance_features_test.go @@ -105,6 +105,10 @@ func TestQueries_GetInstanceFeatures(t *testing.T) { ctx, aggregate, feature_v2.InstanceUserSchemaEventType, false, )), + eventFromEventPusher(feature_v2.NewSetEvent[bool]( + ctx, aggregate, + feature_v2.InstanceActionsEventType, false, + )), ), ), args: args{true}, @@ -128,6 +132,10 @@ func TestQueries_GetInstanceFeatures(t *testing.T) { Level: feature.LevelInstance, Value: false, }, + Actions: FeatureSource[bool]{ + Level: feature.LevelInstance, + Value: false, + }, }, }, { @@ -154,6 +162,10 @@ func TestQueries_GetInstanceFeatures(t *testing.T) { ctx, aggregate, feature_v2.InstanceUserSchemaEventType, false, )), + eventFromEventPusher(feature_v2.NewSetEvent[bool]( + ctx, aggregate, + feature_v2.InstanceActionsEventType, false, + )), eventFromEventPusher(feature_v2.NewResetEvent( ctx, aggregate, feature_v2.InstanceResetEventType, @@ -185,6 +197,10 @@ func TestQueries_GetInstanceFeatures(t *testing.T) { Level: feature.LevelUnspecified, Value: false, }, + Actions: FeatureSource[bool]{ + Level: feature.LevelUnspecified, + Value: false, + }, }, }, { @@ -207,6 +223,10 @@ func TestQueries_GetInstanceFeatures(t *testing.T) { ctx, aggregate, feature_v2.InstanceUserSchemaEventType, false, )), + eventFromEventPusher(feature_v2.NewSetEvent[bool]( + ctx, aggregate, + feature_v2.InstanceActionsEventType, false, + )), eventFromEventPusher(feature_v2.NewResetEvent( ctx, aggregate, feature_v2.InstanceResetEventType, @@ -238,6 +258,10 @@ func TestQueries_GetInstanceFeatures(t *testing.T) { Level: feature.LevelUnspecified, Value: false, }, + Actions: FeatureSource[bool]{ + Level: feature.LevelUnspecified, + Value: false, + }, }, }, } diff --git a/internal/query/projection/instance_features.go b/internal/query/projection/instance_features.go index 22e47cbfe..ebb388da8 100644 --- a/internal/query/projection/instance_features.go +++ b/internal/query/projection/instance_features.go @@ -79,6 +79,10 @@ func (*instanceFeatureProjection) Reducers() []handler.AggregateReducer { Event: feature_v2.InstanceTokenExchangeEventType, Reduce: reduceInstanceSetFeature[bool], }, + { + Event: feature_v2.InstanceActionsEventType, + Reduce: reduceInstanceSetFeature[bool], + }, { Event: instance.InstanceRemovedEventType, Reduce: reduceInstanceRemovedHelper(InstanceDomainInstanceIDCol), diff --git a/internal/query/projection/system_features.go b/internal/query/projection/system_features.go index ee3772a19..94c6282c4 100644 --- a/internal/query/projection/system_features.go +++ b/internal/query/projection/system_features.go @@ -71,6 +71,10 @@ func (*systemFeatureProjection) Reducers() []handler.AggregateReducer { Event: feature_v2.SystemTokenExchangeEventType, Reduce: reduceSystemSetFeature[bool], }, + { + Event: feature_v2.SystemActionsEventType, + Reduce: reduceSystemSetFeature[bool], + }, }, }} } diff --git a/internal/query/system_features.go b/internal/query/system_features.go index 0c18219e6..65087e92d 100644 --- a/internal/query/system_features.go +++ b/internal/query/system_features.go @@ -20,6 +20,7 @@ type SystemFeatures struct { LegacyIntrospection FeatureSource[bool] UserSchema FeatureSource[bool] TokenExchange FeatureSource[bool] + Actions FeatureSource[bool] } func (q *Queries) GetSystemFeatures(ctx context.Context) (_ *SystemFeatures, err error) { diff --git a/internal/query/system_features_model.go b/internal/query/system_features_model.go index 4067b9453..243dc4e6c 100644 --- a/internal/query/system_features_model.go +++ b/internal/query/system_features_model.go @@ -50,6 +50,7 @@ func (m *SystemFeaturesReadModel) Query() *eventstore.SearchQueryBuilder { feature_v2.SystemLegacyIntrospectionEventType, feature_v2.SystemUserSchemaEventType, feature_v2.SystemTokenExchangeEventType, + feature_v2.SystemActionsEventType, ). Builder().ResourceOwner(m.ResourceOwner) } @@ -78,6 +79,8 @@ func (m *SystemFeaturesReadModel) reduceBoolFeature(event *feature_v2.SetEvent[b dst = &m.system.UserSchema case feature.KeyTokenExchange: dst = &m.system.TokenExchange + case feature.KeyActions: + dst = &m.system.Actions } *dst = FeatureSource[bool]{ diff --git a/internal/query/system_features_test.go b/internal/query/system_features_test.go index f1dc18415..e460d38ce 100644 --- a/internal/query/system_features_test.go +++ b/internal/query/system_features_test.go @@ -61,6 +61,10 @@ func TestQueries_GetSystemFeatures(t *testing.T) { context.Background(), aggregate, feature_v2.SystemUserSchemaEventType, false, )), + eventFromEventPusher(feature_v2.NewSetEvent[bool]( + context.Background(), aggregate, + feature_v2.SystemActionsEventType, true, + )), ), ), want: &SystemFeatures{ @@ -83,6 +87,10 @@ func TestQueries_GetSystemFeatures(t *testing.T) { Level: feature.LevelSystem, Value: false, }, + Actions: FeatureSource[bool]{ + Level: feature.LevelSystem, + Value: true, + }, }, }, { @@ -105,6 +113,10 @@ func TestQueries_GetSystemFeatures(t *testing.T) { context.Background(), aggregate, feature_v2.SystemUserSchemaEventType, false, )), + eventFromEventPusher(feature_v2.NewSetEvent[bool]( + context.Background(), aggregate, + feature_v2.SystemActionsEventType, false, + )), eventFromEventPusher(feature_v2.NewResetEvent( context.Background(), aggregate, feature_v2.SystemResetEventType, @@ -135,6 +147,10 @@ func TestQueries_GetSystemFeatures(t *testing.T) { Level: feature.LevelUnspecified, Value: false, }, + Actions: FeatureSource[bool]{ + Level: feature.LevelUnspecified, + Value: false, + }, }, }, { @@ -157,6 +173,10 @@ func TestQueries_GetSystemFeatures(t *testing.T) { context.Background(), aggregate, feature_v2.SystemUserSchemaEventType, false, )), + eventFromEventPusher(feature_v2.NewSetEvent[bool]( + context.Background(), aggregate, + feature_v2.SystemActionsEventType, false, + )), eventFromEventPusher(feature_v2.NewResetEvent( context.Background(), aggregate, feature_v2.SystemResetEventType, @@ -187,6 +207,10 @@ func TestQueries_GetSystemFeatures(t *testing.T) { Level: feature.LevelUnspecified, Value: false, }, + Actions: FeatureSource[bool]{ + Level: feature.LevelUnspecified, + Value: false, + }, }, }, } diff --git a/internal/repository/feature/feature_v2/eventstore.go b/internal/repository/feature/feature_v2/eventstore.go index 7b8d7e2a0..26f33661f 100644 --- a/internal/repository/feature/feature_v2/eventstore.go +++ b/internal/repository/feature/feature_v2/eventstore.go @@ -11,10 +11,12 @@ func init() { eventstore.RegisterFilterEventMapper(AggregateType, SystemLegacyIntrospectionEventType, eventstore.GenericEventMapper[SetEvent[bool]]) eventstore.RegisterFilterEventMapper(AggregateType, SystemUserSchemaEventType, eventstore.GenericEventMapper[SetEvent[bool]]) eventstore.RegisterFilterEventMapper(AggregateType, SystemTokenExchangeEventType, eventstore.GenericEventMapper[SetEvent[bool]]) + eventstore.RegisterFilterEventMapper(AggregateType, SystemActionsEventType, eventstore.GenericEventMapper[SetEvent[bool]]) eventstore.RegisterFilterEventMapper(AggregateType, InstanceResetEventType, eventstore.GenericEventMapper[ResetEvent]) eventstore.RegisterFilterEventMapper(AggregateType, InstanceLoginDefaultOrgEventType, eventstore.GenericEventMapper[SetEvent[bool]]) eventstore.RegisterFilterEventMapper(AggregateType, InstanceTriggerIntrospectionProjectionsEventType, eventstore.GenericEventMapper[SetEvent[bool]]) eventstore.RegisterFilterEventMapper(AggregateType, InstanceLegacyIntrospectionEventType, eventstore.GenericEventMapper[SetEvent[bool]]) eventstore.RegisterFilterEventMapper(AggregateType, InstanceUserSchemaEventType, eventstore.GenericEventMapper[SetEvent[bool]]) eventstore.RegisterFilterEventMapper(AggregateType, InstanceTokenExchangeEventType, eventstore.GenericEventMapper[SetEvent[bool]]) + eventstore.RegisterFilterEventMapper(AggregateType, InstanceActionsEventType, eventstore.GenericEventMapper[SetEvent[bool]]) } diff --git a/internal/repository/feature/feature_v2/feature.go b/internal/repository/feature/feature_v2/feature.go index 1c6ee9e3e..c1f9add2d 100644 --- a/internal/repository/feature/feature_v2/feature.go +++ b/internal/repository/feature/feature_v2/feature.go @@ -17,6 +17,7 @@ var ( SystemLegacyIntrospectionEventType = setEventTypeFromFeature(feature.LevelSystem, feature.KeyLegacyIntrospection) SystemUserSchemaEventType = setEventTypeFromFeature(feature.LevelSystem, feature.KeyUserSchema) SystemTokenExchangeEventType = setEventTypeFromFeature(feature.LevelSystem, feature.KeyTokenExchange) + SystemActionsEventType = setEventTypeFromFeature(feature.LevelSystem, feature.KeyActions) InstanceResetEventType = resetEventTypeFromFeature(feature.LevelInstance) InstanceLoginDefaultOrgEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyLoginDefaultOrg) @@ -24,6 +25,7 @@ var ( InstanceLegacyIntrospectionEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyLegacyIntrospection) InstanceUserSchemaEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyUserSchema) InstanceTokenExchangeEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyTokenExchange) + InstanceActionsEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyActions) ) const ( diff --git a/internal/static/mock/storage_mock.go b/internal/static/mock/storage_mock.go index f61a8dfeb..3ef02efa9 100644 --- a/internal/static/mock/storage_mock.go +++ b/internal/static/mock/storage_mock.go @@ -5,6 +5,7 @@ // // mockgen -source storage.go -destination ./mock/storage_mock.go -package mock // + // Package mock is a generated GoMock package. package mock diff --git a/proto/zitadel/execution/v3alpha/execution_service.proto b/proto/zitadel/action/v3alpha/action_service.proto similarity index 95% rename from proto/zitadel/execution/v3alpha/execution_service.proto rename to proto/zitadel/action/v3alpha/action_service.proto index 7c044a817..4c3727632 100644 --- a/proto/zitadel/execution/v3alpha/execution_service.proto +++ b/proto/zitadel/action/v3alpha/action_service.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -package zitadel.execution.v3alpha; +package zitadel.action.v3alpha; import "google/api/annotations.proto"; import "google/api/field_behavior.proto"; @@ -8,17 +8,17 @@ import "google/protobuf/duration.proto"; import "google/protobuf/struct.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; import "validate/validate.proto"; -import "zitadel/execution/v3alpha/target.proto"; -import "zitadel/execution/v3alpha/execution.proto"; -import "zitadel/execution/v3alpha/query.proto"; +import "zitadel/action/v3alpha/target.proto"; +import "zitadel/action/v3alpha/execution.proto"; +import "zitadel/action/v3alpha/query.proto"; import "zitadel/object/v2beta/object.proto"; import "zitadel/protoc_gen_zitadel/v2/options.proto"; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/execution/v3alpha;execution"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/action/v3alpha;action"; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { info: { - title: "Execution Service"; + title: "Action Service"; version: "3.0-preview"; description: "This API is intended to manage custom executions (previously known as actions) in a ZITADEL instance. This project is in preview state. It can AND will continue breaking until the services provide the same functionality as the current actions."; contact:{ @@ -104,7 +104,7 @@ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { } }; -service ExecutionService { +service ActionService { // Create a target // @@ -516,22 +516,22 @@ message ListTargetsRequest { // list limitations and ordering. zitadel.object.v2beta.ListQuery query = 1; // the field the result is sorted. - zitadel.execution.v3alpha.TargetFieldName sorting_column = 2 [ + zitadel.action.v3alpha.TargetFieldName sorting_column = 2 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"FIELD_NAME_SCHEMA_TYPE\"" } ]; // Define the criteria to query for. - repeated zitadel.execution.v3alpha.TargetSearchQuery queries = 3; + repeated zitadel.action.v3alpha.TargetSearchQuery queries = 3; } message ListTargetsResponse { // Details provides information about the returned result including total amount found. zitadel.object.v2beta.ListDetails details = 1; // States by which field the results are sorted. - zitadel.execution.v3alpha.TargetFieldName sorting_column = 2; + zitadel.action.v3alpha.TargetFieldName sorting_column = 2; // The result contains the user schemas, which matched the queries. - repeated zitadel.execution.v3alpha.Target result = 3; + repeated zitadel.action.v3alpha.Target result = 3; } message GetTargetByIDRequest { @@ -548,7 +548,7 @@ message GetTargetByIDRequest { } message GetTargetByIDResponse { - zitadel.execution.v3alpha.Target target = 1; + zitadel.action.v3alpha.Target target = 1; } message SetExecutionRequest { @@ -579,14 +579,14 @@ message ListExecutionsRequest { // list limitations and ordering. zitadel.object.v2beta.ListQuery query = 1; // Define the criteria to query for. - repeated zitadel.execution.v3alpha.SearchQuery queries = 2; + repeated zitadel.action.v3alpha.SearchQuery queries = 2; } message ListExecutionsResponse { // Details provides information about the returned result including total amount found. zitadel.object.v2beta.ListDetails details = 1; // The result contains the executions, which matched the queries. - repeated zitadel.execution.v3alpha.Execution result = 2; + repeated zitadel.action.v3alpha.Execution result = 2; } message ListExecutionFunctionsRequest{} diff --git a/proto/zitadel/execution/v3alpha/execution.proto b/proto/zitadel/action/v3alpha/execution.proto similarity index 97% rename from proto/zitadel/execution/v3alpha/execution.proto rename to proto/zitadel/action/v3alpha/execution.proto index 14d05446b..c8b85f50a 100644 --- a/proto/zitadel/execution/v3alpha/execution.proto +++ b/proto/zitadel/action/v3alpha/execution.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -package zitadel.execution.v3alpha; +package zitadel.action.v3alpha; import "google/api/annotations.proto"; import "google/api/field_behavior.proto"; @@ -11,7 +11,7 @@ import "validate/validate.proto"; import "zitadel/object/v2beta/object.proto"; import "zitadel/protoc_gen_zitadel/v2/options.proto"; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/execution/v3alpha;execution"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/action/v3alpha;action"; message Execution { string execution_id = 1 [ diff --git a/proto/zitadel/execution/v3alpha/query.proto b/proto/zitadel/action/v3alpha/query.proto similarity index 94% rename from proto/zitadel/execution/v3alpha/query.proto rename to proto/zitadel/action/v3alpha/query.proto index c13bd12cf..26093305b 100644 --- a/proto/zitadel/execution/v3alpha/query.proto +++ b/proto/zitadel/action/v3alpha/query.proto @@ -1,14 +1,14 @@ syntax = "proto3"; -package zitadel.execution.v3alpha; +package zitadel.action.v3alpha; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/execution/v3alpha;execution"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/action/v3alpha;action"; import "google/api/field_behavior.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; import "validate/validate.proto"; import "zitadel/object/v2beta/object.proto"; -import "zitadel/execution/v3alpha/execution.proto"; +import "zitadel/action/v3alpha/execution.proto"; message SearchQuery { oneof query { diff --git a/proto/zitadel/execution/v3alpha/target.proto b/proto/zitadel/action/v3alpha/target.proto similarity index 94% rename from proto/zitadel/execution/v3alpha/target.proto rename to proto/zitadel/action/v3alpha/target.proto index 4320253e3..a034c58ac 100644 --- a/proto/zitadel/execution/v3alpha/target.proto +++ b/proto/zitadel/action/v3alpha/target.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -package zitadel.execution.v3alpha; +package zitadel.action.v3alpha; import "google/api/annotations.proto"; import "google/api/field_behavior.proto"; @@ -11,7 +11,7 @@ import "validate/validate.proto"; import "zitadel/object/v2beta/object.proto"; import "zitadel/protoc_gen_zitadel/v2/options.proto"; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/execution/v3alpha;execution"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/action/v3alpha;action"; message SetRESTWebhook { string url = 1 [ diff --git a/proto/zitadel/feature/v2beta/instance.proto b/proto/zitadel/feature/v2beta/instance.proto index f2df465c6..3cfc2c450 100644 --- a/proto/zitadel/feature/v2beta/instance.proto +++ b/proto/zitadel/feature/v2beta/instance.proto @@ -43,6 +43,12 @@ message SetInstanceFeaturesRequest{ description: "Enable the experimental `urn:ietf:params:oauth:grant-type:token-exchange` grant type for the OIDC token endpoint. Token exchange can be used to request tokens with a lesser scope or impersonate other users. See the security policy to allow impersonation on an instance."; } ]; + optional bool actions = 6 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "true"; + description: "Actions allow to manage data executions and targets. If the flag is enabled, you'll be able to use the new API and its features. Note that it is still in an early stage."; + } + ]; } message SetInstanceFeaturesResponse { @@ -100,4 +106,11 @@ message GetInstanceFeaturesResponse { description: "Enable the experimental `urn:ietf:params:oauth:grant-type:token-exchange` grant type for the OIDC token endpoint. Token exchange can be used to request tokens with a lesser scope or impersonate other users. See the security policy to allow impersonation on an instance."; } ]; + + FeatureFlag actions = 7 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "true"; + description: "Actions v2 allow to manage data executions and targets. If the flag is enabled, you'll be able to use the new API and its features. Note that it is still in an early stage."; + } + ]; } diff --git a/proto/zitadel/feature/v2beta/system.proto b/proto/zitadel/feature/v2beta/system.proto index 0091bcbd3..8f98eb062 100644 --- a/proto/zitadel/feature/v2beta/system.proto +++ b/proto/zitadel/feature/v2beta/system.proto @@ -45,7 +45,14 @@ message SetSystemFeaturesRequest{ description: "Enable the experimental `urn:ietf:params:oauth:grant-type:token-exchange` grant type for the OIDC token endpoint. Token exchange can be used to request tokens with a lesser scope or impersonate other users. See the security policy to allow impersonation on an instance."; } ]; - + + + optional bool actions = 6 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "true"; + description: "Actions allow to manage data executions and targets. If the flag is enabled, you'll be able to use the new API and its features. Note that it is still in an early stage."; + } + ]; } message SetSystemFeaturesResponse { @@ -96,4 +103,11 @@ message GetSystemFeaturesResponse { description: "Enable the experimental `urn:ietf:params:oauth:grant-type:token-exchange` grant type for the OIDC token endpoint. Token exchange can be used to request tokens with a lesser scope or impersonate other users. See the security policy to allow impersonation on an instance."; } ]; + + FeatureFlag actions = 7 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "true"; + description: "Actions v2 allow to manage data executions and targets. If the flag is enabled, you'll be able to use the new API and its features. Note that it is still in an early stage."; + } + ]; }