mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 07:57:32 +00:00
feat(actions): add token customization flow and extend functionally with modules (#4337)
* fix: potential memory leak * feat(actions): possibility to parse json feat(actions): possibility to perform http calls * add query call * feat(api): list flow and trigger types fix(api): switch flow and trigger types to dynamic objects * fix(translations): add action translations * use `domain.FlowType` * localizers * localization * trigger types * options on `query.Action` * add functions for actions * feat: management api: add list flow and trigger (#4352) * console changes * cleanup * fix: wrong localization Co-authored-by: Max Peintner <max@caos.ch> * id token works * check if claims not nil * feat(actions): metadata api * refactor(actions): modules * fix: allow prerelease * fix: test * feat(actions): deny list for http hosts * feat(actions): deny list for http hosts * refactor: actions * fix: different error ids * fix: rename statusCode to status * Actions objects as options (#4418) * fix: rename statusCode to status * fix(actions): objects as options * fix(actions): objects as options * fix(actions): set fields * add http client to old actions * fix(actions): add log module * fix(actions): add user to context where possible * fix(actions): add user to ctx in external authorization/pre creation * fix(actions): query correct flow in claims * test: actions * fix(id-generator): panic if no machine id * tests * maybe this? * fix linting * refactor: improve code * fix: metadata and usergrant usage in actions * fix: appendUserGrant * fix: allowedToFail and timeout in action execution * fix: allowed to fail in token complement flow * docs: add action log claim * Update defaults.yaml * fix log claim * remove prerelease build Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Livio Spring <livio.a@gmail.com>
This commit is contained in:
@@ -9,12 +9,15 @@ import (
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/errors"
|
||||
"github.com/zitadel/zitadel/internal/query/projection"
|
||||
)
|
||||
|
||||
const (
|
||||
maxTimeout = 20 * time.Second
|
||||
)
|
||||
|
||||
var (
|
||||
actionTable = table{
|
||||
name: projection.ActionTable,
|
||||
@@ -80,10 +83,17 @@ type Action struct {
|
||||
|
||||
Name string
|
||||
Script string
|
||||
Timeout time.Duration
|
||||
timeout time.Duration
|
||||
AllowedToFail bool
|
||||
}
|
||||
|
||||
func (a *Action) Timeout() time.Duration {
|
||||
if a.timeout > 0 && a.timeout < maxTimeout {
|
||||
return a.timeout
|
||||
}
|
||||
return maxTimeout
|
||||
}
|
||||
|
||||
type ActionSearchQueries struct {
|
||||
SearchRequest
|
||||
Queries []SearchQuery
|
||||
@@ -180,7 +190,7 @@ func prepareActionsQuery() (sq.SelectBuilder, func(rows *sql.Rows) (*Actions, er
|
||||
&action.State,
|
||||
&action.Name,
|
||||
&action.Script,
|
||||
&action.Timeout,
|
||||
&action.timeout,
|
||||
&action.AllowedToFail,
|
||||
&count,
|
||||
)
|
||||
@@ -227,7 +237,7 @@ func prepareActionQuery() (sq.SelectBuilder, func(row *sql.Row) (*Action, error)
|
||||
&action.State,
|
||||
&action.Name,
|
||||
&action.Script,
|
||||
&action.Timeout,
|
||||
&action.timeout,
|
||||
&action.AllowedToFail,
|
||||
)
|
||||
if err != nil {
|
||||
|
@@ -8,7 +8,6 @@ import (
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/errors"
|
||||
"github.com/zitadel/zitadel/internal/query/projection"
|
||||
@@ -155,6 +154,8 @@ func prepareTriggerActionsQuery() (sq.SelectBuilder, func(*sql.Rows) ([]*Action,
|
||||
ActionColumnSequence.identifier(),
|
||||
ActionColumnName.identifier(),
|
||||
ActionColumnScript.identifier(),
|
||||
ActionColumnAllowedToFail.identifier(),
|
||||
ActionColumnTimeout.identifier(),
|
||||
).
|
||||
From(flowsTriggersTable.name).
|
||||
LeftJoin(join(ActionColumnID, FlowsTriggersColumnActionID)).
|
||||
@@ -172,6 +173,8 @@ func prepareTriggerActionsQuery() (sq.SelectBuilder, func(*sql.Rows) ([]*Action,
|
||||
&action.Sequence,
|
||||
&action.Name,
|
||||
&action.Script,
|
||||
&action.AllowedToFail,
|
||||
&action.timeout,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -197,6 +200,8 @@ func prepareFlowQuery(flowType domain.FlowType) (sq.SelectBuilder, func(*sql.Row
|
||||
ActionColumnSequence.identifier(),
|
||||
ActionColumnName.identifier(),
|
||||
ActionColumnScript.identifier(),
|
||||
ActionColumnAllowedToFail.identifier(),
|
||||
ActionColumnTimeout.identifier(),
|
||||
FlowsTriggersColumnTriggerType.identifier(),
|
||||
FlowsTriggersColumnTriggerSequence.identifier(),
|
||||
FlowsTriggersColumnFlowType.identifier(),
|
||||
@@ -222,6 +227,8 @@ func prepareFlowQuery(flowType domain.FlowType) (sq.SelectBuilder, func(*sql.Row
|
||||
actionSequence sql.NullInt64
|
||||
actionName sql.NullString
|
||||
actionScript sql.NullString
|
||||
actionAllowedToFail sql.NullBool
|
||||
actionTimeout sql.NullInt64
|
||||
|
||||
triggerType domain.TriggerType
|
||||
triggerSequence int
|
||||
@@ -235,6 +242,8 @@ func prepareFlowQuery(flowType domain.FlowType) (sq.SelectBuilder, func(*sql.Row
|
||||
&actionSequence,
|
||||
&actionName,
|
||||
&actionScript,
|
||||
&actionAllowedToFail,
|
||||
&actionTimeout,
|
||||
&triggerType,
|
||||
&triggerSequence,
|
||||
&flow.Type,
|
||||
@@ -257,6 +266,8 @@ func prepareFlowQuery(flowType domain.FlowType) (sq.SelectBuilder, func(*sql.Row
|
||||
Sequence: uint64(actionSequence.Int64),
|
||||
Name: actionName.String,
|
||||
Script: actionScript.String,
|
||||
AllowedToFail: actionAllowedToFail.Bool,
|
||||
timeout: time.Duration(actionTimeout.Int64),
|
||||
})
|
||||
}
|
||||
|
||||
|
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
|
||||
@@ -39,6 +40,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
` projections.actions2.sequence,`+
|
||||
` projections.actions2.name,`+
|
||||
` projections.actions2.script,`+
|
||||
` projections.actions2.allowed_to_fail,`+
|
||||
` projections.actions2.timeout,`+
|
||||
` projections.flows_triggers.trigger_type,`+
|
||||
` projections.flows_triggers.trigger_sequence,`+
|
||||
` projections.flows_triggers.flow_type,`+
|
||||
@@ -71,6 +74,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
` projections.actions2.sequence,`+
|
||||
` projections.actions2.name,`+
|
||||
` projections.actions2.script,`+
|
||||
` projections.actions2.allowed_to_fail,`+
|
||||
` projections.actions2.timeout,`+
|
||||
` projections.flows_triggers.trigger_type,`+
|
||||
` projections.flows_triggers.trigger_sequence,`+
|
||||
` projections.flows_triggers.flow_type,`+
|
||||
@@ -88,6 +93,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
"sequence",
|
||||
"name",
|
||||
"script",
|
||||
"allowed_to_fail",
|
||||
"timeout",
|
||||
//flow
|
||||
"trigger_type",
|
||||
"trigger_sequence",
|
||||
@@ -106,6 +113,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
uint64(20211115),
|
||||
"action-name",
|
||||
"script",
|
||||
true,
|
||||
10000000000,
|
||||
domain.TriggerTypePreCreation,
|
||||
uint64(20211109),
|
||||
domain.FlowTypeExternalAuthentication,
|
||||
@@ -132,6 +141,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
Sequence: 20211115,
|
||||
Name: "action-name",
|
||||
Script: "script",
|
||||
AllowedToFail: true,
|
||||
timeout: 10 * time.Second,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -152,6 +163,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
` projections.actions2.sequence,`+
|
||||
` projections.actions2.name,`+
|
||||
` projections.actions2.script,`+
|
||||
` projections.actions2.allowed_to_fail,`+
|
||||
` projections.actions2.timeout,`+
|
||||
` projections.flows_triggers.trigger_type,`+
|
||||
` projections.flows_triggers.trigger_sequence,`+
|
||||
` projections.flows_triggers.flow_type,`+
|
||||
@@ -169,6 +182,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
"sequence",
|
||||
"name",
|
||||
"script",
|
||||
"allowed_to_fail",
|
||||
"timeout",
|
||||
//flow
|
||||
"trigger_type",
|
||||
"trigger_sequence",
|
||||
@@ -187,6 +202,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
uint64(20211115),
|
||||
"action-name-pre",
|
||||
"script",
|
||||
true,
|
||||
10000000000,
|
||||
domain.TriggerTypePreCreation,
|
||||
uint64(20211109),
|
||||
domain.FlowTypeExternalAuthentication,
|
||||
@@ -203,6 +220,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
uint64(20211115),
|
||||
"action-name-post",
|
||||
"script",
|
||||
false,
|
||||
5000000000,
|
||||
domain.TriggerTypePostCreation,
|
||||
uint64(20211109),
|
||||
domain.FlowTypeExternalAuthentication,
|
||||
@@ -229,6 +248,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
Sequence: 20211115,
|
||||
Name: "action-name-pre",
|
||||
Script: "script",
|
||||
AllowedToFail: true,
|
||||
timeout: 10 * time.Second,
|
||||
},
|
||||
},
|
||||
domain.TriggerTypePostCreation: {
|
||||
@@ -241,6 +262,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
Sequence: 20211115,
|
||||
Name: "action-name-post",
|
||||
Script: "script",
|
||||
AllowedToFail: false,
|
||||
timeout: 5 * time.Second,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -261,6 +284,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
` projections.actions2.sequence,`+
|
||||
` projections.actions2.name,`+
|
||||
` projections.actions2.script,`+
|
||||
` projections.actions2.allowed_to_fail,`+
|
||||
` projections.actions2.timeout,`+
|
||||
` projections.flows_triggers.trigger_type,`+
|
||||
` projections.flows_triggers.trigger_sequence,`+
|
||||
` projections.flows_triggers.flow_type,`+
|
||||
@@ -278,6 +303,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
"sequence",
|
||||
"name",
|
||||
"script",
|
||||
"allowed_to_fail",
|
||||
"timeout",
|
||||
//flow
|
||||
"trigger_type",
|
||||
"trigger_sequence",
|
||||
@@ -296,6 +323,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
domain.TriggerTypePostCreation,
|
||||
uint64(20211109),
|
||||
domain.FlowTypeExternalAuthentication,
|
||||
@@ -329,6 +358,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
` projections.actions2.sequence,`+
|
||||
` projections.actions2.name,`+
|
||||
` projections.actions2.script,`+
|
||||
` projections.actions2.allowed_to_fail,`+
|
||||
` projections.actions2.timeout,`+
|
||||
` projections.flows_triggers.trigger_type,`+
|
||||
` projections.flows_triggers.trigger_sequence,`+
|
||||
` projections.flows_triggers.flow_type,`+
|
||||
@@ -360,7 +391,9 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
` projections.actions2.action_state,`+
|
||||
` projections.actions2.sequence,`+
|
||||
` projections.actions2.name,`+
|
||||
` projections.actions2.script`+
|
||||
` projections.actions2.script,`+
|
||||
` projections.actions2.allowed_to_fail,`+
|
||||
` projections.actions2.timeout`+
|
||||
` FROM projections.flows_triggers`+
|
||||
` LEFT JOIN projections.actions2 ON projections.flows_triggers.action_id = projections.actions2.id`),
|
||||
nil,
|
||||
@@ -381,7 +414,9 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
` projections.actions2.action_state,`+
|
||||
` projections.actions2.sequence,`+
|
||||
` projections.actions2.name,`+
|
||||
` projections.actions2.script`+
|
||||
` projections.actions2.script,`+
|
||||
` projections.actions2.allowed_to_fail,`+
|
||||
` projections.actions2.timeout`+
|
||||
` FROM projections.flows_triggers`+
|
||||
` LEFT JOIN projections.actions2 ON projections.flows_triggers.action_id = projections.actions2.id`),
|
||||
[]string{
|
||||
@@ -393,6 +428,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
"sequence",
|
||||
"name",
|
||||
"script",
|
||||
"allowed_to_fail",
|
||||
"timeout",
|
||||
},
|
||||
[][]driver.Value{
|
||||
{
|
||||
@@ -404,6 +441,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
uint64(20211115),
|
||||
"action-name",
|
||||
"script",
|
||||
true,
|
||||
10000000000,
|
||||
},
|
||||
},
|
||||
),
|
||||
@@ -418,6 +457,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
Sequence: 20211115,
|
||||
Name: "action-name",
|
||||
Script: "script",
|
||||
AllowedToFail: true,
|
||||
timeout: 10 * time.Second,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -433,7 +474,9 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
` projections.actions2.action_state,`+
|
||||
` projections.actions2.sequence,`+
|
||||
` projections.actions2.name,`+
|
||||
` projections.actions2.script`+
|
||||
` projections.actions2.script,`+
|
||||
` projections.actions2.allowed_to_fail,`+
|
||||
` projections.actions2.timeout`+
|
||||
` FROM projections.flows_triggers`+
|
||||
` LEFT JOIN projections.actions2 ON projections.flows_triggers.action_id = projections.actions2.id`),
|
||||
[]string{
|
||||
@@ -445,6 +488,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
"sequence",
|
||||
"name",
|
||||
"script",
|
||||
"allowed_to_fail",
|
||||
"timeout",
|
||||
},
|
||||
[][]driver.Value{
|
||||
{
|
||||
@@ -456,6 +501,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
uint64(20211115),
|
||||
"action-name-1",
|
||||
"script",
|
||||
true,
|
||||
10000000000,
|
||||
},
|
||||
{
|
||||
"action-id-2",
|
||||
@@ -466,6 +513,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
uint64(20211115),
|
||||
"action-name-2",
|
||||
"script",
|
||||
false,
|
||||
5000000000,
|
||||
},
|
||||
},
|
||||
),
|
||||
@@ -480,6 +529,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
Sequence: 20211115,
|
||||
Name: "action-name-1",
|
||||
Script: "script",
|
||||
AllowedToFail: true,
|
||||
timeout: 10 * time.Second,
|
||||
},
|
||||
{
|
||||
ID: "action-id-2",
|
||||
@@ -490,6 +541,8 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
Sequence: 20211115,
|
||||
Name: "action-name-2",
|
||||
Script: "script",
|
||||
AllowedToFail: false,
|
||||
timeout: 5 * time.Second,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -505,7 +558,9 @@ func Test_FlowPrepares(t *testing.T) {
|
||||
` projections.actions2.action_state,`+
|
||||
` projections.actions2.sequence,`+
|
||||
` projections.actions2.name,`+
|
||||
` projections.actions2.script`+
|
||||
` projections.actions2.script,`+
|
||||
` projections.actions2.allowed_to_fail,`+
|
||||
` projections.actions2.timeout`+
|
||||
` FROM projections.flows_triggers`+
|
||||
` LEFT JOIN projections.actions2 ON projections.flows_triggers.action_id = projections.actions2.id`),
|
||||
sql.ErrConnDone,
|
||||
|
@@ -107,7 +107,7 @@ func Test_ActionPrepares(t *testing.T) {
|
||||
Sequence: 20211109,
|
||||
Name: "action-name",
|
||||
Script: "script",
|
||||
Timeout: 1 * time.Second,
|
||||
timeout: 1 * time.Second,
|
||||
AllowedToFail: true,
|
||||
},
|
||||
},
|
||||
@@ -185,7 +185,7 @@ func Test_ActionPrepares(t *testing.T) {
|
||||
Sequence: 20211109,
|
||||
Name: "action-name-1",
|
||||
Script: "script",
|
||||
Timeout: 1 * time.Second,
|
||||
timeout: 1 * time.Second,
|
||||
AllowedToFail: true,
|
||||
},
|
||||
{
|
||||
@@ -197,7 +197,7 @@ func Test_ActionPrepares(t *testing.T) {
|
||||
Sequence: 20211109,
|
||||
Name: "action-name-2",
|
||||
Script: "script",
|
||||
Timeout: 1 * time.Second,
|
||||
timeout: 1 * time.Second,
|
||||
AllowedToFail: true,
|
||||
},
|
||||
},
|
||||
@@ -310,7 +310,7 @@ func Test_ActionPrepares(t *testing.T) {
|
||||
Sequence: 20211109,
|
||||
Name: "action-name",
|
||||
Script: "script",
|
||||
Timeout: 1 * time.Second,
|
||||
timeout: 1 * time.Second,
|
||||
AllowedToFail: true,
|
||||
},
|
||||
},
|
||||
|
@@ -10,11 +10,10 @@ import (
|
||||
"github.com/rakyll/statik/fs"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
sd "github.com/zitadel/zitadel/internal/config/systemdefaults"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
sd "github.com/zitadel/zitadel/internal/config/systemdefaults"
|
||||
"github.com/zitadel/zitadel/internal/crypto"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/query/projection"
|
||||
"github.com/zitadel/zitadel/internal/repository/action"
|
||||
|
@@ -160,7 +160,7 @@ const (
|
||||
textCompareMax
|
||||
)
|
||||
|
||||
//Deprecated: Use TextComparison, will be removed as soon as all calls are changed to query
|
||||
// Deprecated: Use TextComparison, will be removed as soon as all calls are changed to query
|
||||
func TextComparisonFromMethod(m domain.SearchMethod) TextComparison {
|
||||
switch m {
|
||||
case domain.SearchMethodEquals:
|
||||
@@ -244,7 +244,7 @@ const (
|
||||
numberCompareMax
|
||||
)
|
||||
|
||||
//Deprecated: Use NumberComparison, will be removed as soon as all calls are changed to query
|
||||
// Deprecated: Use NumberComparison, will be removed as soon as all calls are changed to query
|
||||
func NumberComparisonFromMethod(m domain.SearchMethod) NumberComparison {
|
||||
switch m {
|
||||
case domain.SearchMethodEquals:
|
||||
|
Reference in New Issue
Block a user