package execution import ( "context" "google.golang.org/protobuf/types/known/durationpb" "github.com/zitadel/zitadel/internal/api/grpc/object/v2" "github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/query" "github.com/zitadel/zitadel/internal/zerrors" execution "github.com/zitadel/zitadel/pkg/grpc/execution/v3alpha" ) func (s *Server) ListTargets(ctx context.Context, req *execution.ListTargetsRequest) (*execution.ListTargetsResponse, error) { queries, err := listTargetsRequestToModel(req) if err != nil { return nil, err } resp, err := s.query.SearchTargets(ctx, queries) if err != nil { return nil, err } return &execution.ListTargetsResponse{ Result: targetsToPb(resp.Targets), Details: object.ToListDetails(resp.SearchResponse), }, nil } func listTargetsRequestToModel(req *execution.ListTargetsRequest) (*query.TargetSearchQueries, error) { offset, limit, asc := object.ListQueryToQuery(req.Query) queries, err := targetQueriesToQuery(req.Queries) if err != nil { return nil, err } return &query.TargetSearchQueries{ SearchRequest: query.SearchRequest{ Offset: offset, Limit: limit, Asc: asc, SortingColumn: targetFieldNameToSortingColumn(req.SortingColumn), }, Queries: queries, }, nil } func targetFieldNameToSortingColumn(field execution.TargetFieldName) query.Column { switch field { case execution.TargetFieldName_FIELD_NAME_UNSPECIFIED: return query.TargetColumnID case execution.TargetFieldName_FIELD_NAME_ID: return query.TargetColumnID case execution.TargetFieldName_FIELD_NAME_CREATION_DATE: return query.TargetColumnCreationDate case execution.TargetFieldName_FIELD_NAME_CHANGE_DATE: return query.TargetColumnChangeDate case execution.TargetFieldName_FIELD_NAME_NAME: return query.TargetColumnName case execution.TargetFieldName_FIELD_NAME_TARGET_TYPE: return query.TargetColumnTargetType case execution.TargetFieldName_FIELD_NAME_URL: return query.TargetColumnURL case execution.TargetFieldName_FIELD_NAME_TIMEOUT: return query.TargetColumnTimeout case execution.TargetFieldName_FIELD_NAME_ASYNC: return query.TargetColumnAsync case execution.TargetFieldName_FIELD_NAME_INTERRUPT_ON_ERROR: return query.TargetColumnInterruptOnError default: return query.TargetColumnID } } func targetQueriesToQuery(queries []*execution.TargetSearchQuery) (_ []query.SearchQuery, err error) { q := make([]query.SearchQuery, len(queries)) for i, query := range queries { q[i], err = targetQueryToQuery(query) if err != nil { return nil, err } } return q, nil } func targetQueryToQuery(query *execution.TargetSearchQuery) (query.SearchQuery, error) { switch q := query.Query.(type) { case *execution.TargetSearchQuery_TargetNameQuery: return targetNameQueryToQuery(q.TargetNameQuery) case *execution.TargetSearchQuery_InTargetIdsQuery: return targetInTargetIdsQueryToQuery(q.InTargetIdsQuery) default: return nil, zerrors.ThrowInvalidArgument(nil, "GRPC-vR9nC", "List.Query.Invalid") } } func targetNameQueryToQuery(q *execution.TargetNameQuery) (query.SearchQuery, error) { return query.NewTargetNameSearchQuery(object.TextMethodToQuery(q.Method), q.GetTargetName()) } func targetInTargetIdsQueryToQuery(q *execution.InTargetIDsQuery) (query.SearchQuery, error) { return query.NewTargetInIDsSearchQuery(q.GetTargetIds()) } func (s *Server) GetTargetByID(ctx context.Context, req *execution.GetTargetByIDRequest) (_ *execution.GetTargetByIDResponse, err error) { resp, err := s.query.GetTargetByID(ctx, req.GetTargetId()) if err != nil { return nil, err } return &execution.GetTargetByIDResponse{ Target: targetToPb(resp), }, nil } func targetsToPb(targets []*query.Target) []*execution.Target { t := make([]*execution.Target, len(targets)) for i, target := range targets { t[i] = targetToPb(target) } return t } func targetToPb(t *query.Target) *execution.Target { target := &execution.Target{ Details: object.DomainToDetailsPb(&t.ObjectDetails), TargetId: t.ID, Name: t.Name, Timeout: durationpb.New(t.Timeout), } if t.Async { target.ExecutionType = &execution.Target_IsAsync{IsAsync: t.Async} } if t.InterruptOnError { target.ExecutionType = &execution.Target_InterruptOnError{InterruptOnError: t.InterruptOnError} } switch t.TargetType { case domain.TargetTypeWebhook: target.TargetType = &execution.Target_RestWebhook{RestWebhook: &execution.SetRESTWebhook{Url: t.URL}} case domain.TargetTypeRequestResponse: target.TargetType = &execution.Target_RestRequestResponse{RestRequestResponse: &execution.SetRESTRequestResponse{Url: t.URL}} default: target.TargetType = nil } return target } func (s *Server) ListExecutions(ctx context.Context, req *execution.ListExecutionsRequest) (*execution.ListExecutionsResponse, error) { queries, err := listExecutionsRequestToModel(req) if err != nil { return nil, err } resp, err := s.query.SearchExecutions(ctx, queries) if err != nil { return nil, err } return &execution.ListExecutionsResponse{ Result: executionsToPb(resp.Executions), Details: object.ToListDetails(resp.SearchResponse), }, nil } func listExecutionsRequestToModel(req *execution.ListExecutionsRequest) (*query.ExecutionSearchQueries, error) { offset, limit, asc := object.ListQueryToQuery(req.Query) queries, err := executionQueriesToQuery(req.Queries) if err != nil { return nil, err } return &query.ExecutionSearchQueries{ SearchRequest: query.SearchRequest{ Offset: offset, Limit: limit, Asc: asc, }, Queries: queries, }, nil } func executionQueriesToQuery(queries []*execution.SearchQuery) (_ []query.SearchQuery, err error) { q := make([]query.SearchQuery, len(queries)) for i, query := range queries { q[i], err = executionQueryToQuery(query) if err != nil { return nil, err } } return q, nil } func executionQueryToQuery(searchQuery *execution.SearchQuery) (query.SearchQuery, error) { switch q := searchQuery.Query.(type) { case *execution.SearchQuery_InConditionsQuery: return inConditionsQueryToQuery(q.InConditionsQuery) case *execution.SearchQuery_ExecutionTypeQuery: return executionTypeToQuery(q.ExecutionTypeQuery) case *execution.SearchQuery_TargetQuery: return query.NewExecutionTargetSearchQuery(q.TargetQuery.GetTargetId()) case *execution.SearchQuery_IncludeQuery: return query.NewExecutionIncludeSearchQuery(q.IncludeQuery.GetInclude()) default: return nil, zerrors.ThrowInvalidArgument(nil, "GRPC-vR9nC", "List.Query.Invalid") } } func executionTypeToQuery(q *execution.ExecutionTypeQuery) (query.SearchQuery, error) { switch q.ExecutionType { case execution.ExecutionType_EXECUTION_TYPE_UNSPECIFIED: return query.NewExecutionTypeSearchQuery(domain.ExecutionTypeUnspecified) case execution.ExecutionType_EXECUTION_TYPE_REQUEST: return query.NewExecutionTypeSearchQuery(domain.ExecutionTypeRequest) case execution.ExecutionType_EXECUTION_TYPE_RESPONSE: return query.NewExecutionTypeSearchQuery(domain.ExecutionTypeResponse) case execution.ExecutionType_EXECUTION_TYPE_EVENT: return query.NewExecutionTypeSearchQuery(domain.ExecutionTypeEvent) case execution.ExecutionType_EXECUTION_TYPE_FUNCTION: return query.NewExecutionTypeSearchQuery(domain.ExecutionTypeFunction) default: return query.NewExecutionTypeSearchQuery(domain.ExecutionTypeUnspecified) } } func inConditionsQueryToQuery(q *execution.InConditionsQuery) (query.SearchQuery, error) { values := make([]string, len(q.GetConditions())) for i, condition := range q.GetConditions() { id, err := conditionToID(condition) if err != nil { return nil, err } values[i] = id } return query.NewExecutionInIDsSearchQuery(values) } func conditionToID(q *execution.Condition) (string, error) { switch t := q.GetConditionType().(type) { case *execution.Condition_Request: cond := &command.ExecutionAPICondition{ Method: t.Request.GetMethod(), Service: t.Request.GetService(), All: t.Request.GetAll(), } return cond.ID(domain.ExecutionTypeRequest), nil case *execution.Condition_Response: cond := &command.ExecutionAPICondition{ Method: t.Response.GetMethod(), Service: t.Response.GetService(), All: t.Response.GetAll(), } return cond.ID(domain.ExecutionTypeResponse), nil case *execution.Condition_Event: cond := &command.ExecutionEventCondition{ Event: t.Event.GetEvent(), Group: t.Event.GetGroup(), All: t.Event.GetAll(), } return cond.ID(), nil case *execution.Condition_Function: return t.Function, nil default: return "", zerrors.ThrowInvalidArgument(nil, "GRPC-vR9nC", "List.Query.Invalid") } } func executionsToPb(executions []*query.Execution) []*execution.Execution { e := make([]*execution.Execution, len(executions)) for i, execution := range executions { e[i] = executionToPb(execution) } return e } func executionToPb(e *query.Execution) *execution.Execution { var targets, includes []string if len(e.Targets) > 0 { targets = e.Targets } if len(e.Includes) > 0 { includes = e.Includes } return &execution.Execution{ Details: object.DomainToDetailsPb(&e.ObjectDetails), ExecutionId: e.ID, Targets: targets, Includes: includes, } }