feat: actions (#2377)

* feat(actions): begin api

* feat(actions): begin api

* api and projections

* fix: handle multiple statements for a single event in projections

* export func type

* fix test

* update to new reduce interface

* flows in login

* feat: jwt idp

* feat: command side

* feat: add tests

* actions and flows

* fill idp views with jwt idps and return apis

* add jwtEndpoint to jwt idp

* begin jwt request handling

* add feature

* merge

* merge

* handle jwt idp

* cleanup

* bug fixes

* autoregister

* get token from specific header name

* fix: proto

* fixes

* i18n

* begin tests

* fix and log http proxy

* remove docker cache

* fixes

* usergrants in actions api

* tests adn cleanup

* cleanup

* fix add user grant

* set login context

* i18n

Co-authored-by: fabi <fabienne.gerschwiler@gmail.com>
This commit is contained in:
Livio Amstutz
2021-09-27 13:43:49 +02:00
committed by GitHub
parent 5c32fc9c12
commit ed80a8bb1e
73 changed files with 5197 additions and 64 deletions

155
proto/zitadel/action.proto Normal file
View File

@@ -0,0 +1,155 @@
syntax = "proto3";
import "zitadel/object.proto";
import "validate/validate.proto";
import "google/protobuf/duration.proto";
import "protoc-gen-openapiv2/options/annotations.proto";
package zitadel.action.v1;
option go_package ="github.com/caos/zitadel/pkg/grpc/action";
message Action {
string id = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"69629023906488334\"";
}
];
zitadel.v1.ObjectDetails details = 2;
ActionState state = 3 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
description: "the state of the action";
}
];
string name = 4 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"log context\"";
}
];
string script = 5 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"function log(context, calls){console.log(context)}\"";
}
];
google.protobuf.Duration timeout = 6 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
description: "after which time the action will be terminated if not finished";
}
];
bool allowed_to_fail = 7 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
description: "when true, the next action will be called even if this action fails";
}
];
}
enum ActionState {
ACTION_STATE_UNSPECIFIED = 0;
ACTION_STATE_INACTIVE = 1;
ACTION_STATE_ACTIVE = 2;
}
message ActionIDQuery {
string id = 1 [
(validate.rules).string = {max_len: 200},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"69629023906488334\"";
}
];
}
message ActionNameQuery {
string name = 1 [
(validate.rules).string = {max_len: 200},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"log\"";
}
];
zitadel.v1.TextQueryMethod method = 2 [
(validate.rules).enum.defined_only = true,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
description: "defines which text equality method is used";
}
];
}
//ActionStateQuery is always equals
message ActionStateQuery {
ActionState state = 1 [
(validate.rules).enum.defined_only = true,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
description: "current state of the action";
}
];
}
enum ActionFieldName {
ACTION_FIELD_NAME_UNSPECIFIED = 0;
ACTION_FIELD_NAME_NAME = 1;
ACTION_FIELD_NAME_ID = 2;
ACTION_FIELD_NAME_STATE = 3;
}
message Flow {
FlowType type = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
description: "\"the type of the flow\"";
}
];
zitadel.v1.ObjectDetails details = 2;
FlowState state = 3 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
description: "the state of the flow";
}
];
repeated TriggerAction trigger_actions = 4;
}
enum FlowType {
FLOW_TYPE_UNSPECIFIED = 0;
FLOW_TYPE_EXTERNAL_AUTHENTICATION = 1;
}
enum FlowState {
FLOW_STATE_UNSPECIFIED = 0;
FLOW_STATE_INACTIVE = 1;
FLOW_STATE_ACTIVE = 2;
}
enum TriggerType {
TRIGGER_TYPE_UNSPECIFIED = 0;
TRIGGER_TYPE_POST_AUTHENTICATION = 1;
TRIGGER_TYPE_PRE_CREATION = 2;
TRIGGER_TYPE_POST_CREATION = 3;
}
message TriggerAction {
TriggerType trigger_type = 1;
repeated Action actions = 2;
}
enum FlowFieldName {
FLOW_FIELD_NAME_UNSPECIFIED = 0;
FLOW_FIELD_NAME_TYPE = 1;
FLOW_FIELD_NAME_STATE = 2;
}
//FlowTypeQuery is always equals
message FlowTypeQuery {
FlowType state = 1 [
(validate.rules).enum.defined_only = true,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
description: "type of the flow";
}
];
}
//FlowStateQuery is always equals
message FlowStateQuery {
FlowState state = 1 [
(validate.rules).enum.defined_only = true,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
description: "current state of the flow";
}
];
}

View File

@@ -2813,6 +2813,7 @@ message SetDefaultFeaturesRequest {
bool custom_text_message = 20;
bool custom_text_login = 21;
bool lockout_policy = 22;
bool actions = 23;
}
message SetDefaultFeaturesResponse {
@@ -2852,6 +2853,7 @@ message SetOrgFeaturesRequest {
bool custom_text_message = 21;
bool custom_text_login = 22;
bool lockout_policy = 23;
bool actions = 24;
}
message SetOrgFeaturesResponse {

View File

@@ -30,6 +30,7 @@ message Features {
bool custom_text_message = 19;
bool custom_text_login = 20;
bool lockout_policy = 21;
bool actions = 22;
}
message FeatureTier {
@@ -45,4 +46,4 @@ enum FeaturesState {
FEATURES_STATE_ACTION_REQUIRED = 1;
FEATURES_STATE_CANCELED = 2;
FEATURES_STATE_GRANDFATHERED = 3;
}
}

View File

@@ -15,6 +15,7 @@ import "zitadel/change.proto";
import "zitadel/auth_n_key.proto";
import "zitadel/features.proto";
import "zitadel/metadata.proto";
import "zitadel/action.proto";
import "google/api/annotations.proto";
import "google/protobuf/timestamp.proto";
@@ -2710,6 +2711,124 @@ service ManagementService {
feature: "login_policy.idp"
};
}
rpc ListActions(ListActionsRequest) returns (ListActionsResponse) {
option (google.api.http) = {
post: "/actions/_search"
body: "*"
};
option (zitadel.v1.auth_option) = {
permission: "org.action.read"
feature: "actions"
};
}
rpc GetAction(GetActionRequest) returns (GetActionResponse) {
option (google.api.http) = {
get: "/actions/{id}"
};
option (zitadel.v1.auth_option) = {
permission: "org.action.read"
feature: "actions"
};
}
rpc CreateAction(CreateActionRequest) returns (CreateActionResponse) {
option (google.api.http) = {
post: "/actions"
body: "*"
};
option (zitadel.v1.auth_option) = {
permission: "org.action.write"
feature: "actions"
};
}
rpc UpdateAction(UpdateActionRequest) returns (UpdateActionResponse) {
option (google.api.http) = {
put: "/actions/{id}"
body: "*"
};
option (zitadel.v1.auth_option) = {
permission: "org.action.write"
feature: "actions"
};
}
//TODO: enable in next release
// rpc DeactivateAction(DeactivateActionRequest) returns (DeactivateActionResponse) {
// option (google.api.http) = {
// post: "/actions/{id}/_deactivate"
// body: "*"
// };
//
// option (zitadel.v1.auth_option) = {
// permission: "org.action.write"
// feature: "actions"
// };
// }
//
// rpc ReactivateAction(ReactivateActionRequest) returns (ReactivateActionResponse) {
// option (google.api.http) = {
// post: "/actions/{id}/_reactivate"
// body: "*"
// };
//
// option (zitadel.v1.auth_option) = {
// permission: "org.action.write"
// feature: "actions"
// };
// }
rpc DeleteAction(DeleteActionRequest) returns (DeleteActionResponse) {
option (google.api.http) = {
delete: "/actions/{id}"
body: "*"
};
option (zitadel.v1.auth_option) = {
permission: "org.action.delete"
feature: "actions"
};
}
rpc GetFlow(GetFlowRequest) returns (GetFlowResponse) {
option (google.api.http) = {
get: "/flows/{type}"
};
option (zitadel.v1.auth_option) = {
permission: "org.flow.read"
feature: "actions"
};
}
rpc ClearFlow(ClearFlowRequest) returns (ClearFlowResponse) {
option (google.api.http) = {
post: "/flows/{type}/_clear"
};
option (zitadel.v1.auth_option) = {
permission: "org.flow.delete"
feature: "actions"
};
}
rpc SetTriggerActions(SetTriggerActionsRequest) returns (SetTriggerActionsResponse) {
option (google.api.http) = {
post: "/flows/{flow_type}/trigger/{trigger_type}"
body: "*"
};
option (zitadel.v1.auth_option) = {
permission: "org.flow.write"
feature: "actions"
};
}
}
//This is an empty request
@@ -5117,3 +5236,151 @@ message UpdateOrgIDPJWTConfigRequest {
message UpdateOrgIDPJWTConfigResponse {
zitadel.v1.ObjectDetails details = 1;
}
message ListActionsRequest {
//list limitations and ordering
zitadel.v1.ListQuery query = 1;
//the field the result is sorted
zitadel.action.v1.ActionFieldName sorting_column = 2;
//criteria the client is looking for
repeated ActionQuery queries = 3;
}
message ActionQuery {
oneof query {
option (validate.required) = true;
zitadel.action.v1.ActionIDQuery action_id_query = 1;
zitadel.action.v1.ActionNameQuery action_name_query = 2;
zitadel.action.v1.ActionStateQuery action_state_query = 3;
}
}
message ListActionsResponse {
zitadel.v1.ListDetails details = 1;
zitadel.action.v1.ActionFieldName sorting_column = 2;
repeated zitadel.action.v1.Action result = 3;
}
message CreateActionRequest {
string name = 1 [
(validate.rules).string = {min_len: 1, max_len: 200},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"log context\"";
}
];
string script = 2 [
(validate.rules).string = {min_len: 1, max_len: 2000},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"function log(context, calls){console.log(context)}\"";
}
];
google.protobuf.Duration timeout = 3 [
(validate.rules).duration = {gte: {}, lte: {seconds: 20}},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
description: "after which time the action will be terminated if not finished";
}
];
bool allowed_to_fail = 4 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
description: "when true, the next action will be called even if this action fails";
}
];
}
message CreateActionResponse {
zitadel.v1.ObjectDetails details = 1;
string id = 2;
}
message GetActionRequest {
string id = 1;
}
message GetActionResponse {
zitadel.action.v1.Action action = 1;
}
message UpdateActionRequest {
string id = 1 [
(validate.rules).string = {min_len: 1, max_len: 200},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"69629023906488334\"";
}
];
string name = 2 [
(validate.rules).string = {min_len: 1, max_len: 200},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"log context\"";
}
];
string script = 3 [
(validate.rules).string = {min_len: 1, max_len: 2000},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"function log(context, calls){console.log(context)}\"";
}
];
google.protobuf.Duration timeout = 4 [
(validate.rules).duration = {gte: {}, lte: {seconds: 20}},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
description: "after which time the action will be terminated if not finished";
}
];
bool allowed_to_fail = 5 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
description: "when true, the next action will be called even if this action fails";
}
];
}
message UpdateActionResponse {
zitadel.v1.ObjectDetails details = 1;
}
message DeleteActionRequest {
string id = 1;
}
message DeleteActionResponse {}
message DeactivateActionRequest {
string id = 1;
}
message DeactivateActionResponse {
zitadel.v1.ObjectDetails details = 1;
}
message ReactivateActionRequest {
string id = 1;
}
message ReactivateActionResponse {
zitadel.v1.ObjectDetails details = 1;
}
message GetFlowRequest {
zitadel.action.v1.FlowType type = 1;
}
message GetFlowResponse {
zitadel.action.v1.Flow flow = 1;
}
message ClearFlowRequest {
zitadel.action.v1.FlowType type = 1;
}
message ClearFlowResponse {
zitadel.v1.ObjectDetails details = 1;
}
message SetTriggerActionsRequest {
zitadel.action.v1.FlowType flow_type = 1;
zitadel.action.v1.TriggerType trigger_type = 2;
repeated string action_ids = 3;
}
message SetTriggerActionsResponse {
zitadel.v1.ObjectDetails details = 1;
}