From ff6d593922f6199013a1fafaebf36cfe8c1e6f98 Mon Sep 17 00:00:00 2001 From: Stefan Benz <46600784+stebenz@users.noreply.github.com> Date: Mon, 28 Apr 2025 11:24:50 +0200 Subject: [PATCH] fix: remove action feature flag and include execution (#9727) # Which Problems Are Solved Actions v2 is not a feature flag anymore, include functionality on executions is not used and json tags of proto messages are handled incorrectly. # How the Problems Are Solved - Remove actions from the feature flags on system and instance level - Remove include type on executions, only in the API, later maybe in the handling logic as well - Use protojson in request and response handling of actions v2 # Additional Changes - Correct integration tests for request and response handling - Use json.RawMessage for events, so that the event payload is not base64 encoded - Added separate context for async webhook calls, that executions are not cancelled when called async # Additional Context Related to #9759 Closes #9710 --------- Co-authored-by: Livio Spring (cherry picked from commit b8ba7bd5badd8b9ee43316465ae5748e6fab0f50) --- .../guides/integrate/actions/testing-event.md | 9 +- .../actions/testing-request-manipulation.md | 25 ++- .../actions/testing-request-signature.md | 5 + .../integrate/actions/testing-request.md | 5 + .../actions/testing-response-manipulation.md | 48 ++++- .../integrate/actions/testing-response.md | 5 + docs/docs/guides/integrate/actions/usage.md | 12 +- internal/api/grpc/action/v2beta/execution.go | 54 +----- .../integration_test/execution_target_test.go | 99 +++++----- .../v2beta/integration_test/execution_test.go | 172 +++--------------- .../v2beta/integration_test/query_test.go | 145 ++++++++------- .../v2beta/integration_test/server_test.go | 46 ----- .../v2beta/integration_test/target_test.go | 3 - internal/api/grpc/action/v2beta/query.go | 24 +-- internal/api/grpc/action/v2beta/server.go | 10 - internal/api/grpc/action/v2beta/target.go | 9 - internal/api/grpc/feature/v2/converter.go | 4 - .../api/grpc/feature/v2/converter_test.go | 20 -- .../v2/integration_test/feature_test.go | 14 -- internal/api/grpc/feature/v2beta/converter.go | 4 - .../api/grpc/feature/v2beta/converter_test.go | 20 -- .../v2beta/integration_test/feature_test.go | 13 -- .../middleware/execution_interceptor.go | 62 ++++--- .../middleware/execution_interceptor_test.go | 32 ++-- internal/command/instance_features.go | 2 - internal/command/instance_features_model.go | 5 - internal/command/instance_features_test.go | 23 --- internal/command/system_features.go | 2 - internal/command/system_features_model.go | 5 - internal/command/system_features_test.go | 28 --- internal/execution/execution.go | 6 +- internal/execution/execution_test.go | 43 ++--- internal/feature/feature.go | 3 +- internal/feature/key_enumer.go | 8 +- internal/integration/action.go | 61 +++++++ internal/integration/client.go | 2 +- internal/query/instance_features.go | 1 - internal/query/instance_features_model.go | 7 +- 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 | 6 +- internal/query/system_features_test.go | 24 --- internal/repository/execution/queue.go | 20 +- .../feature/feature_v2/eventstore.go | 2 - .../repository/feature/feature_v2/feature.go | 2 - proto/buf.yaml | 4 + .../action/v2beta/action_service.proto | 4 +- proto/zitadel/action/v2beta/execution.proto | 14 +- proto/zitadel/action/v2beta/query.proto | 11 -- proto/zitadel/feature/v2/instance.proto | 17 +- proto/zitadel/feature/v2/system.proto | 18 +- proto/zitadel/feature/v2beta/instance.proto | 17 +- proto/zitadel/feature/v2beta/system.proto | 18 +- 55 files changed, 427 insertions(+), 799 deletions(-) diff --git a/docs/docs/guides/integrate/actions/testing-event.md b/docs/docs/guides/integrate/actions/testing-event.md index 69a33f6d3e..8b4502703b 100644 --- a/docs/docs/guides/integrate/actions/testing-event.md +++ b/docs/docs/guides/integrate/actions/testing-event.md @@ -145,7 +145,14 @@ the [Sent information Event](./usage#sent-information-event) payload description "event_type": "user.human.added", "created_at": "2025-03-27T10:22:43.262665+01:00", "userID": "312909075212468632", - "event_payload": "eyJ1c2VyTmFtZSI6ImV4YW1wbGVAdGVzdC5jb20iLCJmaXJzdE5hbWUiOiJUZXN0IiwibGFzdE5hbWUiOiJVc2VyIiwiZGlzcGxheU5hbWUiOiJUZXN0IFVzZXIiLCJwcmVmZXJyZWRMYW5ndWFnZSI6InVuZCIsImVtYWlsIjoiZXhhbXBsZUB0ZXN0LmNvbSJ9" + "event_payload": { + "userName":"example@test.com", + "firstName":"Test", + "lastName":"User", + "displayName":"Test User", + "preferredLanguage":"und", + "email":"example@test.com" + } } ``` diff --git a/docs/docs/guides/integrate/actions/testing-request-manipulation.md b/docs/docs/guides/integrate/actions/testing-request-manipulation.md index f727b56144..1cb4f1776a 100644 --- a/docs/docs/guides/integrate/actions/testing-request-manipulation.md +++ b/docs/docs/guides/integrate/actions/testing-request-manipulation.md @@ -18,6 +18,11 @@ Note that this guide assumes that ZITADEL is running on the same machine as the In case you are using a different setup, you need to adjust the target URL accordingly and will need to make sure that the target is reachable from ZITADEL. ::: +:::warning +To marshal and unmarshal the request please use a package like [protojson](https://pkg.go.dev/google.golang.org/protobuf/encoding/protojson), +as the request is a protocol buffer message, to avoid potential problems with the attribute names. +::: + ## Start example target To test the actions feature, you need to create a target that will be called when an API endpoint is called. @@ -37,10 +42,28 @@ import ( "net/http" "github.com/zitadel/zitadel/pkg/grpc/user/v2" + "google.golang.org/protobuf/encoding/protojson" ) type contextRequest struct { - Request *user.AddHumanUserRequest `json:"request"` + Request *addHumanUserRequestWrapper `json:"request"` +} + +// addHumanUserRequestWrapper necessary to marshal and unmarshal the JSON into the proto message correctly +type addHumanUserRequestWrapper struct { + user.AddHumanUserRequest +} + +func (r *addHumanUserRequestWrapper) MarshalJSON() ([]byte, error) { + data, err := protojson.Marshal(r) + if err != nil { + return nil, err + } + return data, nil +} + +func (r *addHumanUserRequestWrapper) UnmarshalJSON(data []byte) error { + return protojson.Unmarshal(data, r) } // call HandleFunc to read the request body, manipulate the content and return the manipulated request diff --git a/docs/docs/guides/integrate/actions/testing-request-signature.md b/docs/docs/guides/integrate/actions/testing-request-signature.md index 4565328e63..c1932a7d5b 100644 --- a/docs/docs/guides/integrate/actions/testing-request-signature.md +++ b/docs/docs/guides/integrate/actions/testing-request-signature.md @@ -18,6 +18,11 @@ Note that this guide assumes that ZITADEL is running on the same machine as the In case you are using a different setup, you need to adjust the target URL accordingly and will need to make sure that the target is reachable from ZITADEL. ::: +:::warning +To marshal and unmarshal the request please use a package like [protojson](https://pkg.go.dev/google.golang.org/protobuf/encoding/protojson), +as the request is a protocol buffer message, to avoid potential problems with the attribute names. +::: + ## Start example target To test the actions feature, you need to create a target that will be called when an API endpoint is called. diff --git a/docs/docs/guides/integrate/actions/testing-request.md b/docs/docs/guides/integrate/actions/testing-request.md index e97b0ef25f..b2413e606e 100644 --- a/docs/docs/guides/integrate/actions/testing-request.md +++ b/docs/docs/guides/integrate/actions/testing-request.md @@ -18,6 +18,11 @@ Note that this guide assumes that ZITADEL is running on the same machine as the In case you are using a different setup, you need to adjust the target URL accordingly and will need to make sure that the target is reachable from ZITADEL. ::: +:::warning +To marshal and unmarshal the request please use a package like [protojson](https://pkg.go.dev/google.golang.org/protobuf/encoding/protojson), +as the request is a protocol buffer message, to avoid potential problems with the attribute names. +::: + ## Start example target To test the actions feature, you need to create a target that will be called when an API endpoint is called. diff --git a/docs/docs/guides/integrate/actions/testing-response-manipulation.md b/docs/docs/guides/integrate/actions/testing-response-manipulation.md index cc10b8252a..9d95479b05 100644 --- a/docs/docs/guides/integrate/actions/testing-response-manipulation.md +++ b/docs/docs/guides/integrate/actions/testing-response-manipulation.md @@ -18,6 +18,11 @@ Note that this guide assumes that ZITADEL is running on the same machine as the In case you are using a different setup, you need to adjust the target URL accordingly and will need to make sure that the target is reachable from ZITADEL. ::: +:::warning +To marshal and unmarshal the request and response please use a package like [protojson](https://pkg.go.dev/google.golang.org/protobuf/encoding/protojson), +as the request and response are protocol buffer messages, to avoid potential problems with the attribute names. +::: + ## Start example target To test the actions feature, you need to create a target that will be called when an API endpoint is called. @@ -37,11 +42,46 @@ import ( "net/http" "github.com/zitadel/zitadel/pkg/grpc/user/v2" + "google.golang.org/protobuf/encoding/protojson" ) -type response struct { - Request *user.RetrieveIdentityProviderIntentRequest `json:"request"` - Response *user.RetrieveIdentityProviderIntentResponse `json:"response"` +type contextResponse struct { + Request *retrieveIdentityProviderIntentRequestWrapper `json:"request"` + Response *retrieveIdentityProviderIntentResponseWrapper `json:"response"` +} + +// RetrieveIdentityProviderIntentRequestWrapper necessary to marshal and unmarshal the JSON into the proto message correctly +type retrieveIdentityProviderIntentRequestWrapper struct { + user.RetrieveIdentityProviderIntentRequest +} + +func (r *retrieveIdentityProviderIntentRequestWrapper) MarshalJSON() ([]byte, error) { + data, err := protojson.Marshal(r) + if err != nil { + return nil, err + } + return data, nil +} + +func (r *retrieveIdentityProviderIntentRequestWrapper) UnmarshalJSON(data []byte) error { + return protojson.Unmarshal(data, r) +} + +// RetrieveIdentityProviderIntentResponseWrapper necessary to marshal and unmarshal the JSON into the proto message correctly +type retrieveIdentityProviderIntentResponseWrapper struct { + user.RetrieveIdentityProviderIntentResponse +} + +func (r *retrieveIdentityProviderIntentResponseWrapper) MarshalJSON() ([]byte, error) { + data, err := protojson.Marshal(r) + if err != nil { + return nil, err + } + return data, nil +} + +func (r *retrieveIdentityProviderIntentResponseWrapper) UnmarshalJSON(data []byte) error { + return protojson.Unmarshal(data, r) } // call HandleFunc to read the response body, manipulate the content and return the response @@ -56,7 +96,7 @@ func call(w http.ResponseWriter, req *http.Request) { defer req.Body.Close() // read the response into the expected structure - request := new(response) + request := new(contextResponse) if err := json.Unmarshal(sentBody, request); err != nil { http.Error(w, "error", http.StatusInternalServerError) } diff --git a/docs/docs/guides/integrate/actions/testing-response.md b/docs/docs/guides/integrate/actions/testing-response.md index 3eb824e95b..a2ab736505 100644 --- a/docs/docs/guides/integrate/actions/testing-response.md +++ b/docs/docs/guides/integrate/actions/testing-response.md @@ -18,6 +18,11 @@ Note that this guide assumes that ZITADEL is running on the same machine as the In case you are using a different setup, you need to adjust the target URL accordingly and will need to make sure that the target is reachable from ZITADEL. ::: +:::warning +To marshal and unmarshal the request and response please use a package like [protojson](https://pkg.go.dev/google.golang.org/protobuf/encoding/protojson), +as the request and response are protocol buffer messages, to avoid potential problems with the attribute names. +::: + ## Start example target To test the actions feature, you need to create a target that will be called when an API endpoint is called. diff --git a/docs/docs/guides/integrate/actions/usage.md b/docs/docs/guides/integrate/actions/usage.md index 8a639f3c27..ba512ae549 100644 --- a/docs/docs/guides/integrate/actions/usage.md +++ b/docs/docs/guides/integrate/actions/usage.md @@ -36,6 +36,11 @@ The information sent to the Endpoint is structured as JSON: } ``` +:::warning +To marshal and unmarshal the request please use a package like [protojson](https://pkg.go.dev/google.golang.org/protobuf/encoding/protojson), +as the request is a protocol buffer message, to avoid potential problems with the attribute names. +::: + ### Sent information Response The information sent to the Endpoint is structured as JSON: @@ -56,6 +61,11 @@ The information sent to the Endpoint is structured as JSON: } ``` +:::warning +To marshal and unmarshal the request and response please use a package like [protojson](https://pkg.go.dev/google.golang.org/protobuf/encoding/protojson), +as the request and response are protocol buffer messages, to avoid potential problems with the attribute names. +::: + ### Sent information Function Information sent and expected back are specific to the function. @@ -338,7 +348,7 @@ The information sent to the Endpoint is structured as JSON: "event_type": "Type of the event", "created_at": "Time the event was created", "userID": "ID of the creator of the event", - "event_payload": "Base64 encoded content of the event" + "event_payload": "Content of the event in JSON format" } ``` diff --git a/internal/api/grpc/action/v2beta/execution.go b/internal/api/grpc/action/v2beta/execution.go index 8a7cd18ab4..5477a8128e 100644 --- a/internal/api/grpc/action/v2beta/execution.go +++ b/internal/api/grpc/action/v2beta/execution.go @@ -14,22 +14,10 @@ import ( ) func (s *Server) SetExecution(ctx context.Context, req *action.SetExecutionRequest) (*action.SetExecutionResponse, error) { - if err := checkActionsEnabled(ctx); err != nil { - return nil, err - } reqTargets := req.GetTargets() targets := make([]*execution.Target, len(reqTargets)) for i, target := range reqTargets { - switch t := target.GetType().(type) { - case *action.ExecutionTargetType_Include: - include, err := conditionToInclude(t.Include) - if err != nil { - return nil, err - } - targets[i] = &execution.Target{Type: domain.ExecutionTargetTypeInclude, Target: include} - case *action.ExecutionTargetType_Target: - targets[i] = &execution.Target{Type: domain.ExecutionTargetTypeTarget, Target: t.Target} - } + targets[i] = &execution.Target{Type: domain.ExecutionTargetTypeTarget, Target: target} } set := &command.SetExecution{ Targets: targets, @@ -60,59 +48,19 @@ func (s *Server) SetExecution(ctx context.Context, req *action.SetExecutionReque }, nil } -func conditionToInclude(cond *action.Condition) (string, error) { - switch t := cond.GetConditionType().(type) { - case *action.Condition_Request: - cond := executionConditionFromRequest(t.Request) - if err := cond.IsValid(); err != nil { - return "", err - } - return cond.ID(domain.ExecutionTypeRequest), nil - case *action.Condition_Response: - cond := executionConditionFromResponse(t.Response) - if err := cond.IsValid(); err != nil { - return "", err - } - return cond.ID(domain.ExecutionTypeRequest), nil - case *action.Condition_Event: - cond := executionConditionFromEvent(t.Event) - if err := cond.IsValid(); err != nil { - return "", err - } - return cond.ID(), nil - case *action.Condition_Function: - cond := command.ExecutionFunctionCondition(t.Function.GetName()) - if err := cond.IsValid(); err != nil { - return "", err - } - return cond.ID(), nil - default: - return "", zerrors.ThrowInvalidArgument(nil, "ACTION-9BBob", "Errors.Execution.ConditionInvalid") - } -} - func (s *Server) ListExecutionFunctions(ctx context.Context, _ *action.ListExecutionFunctionsRequest) (*action.ListExecutionFunctionsResponse, error) { - if err := checkActionsEnabled(ctx); err != nil { - return nil, err - } return &action.ListExecutionFunctionsResponse{ Functions: s.ListActionFunctions(), }, nil } func (s *Server) ListExecutionMethods(ctx context.Context, _ *action.ListExecutionMethodsRequest) (*action.ListExecutionMethodsResponse, error) { - if err := checkActionsEnabled(ctx); err != nil { - return nil, err - } return &action.ListExecutionMethodsResponse{ Methods: s.ListGRPCMethods(), }, nil } func (s *Server) ListExecutionServices(ctx context.Context, _ *action.ListExecutionServicesRequest) (*action.ListExecutionServicesResponse, error) { - if err := checkActionsEnabled(ctx); err != nil { - return nil, err - } return &action.ListExecutionServicesResponse{ Services: s.ListGRPCServices(), }, nil diff --git a/internal/api/grpc/action/v2beta/integration_test/execution_target_test.go b/internal/api/grpc/action/v2beta/integration_test/execution_target_test.go index 6e3ab76fac..0c5018dbb6 100644 --- a/internal/api/grpc/action/v2beta/integration_test/execution_target_test.go +++ b/internal/api/grpc/action/v2beta/integration_test/execution_target_test.go @@ -48,7 +48,6 @@ var ( func TestServer_ExecutionTarget(t *testing.T) { instance := integration.NewInstance(CTX) - ensureFeatureEnabled(t, instance) isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) fullMethod := action.ActionService_GetTarget_FullMethodName @@ -77,14 +76,14 @@ func TestServer_ExecutionTarget(t *testing.T) { targetCreated := instance.CreateTarget(ctx, t, targetCreatedName, targetCreatedURL, domain.TargetTypeCall, false) // request received by target - wantRequest := &middleware.ContextInfoRequest{FullMethod: fullMethod, InstanceID: instance.ID(), OrgID: orgID, ProjectID: projectID, UserID: userID, Request: request} + wantRequest := &middleware.ContextInfoRequest{FullMethod: fullMethod, InstanceID: instance.ID(), OrgID: orgID, ProjectID: projectID, UserID: userID, Request: middleware.Message{Message: request}} changedRequest := &action.GetTargetRequest{Id: targetCreated.GetId()} // replace original request with different targetID - urlRequest, closeRequest, calledRequest, _ := integration.TestServerCall(wantRequest, 0, http.StatusOK, changedRequest) + urlRequest, closeRequest, calledRequest, _ := integration.TestServerCallProto(wantRequest, 0, http.StatusOK, changedRequest) targetRequest := waitForTarget(ctx, t, instance, urlRequest, domain.TargetTypeCall, false) - waitForExecutionOnCondition(ctx, t, instance, conditionRequestFullMethod(fullMethod), executionTargetsSingleTarget(targetRequest.GetId())) + waitForExecutionOnCondition(ctx, t, instance, conditionRequestFullMethod(fullMethod), []string{targetRequest.GetId()}) // expected response from the GetTarget expectedResponse := &action.GetTargetResponse{ @@ -103,9 +102,26 @@ func TestServer_ExecutionTarget(t *testing.T) { SigningKey: targetCreated.GetSigningKey(), }, } - // has to be set separately because of the pointers + + changedResponse := &action.GetTargetResponse{ + Target: &action.Target{ + Id: "changed", + CreationDate: targetCreated.GetCreationDate(), + ChangeDate: targetCreated.GetCreationDate(), + Name: targetCreatedName, + TargetType: &action.Target_RestCall{ + RestCall: &action.RESTCall{ + InterruptOnError: false, + }, + }, + Timeout: durationpb.New(5 * time.Second), + Endpoint: targetCreatedURL, + SigningKey: targetCreated.GetSigningKey(), + }, + } + // content for update response.Target = &action.Target{ - Id: targetCreated.GetId(), + Id: "changed", CreationDate: targetCreated.GetCreationDate(), ChangeDate: targetCreated.GetCreationDate(), Name: targetCreatedName, @@ -119,18 +135,6 @@ func TestServer_ExecutionTarget(t *testing.T) { SigningKey: targetCreated.GetSigningKey(), } - // content for partial update - changedResponse := &action.GetTargetResponse{ - Target: &action.Target{ - Id: targetCreated.GetId(), - TargetType: &action.Target_RestCall{ - RestCall: &action.RESTCall{ - InterruptOnError: false, - }, - }, - }, - } - // response received by target wantResponse := &middleware.ContextInfoResponse{ FullMethod: fullMethod, @@ -138,14 +142,14 @@ func TestServer_ExecutionTarget(t *testing.T) { OrgID: orgID, ProjectID: projectID, UserID: userID, - Request: changedRequest, - Response: expectedResponse, + Request: middleware.Message{Message: changedRequest}, + Response: middleware.Message{Message: expectedResponse}, } // after request with different targetID, return changed response - targetResponseURL, closeResponse, calledResponse, _ := integration.TestServerCall(wantResponse, 0, http.StatusOK, changedResponse) + targetResponseURL, closeResponse, calledResponse, _ := integration.TestServerCallProto(wantResponse, 0, http.StatusOK, changedResponse) targetResponse := waitForTarget(ctx, t, instance, targetResponseURL, domain.TargetTypeCall, false) - waitForExecutionOnCondition(ctx, t, instance, conditionResponseFullMethod(fullMethod), executionTargetsSingleTarget(targetResponse.GetId())) + waitForExecutionOnCondition(ctx, t, instance, conditionResponseFullMethod(fullMethod), []string{targetResponse.GetId()}) return func() { closeRequest() closeResponse() @@ -167,9 +171,7 @@ func TestServer_ExecutionTarget(t *testing.T) { Id: "something", }, want: &action.GetTargetResponse{ - Target: &action.Target{ - Id: "changed", - }, + // defined in the dependency function }, }, { @@ -181,11 +183,11 @@ func TestServer_ExecutionTarget(t *testing.T) { userID := instance.Users.Get(integration.UserTypeIAMOwner).ID // request received by target - wantRequest := &middleware.ContextInfoRequest{FullMethod: fullMethod, InstanceID: instance.ID(), OrgID: orgID, ProjectID: projectID, UserID: userID, Request: request} - urlRequest, closeRequest, calledRequest, _ := integration.TestServerCall(wantRequest, 0, http.StatusInternalServerError, &action.GetTargetRequest{Id: "notchanged"}) + wantRequest := &middleware.ContextInfoRequest{FullMethod: fullMethod, InstanceID: instance.ID(), OrgID: orgID, ProjectID: projectID, UserID: userID, Request: middleware.Message{Message: request}} + urlRequest, closeRequest, calledRequest, _ := integration.TestServerCallProto(wantRequest, 0, http.StatusInternalServerError, nil) targetRequest := waitForTarget(ctx, t, instance, urlRequest, domain.TargetTypeCall, true) - waitForExecutionOnCondition(ctx, t, instance, conditionRequestFullMethod(fullMethod), executionTargetsSingleTarget(targetRequest.GetId())) + waitForExecutionOnCondition(ctx, t, instance, conditionRequestFullMethod(fullMethod), []string{targetRequest.GetId()}) // GetTarget with used target request.Id = targetRequest.GetId() return func() { @@ -234,17 +236,6 @@ func TestServer_ExecutionTarget(t *testing.T) { SigningKey: targetCreated.GetSigningKey(), }, } - // content for partial update - changedResponse := &action.GetTargetResponse{ - Target: &action.Target{ - Id: "changed", - TargetType: &action.Target_RestCall{ - RestCall: &action.RESTCall{ - InterruptOnError: false, - }, - }, - }, - } // response received by target wantResponse := &middleware.ContextInfoResponse{ @@ -253,14 +244,14 @@ func TestServer_ExecutionTarget(t *testing.T) { OrgID: orgID, ProjectID: projectID, UserID: userID, - Request: request, - Response: expectedResponse, + Request: middleware.Message{Message: request}, + Response: middleware.Message{Message: expectedResponse}, } // after request with different targetID, return changed response - targetResponseURL, closeResponse, calledResponse, _ := integration.TestServerCall(wantResponse, 0, http.StatusInternalServerError, changedResponse) + targetResponseURL, closeResponse, calledResponse, _ := integration.TestServerCallProto(wantResponse, 0, http.StatusInternalServerError, nil) targetResponse := waitForTarget(ctx, t, instance, targetResponseURL, domain.TargetTypeCall, true) - waitForExecutionOnCondition(ctx, t, instance, conditionResponseFullMethod(fullMethod), executionTargetsSingleTarget(targetResponse.GetId())) + waitForExecutionOnCondition(ctx, t, instance, conditionResponseFullMethod(fullMethod), []string{targetResponse.GetId()}) return func() { closeResponse() }, func() bool { @@ -301,7 +292,6 @@ func TestServer_ExecutionTarget(t *testing.T) { func TestServer_ExecutionTarget_Event(t *testing.T) { instance := integration.NewInstance(CTX) - ensureFeatureEnabled(t, instance) isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) event := "session.added" @@ -309,7 +299,7 @@ func TestServer_ExecutionTarget_Event(t *testing.T) { defer closeF() targetResponse := waitForTarget(isolatedIAMOwnerCTX, t, instance, urlRequest, domain.TargetTypeWebhook, true) - waitForExecutionOnCondition(isolatedIAMOwnerCTX, t, instance, conditionEvent(event), executionTargetsSingleTarget(targetResponse.GetId())) + waitForExecutionOnCondition(isolatedIAMOwnerCTX, t, instance, conditionEvent(event), []string{targetResponse.GetId()}) tests := []struct { name string @@ -359,7 +349,6 @@ func TestServer_ExecutionTarget_Event(t *testing.T) { func TestServer_ExecutionTarget_Event_LongerThanTargetTimeout(t *testing.T) { instance := integration.NewInstance(CTX) - ensureFeatureEnabled(t, instance) isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) event := "session.added" @@ -368,7 +357,7 @@ func TestServer_ExecutionTarget_Event_LongerThanTargetTimeout(t *testing.T) { defer closeF() targetResponse := waitForTarget(isolatedIAMOwnerCTX, t, instance, urlRequest, domain.TargetTypeWebhook, true) - waitForExecutionOnCondition(isolatedIAMOwnerCTX, t, instance, conditionEvent(event), executionTargetsSingleTarget(targetResponse.GetId())) + waitForExecutionOnCondition(isolatedIAMOwnerCTX, t, instance, conditionEvent(event), []string{targetResponse.GetId()}) tests := []struct { name string @@ -412,7 +401,6 @@ func TestServer_ExecutionTarget_Event_LongerThanTargetTimeout(t *testing.T) { func TestServer_ExecutionTarget_Event_LongerThanTransactionTimeout(t *testing.T) { instance := integration.NewInstance(CTX) - ensureFeatureEnabled(t, instance) isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) event := "session.added" @@ -420,7 +408,7 @@ func TestServer_ExecutionTarget_Event_LongerThanTransactionTimeout(t *testing.T) defer closeF() targetResponse := waitForTarget(isolatedIAMOwnerCTX, t, instance, urlRequest, domain.TargetTypeWebhook, true) - waitForExecutionOnCondition(isolatedIAMOwnerCTX, t, instance, conditionEvent(event), executionTargetsSingleTarget(targetResponse.GetId())) + waitForExecutionOnCondition(isolatedIAMOwnerCTX, t, instance, conditionEvent(event), []string{targetResponse.GetId()}) tests := []struct { name string @@ -474,7 +462,7 @@ func TestServer_ExecutionTarget_Event_LongerThanTransactionTimeout(t *testing.T) } } -func waitForExecutionOnCondition(ctx context.Context, t *testing.T, instance *integration.Instance, condition *action.Condition, targets []*action.ExecutionTargetType) { +func waitForExecutionOnCondition(ctx context.Context, t *testing.T, instance *integration.Instance, condition *action.Condition, targets []string) { instance.SetExecution(ctx, t, condition, targets) retryDuration, tick := integration.WaitForAndTickWithMaxDuration(ctx, time.Minute) @@ -496,7 +484,7 @@ func waitForExecutionOnCondition(ctx context.Context, t *testing.T, instance *in // always first check length, otherwise its failed anyway if assert.Len(ttt, gotTargets, len(targets)) { for i := range targets { - assert.EqualExportedValues(ttt, targets[i].GetType(), gotTargets[i].GetType()) + assert.EqualExportedValues(ttt, targets[i], gotTargets[i]) } } }, retryDuration, tick, "timeout waiting for expected execution result") @@ -589,7 +577,6 @@ func conditionFunction(function string) *action.Condition { func TestServer_ExecutionTargetPreUserinfo(t *testing.T) { instance := integration.NewInstance(CTX) - ensureFeatureEnabled(t, instance) isolatedIAMCtx := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) ctxLoginClient := instance.WithAuthorization(CTX, integration.UserTypeLogin) @@ -785,7 +772,7 @@ func expectPreUserinfoExecution(ctx context.Context, t *testing.T, instance *int targetURL, closeF, _, _ := integration.TestServerCall(expectedContextInfo, 0, http.StatusOK, response) targetResp := waitForTarget(ctx, t, instance, targetURL, domain.TargetTypeCall, true) - waitForExecutionOnCondition(ctx, t, instance, conditionFunction("preuserinfo"), executionTargetsSingleTarget(targetResp.GetId())) + waitForExecutionOnCondition(ctx, t, instance, conditionFunction("preuserinfo"), []string{targetResp.GetId()}) return userResp.GetUserId(), closeF } @@ -903,7 +890,6 @@ func contextInfoForUserOIDC(instance *integration.Instance, function string, use func TestServer_ExecutionTargetPreAccessToken(t *testing.T) { instance := integration.NewInstance(CTX) - ensureFeatureEnabled(t, instance) isolatedIAMCtx := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) ctxLoginClient := instance.WithAuthorization(CTX, integration.UserTypeLogin) @@ -1091,13 +1077,12 @@ func expectPreAccessTokenExecution(ctx context.Context, t *testing.T, instance * targetURL, closeF, _, _ := integration.TestServerCall(expectedContextInfo, 0, http.StatusOK, response) targetResp := waitForTarget(ctx, t, instance, targetURL, domain.TargetTypeCall, true) - waitForExecutionOnCondition(ctx, t, instance, conditionFunction("preaccesstoken"), executionTargetsSingleTarget(targetResp.GetId())) + waitForExecutionOnCondition(ctx, t, instance, conditionFunction("preaccesstoken"), []string{targetResp.GetId()}) return userResp.GetUserId(), closeF } func TestServer_ExecutionTargetPreSAMLResponse(t *testing.T) { instance := integration.NewInstance(CTX) - ensureFeatureEnabled(t, instance) isolatedIAMCtx := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) ctxLoginClient := instance.WithAuthorization(CTX, integration.UserTypeLogin) @@ -1257,7 +1242,7 @@ func expectPreSAMLResponseExecution(ctx context.Context, t *testing.T, instance targetURL, closeF, _, _ := integration.TestServerCall(expectedContextInfo, 0, http.StatusOK, response) targetResp := waitForTarget(ctx, t, instance, targetURL, domain.TargetTypeCall, true) - waitForExecutionOnCondition(ctx, t, instance, conditionFunction("presamlresponse"), executionTargetsSingleTarget(targetResp.GetId())) + waitForExecutionOnCondition(ctx, t, instance, conditionFunction("presamlresponse"), []string{targetResp.GetId()}) return userResp.GetUserId(), closeF } diff --git a/internal/api/grpc/action/v2beta/integration_test/execution_test.go b/internal/api/grpc/action/v2beta/integration_test/execution_test.go index 3af419d97b..2199b9f454 100644 --- a/internal/api/grpc/action/v2beta/integration_test/execution_test.go +++ b/internal/api/grpc/action/v2beta/integration_test/execution_test.go @@ -15,17 +15,8 @@ import ( action "github.com/zitadel/zitadel/pkg/grpc/action/v2beta" ) -func executionTargetsSingleTarget(id string) []*action.ExecutionTargetType { - return []*action.ExecutionTargetType{{Type: &action.ExecutionTargetType_Target{Target: id}}} -} - -func executionTargetsSingleInclude(include *action.Condition) []*action.ExecutionTargetType { - return []*action.ExecutionTargetType{{Type: &action.ExecutionTargetType_Include{Include: include}}} -} - func TestServer_SetExecution_Request(t *testing.T) { instance := integration.NewInstance(CTX) - ensureFeatureEnabled(t, instance) isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://notexisting", domain.TargetTypeWebhook, false) @@ -59,7 +50,7 @@ func TestServer_SetExecution_Request(t *testing.T) { Request: &action.RequestExecution{}, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantErr: true, }, @@ -76,7 +67,7 @@ func TestServer_SetExecution_Request(t *testing.T) { }, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantErr: true, }, @@ -93,7 +84,7 @@ func TestServer_SetExecution_Request(t *testing.T) { }, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantSetDate: true, }, @@ -110,7 +101,7 @@ func TestServer_SetExecution_Request(t *testing.T) { }, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantErr: true, }, @@ -127,7 +118,7 @@ func TestServer_SetExecution_Request(t *testing.T) { }, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantSetDate: true, }, @@ -144,7 +135,7 @@ func TestServer_SetExecution_Request(t *testing.T) { }, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantSetDate: true, }, @@ -181,125 +172,8 @@ func assertSetExecutionResponse(t *testing.T, creationDate, setDate time.Time, e } } -func TestServer_SetExecution_Request_Include(t *testing.T) { - instance := integration.NewInstance(CTX) - ensureFeatureEnabled(t, instance) - isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) - targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://notexisting", domain.TargetTypeWebhook, false) - executionCond := &action.Condition{ - ConditionType: &action.Condition_Request{ - Request: &action.RequestExecution{ - Condition: &action.RequestExecution_All{ - All: true, - }, - }, - }, - } - instance.SetExecution(isolatedIAMOwnerCTX, t, - executionCond, - executionTargetsSingleTarget(targetResp.GetId()), - ) - - circularExecutionService := &action.Condition{ - ConditionType: &action.Condition_Request{ - Request: &action.RequestExecution{ - Condition: &action.RequestExecution_Service{ - Service: "zitadel.session.v2beta.SessionService", - }, - }, - }, - } - instance.SetExecution(isolatedIAMOwnerCTX, t, - circularExecutionService, - executionTargetsSingleInclude(executionCond), - ) - circularExecutionMethod := &action.Condition{ - ConditionType: &action.Condition_Request{ - Request: &action.RequestExecution{ - Condition: &action.RequestExecution_Method{ - Method: "/zitadel.session.v2beta.SessionService/ListSessions", - }, - }, - }, - } - instance.SetExecution(isolatedIAMOwnerCTX, t, - circularExecutionMethod, - executionTargetsSingleInclude(circularExecutionService), - ) - - tests := []struct { - name string - ctx context.Context - req *action.SetExecutionRequest - wantSetDate bool - wantErr bool - }{ - { - name: "method, circular error", - ctx: isolatedIAMOwnerCTX, - req: &action.SetExecutionRequest{ - Condition: circularExecutionService, - Targets: executionTargetsSingleInclude(circularExecutionMethod), - }, - wantErr: true, - }, - { - name: "method, ok", - ctx: isolatedIAMOwnerCTX, - req: &action.SetExecutionRequest{ - Condition: &action.Condition{ - ConditionType: &action.Condition_Request{ - Request: &action.RequestExecution{ - Condition: &action.RequestExecution_Method{ - Method: "/zitadel.session.v2beta.SessionService/ListSessions", - }, - }, - }, - }, - Targets: executionTargetsSingleInclude(executionCond), - }, - wantSetDate: true, - }, - { - name: "service, ok", - ctx: isolatedIAMOwnerCTX, - req: &action.SetExecutionRequest{ - Condition: &action.Condition{ - ConditionType: &action.Condition_Request{ - Request: &action.RequestExecution{ - Condition: &action.RequestExecution_Service{ - Service: "zitadel.user.v2beta.UserService", - }, - }, - }, - }, - Targets: executionTargetsSingleInclude(executionCond), - }, - wantSetDate: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - creationDate := time.Now().UTC() - got, err := instance.Client.ActionV2beta.SetExecution(tt.ctx, tt.req) - setDate := time.Now().UTC() - if tt.wantErr { - require.Error(t, err) - return - } - require.NoError(t, err) - - assertSetExecutionResponse(t, creationDate, setDate, tt.wantSetDate, got) - - // cleanup to not impact other requests - instance.DeleteExecution(tt.ctx, t, tt.req.GetCondition()) - }) - } -} - func TestServer_SetExecution_Response(t *testing.T) { instance := integration.NewInstance(CTX) - ensureFeatureEnabled(t, instance) isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://notexisting", domain.TargetTypeWebhook, false) @@ -333,7 +207,7 @@ func TestServer_SetExecution_Response(t *testing.T) { Response: &action.ResponseExecution{}, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantErr: true, }, @@ -350,7 +224,7 @@ func TestServer_SetExecution_Response(t *testing.T) { }, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantErr: true, }, @@ -367,7 +241,7 @@ func TestServer_SetExecution_Response(t *testing.T) { }, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantSetDate: true, }, @@ -384,7 +258,7 @@ func TestServer_SetExecution_Response(t *testing.T) { }, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantErr: true, }, @@ -401,7 +275,7 @@ func TestServer_SetExecution_Response(t *testing.T) { }, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantSetDate: true, }, @@ -418,7 +292,7 @@ func TestServer_SetExecution_Response(t *testing.T) { }, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantSetDate: true, }, @@ -444,7 +318,6 @@ func TestServer_SetExecution_Response(t *testing.T) { func TestServer_SetExecution_Event(t *testing.T) { instance := integration.NewInstance(CTX) - ensureFeatureEnabled(t, instance) isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://notexisting", domain.TargetTypeWebhook, false) @@ -480,7 +353,7 @@ func TestServer_SetExecution_Event(t *testing.T) { Event: &action.EventExecution{}, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantErr: true, }, @@ -497,7 +370,7 @@ func TestServer_SetExecution_Event(t *testing.T) { }, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantErr: true, }, @@ -514,7 +387,7 @@ func TestServer_SetExecution_Event(t *testing.T) { }, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantSetDate: true, }, @@ -531,7 +404,7 @@ func TestServer_SetExecution_Event(t *testing.T) { }, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantErr: true, }, @@ -548,7 +421,7 @@ func TestServer_SetExecution_Event(t *testing.T) { }, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantSetDate: true, }, @@ -565,7 +438,7 @@ func TestServer_SetExecution_Event(t *testing.T) { }, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantSetDate: true, }, @@ -582,7 +455,7 @@ func TestServer_SetExecution_Event(t *testing.T) { }, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantSetDate: true, }, @@ -608,7 +481,6 @@ func TestServer_SetExecution_Event(t *testing.T) { func TestServer_SetExecution_Function(t *testing.T) { instance := integration.NewInstance(CTX) - ensureFeatureEnabled(t, instance) isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://notexisting", domain.TargetTypeWebhook, false) @@ -642,7 +514,7 @@ func TestServer_SetExecution_Function(t *testing.T) { Response: &action.ResponseExecution{}, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantErr: true, }, @@ -655,7 +527,7 @@ func TestServer_SetExecution_Function(t *testing.T) { Function: &action.FunctionExecution{Name: "xxx"}, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantErr: true, }, @@ -668,7 +540,7 @@ func TestServer_SetExecution_Function(t *testing.T) { Function: &action.FunctionExecution{Name: "presamlresponse"}, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, wantSetDate: true, }, diff --git a/internal/api/grpc/action/v2beta/integration_test/query_test.go b/internal/api/grpc/action/v2beta/integration_test/query_test.go index c5159d39da..5c59bee5d1 100644 --- a/internal/api/grpc/action/v2beta/integration_test/query_test.go +++ b/internal/api/grpc/action/v2beta/integration_test/query_test.go @@ -8,6 +8,7 @@ import ( "time" "github.com/brianvoe/gofakeit/v6" + "github.com/muhlemmer/gu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/protobuf/types/known/durationpb" @@ -20,7 +21,6 @@ import ( func TestServer_GetTarget(t *testing.T) { instance := integration.NewInstance(CTX) - ensureFeatureEnabled(t, instance) isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) type args struct { ctx context.Context @@ -213,7 +213,6 @@ func TestServer_GetTarget(t *testing.T) { func TestServer_ListTargets(t *testing.T) { instance := integration.NewInstance(CTX) - ensureFeatureEnabled(t, instance) isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) type args struct { ctx context.Context @@ -446,7 +445,6 @@ func assertPaginationResponse(t *assert.CollectT, expected *filter.PaginationRes func TestServer_ListExecutions(t *testing.T) { instance := integration.NewInstance(CTX) - ensureFeatureEnabled(t, instance) isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) targetResp := instance.CreateTarget(isolatedIAMOwnerCTX, t, "", "https://example.com", domain.TargetTypeWebhook, false) @@ -475,7 +473,7 @@ func TestServer_ListExecutions(t *testing.T) { ctx: isolatedIAMOwnerCTX, dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) { cond := request.Filters[0].GetInConditionsFilter().GetConditions()[0] - resp := instance.SetExecution(ctx, t, cond, executionTargetsSingleTarget(targetResp.GetId())) + resp := instance.SetExecution(ctx, t, cond, []string{targetResp.GetId()}) // Set expected response with used values for SetExecution response.Result[0].CreationDate = resp.GetSetDate() @@ -516,7 +514,7 @@ func TestServer_ListExecutions(t *testing.T) { }, }, }, - Targets: executionTargetsSingleTarget(targetResp.GetId()), + Targets: []string{targetResp.GetId()}, }, }, }, @@ -544,13 +542,12 @@ func TestServer_ListExecutions(t *testing.T) { }, }, } - targets := executionTargetsSingleTarget(target.GetId()) - resp := instance.SetExecution(ctx, t, cond, targets) + resp := instance.SetExecution(ctx, t, cond, []string{target.GetId()}) response.Result[0].CreationDate = resp.GetSetDate() response.Result[0].ChangeDate = resp.GetSetDate() response.Result[0].Condition = cond - response.Result[0].Targets = targets + response.Result[0].Targets = []string{target.GetId()} }, req: &action.ListExecutionsRequest{ Filters: []*action.ExecutionSearchFilter{{}}, @@ -564,63 +561,10 @@ func TestServer_ListExecutions(t *testing.T) { Result: []*action.Execution{ { Condition: &action.Condition{}, - Targets: executionTargetsSingleTarget(""), + Targets: []string{""}, }, }, }, - }, { - name: "list request single include", - args: args{ - ctx: isolatedIAMOwnerCTX, - dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) { - cond := &action.Condition{ - ConditionType: &action.Condition_Request{ - Request: &action.RequestExecution{ - Condition: &action.RequestExecution_Method{ - Method: "/zitadel.management.v1.ManagementService/GetAction", - }, - }, - }, - } - instance.SetExecution(ctx, t, cond, executionTargetsSingleTarget(targetResp.GetId())) - request.Filters[0].GetIncludeFilter().Include = cond - - includeCond := &action.Condition{ - ConditionType: &action.Condition_Request{ - Request: &action.RequestExecution{ - Condition: &action.RequestExecution_Method{ - Method: "/zitadel.management.v1.ManagementService/ListActions", - }, - }, - }, - } - includeTargets := executionTargetsSingleInclude(cond) - resp2 := instance.SetExecution(ctx, t, includeCond, includeTargets) - - response.Result[0] = &action.Execution{ - Condition: includeCond, - CreationDate: resp2.GetSetDate(), - ChangeDate: resp2.GetSetDate(), - Targets: includeTargets, - } - }, - req: &action.ListExecutionsRequest{ - Filters: []*action.ExecutionSearchFilter{{ - Filter: &action.ExecutionSearchFilter_IncludeFilter{ - IncludeFilter: &action.IncludeFilter{}, - }, - }}, - }, - }, - want: &action.ListExecutionsResponse{ - Pagination: &filter.PaginationResponse{ - TotalResult: 1, - AppliedLimit: 100, - }, - Result: []*action.Execution{ - {}, - }, - }, }, { name: "list multiple conditions", @@ -659,33 +603,30 @@ func TestServer_ListExecutions(t *testing.T) { } cond1 := request.Filters[0].GetInConditionsFilter().GetConditions()[0] - targets1 := executionTargetsSingleTarget(targetResp.GetId()) - resp1 := instance.SetExecution(ctx, t, cond1, targets1) + resp1 := instance.SetExecution(ctx, t, cond1, []string{targetResp.GetId()}) response.Result[2] = &action.Execution{ CreationDate: resp1.GetSetDate(), ChangeDate: resp1.GetSetDate(), Condition: cond1, - Targets: targets1, + Targets: []string{targetResp.GetId()}, } cond2 := request.Filters[0].GetInConditionsFilter().GetConditions()[1] - targets2 := executionTargetsSingleTarget(targetResp.GetId()) - resp2 := instance.SetExecution(ctx, t, cond2, targets2) + resp2 := instance.SetExecution(ctx, t, cond2, []string{targetResp.GetId()}) response.Result[1] = &action.Execution{ CreationDate: resp2.GetSetDate(), ChangeDate: resp2.GetSetDate(), Condition: cond2, - Targets: targets2, + Targets: []string{targetResp.GetId()}, } cond3 := request.Filters[0].GetInConditionsFilter().GetConditions()[2] - targets3 := executionTargetsSingleTarget(targetResp.GetId()) - resp3 := instance.SetExecution(ctx, t, cond3, targets3) + resp3 := instance.SetExecution(ctx, t, cond3, []string{targetResp.GetId()}) response.Result[0] = &action.Execution{ CreationDate: resp3.GetSetDate(), ChangeDate: resp3.GetSetDate(), Condition: cond3, - Targets: targets3, + Targets: []string{targetResp.GetId()}, } }, req: &action.ListExecutionsRequest{ @@ -709,15 +650,14 @@ func TestServer_ListExecutions(t *testing.T) { args: args{ ctx: isolatedIAMOwnerCTX, dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) { - targets := executionTargetsSingleTarget(targetResp.GetId()) conditions := request.Filters[0].GetInConditionsFilter().GetConditions() for i, cond := range conditions { - resp := instance.SetExecution(ctx, t, cond, targets) + resp := instance.SetExecution(ctx, t, cond, []string{targetResp.GetId()}) response.Result[(len(conditions)-1)-i] = &action.Execution{ CreationDate: resp.GetSetDate(), ChangeDate: resp.GetSetDate(), Condition: cond, - Targets: targets, + Targets: []string{targetResp.GetId()}, } } }, @@ -761,6 +701,63 @@ func TestServer_ListExecutions(t *testing.T) { }, }, }, + { + name: "list multiple conditions all types, sort id", + args: args{ + ctx: isolatedIAMOwnerCTX, + dep: func(ctx context.Context, request *action.ListExecutionsRequest, response *action.ListExecutionsResponse) { + conditions := request.Filters[0].GetInConditionsFilter().GetConditions() + for i, cond := range conditions { + resp := instance.SetExecution(ctx, t, cond, []string{targetResp.GetId()}) + response.Result[i] = &action.Execution{ + CreationDate: resp.GetSetDate(), + ChangeDate: resp.GetSetDate(), + Condition: cond, + Targets: []string{targetResp.GetId()}, + } + } + }, + req: &action.ListExecutionsRequest{ + SortingColumn: gu.Ptr(action.ExecutionFieldName_EXECUTION_FIELD_NAME_ID), + Filters: []*action.ExecutionSearchFilter{{ + Filter: &action.ExecutionSearchFilter_InConditionsFilter{ + InConditionsFilter: &action.InConditionsFilter{ + Conditions: []*action.Condition{ + {ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_Method{Method: "/zitadel.session.v2.SessionService/GetSession"}}}}, + {ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_Service{Service: "zitadel.session.v2.SessionService"}}}}, + {ConditionType: &action.Condition_Response{Response: &action.ResponseExecution{Condition: &action.ResponseExecution_All{All: true}}}}, + {ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_Method{Method: "/zitadel.session.v2.SessionService/GetSession"}}}}, + {ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_Service{Service: "zitadel.session.v2.SessionService"}}}}, + {ConditionType: &action.Condition_Request{Request: &action.RequestExecution{Condition: &action.RequestExecution_All{All: true}}}}, + {ConditionType: &action.Condition_Function{Function: &action.FunctionExecution{Name: "presamlresponse"}}}, + {ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_Event{Event: "user.added"}}}}, + {ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_Group{Group: "user"}}}}, + {ConditionType: &action.Condition_Event{Event: &action.EventExecution{Condition: &action.EventExecution_All{All: true}}}}, + }, + }, + }, + }}, + }, + }, + want: &action.ListExecutionsResponse{ + Pagination: &filter.PaginationResponse{ + TotalResult: 10, + AppliedLimit: 100, + }, + Result: []*action.Execution{ + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/api/grpc/action/v2beta/integration_test/server_test.go b/internal/api/grpc/action/v2beta/integration_test/server_test.go index 89a33dd40e..07ee051c63 100644 --- a/internal/api/grpc/action/v2beta/integration_test/server_test.go +++ b/internal/api/grpc/action/v2beta/integration_test/server_test.go @@ -7,14 +7,6 @@ import ( "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/v2beta" - "github.com/zitadel/zitadel/pkg/grpc/feature/v2" ) var ( @@ -29,41 +21,3 @@ func TestMain(m *testing.M) { return m.Run() }()) } - -func ensureFeatureEnabled(t *testing.T, instance *integration.Instance) { - ctx := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) - f, err := instance.Client.FeatureV2.GetInstanceFeatures(ctx, &feature.GetInstanceFeaturesRequest{ - Inheritance: true, - }) - require.NoError(t, err) - if f.Actions.GetEnabled() { - return - } - _, err = instance.Client.FeatureV2.SetInstanceFeatures(ctx, &feature.SetInstanceFeaturesRequest{ - Actions: gu.Ptr(true), - }) - require.NoError(t, err) - - retryDuration, tick := integration.WaitForAndTickWithMaxDuration(ctx, 5*time.Minute) - require.EventuallyWithT(t, - func(ttt *assert.CollectT) { - f, err := instance.Client.FeatureV2.GetInstanceFeatures(ctx, &feature.GetInstanceFeaturesRequest{ - Inheritance: true, - }) - assert.NoError(ttt, err) - assert.True(ttt, f.Actions.GetEnabled()) - }, - retryDuration, - tick, - "timed out waiting for ensuring instance feature") - - retryDuration, tick = integration.WaitForAndTickWithMaxDuration(ctx, 5*time.Minute) - require.EventuallyWithT(t, - func(ttt *assert.CollectT) { - _, err := instance.Client.ActionV2beta.ListExecutionMethods(ctx, &action.ListExecutionMethodsRequest{}) - assert.NoError(ttt, err) - }, - retryDuration, - tick, - "timed out waiting for ensuring instance feature call") -} diff --git a/internal/api/grpc/action/v2beta/integration_test/target_test.go b/internal/api/grpc/action/v2beta/integration_test/target_test.go index 2fda64b86a..8238d3146d 100644 --- a/internal/api/grpc/action/v2beta/integration_test/target_test.go +++ b/internal/api/grpc/action/v2beta/integration_test/target_test.go @@ -19,7 +19,6 @@ import ( func TestServer_CreateTarget(t *testing.T) { instance := integration.NewInstance(CTX) - ensureFeatureEnabled(t, instance) isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) type want struct { id bool @@ -244,7 +243,6 @@ func assertCreateTargetResponse(t *testing.T, creationDate, changeDate time.Time func TestServer_UpdateTarget(t *testing.T) { instance := integration.NewInstance(CTX) - ensureFeatureEnabled(t, instance) isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) type args struct { ctx context.Context @@ -463,7 +461,6 @@ func assertUpdateTargetResponse(t *testing.T, creationDate, changeDate time.Time func TestServer_DeleteTarget(t *testing.T) { instance := integration.NewInstance(CTX) - ensureFeatureEnabled(t, instance) iamOwnerCtx := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) tests := []struct { name string diff --git a/internal/api/grpc/action/v2beta/query.go b/internal/api/grpc/action/v2beta/query.go index d8d6cd3e95..66bafa4e7d 100644 --- a/internal/api/grpc/action/v2beta/query.go +++ b/internal/api/grpc/action/v2beta/query.go @@ -23,10 +23,6 @@ const ( ) func (s *Server) GetTarget(ctx context.Context, req *action.GetTargetRequest) (*action.GetTargetResponse, error) { - if err := checkActionsEnabled(ctx); err != nil { - return nil, err - } - resp, err := s.query.GetTargetByID(ctx, req.GetId()) if err != nil { return nil, err @@ -46,9 +42,6 @@ type Context interface { } func (s *Server) ListTargets(ctx context.Context, req *action.ListTargetsRequest) (*action.ListTargetsResponse, error) { - if err := checkActionsEnabled(ctx); err != nil { - return nil, err - } queries, err := s.ListTargetsRequestToModel(req) if err != nil { return nil, err @@ -64,9 +57,6 @@ func (s *Server) ListTargets(ctx context.Context, req *action.ListTargetsRequest } func (s *Server) ListExecutions(ctx context.Context, req *action.ListExecutionsRequest) (*action.ListExecutionsResponse, error) { - if err := checkActionsEnabled(ctx); err != nil { - return nil, err - } queries, err := s.ListExecutionsRequestToModel(req) if err != nil { return nil, err @@ -252,12 +242,6 @@ func executionQueryToQuery(searchQuery *action.ExecutionSearchFilter) (query.Sea return inConditionsQueryToQuery(q.InConditionsFilter) case *action.ExecutionSearchFilter_ExecutionTypeFilter: return executionTypeToQuery(q.ExecutionTypeFilter) - case *action.ExecutionSearchFilter_IncludeFilter: - include, err := conditionToInclude(q.IncludeFilter.GetInclude()) - if err != nil { - return nil, err - } - return query.NewIncludeSearchQuery(include) case *action.ExecutionSearchFilter_TargetFilter: return query.NewTargetSearchQuery(q.TargetFilter.GetTargetId()) default: @@ -333,14 +317,12 @@ func executionsToPb(executions []*query.Execution) []*action.Execution { } func executionToPb(e *query.Execution) *action.Execution { - targets := make([]*action.ExecutionTargetType, len(e.Targets)) + targets := make([]string, len(e.Targets)) for i := range e.Targets { switch e.Targets[i].Type { - case domain.ExecutionTargetTypeInclude: - targets[i] = &action.ExecutionTargetType{Type: &action.ExecutionTargetType_Include{Include: executionIDToCondition(e.Targets[i].Target)}} case domain.ExecutionTargetTypeTarget: - targets[i] = &action.ExecutionTargetType{Type: &action.ExecutionTargetType_Target{Target: e.Targets[i].Target}} - case domain.ExecutionTargetTypeUnspecified: + targets[i] = e.Targets[i].Target + case domain.ExecutionTargetTypeInclude, domain.ExecutionTargetTypeUnspecified: continue default: continue diff --git a/internal/api/grpc/action/v2beta/server.go b/internal/api/grpc/action/v2beta/server.go index 069f456ceb..ef0d8eb2ba 100644 --- a/internal/api/grpc/action/v2beta/server.go +++ b/internal/api/grpc/action/v2beta/server.go @@ -1,8 +1,6 @@ package action import ( - "context" - "google.golang.org/grpc" "github.com/zitadel/zitadel/internal/api/authz" @@ -10,7 +8,6 @@ import ( "github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/config/systemdefaults" "github.com/zitadel/zitadel/internal/query" - "github.com/zitadel/zitadel/internal/zerrors" action "github.com/zitadel/zitadel/pkg/grpc/action/v2beta" ) @@ -65,10 +62,3 @@ func (s *Server) AuthMethods() authz.MethodMapping { func (s *Server) RegisterGateway() server.RegisterGatewayFunc { return action.RegisterActionServiceHandler } - -func checkActionsEnabled(ctx context.Context) error { - if authz.GetInstance(ctx).Features().Actions { - return nil - } - return zerrors.ThrowPreconditionFailed(nil, "ACTION-8o6pvqfjhs", "Errors.Action.NotEnabled") -} diff --git a/internal/api/grpc/action/v2beta/target.go b/internal/api/grpc/action/v2beta/target.go index 7dc636f29a..26c88b9683 100644 --- a/internal/api/grpc/action/v2beta/target.go +++ b/internal/api/grpc/action/v2beta/target.go @@ -14,9 +14,6 @@ import ( ) func (s *Server) CreateTarget(ctx context.Context, req *action.CreateTargetRequest) (*action.CreateTargetResponse, error) { - if err := checkActionsEnabled(ctx); err != nil { - return nil, err - } add := createTargetToCommand(req) instanceID := authz.GetInstance(ctx).InstanceID() createdAt, err := s.command.AddTarget(ctx, add, instanceID) @@ -35,9 +32,6 @@ func (s *Server) CreateTarget(ctx context.Context, req *action.CreateTargetReque } func (s *Server) UpdateTarget(ctx context.Context, req *action.UpdateTargetRequest) (*action.UpdateTargetResponse, error) { - if err := checkActionsEnabled(ctx); err != nil { - return nil, err - } instanceID := authz.GetInstance(ctx).InstanceID() update := updateTargetToCommand(req) changedAt, err := s.command.ChangeTarget(ctx, update, instanceID) @@ -55,9 +49,6 @@ func (s *Server) UpdateTarget(ctx context.Context, req *action.UpdateTargetReque } func (s *Server) DeleteTarget(ctx context.Context, req *action.DeleteTargetRequest) (*action.DeleteTargetResponse, error) { - if err := checkActionsEnabled(ctx); err != nil { - return nil, err - } instanceID := authz.GetInstance(ctx).InstanceID() deletedAt, err := s.command.DeleteTarget(ctx, req.GetId(), instanceID) if err != nil { diff --git a/internal/api/grpc/feature/v2/converter.go b/internal/api/grpc/feature/v2/converter.go index 60cf569082..baa45c6c6e 100644 --- a/internal/api/grpc/feature/v2/converter.go +++ b/internal/api/grpc/feature/v2/converter.go @@ -22,7 +22,6 @@ func systemFeaturesToCommand(req *feature_pb.SetSystemFeaturesRequest) (*command TriggerIntrospectionProjections: req.OidcTriggerIntrospectionProjections, LegacyIntrospection: req.OidcLegacyIntrospection, UserSchema: req.UserSchema, - Actions: req.Actions, TokenExchange: req.OidcTokenExchange, ImprovedPerformance: improvedPerformanceListToDomain(req.ImprovedPerformance), OIDCSingleV1SessionTermination: req.OidcSingleV1SessionTermination, @@ -41,7 +40,6 @@ func systemFeaturesToPb(f *query.SystemFeatures) *feature_pb.GetSystemFeaturesRe OidcLegacyIntrospection: featureSourceToFlagPb(&f.LegacyIntrospection), UserSchema: featureSourceToFlagPb(&f.UserSchema), OidcTokenExchange: featureSourceToFlagPb(&f.TokenExchange), - Actions: featureSourceToFlagPb(&f.Actions), ImprovedPerformance: featureSourceToImprovedPerformanceFlagPb(&f.ImprovedPerformance), OidcSingleV1SessionTermination: featureSourceToFlagPb(&f.OIDCSingleV1SessionTermination), DisableUserTokenEvent: featureSourceToFlagPb(&f.DisableUserTokenEvent), @@ -62,7 +60,6 @@ func instanceFeaturesToCommand(req *feature_pb.SetInstanceFeaturesRequest) (*com LegacyIntrospection: req.OidcLegacyIntrospection, UserSchema: req.UserSchema, TokenExchange: req.OidcTokenExchange, - Actions: req.Actions, ImprovedPerformance: improvedPerformanceListToDomain(req.ImprovedPerformance), WebKey: req.WebKey, DebugOIDCParentError: req.DebugOidcParentError, @@ -83,7 +80,6 @@ func instanceFeaturesToPb(f *query.InstanceFeatures) *feature_pb.GetInstanceFeat OidcLegacyIntrospection: featureSourceToFlagPb(&f.LegacyIntrospection), UserSchema: featureSourceToFlagPb(&f.UserSchema), OidcTokenExchange: featureSourceToFlagPb(&f.TokenExchange), - Actions: featureSourceToFlagPb(&f.Actions), ImprovedPerformance: featureSourceToImprovedPerformanceFlagPb(&f.ImprovedPerformance), WebKey: featureSourceToFlagPb(&f.WebKey), DebugOidcParentError: featureSourceToFlagPb(&f.DebugOIDCParentError), diff --git a/internal/api/grpc/feature/v2/converter_test.go b/internal/api/grpc/feature/v2/converter_test.go index 62cf701eec..f481e4f65a 100644 --- a/internal/api/grpc/feature/v2/converter_test.go +++ b/internal/api/grpc/feature/v2/converter_test.go @@ -23,7 +23,6 @@ func Test_systemFeaturesToCommand(t *testing.T) { OidcTriggerIntrospectionProjections: gu.Ptr(false), OidcLegacyIntrospection: nil, UserSchema: gu.Ptr(true), - Actions: gu.Ptr(true), OidcTokenExchange: gu.Ptr(true), ImprovedPerformance: nil, OidcSingleV1SessionTermination: gu.Ptr(true), @@ -37,7 +36,6 @@ func Test_systemFeaturesToCommand(t *testing.T) { TriggerIntrospectionProjections: gu.Ptr(false), LegacyIntrospection: nil, UserSchema: gu.Ptr(true), - Actions: gu.Ptr(true), TokenExchange: gu.Ptr(true), ImprovedPerformance: nil, OIDCSingleV1SessionTermination: gu.Ptr(true), @@ -74,10 +72,6 @@ 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, @@ -132,10 +126,6 @@ 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, - }, ImprovedPerformance: &feature_pb.ImprovedPerformanceFeatureFlag{ ExecutionPaths: []feature_pb.ImprovedPerformance{feature_pb.ImprovedPerformance_IMPROVED_PERFORMANCE_ORG_BY_ID}, Source: feature_pb.Source_SOURCE_SYSTEM, @@ -173,7 +163,6 @@ func Test_instanceFeaturesToCommand(t *testing.T) { OidcLegacyIntrospection: nil, UserSchema: gu.Ptr(true), OidcTokenExchange: gu.Ptr(true), - Actions: gu.Ptr(true), ImprovedPerformance: nil, WebKey: gu.Ptr(true), DebugOidcParentError: gu.Ptr(true), @@ -191,7 +180,6 @@ func Test_instanceFeaturesToCommand(t *testing.T) { LegacyIntrospection: nil, UserSchema: gu.Ptr(true), TokenExchange: gu.Ptr(true), - Actions: gu.Ptr(true), ImprovedPerformance: nil, WebKey: gu.Ptr(true), DebugOIDCParentError: gu.Ptr(true), @@ -231,10 +219,6 @@ 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, @@ -293,10 +277,6 @@ 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/integration_test/feature_test.go b/internal/api/grpc/feature/v2/integration_test/feature_test.go index 8d6c295350..f27b57ff8c 100644 --- a/internal/api/grpc/feature/v2/integration_test/feature_test.go +++ b/internal/api/grpc/feature/v2/integration_test/feature_test.go @@ -211,7 +211,6 @@ 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) }) } } @@ -374,10 +373,6 @@ func TestServer_GetInstanceFeatures(t *testing.T) { Enabled: false, Source: feature.Source_SOURCE_UNSPECIFIED, }, - Actions: &feature.FeatureFlag{ - Enabled: false, - Source: feature.Source_SOURCE_UNSPECIFIED, - }, }, }, { @@ -387,7 +382,6 @@ 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) }, @@ -408,10 +402,6 @@ func TestServer_GetInstanceFeatures(t *testing.T) { Enabled: true, Source: feature.Source_SOURCE_INSTANCE, }, - Actions: &feature.FeatureFlag{ - Enabled: true, - Source: feature.Source_SOURCE_INSTANCE, - }, }, }, { @@ -445,10 +435,6 @@ 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/feature/v2beta/converter.go b/internal/api/grpc/feature/v2beta/converter.go index 39f2284beb..bbb375716e 100644 --- a/internal/api/grpc/feature/v2beta/converter.go +++ b/internal/api/grpc/feature/v2beta/converter.go @@ -14,7 +14,6 @@ func systemFeaturesToCommand(req *feature_pb.SetSystemFeaturesRequest) *command. TriggerIntrospectionProjections: req.OidcTriggerIntrospectionProjections, LegacyIntrospection: req.OidcLegacyIntrospection, UserSchema: req.UserSchema, - Actions: req.Actions, TokenExchange: req.OidcTokenExchange, ImprovedPerformance: improvedPerformanceListToDomain(req.ImprovedPerformance), OIDCSingleV1SessionTermination: req.OidcSingleV1SessionTermination, @@ -29,7 +28,6 @@ func systemFeaturesToPb(f *query.SystemFeatures) *feature_pb.GetSystemFeaturesRe OidcLegacyIntrospection: featureSourceToFlagPb(&f.LegacyIntrospection), UserSchema: featureSourceToFlagPb(&f.UserSchema), OidcTokenExchange: featureSourceToFlagPb(&f.TokenExchange), - Actions: featureSourceToFlagPb(&f.Actions), ImprovedPerformance: featureSourceToImprovedPerformanceFlagPb(&f.ImprovedPerformance), OidcSingleV1SessionTermination: featureSourceToFlagPb(&f.OIDCSingleV1SessionTermination), } @@ -42,7 +40,6 @@ func instanceFeaturesToCommand(req *feature_pb.SetInstanceFeaturesRequest) *comm LegacyIntrospection: req.OidcLegacyIntrospection, UserSchema: req.UserSchema, TokenExchange: req.OidcTokenExchange, - Actions: req.Actions, ImprovedPerformance: improvedPerformanceListToDomain(req.ImprovedPerformance), WebKey: req.WebKey, DebugOIDCParentError: req.DebugOidcParentError, @@ -58,7 +55,6 @@ func instanceFeaturesToPb(f *query.InstanceFeatures) *feature_pb.GetInstanceFeat OidcLegacyIntrospection: featureSourceToFlagPb(&f.LegacyIntrospection), UserSchema: featureSourceToFlagPb(&f.UserSchema), OidcTokenExchange: featureSourceToFlagPb(&f.TokenExchange), - Actions: featureSourceToFlagPb(&f.Actions), ImprovedPerformance: featureSourceToImprovedPerformanceFlagPb(&f.ImprovedPerformance), WebKey: featureSourceToFlagPb(&f.WebKey), DebugOidcParentError: featureSourceToFlagPb(&f.DebugOIDCParentError), diff --git a/internal/api/grpc/feature/v2beta/converter_test.go b/internal/api/grpc/feature/v2beta/converter_test.go index 2896d8f77b..72d91b10d4 100644 --- a/internal/api/grpc/feature/v2beta/converter_test.go +++ b/internal/api/grpc/feature/v2beta/converter_test.go @@ -22,7 +22,6 @@ func Test_systemFeaturesToCommand(t *testing.T) { OidcTriggerIntrospectionProjections: gu.Ptr(false), OidcLegacyIntrospection: nil, UserSchema: gu.Ptr(true), - Actions: gu.Ptr(true), OidcTokenExchange: gu.Ptr(true), ImprovedPerformance: nil, OidcSingleV1SessionTermination: gu.Ptr(true), @@ -32,7 +31,6 @@ func Test_systemFeaturesToCommand(t *testing.T) { TriggerIntrospectionProjections: gu.Ptr(false), LegacyIntrospection: nil, UserSchema: gu.Ptr(true), - Actions: gu.Ptr(true), TokenExchange: gu.Ptr(true), ImprovedPerformance: nil, OIDCSingleV1SessionTermination: gu.Ptr(true), @@ -64,10 +62,6 @@ 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, @@ -107,10 +101,6 @@ 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, - }, ImprovedPerformance: &feature_pb.ImprovedPerformanceFeatureFlag{ ExecutionPaths: []feature_pb.ImprovedPerformance{feature_pb.ImprovedPerformance_IMPROVED_PERFORMANCE_ORG_BY_ID}, Source: feature_pb.Source_SOURCE_SYSTEM, @@ -131,7 +121,6 @@ func Test_instanceFeaturesToCommand(t *testing.T) { OidcLegacyIntrospection: nil, UserSchema: gu.Ptr(true), OidcTokenExchange: gu.Ptr(true), - Actions: gu.Ptr(true), ImprovedPerformance: nil, WebKey: gu.Ptr(true), OidcSingleV1SessionTermination: gu.Ptr(true), @@ -142,7 +131,6 @@ func Test_instanceFeaturesToCommand(t *testing.T) { LegacyIntrospection: nil, UserSchema: gu.Ptr(true), TokenExchange: gu.Ptr(true), - Actions: gu.Ptr(true), ImprovedPerformance: nil, WebKey: gu.Ptr(true), OIDCSingleV1SessionTermination: gu.Ptr(true), @@ -174,10 +162,6 @@ 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, @@ -217,10 +201,6 @@ 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/v2beta/integration_test/feature_test.go b/internal/api/grpc/feature/v2beta/integration_test/feature_test.go index 69e05352d0..cbd9f5f939 100644 --- a/internal/api/grpc/feature/v2beta/integration_test/feature_test.go +++ b/internal/api/grpc/feature/v2beta/integration_test/feature_test.go @@ -202,10 +202,6 @@ func TestServer_GetInstanceFeatures(t *testing.T) { Enabled: false, Source: feature.Source_SOURCE_UNSPECIFIED, }, - Actions: &feature.FeatureFlag{ - Enabled: false, - Source: feature.Source_SOURCE_UNSPECIFIED, - }, }, }, { @@ -215,7 +211,6 @@ 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) }, @@ -236,10 +231,6 @@ func TestServer_GetInstanceFeatures(t *testing.T) { Enabled: true, Source: feature.Source_SOURCE_INSTANCE, }, - Actions: &feature.FeatureFlag{ - Enabled: true, - Source: feature.Source_SOURCE_INSTANCE, - }, }, }, { @@ -273,10 +264,6 @@ 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/server/middleware/execution_interceptor.go b/internal/api/grpc/server/middleware/execution_interceptor.go index 053386caae..4aeea6c4da 100644 --- a/internal/api/grpc/server/middleware/execution_interceptor.go +++ b/internal/api/grpc/server/middleware/execution_interceptor.go @@ -5,12 +5,13 @@ import ( "encoding/json" "google.golang.org/grpc" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/execution" "github.com/zitadel/zitadel/internal/query" "github.com/zitadel/zitadel/internal/telemetry/tracing" - "github.com/zitadel/zitadel/internal/zerrors" ) func ExecutionHandler(queries *query.Queries) grpc.UnaryServerInterceptor { @@ -48,7 +49,7 @@ func executeTargetsForRequest(ctx context.Context, targets []execution.Target, f ProjectID: ctxData.ProjectID, OrgID: ctxData.OrgID, UserID: ctxData.UserID, - Request: req, + Request: Message{req.(proto.Message)}, } return execution.CallTargets(ctx, targets, info) @@ -70,8 +71,8 @@ func executeTargetsForResponse(ctx context.Context, targets []execution.Target, ProjectID: ctxData.ProjectID, OrgID: ctxData.OrgID, UserID: ctxData.UserID, - Request: req, - Response: resp, + Request: Message{req.(proto.Message)}, + Response: Message{resp.(proto.Message)}, } return execution.CallTargets(ctx, targets, info) @@ -80,12 +81,28 @@ func executeTargetsForResponse(ctx context.Context, targets []execution.Target, var _ execution.ContextInfo = &ContextInfoRequest{} type ContextInfoRequest struct { - FullMethod string `json:"fullMethod,omitempty"` - InstanceID string `json:"instanceID,omitempty"` - OrgID string `json:"orgID,omitempty"` - ProjectID string `json:"projectID,omitempty"` - UserID string `json:"userID,omitempty"` - Request interface{} `json:"request,omitempty"` + FullMethod string `json:"fullMethod,omitempty"` + InstanceID string `json:"instanceID,omitempty"` + OrgID string `json:"orgID,omitempty"` + ProjectID string `json:"projectID,omitempty"` + UserID string `json:"userID,omitempty"` + Request Message `json:"request,omitempty"` +} + +type Message struct { + proto.Message +} + +func (r *Message) MarshalJSON() ([]byte, error) { + data, err := protojson.Marshal(r.Message) + if err != nil { + return nil, err + } + return data, nil +} + +func (r *Message) UnmarshalJSON(data []byte) error { + return protojson.Unmarshal(data, r.Message) } func (c *ContextInfoRequest) GetHTTPRequestBody() []byte { @@ -97,26 +114,23 @@ func (c *ContextInfoRequest) GetHTTPRequestBody() []byte { } func (c *ContextInfoRequest) SetHTTPResponseBody(resp []byte) error { - if !json.Valid(resp) { - return zerrors.ThrowPreconditionFailed(nil, "ACTION-4m9s2", "Errors.Execution.ResponseIsNotValidJSON") - } - return json.Unmarshal(resp, c.Request) + return json.Unmarshal(resp, &c.Request) } func (c *ContextInfoRequest) GetContent() interface{} { - return c.Request + return c.Request.Message } var _ execution.ContextInfo = &ContextInfoResponse{} type ContextInfoResponse struct { - FullMethod string `json:"fullMethod,omitempty"` - InstanceID string `json:"instanceID,omitempty"` - OrgID string `json:"orgID,omitempty"` - ProjectID string `json:"projectID,omitempty"` - UserID string `json:"userID,omitempty"` - Request interface{} `json:"request,omitempty"` - Response interface{} `json:"response,omitempty"` + FullMethod string `json:"fullMethod,omitempty"` + InstanceID string `json:"instanceID,omitempty"` + OrgID string `json:"orgID,omitempty"` + ProjectID string `json:"projectID,omitempty"` + UserID string `json:"userID,omitempty"` + Request Message `json:"request,omitempty"` + Response Message `json:"response,omitempty"` } func (c *ContextInfoResponse) GetHTTPRequestBody() []byte { @@ -128,9 +142,9 @@ func (c *ContextInfoResponse) GetHTTPRequestBody() []byte { } func (c *ContextInfoResponse) SetHTTPResponseBody(resp []byte) error { - return json.Unmarshal(resp, c.Response) + return json.Unmarshal(resp, &c.Response) } func (c *ContextInfoResponse) GetContent() interface{} { - return c.Response + return c.Response.Message } diff --git a/internal/api/grpc/server/middleware/execution_interceptor_test.go b/internal/api/grpc/server/middleware/execution_interceptor_test.go index 6a5b74c5e4..281db4617a 100644 --- a/internal/api/grpc/server/middleware/execution_interceptor_test.go +++ b/internal/api/grpc/server/middleware/execution_interceptor_test.go @@ -11,6 +11,9 @@ import ( "time" "github.com/stretchr/testify/assert" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/structpb" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/execution" @@ -54,28 +57,28 @@ func (e *mockExecutionTarget) GetSigningKey() string { return e.SigningKey } -type mockContentRequest struct { - Content string -} - -func newMockContentRequest(content string) *mockContentRequest { - return &mockContentRequest{ - Content: content, +func newMockContentRequest(content string) proto.Message { + return &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "content": { + Kind: &structpb.Value_StringValue{StringValue: content}, + }, + }, } } func newMockContextInfoRequest(fullMethod, request string) *ContextInfoRequest { return &ContextInfoRequest{ FullMethod: fullMethod, - Request: newMockContentRequest(request), + Request: Message{Message: newMockContentRequest(request)}, } } func newMockContextInfoResponse(fullMethod, request, response string) *ContextInfoResponse { return &ContextInfoResponse{ FullMethod: fullMethod, - Request: newMockContentRequest(request), - Response: newMockContentRequest(response), + Request: Message{Message: newMockContentRequest(request)}, + Response: Message{Message: newMockContentRequest(response)}, } } @@ -591,7 +594,7 @@ func Test_executeTargetsForGRPCFullMethod_request(t *testing.T) { } else { assert.NoError(t, err) } - assert.Equal(t, tt.res.want, resp) + assert.EqualExportedValues(t, tt.res.want, resp) for _, closeF := range closeFuncs { closeF() @@ -632,7 +635,7 @@ func testServerCall( time.Sleep(sleep) w.Header().Set("Content-Type", "application/json") - resp, err := json.Marshal(respBody) + resp, err := protojson.Marshal(respBody.(proto.Message)) if err != nil { http.Error(w, "error", http.StatusInternalServerError) return @@ -723,7 +726,8 @@ func Test_executeTargetsForGRPCFullMethod_response(t *testing.T) { statusCode: http.StatusOK, }, }, - req: []byte{}, + req: newMockContentRequest(""), + resp: newMockContentRequest(""), }, res{ wantErr: true, @@ -790,7 +794,7 @@ func Test_executeTargetsForGRPCFullMethod_response(t *testing.T) { } else { assert.NoError(t, err) } - assert.Equal(t, tt.res.want, resp) + assert.EqualExportedValues(t, tt.res.want, resp) for _, closeF := range closeFuncs { closeF() diff --git a/internal/command/instance_features.go b/internal/command/instance_features.go index 3e927cc0c5..cb12bff828 100644 --- a/internal/command/instance_features.go +++ b/internal/command/instance_features.go @@ -21,7 +21,6 @@ type InstanceFeatures struct { LegacyIntrospection *bool UserSchema *bool TokenExchange *bool - Actions *bool ImprovedPerformance []feature.ImprovedPerformanceType WebKey *bool DebugOIDCParentError *bool @@ -39,7 +38,6 @@ func (m *InstanceFeatures) isEmpty() bool { m.LegacyIntrospection == nil && m.UserSchema == nil && m.TokenExchange == nil && - m.Actions == nil && // nil check to allow unset improvements m.ImprovedPerformance == nil && m.WebKey == nil && diff --git a/internal/command/instance_features_model.go b/internal/command/instance_features_model.go index 954c769304..977a46b6c2 100644 --- a/internal/command/instance_features_model.go +++ b/internal/command/instance_features_model.go @@ -71,7 +71,6 @@ func (m *InstanceFeaturesWriteModel) Query() *eventstore.SearchQueryBuilder { feature_v2.InstanceLegacyIntrospectionEventType, feature_v2.InstanceUserSchemaEventType, feature_v2.InstanceTokenExchangeEventType, - feature_v2.InstanceActionsEventType, feature_v2.InstanceImprovedPerformanceEventType, feature_v2.InstanceWebKeyEventType, feature_v2.InstanceDebugOIDCParentErrorEventType, @@ -108,9 +107,6 @@ func reduceInstanceFeature(features *InstanceFeatures, key feature.Key, value an case feature.KeyUserSchema: v := value.(bool) features.UserSchema = &v - case feature.KeyActions: - v := value.(bool) - features.Actions = &v case feature.KeyImprovedPerformance: v := value.([]feature.ImprovedPerformanceType) features.ImprovedPerformance = v @@ -148,7 +144,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) cmds = appendFeatureSliceUpdate(ctx, cmds, aggregate, wm.ImprovedPerformance, f.ImprovedPerformance, feature_v2.InstanceImprovedPerformanceEventType) cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.WebKey, f.WebKey, feature_v2.InstanceWebKeyEventType) cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.DebugOIDCParentError, f.DebugOIDCParentError, feature_v2.InstanceDebugOIDCParentErrorEventType) diff --git a/internal/command/instance_features_test.go b/internal/command/instance_features_test.go index e6b6bb4346..02e8896a0c 100644 --- a/internal/command/instance_features_test.go +++ b/internal/command/instance_features_test.go @@ -149,24 +149,6 @@ 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( @@ -204,10 +186,6 @@ func TestCommands_SetInstanceFeatures(t *testing.T) { ctx, aggregate, feature_v2.InstanceUserSchemaEventType, true, ), - feature_v2.NewSetEvent[bool]( - ctx, aggregate, - feature_v2.InstanceActionsEventType, true, - ), feature_v2.NewSetEvent[bool]( ctx, aggregate, feature_v2.InstanceOIDCSingleV1SessionTerminationEventType, true, @@ -219,7 +197,6 @@ func TestCommands_SetInstanceFeatures(t *testing.T) { TriggerIntrospectionProjections: gu.Ptr(false), LegacyIntrospection: gu.Ptr(true), UserSchema: gu.Ptr(true), - Actions: gu.Ptr(true), OIDCSingleV1SessionTermination: gu.Ptr(true), }}, want: &domain.ObjectDetails{ diff --git a/internal/command/system_features.go b/internal/command/system_features.go index dc886de318..b317ea93bb 100644 --- a/internal/command/system_features.go +++ b/internal/command/system_features.go @@ -15,7 +15,6 @@ type SystemFeatures struct { LegacyIntrospection *bool TokenExchange *bool UserSchema *bool - Actions *bool ImprovedPerformance []feature.ImprovedPerformanceType OIDCSingleV1SessionTermination *bool DisableUserTokenEvent *bool @@ -30,7 +29,6 @@ func (m *SystemFeatures) isEmpty() bool { m.LegacyIntrospection == nil && m.UserSchema == nil && m.TokenExchange == nil && - m.Actions == nil && // nil check to allow unset improvements m.ImprovedPerformance == nil && m.OIDCSingleV1SessionTermination == nil && diff --git a/internal/command/system_features_model.go b/internal/command/system_features_model.go index 15fc3e0bf0..28e56f8bd4 100644 --- a/internal/command/system_features_model.go +++ b/internal/command/system_features_model.go @@ -64,7 +64,6 @@ func (m *SystemFeaturesWriteModel) Query() *eventstore.SearchQueryBuilder { feature_v2.SystemLegacyIntrospectionEventType, feature_v2.SystemUserSchemaEventType, feature_v2.SystemTokenExchangeEventType, - feature_v2.SystemActionsEventType, feature_v2.SystemImprovedPerformanceEventType, feature_v2.SystemOIDCSingleV1SessionTerminationEventType, feature_v2.SystemDisableUserTokenEvent, @@ -98,9 +97,6 @@ func reduceSystemFeature(features *SystemFeatures, key feature.Key, value any) { case feature.KeyTokenExchange: v := value.(bool) features.TokenExchange = &v - case feature.KeyActions: - v := value.(bool) - features.Actions = &v case feature.KeyImprovedPerformance: features.ImprovedPerformance = value.([]feature.ImprovedPerformanceType) case feature.KeyOIDCSingleV1SessionTermination: @@ -128,7 +124,6 @@ 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) cmds = appendFeatureSliceUpdate(ctx, cmds, aggregate, wm.ImprovedPerformance, f.ImprovedPerformance, feature_v2.SystemImprovedPerformanceEventType) cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.OIDCSingleV1SessionTermination, f.OIDCSingleV1SessionTermination, feature_v2.SystemOIDCSingleV1SessionTerminationEventType) cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.DisableUserTokenEvent, f.DisableUserTokenEvent, feature_v2.SystemDisableUserTokenEvent) diff --git a/internal/command/system_features_test.go b/internal/command/system_features_test.go index 9c5f4cc2a9..b1b5207b8c 100644 --- a/internal/command/system_features_test.go +++ b/internal/command/system_features_test.go @@ -117,24 +117,6 @@ 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( @@ -172,10 +154,6 @@ func TestCommands_SetSystemFeatures(t *testing.T) { context.Background(), aggregate, feature_v2.SystemUserSchemaEventType, true, ), - feature_v2.NewSetEvent[bool]( - context.Background(), aggregate, - feature_v2.SystemActionsEventType, true, - ), feature_v2.NewSetEvent[bool]( context.Background(), aggregate, feature_v2.SystemOIDCSingleV1SessionTerminationEventType, true, @@ -187,7 +165,6 @@ func TestCommands_SetSystemFeatures(t *testing.T) { TriggerIntrospectionProjections: gu.Ptr(false), LegacyIntrospection: gu.Ptr(true), UserSchema: gu.Ptr(true), - Actions: gu.Ptr(true), OIDCSingleV1SessionTermination: gu.Ptr(true), }}, want: &domain.ObjectDetails{ @@ -233,10 +210,6 @@ func TestCommands_SetSystemFeatures(t *testing.T) { context.Background(), aggregate, feature_v2.SystemUserSchemaEventType, true, ), - feature_v2.NewSetEvent[bool]( - context.Background(), aggregate, - feature_v2.SystemActionsEventType, false, - ), feature_v2.NewSetEvent[bool]( context.Background(), aggregate, feature_v2.SystemOIDCSingleV1SessionTerminationEventType, false, @@ -248,7 +221,6 @@ func TestCommands_SetSystemFeatures(t *testing.T) { TriggerIntrospectionProjections: gu.Ptr(false), LegacyIntrospection: gu.Ptr(true), UserSchema: gu.Ptr(true), - Actions: gu.Ptr(false), OIDCSingleV1SessionTermination: gu.Ptr(false), }}, want: &domain.ObjectDetails{ diff --git a/internal/execution/execution.go b/internal/execution/execution.go index 575c86ecc4..b885858d94 100644 --- a/internal/execution/execution.go +++ b/internal/execution/execution.go @@ -82,11 +82,11 @@ func CallTarget( case domain.TargetTypeCall: return Call(ctx, target.GetEndpoint(), target.GetTimeout(), info.GetHTTPRequestBody(), target.GetSigningKey()) case domain.TargetTypeAsync: - go func(target Target, info ContextInfoRequest) { - if _, err := Call(ctx, target.GetEndpoint(), target.GetTimeout(), info.GetHTTPRequestBody(), target.GetSigningKey()); err != nil { + go func(ctx context.Context, target Target, info []byte) { + if _, err := Call(ctx, target.GetEndpoint(), target.GetTimeout(), info, target.GetSigningKey()); err != nil { logging.WithFields("target", target.GetTargetID()).OnError(err).Info(err) } - }(target, info) + }(context.WithoutCancel(ctx), target, info.GetHTTPRequestBody()) return nil, nil default: return nil, zerrors.ThrowInternal(nil, "EXEC-auqnansr2m", "Errors.Execution.Unknown") diff --git a/internal/execution/execution_test.go b/internal/execution/execution_test.go index 40731a840a..036b160ab7 100644 --- a/internal/execution/execution_test.go +++ b/internal/execution/execution_test.go @@ -13,6 +13,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/types/known/structpb" "github.com/zitadel/zitadel/internal/api/grpc/server/middleware" "github.com/zitadel/zitadel/internal/domain" @@ -149,8 +150,8 @@ func Test_CallTarget(t *testing.T) { info: requestContextInfo1, server: &callTestServer{ method: http.MethodPost, - expectBody: []byte("{\"request\":{\"request\":\"content1\"}}"), - respondBody: []byte("{\"request\":\"content2\"}"), + expectBody: []byte("{\"request\":{\"content\":\"request1\"}}"), + respondBody: []byte("{\"content\":\"request2\"}"), timeout: time.Second, statusCode: http.StatusInternalServerError, }, @@ -170,8 +171,8 @@ func Test_CallTarget(t *testing.T) { server: &callTestServer{ timeout: time.Second, method: http.MethodPost, - expectBody: []byte("{\"request\":{\"request\":\"content1\"}}"), - respondBody: []byte("{\"request\":\"content2\"}"), + expectBody: []byte("{\"request\":{\"content\":\"request1\"}}"), + respondBody: []byte("{\"content\":\"request2\"}"), statusCode: http.StatusInternalServerError, }, target: &mockTarget{ @@ -191,8 +192,8 @@ func Test_CallTarget(t *testing.T) { server: &callTestServer{ timeout: time.Second, method: http.MethodPost, - expectBody: []byte("{\"request\":{\"request\":\"content1\"}}"), - respondBody: []byte("{\"request\":\"content2\"}"), + expectBody: []byte("{\"request\":{\"content\":\"request1\"}}"), + respondBody: []byte("{\"content\":\"request2\"}"), statusCode: http.StatusOK, }, target: &mockTarget{ @@ -212,8 +213,8 @@ func Test_CallTarget(t *testing.T) { server: &callTestServer{ timeout: time.Second, method: http.MethodPost, - expectBody: []byte("{\"request\":{\"request\":\"content1\"}}"), - respondBody: []byte("{\"request\":\"content2\"}"), + expectBody: []byte("{\"request\":{\"content\":\"request1\"}}"), + respondBody: []byte("{\"content\":\"request2\"}"), statusCode: http.StatusOK, signingKey: "signingkey", }, @@ -235,8 +236,8 @@ func Test_CallTarget(t *testing.T) { server: &callTestServer{ timeout: time.Second, method: http.MethodPost, - expectBody: []byte("{\"request\":{\"request\":\"content1\"}}"), - respondBody: []byte("{\"request\":\"content2\"}"), + expectBody: []byte("{\"request\":{\"content\":\"request1\"}}"), + respondBody: []byte("{\"content\":\"request2\"}"), statusCode: http.StatusInternalServerError, }, target: &mockTarget{ @@ -256,8 +257,8 @@ func Test_CallTarget(t *testing.T) { server: &callTestServer{ timeout: time.Second, method: http.MethodPost, - expectBody: []byte("{\"request\":{\"request\":\"content1\"}}"), - respondBody: []byte("{\"request\":\"content2\"}"), + expectBody: []byte("{\"request\":{\"content\":\"request1\"}}"), + respondBody: []byte("{\"content\":\"request2\"}"), statusCode: http.StatusOK, }, target: &mockTarget{ @@ -266,7 +267,7 @@ func Test_CallTarget(t *testing.T) { }, }, res{ - body: []byte("{\"request\":\"content2\"}"), + body: []byte("{\"content\":\"request2\"}"), }, }, { @@ -277,8 +278,8 @@ func Test_CallTarget(t *testing.T) { server: &callTestServer{ timeout: time.Second, method: http.MethodPost, - expectBody: []byte("{\"request\":{\"request\":\"content1\"}}"), - respondBody: []byte("{\"request\":\"content2\"}"), + expectBody: []byte("{\"request\":{\"content\":\"request1\"}}"), + respondBody: []byte("{\"content\":\"request2\"}"), statusCode: http.StatusOK, signingKey: "signingkey", }, @@ -289,7 +290,7 @@ func Test_CallTarget(t *testing.T) { }, }, res{ - body: []byte("{\"request\":\"content2\"}"), + body: []byte("{\"content\":\"request2\"}"), }, }, } @@ -576,13 +577,13 @@ func testCallTargets(ctx context.Context, } var requestContextInfo1 = &middleware.ContextInfoRequest{ - Request: &request{ - Request: "content1", - }, + Request: middleware.Message{Message: &structpb.Struct{ + Fields: map[string]*structpb.Value{"content": structpb.NewStringValue("request1")}, + }}, } -var requestContextInfoBody1 = []byte("{\"request\":{\"request\":\"content1\"}}") -var requestContextInfoBody2 = []byte("{\"request\":{\"request\":\"content2\"}}") +var requestContextInfoBody1 = []byte("{\"request\":{\"content\":\"request1\"}}") +var requestContextInfoBody2 = []byte("{\"request\":{\"content\":\"request2\"}}") type request struct { Request string `json:"request"` diff --git a/internal/feature/feature.go b/internal/feature/feature.go index 638917fd68..389b750483 100644 --- a/internal/feature/feature.go +++ b/internal/feature/feature.go @@ -15,7 +15,7 @@ const ( KeyLegacyIntrospection KeyUserSchema KeyTokenExchange - KeyActions + KeyActionsDeprecated KeyImprovedPerformance KeyWebKey KeyDebugOIDCParentError @@ -46,7 +46,6 @@ 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"` ImprovedPerformance []ImprovedPerformanceType `json:"improved_performance,omitempty"` WebKey bool `json:"web_key,omitempty"` DebugOIDCParentError bool `json:"debug_oidc_parent_error,omitempty"` diff --git a/internal/feature/key_enumer.go b/internal/feature/key_enumer.go index 5a37b96270..6466061718 100644 --- a/internal/feature/key_enumer.go +++ b/internal/feature/key_enumer.go @@ -30,7 +30,7 @@ func _KeyNoOp() { _ = x[KeyLegacyIntrospection-(3)] _ = x[KeyUserSchema-(4)] _ = x[KeyTokenExchange-(5)] - _ = x[KeyActions-(6)] + _ = x[KeyActionsDeprecated-(6)] _ = x[KeyImprovedPerformance-(7)] _ = x[KeyWebKey-(8)] _ = x[KeyDebugOIDCParentError-(9)] @@ -42,7 +42,7 @@ func _KeyNoOp() { _ = x[KeyConsoleUseV2UserApi-(15)] } -var _KeyValues = []Key{KeyUnspecified, KeyLoginDefaultOrg, KeyTriggerIntrospectionProjections, KeyLegacyIntrospection, KeyUserSchema, KeyTokenExchange, KeyActions, KeyImprovedPerformance, KeyWebKey, KeyDebugOIDCParentError, KeyOIDCSingleV1SessionTermination, KeyDisableUserTokenEvent, KeyEnableBackChannelLogout, KeyLoginV2, KeyPermissionCheckV2, KeyConsoleUseV2UserApi} +var _KeyValues = []Key{KeyUnspecified, KeyLoginDefaultOrg, KeyTriggerIntrospectionProjections, KeyLegacyIntrospection, KeyUserSchema, KeyTokenExchange, KeyActionsDeprecated, KeyImprovedPerformance, KeyWebKey, KeyDebugOIDCParentError, KeyOIDCSingleV1SessionTermination, KeyDisableUserTokenEvent, KeyEnableBackChannelLogout, KeyLoginV2, KeyPermissionCheckV2, KeyConsoleUseV2UserApi} var _KeyNameToValueMap = map[string]Key{ _KeyName[0:11]: KeyUnspecified, @@ -57,8 +57,8 @@ var _KeyNameToValueMap = map[string]Key{ _KeyLowerName[81:92]: KeyUserSchema, _KeyName[92:106]: KeyTokenExchange, _KeyLowerName[92:106]: KeyTokenExchange, - _KeyName[106:113]: KeyActions, - _KeyLowerName[106:113]: KeyActions, + _KeyName[106:113]: KeyActionsDeprecated, + _KeyLowerName[106:113]: KeyActionsDeprecated, _KeyName[113:133]: KeyImprovedPerformance, _KeyLowerName[113:133]: KeyImprovedPerformance, _KeyName[133:140]: KeyWebKey, diff --git a/internal/integration/action.go b/internal/integration/action.go index b8f69c5788..e849b5c21c 100644 --- a/internal/integration/action.go +++ b/internal/integration/action.go @@ -8,6 +8,9 @@ import ( "reflect" "sync" "time" + + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" ) type server struct { @@ -100,3 +103,61 @@ func TestServerCall( server.server = httptest.NewServer(http.HandlerFunc(handler)) return server.URL(), server.Close, server.Called, server.ResetCalled } + +func TestServerCallProto( + reqBody interface{}, + sleep time.Duration, + statusCode int, + respBody proto.Message, +) (url string, closeF func(), calledF func() int, resetCalledF func()) { + server := &server{ + called: 0, + } + + handler := func(w http.ResponseWriter, r *http.Request) { + server.Increase() + if reqBody != nil { + data, err := json.Marshal(reqBody) + if err != nil { + http.Error(w, "error, marshall: "+err.Error(), http.StatusInternalServerError) + return + } + sentBody, err := io.ReadAll(r.Body) + if err != nil { + http.Error(w, "error, read body: "+err.Error(), http.StatusInternalServerError) + return + } + if !reflect.DeepEqual(data, sentBody) { + http.Error(w, "error, equal:\n"+string(data)+"\nsent:\n"+string(sentBody), http.StatusInternalServerError) + return + } + } + if statusCode != http.StatusOK { + http.Error(w, "error, statusCode", statusCode) + return + } + + time.Sleep(sleep) + + if respBody != nil { + w.Header().Set("Content-Type", "application/json") + resp, err := protojson.Marshal(respBody) + if err != nil { + http.Error(w, "error", http.StatusInternalServerError) + return + } + if _, err := io.Writer.Write(w, resp); err != nil { + http.Error(w, "error", http.StatusInternalServerError) + return + } + } else { + if _, err := io.WriteString(w, "finished successfully"); err != nil { + http.Error(w, "error", http.StatusInternalServerError) + return + } + } + } + + server.server = httptest.NewServer(http.HandlerFunc(handler)) + return server.URL(), server.Close, server.Called, server.ResetCalled +} diff --git a/internal/integration/client.go b/internal/integration/client.go index 2cb8fa3641..e82a6bec55 100644 --- a/internal/integration/client.go +++ b/internal/integration/client.go @@ -763,7 +763,7 @@ func (i *Instance) DeleteExecution(ctx context.Context, t *testing.T, cond *acti require.NoError(t, err) } -func (i *Instance) SetExecution(ctx context.Context, t *testing.T, cond *action.Condition, targets []*action.ExecutionTargetType) *action.SetExecutionResponse { +func (i *Instance) SetExecution(ctx context.Context, t *testing.T, cond *action.Condition, targets []string) *action.SetExecutionResponse { target, err := i.Client.ActionV2beta.SetExecution(ctx, &action.SetExecutionRequest{ Condition: cond, Targets: targets, diff --git a/internal/query/instance_features.go b/internal/query/instance_features.go index 911edaa606..4ec40dc9d5 100644 --- a/internal/query/instance_features.go +++ b/internal/query/instance_features.go @@ -14,7 +14,6 @@ type InstanceFeatures struct { LegacyIntrospection FeatureSource[bool] UserSchema FeatureSource[bool] TokenExchange FeatureSource[bool] - Actions FeatureSource[bool] ImprovedPerformance FeatureSource[[]feature.ImprovedPerformanceType] WebKey FeatureSource[bool] DebugOIDCParentError FeatureSource[bool] diff --git a/internal/query/instance_features_model.go b/internal/query/instance_features_model.go index 11deb30f34..6a0abbb58c 100644 --- a/internal/query/instance_features_model.go +++ b/internal/query/instance_features_model.go @@ -67,7 +67,6 @@ func (m *InstanceFeaturesReadModel) Query() *eventstore.SearchQueryBuilder { feature_v2.InstanceLegacyIntrospectionEventType, feature_v2.InstanceUserSchemaEventType, feature_v2.InstanceTokenExchangeEventType, - feature_v2.InstanceActionsEventType, feature_v2.InstanceImprovedPerformanceEventType, feature_v2.InstanceWebKeyEventType, feature_v2.InstanceDebugOIDCParentErrorEventType, @@ -98,7 +97,6 @@ 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 m.instance.ImprovedPerformance = m.system.ImprovedPerformance m.instance.OIDCSingleV1SessionTermination = m.system.OIDCSingleV1SessionTermination m.instance.DisableUserTokenEvent = m.system.DisableUserTokenEvent @@ -113,7 +111,8 @@ func reduceInstanceFeatureSet[T any](features *InstanceFeatures, event *feature_ return err } switch key { - case feature.KeyUnspecified: + case feature.KeyUnspecified, + feature.KeyActionsDeprecated: return nil case feature.KeyLoginDefaultOrg: features.LoginDefaultOrg.set(level, event.Value) @@ -125,8 +124,6 @@ func reduceInstanceFeatureSet[T any](features *InstanceFeatures, event *feature_ features.UserSchema.set(level, event.Value) case feature.KeyTokenExchange: features.TokenExchange.set(level, event.Value) - case feature.KeyActions: - features.Actions.set(level, event.Value) case feature.KeyImprovedPerformance: features.ImprovedPerformance.set(level, event.Value) case feature.KeyWebKey: diff --git a/internal/query/instance_features_test.go b/internal/query/instance_features_test.go index 903c2872a9..d80a3b05fc 100644 --- a/internal/query/instance_features_test.go +++ b/internal/query/instance_features_test.go @@ -105,10 +105,6 @@ func TestQueries_GetInstanceFeatures(t *testing.T) { ctx, aggregate, feature_v2.InstanceUserSchemaEventType, false, )), - eventFromEventPusher(feature_v2.NewSetEvent( - ctx, aggregate, - feature_v2.InstanceActionsEventType, false, - )), ), ), args: args{true}, @@ -132,10 +128,6 @@ func TestQueries_GetInstanceFeatures(t *testing.T) { Level: feature.LevelInstance, Value: false, }, - Actions: FeatureSource[bool]{ - Level: feature.LevelInstance, - Value: false, - }, }, }, { @@ -162,10 +154,6 @@ func TestQueries_GetInstanceFeatures(t *testing.T) { ctx, aggregate, feature_v2.InstanceUserSchemaEventType, false, )), - eventFromEventPusher(feature_v2.NewSetEvent( - ctx, aggregate, - feature_v2.InstanceActionsEventType, false, - )), eventFromEventPusher(feature_v2.NewResetEvent( ctx, aggregate, feature_v2.InstanceResetEventType, @@ -197,10 +185,6 @@ func TestQueries_GetInstanceFeatures(t *testing.T) { Level: feature.LevelUnspecified, Value: false, }, - Actions: FeatureSource[bool]{ - Level: feature.LevelUnspecified, - Value: false, - }, }, }, { @@ -223,10 +207,6 @@ func TestQueries_GetInstanceFeatures(t *testing.T) { ctx, aggregate, feature_v2.InstanceUserSchemaEventType, false, )), - eventFromEventPusher(feature_v2.NewSetEvent( - ctx, aggregate, - feature_v2.InstanceActionsEventType, false, - )), eventFromEventPusher(feature_v2.NewResetEvent( ctx, aggregate, feature_v2.InstanceResetEventType, @@ -258,10 +238,6 @@ 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 798af6693c..34100a0d66 100644 --- a/internal/query/projection/instance_features.go +++ b/internal/query/projection/instance_features.go @@ -80,10 +80,6 @@ func (*instanceFeatureProjection) Reducers() []handler.AggregateReducer { Event: feature_v2.InstanceTokenExchangeEventType, Reduce: reduceInstanceSetFeature[bool], }, - { - Event: feature_v2.InstanceActionsEventType, - Reduce: reduceInstanceSetFeature[bool], - }, { Event: feature_v2.InstanceImprovedPerformanceEventType, Reduce: reduceInstanceSetFeature[[]feature.ImprovedPerformanceType], diff --git a/internal/query/projection/system_features.go b/internal/query/projection/system_features.go index f6f0a36d56..de54054e78 100644 --- a/internal/query/projection/system_features.go +++ b/internal/query/projection/system_features.go @@ -72,10 +72,6 @@ func (*systemFeatureProjection) Reducers() []handler.AggregateReducer { Event: feature_v2.SystemTokenExchangeEventType, Reduce: reduceSystemSetFeature[bool], }, - { - Event: feature_v2.SystemActionsEventType, - Reduce: reduceSystemSetFeature[bool], - }, { Event: feature_v2.SystemImprovedPerformanceEventType, Reduce: reduceSystemSetFeature[[]feature.ImprovedPerformanceType], diff --git a/internal/query/system_features.go b/internal/query/system_features.go index 31ad402d12..dcbbb7d6fe 100644 --- a/internal/query/system_features.go +++ b/internal/query/system_features.go @@ -25,7 +25,6 @@ type SystemFeatures struct { LegacyIntrospection FeatureSource[bool] UserSchema FeatureSource[bool] TokenExchange FeatureSource[bool] - Actions FeatureSource[bool] ImprovedPerformance FeatureSource[[]feature.ImprovedPerformanceType] OIDCSingleV1SessionTermination FeatureSource[bool] DisableUserTokenEvent FeatureSource[bool] diff --git a/internal/query/system_features_model.go b/internal/query/system_features_model.go index 217154e3ed..69e1f35968 100644 --- a/internal/query/system_features_model.go +++ b/internal/query/system_features_model.go @@ -60,7 +60,6 @@ func (m *SystemFeaturesReadModel) Query() *eventstore.SearchQueryBuilder { feature_v2.SystemLegacyIntrospectionEventType, feature_v2.SystemUserSchemaEventType, feature_v2.SystemTokenExchangeEventType, - feature_v2.SystemActionsEventType, feature_v2.SystemImprovedPerformanceEventType, feature_v2.SystemOIDCSingleV1SessionTerminationEventType, feature_v2.SystemDisableUserTokenEvent, @@ -82,7 +81,8 @@ func reduceSystemFeatureSet[T any](features *SystemFeatures, event *feature_v2.S return err } switch key { - case feature.KeyUnspecified: + case feature.KeyUnspecified, + feature.KeyActionsDeprecated: return nil case feature.KeyLoginDefaultOrg: features.LoginDefaultOrg.set(level, event.Value) @@ -94,8 +94,6 @@ func reduceSystemFeatureSet[T any](features *SystemFeatures, event *feature_v2.S features.UserSchema.set(level, event.Value) case feature.KeyTokenExchange: features.TokenExchange.set(level, event.Value) - case feature.KeyActions: - features.Actions.set(level, event.Value) case feature.KeyImprovedPerformance: features.ImprovedPerformance.set(level, event.Value) case feature.KeyOIDCSingleV1SessionTermination: diff --git a/internal/query/system_features_test.go b/internal/query/system_features_test.go index fcd0f812f5..5a58ac23d7 100644 --- a/internal/query/system_features_test.go +++ b/internal/query/system_features_test.go @@ -61,10 +61,6 @@ func TestQueries_GetSystemFeatures(t *testing.T) { context.Background(), aggregate, feature_v2.SystemUserSchemaEventType, false, )), - eventFromEventPusher(feature_v2.NewSetEvent( - context.Background(), aggregate, - feature_v2.SystemActionsEventType, true, - )), ), ), want: &SystemFeatures{ @@ -87,10 +83,6 @@ func TestQueries_GetSystemFeatures(t *testing.T) { Level: feature.LevelSystem, Value: false, }, - Actions: FeatureSource[bool]{ - Level: feature.LevelSystem, - Value: true, - }, }, }, { @@ -113,10 +105,6 @@ func TestQueries_GetSystemFeatures(t *testing.T) { context.Background(), aggregate, feature_v2.SystemUserSchemaEventType, false, )), - eventFromEventPusher(feature_v2.NewSetEvent( - context.Background(), aggregate, - feature_v2.SystemActionsEventType, false, - )), eventFromEventPusher(feature_v2.NewResetEvent( context.Background(), aggregate, feature_v2.SystemResetEventType, @@ -147,10 +135,6 @@ func TestQueries_GetSystemFeatures(t *testing.T) { Level: feature.LevelUnspecified, Value: false, }, - Actions: FeatureSource[bool]{ - Level: feature.LevelUnspecified, - Value: false, - }, }, }, { @@ -173,10 +157,6 @@ func TestQueries_GetSystemFeatures(t *testing.T) { context.Background(), aggregate, feature_v2.SystemUserSchemaEventType, false, )), - eventFromEventPusher(feature_v2.NewSetEvent( - context.Background(), aggregate, - feature_v2.SystemActionsEventType, false, - )), eventFromEventPusher(feature_v2.NewResetEvent( context.Background(), aggregate, feature_v2.SystemResetEventType, @@ -207,10 +187,6 @@ func TestQueries_GetSystemFeatures(t *testing.T) { Level: feature.LevelUnspecified, Value: false, }, - Actions: FeatureSource[bool]{ - Level: feature.LevelUnspecified, - Value: false, - }, }, }, } diff --git a/internal/repository/execution/queue.go b/internal/repository/execution/queue.go index 28f8edbf31..ed3a6ce4a0 100644 --- a/internal/repository/execution/queue.go +++ b/internal/repository/execution/queue.go @@ -41,16 +41,16 @@ func ContextInfoFromRequest(e *Request) *ContextInfoEvent { } type ContextInfoEvent struct { - AggregateID string `json:"aggregateID,omitempty"` - AggregateType string `json:"aggregateType,omitempty"` - ResourceOwner string `json:"resourceOwner,omitempty"` - InstanceID string `json:"instanceID,omitempty"` - Version string `json:"version,omitempty"` - Sequence uint64 `json:"sequence,omitempty"` - EventType string `json:"event_type,omitempty"` - CreatedAt string `json:"created_at,omitempty"` - UserID string `json:"userID,omitempty"` - EventPayload []byte `json:"event_payload,omitempty"` + AggregateID string `json:"aggregateID,omitempty"` + AggregateType string `json:"aggregateType,omitempty"` + ResourceOwner string `json:"resourceOwner,omitempty"` + InstanceID string `json:"instanceID,omitempty"` + Version string `json:"version,omitempty"` + Sequence uint64 `json:"sequence,omitempty"` + EventType string `json:"event_type,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UserID string `json:"userID,omitempty"` + EventPayload json.RawMessage `json:"event_payload,omitempty"` } func (c *ContextInfoEvent) GetHTTPRequestBody() []byte { diff --git a/internal/repository/feature/feature_v2/eventstore.go b/internal/repository/feature/feature_v2/eventstore.go index e8d0da1ab0..00618f56c2 100644 --- a/internal/repository/feature/feature_v2/eventstore.go +++ b/internal/repository/feature/feature_v2/eventstore.go @@ -12,7 +12,6 @@ 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, SystemImprovedPerformanceEventType, eventstore.GenericEventMapper[SetEvent[[]feature.ImprovedPerformanceType]]) eventstore.RegisterFilterEventMapper(AggregateType, SystemOIDCSingleV1SessionTerminationEventType, eventstore.GenericEventMapper[SetEvent[bool]]) eventstore.RegisterFilterEventMapper(AggregateType, SystemDisableUserTokenEvent, eventstore.GenericEventMapper[SetEvent[bool]]) @@ -26,7 +25,6 @@ func init() { 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]]) eventstore.RegisterFilterEventMapper(AggregateType, InstanceImprovedPerformanceEventType, eventstore.GenericEventMapper[SetEvent[[]feature.ImprovedPerformanceType]]) eventstore.RegisterFilterEventMapper(AggregateType, InstanceWebKeyEventType, eventstore.GenericEventMapper[SetEvent[bool]]) eventstore.RegisterFilterEventMapper(AggregateType, InstanceDebugOIDCParentErrorEventType, eventstore.GenericEventMapper[SetEvent[bool]]) diff --git a/internal/repository/feature/feature_v2/feature.go b/internal/repository/feature/feature_v2/feature.go index 008986824b..d5e8941df2 100644 --- a/internal/repository/feature/feature_v2/feature.go +++ b/internal/repository/feature/feature_v2/feature.go @@ -17,7 +17,6 @@ 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) SystemImprovedPerformanceEventType = setEventTypeFromFeature(feature.LevelSystem, feature.KeyImprovedPerformance) SystemOIDCSingleV1SessionTerminationEventType = setEventTypeFromFeature(feature.LevelSystem, feature.KeyOIDCSingleV1SessionTermination) SystemDisableUserTokenEvent = setEventTypeFromFeature(feature.LevelSystem, feature.KeyDisableUserTokenEvent) @@ -31,7 +30,6 @@ 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) InstanceImprovedPerformanceEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyImprovedPerformance) InstanceWebKeyEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyWebKey) InstanceDebugOIDCParentErrorEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyDebugOIDCParentError) diff --git a/proto/buf.yaml b/proto/buf.yaml index f8cf192a95..31bc7b4ccc 100644 --- a/proto/buf.yaml +++ b/proto/buf.yaml @@ -7,6 +7,10 @@ deps: breaking: use: - FILE + - FIELD_NO_DELETE_UNLESS_NAME_RESERVED + - FIELD_NO_DELETE_UNLESS_NUMBER_RESERVED + except: + - FIELD_NO_DELETE ignore_unstable_packages: true lint: use: diff --git a/proto/zitadel/action/v2beta/action_service.proto b/proto/zitadel/action/v2beta/action_service.proto index d1eebfa344..f225905225 100644 --- a/proto/zitadel/action/v2beta/action_service.proto +++ b/proto/zitadel/action/v2beta/action_service.proto @@ -670,8 +670,8 @@ message ListTargetsResponse { message SetExecutionRequest { // Condition defining when the execution should be used. Condition condition = 1; - // Ordered list of targets/includes called during the execution. - repeated ExecutionTargetType targets = 2; + // Ordered list of targets called during the execution. + repeated string targets = 2; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { example: "{\"condition\":{\"request\":{\"method\":\"zitadel.session.v2.SessionService/ListSessions\"}},\"targets\":[{\"target\":\"69629026806489455\"}]}"; }; diff --git a/proto/zitadel/action/v2beta/execution.proto b/proto/zitadel/action/v2beta/execution.proto index 4f4ad1ce88..e93470e5dc 100644 --- a/proto/zitadel/action/v2beta/execution.proto +++ b/proto/zitadel/action/v2beta/execution.proto @@ -29,18 +29,8 @@ message Execution { example: "\"2025-01-23T10:34:18.051Z\""; } ]; - // Ordered list of targets/includes called during the execution. - repeated ExecutionTargetType targets = 4; -} - -message ExecutionTargetType { - oneof type { - option (validate.required) = true; - // Unique identifier of existing target to call. - string target = 1; - // Unique identifier of existing execution to include targets of. - Condition include = 2; - } + // Ordered list of targets called during the execution. + repeated string targets = 4; } message Condition { diff --git a/proto/zitadel/action/v2beta/query.proto b/proto/zitadel/action/v2beta/query.proto index 564db8bc9f..fe4f72f294 100644 --- a/proto/zitadel/action/v2beta/query.proto +++ b/proto/zitadel/action/v2beta/query.proto @@ -19,7 +19,6 @@ message ExecutionSearchFilter { InConditionsFilter in_conditions_filter = 1; ExecutionTypeFilter execution_type_filter = 2; TargetFilter target_filter = 3; - IncludeFilter include_filter = 4; } } @@ -43,16 +42,6 @@ message TargetFilter { ]; } -message IncludeFilter { - // Defines the include to query for. - Condition include = 1 [ - (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { - description: "the id of the include" - example: "\"request.zitadel.session.v2.SessionService\""; - } - ]; -} - enum TargetFieldName { TARGET_FIELD_NAME_UNSPECIFIED = 0; TARGET_FIELD_NAME_ID = 1; diff --git a/proto/zitadel/feature/v2/instance.proto b/proto/zitadel/feature/v2/instance.proto index efd7f83e4c..fe8d3f7a39 100644 --- a/proto/zitadel/feature/v2/instance.proto +++ b/proto/zitadel/feature/v2/instance.proto @@ -11,6 +11,8 @@ import "zitadel/feature/v2/feature.proto"; option go_package = "github.com/zitadel/zitadel/pkg/grpc/feature/v2;feature"; message SetInstanceFeaturesRequest{ + reserved 6; + reserved "actions"; optional bool login_default_org = 1 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "true"; @@ -43,12 +45,6 @@ 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."; - } - ]; repeated ImprovedPerformance improved_performance = 7 [ (validate.rules).repeated.unique = true, @@ -135,6 +131,8 @@ message GetInstanceFeaturesRequest { } message GetInstanceFeaturesResponse { + reserved 7; + reserved "actions"; zitadel.object.v2.Details details = 1; FeatureFlag login_default_org = 2 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { @@ -171,13 +169,6 @@ message GetInstanceFeaturesResponse { } ]; - 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."; - } - ]; - ImprovedPerformanceFeatureFlag improved_performance = 8 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "[1]"; diff --git a/proto/zitadel/feature/v2/system.proto b/proto/zitadel/feature/v2/system.proto index c734905fb2..d222e2a90c 100644 --- a/proto/zitadel/feature/v2/system.proto +++ b/proto/zitadel/feature/v2/system.proto @@ -11,6 +11,8 @@ import "zitadel/feature/v2/feature.proto"; option go_package = "github.com/zitadel/zitadel/pkg/grpc/feature/v2;feature"; message SetSystemFeaturesRequest{ + reserved 6; + reserved "actions"; optional bool login_default_org = 1 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "true"; @@ -46,13 +48,6 @@ message SetSystemFeaturesRequest{ } ]; - 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."; - } - ]; - repeated ImprovedPerformance improved_performance = 7 [ (validate.rules).repeated.unique = true, (validate.rules).repeated.items.enum = {defined_only: true, not_in: [0]}, @@ -110,6 +105,8 @@ message ResetSystemFeaturesResponse { message GetSystemFeaturesRequest {} message GetSystemFeaturesResponse { + reserved 7; + reserved "actions"; zitadel.object.v2.Details details = 1; FeatureFlag login_default_org = 2 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { @@ -146,13 +143,6 @@ message GetSystemFeaturesResponse { } ]; - 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."; - } - ]; - ImprovedPerformanceFeatureFlag improved_performance = 8 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "[1]"; diff --git a/proto/zitadel/feature/v2beta/instance.proto b/proto/zitadel/feature/v2beta/instance.proto index 865a1d2308..7717dd7556 100644 --- a/proto/zitadel/feature/v2beta/instance.proto +++ b/proto/zitadel/feature/v2beta/instance.proto @@ -11,6 +11,8 @@ import "zitadel/feature/v2beta/feature.proto"; option go_package = "github.com/zitadel/zitadel/pkg/grpc/feature/v2beta;feature"; message SetInstanceFeaturesRequest{ + reserved 6; + reserved "actions"; optional bool login_default_org = 1 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "true"; @@ -43,12 +45,6 @@ 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."; - } - ]; repeated ImprovedPerformance improved_performance = 7 [ (validate.rules).repeated.unique = true, @@ -101,6 +97,8 @@ message GetInstanceFeaturesRequest { } message GetInstanceFeaturesResponse { + reserved 7; + reserved "actions"; zitadel.object.v2beta.Details details = 1; FeatureFlag login_default_org = 2 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { @@ -137,13 +135,6 @@ message GetInstanceFeaturesResponse { } ]; - 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."; - } - ]; - ImprovedPerformanceFeatureFlag improved_performance = 8 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "[1]"; diff --git a/proto/zitadel/feature/v2beta/system.proto b/proto/zitadel/feature/v2beta/system.proto index 98b37ad893..624e68ec79 100644 --- a/proto/zitadel/feature/v2beta/system.proto +++ b/proto/zitadel/feature/v2beta/system.proto @@ -11,6 +11,8 @@ import "zitadel/feature/v2beta/feature.proto"; option go_package = "github.com/zitadel/zitadel/pkg/grpc/feature/v2beta;feature"; message SetSystemFeaturesRequest{ + reserved 6; + reserved "actions"; optional bool login_default_org = 1 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "true"; @@ -46,13 +48,6 @@ message SetSystemFeaturesRequest{ } ]; - 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."; - } - ]; - repeated ImprovedPerformance improved_performance = 7 [ (validate.rules).repeated.unique = true, (validate.rules).repeated.items.enum = {defined_only: true, not_in: [0]}, @@ -83,6 +78,8 @@ message ResetSystemFeaturesResponse { message GetSystemFeaturesRequest {} message GetSystemFeaturesResponse { + reserved 7; + reserved "actions"; zitadel.object.v2beta.Details details = 1; FeatureFlag login_default_org = 2 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { @@ -119,13 +116,6 @@ message GetSystemFeaturesResponse { } ]; - 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."; - } - ]; - ImprovedPerformanceFeatureFlag improved_performance = 8 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "[1]";