diff --git a/cmd/admin/setup/03.go b/cmd/admin/setup/03.go
index 5fb2d3f8d..0cef02597 100644
--- a/cmd/admin/setup/03.go
+++ b/cmd/admin/setup/03.go
@@ -50,7 +50,6 @@ func (mig *DefaultInstance) Execute(ctx context.Context) error {
mig.zitadelRoles,
nil,
nil,
- nil,
mig.externalDomain,
mig.externalSecure,
mig.externalPort,
diff --git a/cmd/admin/start/config.go b/cmd/admin/start/config.go
index fa45ec217..2550ae894 100644
--- a/cmd/admin/start/config.go
+++ b/cmd/admin/start/config.go
@@ -1,6 +1,8 @@
package start
import (
+ "time"
+
"github.com/mitchellh/mapstructure"
"github.com/spf13/viper"
"github.com/zitadel/logging"
@@ -25,30 +27,31 @@ import (
)
type Config struct {
- Log *logging.Config
- Port uint16
- ExternalPort uint16
- ExternalDomain string
- ExternalSecure bool
- HTTP2HostHeader string
- HTTP1HostHeader string
- WebAuthNName string
- Database database.Config
- Tracing tracing.Config
- Projections projection.Config
- AuthZ authz.Config
- Auth auth_es.Config
- Admin admin_es.Config
- UserAgentCookie *middleware.UserAgentCookieConfig
- OIDC oidc.Config
- Login login.Config
- Console console.Config
- Notification notification.Config
- AssetStorage static_config.AssetStorageConfig
- InternalAuthZ internal_authz.Config
- SystemDefaults systemdefaults.SystemDefaults
- EncryptionKeys *encryptionKeyConfig
- DefaultInstance command.InstanceSetup
+ Log *logging.Config
+ Port uint16
+ ExternalPort uint16
+ ExternalDomain string
+ ExternalSecure bool
+ HTTP2HostHeader string
+ HTTP1HostHeader string
+ WebAuthNName string
+ Database database.Config
+ Tracing tracing.Config
+ Projections projection.Config
+ AuthZ authz.Config
+ Auth auth_es.Config
+ Admin admin_es.Config
+ UserAgentCookie *middleware.UserAgentCookieConfig
+ OIDC oidc.Config
+ Login login.Config
+ Console console.Config
+ Notification notification.Config
+ AssetStorage static_config.AssetStorageConfig
+ InternalAuthZ internal_authz.Config
+ SystemDefaults systemdefaults.SystemDefaults
+ EncryptionKeys *encryptionKeyConfig
+ DefaultInstance command.InstanceSetup
+ AuditLogRetention time.Duration
}
func MustNewConfig(v *viper.Viper) *Config {
diff --git a/cmd/admin/start/start.go b/cmd/admin/start/start.go
index d1f49d68a..8ac50f7a2 100644
--- a/cmd/admin/start/start.go
+++ b/cmd/admin/start/start.go
@@ -116,7 +116,6 @@ func startZitadel(config *Config, masterKey string) error {
config.SystemDefaults,
config.InternalAuthZ.RolePermissionMappings,
storage,
- authZRepo,
webAuthNConfig,
config.ExternalDomain,
config.ExternalSecure,
@@ -168,10 +167,10 @@ func startAPIs(ctx context.Context, router *mux.Router, commands *command.Comman
if err := authenticatedAPIs.RegisterServer(ctx, admin.CreateServer(commands, queries, adminRepo, assets.HandlerPrefix, keys.User)); err != nil {
return err
}
- if err := authenticatedAPIs.RegisterServer(ctx, management.CreateServer(commands, queries, config.SystemDefaults, assets.HandlerPrefix, keys.User, config.ExternalSecure, oidc.HandlerPrefix)); err != nil {
+ if err := authenticatedAPIs.RegisterServer(ctx, management.CreateServer(commands, queries, config.SystemDefaults, assets.HandlerPrefix, keys.User, config.ExternalSecure, oidc.HandlerPrefix, config.AuditLogRetention)); err != nil {
return err
}
- if err := authenticatedAPIs.RegisterServer(ctx, auth.CreateServer(commands, queries, authRepo, config.SystemDefaults, assets.HandlerPrefix, keys.User, config.ExternalSecure)); err != nil {
+ if err := authenticatedAPIs.RegisterServer(ctx, auth.CreateServer(commands, queries, authRepo, config.SystemDefaults, assets.HandlerPrefix, keys.User, config.ExternalSecure, config.AuditLogRetention)); err != nil {
return err
}
diff --git a/cmd/defaults.yaml b/cmd/defaults.yaml
index 4e9e76dfc..c02e9d7b9 100644
--- a/cmd/defaults.yaml
+++ b/cmd/defaults.yaml
@@ -228,29 +228,6 @@ DefaultInstance:
IncludeUpperLetters: true
IncludeDigits: true
IncludeSymbols: false
- Features:
- TierName: Default Tier
- TierDescription: ""
- State: 1 #active
- StateDescription: ""
- Retention: 8760h #1year
- LoginPolicyFactors: true
- LoginPolicyIDP: true
- LoginPolicyPasswordless: true
- LoginPolicyRegistration: true
- LoginPolicyUsernameLogin: true
- LoginPolicyPasswordReset: true
- PasswordComplexityPolicy: true
- LabelPolicyPrivateLabel: true
- LabelPolicyWatermark: true
- CustomDomain: true
- PrivacyPolicy: true
- MetadataUser: true
- CustomTextMessage: true
- CustomTextLogin: true
- LockoutPolicy: true
- ActionsAllowed: 2 #ActionsAllowedUnlimited
- MaxActions: #not necessary because of ActionsAllowedUnlimited
PasswordComplexityPolicy:
MinLength: 8
HasLowercase: true
@@ -383,8 +360,6 @@ InternalAuthZ:
Permissions:
- "iam.read"
- "iam.write"
- - "iam.features.read"
- - "iam.features.write"
- "iam.policy.read"
- "iam.policy.write"
- "iam.policy.delete"
@@ -425,7 +400,6 @@ InternalAuthZ:
- "user.grant.delete"
- "user.membership.read"
- "user.credential.write"
- - "features.read"
- "policy.read"
- "policy.write"
- "policy.delete"
@@ -451,7 +425,6 @@ InternalAuthZ:
- Role: "IAM_OWNER_VIEWER"
Permissions:
- "iam.read"
- - "iam.features.read"
- "iam.policy.read"
- "iam.member.read"
- "iam.idp.read"
@@ -466,7 +439,6 @@ InternalAuthZ:
- "user.global.read"
- "user.grant.read"
- "user.membership.read"
- - "features.read"
- "policy.read"
- "project.read"
- "project.member.read"
@@ -501,7 +473,6 @@ InternalAuthZ:
- "user.grant.delete"
- "user.membership.read"
- "user.credential.write"
- - "features.read"
- "policy.read"
- "policy.write"
- "policy.delete"
@@ -538,7 +509,6 @@ InternalAuthZ:
- "user.grant.write"
- "user.grant.delete"
- "user.membership.read"
- - "features.read"
- "project.read"
- "project.member.read"
- "project.role.read"
@@ -574,7 +544,6 @@ InternalAuthZ:
- "user.grant.delete"
- "user.membership.read"
- "user.credential.write"
- - "features.read"
- "policy.read"
- "policy.write"
- "policy.delete"
@@ -619,7 +588,6 @@ InternalAuthZ:
- "user.global.read"
- "user.grant.read"
- "user.membership.read"
- - "features.read"
- "policy.read"
- "project.read"
- "project.member.read"
diff --git a/console/src/assets/i18n/de.json b/console/src/assets/i18n/de.json
index 856286989..64995f2de 100644
--- a/console/src/assets/i18n/de.json
+++ b/console/src/assets/i18n/de.json
@@ -112,7 +112,6 @@
"NEWVALUE": "Neuer Wert",
"RESTORE": "Wiederherstellen",
"CONTINUEWITHOUTSAVE": "Ohne speichern fortfahren",
- "GOTOFEATURES": "Zu den Features",
"OF": "von",
"PREVIOUS": "Zurück",
"NEXT": "Weiter",
diff --git a/console/src/assets/i18n/en.json b/console/src/assets/i18n/en.json
index 3279e01b4..6583b0566 100644
--- a/console/src/assets/i18n/en.json
+++ b/console/src/assets/i18n/en.json
@@ -112,7 +112,6 @@
"NEWVALUE": "New Value",
"RESTORE": "Restore",
"CONTINUEWITHOUTSAVE": "Continue without saving",
- "GOTOFEATURES": "Go to features",
"OF": "of",
"PREVIOUS": "Previous",
"NEXT": "Next",
diff --git a/console/src/assets/i18n/it.json b/console/src/assets/i18n/it.json
index 9c25a3619..247aba981 100644
--- a/console/src/assets/i18n/it.json
+++ b/console/src/assets/i18n/it.json
@@ -112,7 +112,6 @@
"NEWVALUE": "Nuovo valore",
"RESTORE": "Ripristina",
"CONTINUEWITHOUTSAVE": "Continua senza salvare",
- "GOTOFEATURES": "Vai alle caratteristiche",
"OF": "di",
"PREVIOUS": "Precedente",
"NEXT": "Avanti",
diff --git a/docs/docs/apis/proto/admin.md b/docs/docs/apis/proto/admin.md
index 300300fdc..d45220f55 100644
--- a/docs/docs/apis/proto/admin.md
+++ b/docs/docs/apis/proto/admin.md
@@ -423,66 +423,6 @@ all fields are updated. If no value is provided the field will be empty afterwar
PUT: /idps/{idp_id}/jwt_config
-### GetDefaultFeatures
-
-> **rpc** GetDefaultFeatures([GetDefaultFeaturesRequest](#getdefaultfeaturesrequest))
-[GetDefaultFeaturesResponse](#getdefaultfeaturesresponse)
-
-
-
-
-
- GET: /features
-
-
-### SetDefaultFeatures
-
-> **rpc** SetDefaultFeatures([SetDefaultFeaturesRequest](#setdefaultfeaturesrequest))
-[SetDefaultFeaturesResponse](#setdefaultfeaturesresponse)
-
-
-
-
-
- PUT: /features
-
-
-### GetOrgFeatures
-
-> **rpc** GetOrgFeatures([GetOrgFeaturesRequest](#getorgfeaturesrequest))
-[GetOrgFeaturesResponse](#getorgfeaturesresponse)
-
-
-
-
-
- GET: /orgs/{org_id}/features
-
-
-### SetOrgFeatures
-
-> **rpc** SetOrgFeatures([SetOrgFeaturesRequest](#setorgfeaturesrequest))
-[SetOrgFeaturesResponse](#setorgfeaturesresponse)
-
-
-
-
-
- PUT: /orgs/{org_id}/features
-
-
-### ResetOrgFeatures
-
-> **rpc** ResetOrgFeatures([ResetOrgFeaturesRequest](#resetorgfeaturesrequest))
-[ResetOrgFeaturesResponse](#resetorgfeaturesresponse)
-
-
-
-
-
- DELETE: /orgs/{org_id}/features
-
-
### GetOrgIAMPolicy
> **rpc** GetOrgIAMPolicy([GetOrgIAMPolicyRequest](#getorgiampolicyrequest))
@@ -1962,23 +1902,6 @@ This is an empty request
-### GetDefaultFeaturesRequest
-
-
-
-
-
-### GetDefaultFeaturesResponse
-
-
-
-| Field | Type | Description | Validation |
-| ----- | ---- | ----------- | ----------- |
-| features | zitadel.features.v1.Features | - | |
-
-
-
-
### GetDefaultInitMessageTextRequest
@@ -2291,28 +2214,6 @@ This is an empty request
-### GetOrgFeaturesRequest
-
-
-
-| Field | Type | Description | Validation |
-| ----- | ---- | ----------- | ----------- |
-| org_id | string | - | string.min_len: 1
string.max_len: 200
|
-
-
-
-
-### GetOrgFeaturesResponse
-
-
-
-| Field | Type | Description | Validation |
-| ----- | ---- | ----------- | ----------- |
-| features | zitadel.features.v1.Features | - | |
-
-
-
-
### GetOrgIAMPolicyRequest
@@ -3217,28 +3118,6 @@ This is an empty request
-### ResetOrgFeaturesRequest
-
-
-
-| Field | Type | Description | Validation |
-| ----- | ---- | ----------- | ----------- |
-| org_id | string | - | string.min_len: 1
string.max_len: 200
|
-
-
-
-
-### ResetOrgFeaturesResponse
-
-
-
-| Field | Type | Description | Validation |
-| ----- | ---- | ----------- | ----------- |
-| details | zitadel.v1.ObjectDetails | - | |
-
-
-
-
### SetCustomLoginTextsRequest
@@ -3324,50 +3203,6 @@ This is an empty request
-### SetDefaultFeaturesRequest
-
-
-
-| Field | Type | Description | Validation |
-| ----- | ---- | ----------- | ----------- |
-| tier_name | string | - | string.max_len: 200
|
-| description | string | - | string.max_len: 200
|
-| audit_log_retention | google.protobuf.Duration | - | duration.gte.seconds: 0
duration.gte.nanos: 0
|
-| login_policy_username_login | bool | - | |
-| login_policy_registration | bool | - | |
-| login_policy_idp | bool | - | |
-| login_policy_factors | bool | - | |
-| login_policy_passwordless | bool | - | |
-| password_complexity_policy | bool | - | |
-| label_policy | bool | - | |
-| custom_domain | bool | - | |
-| login_policy_password_reset | bool | - | |
-| label_policy_private_label | bool | - | |
-| label_policy_watermark | bool | - | |
-| custom_text | bool | - | |
-| privacy_policy | bool | - | |
-| metadata_user | bool | - | |
-| custom_text_message | bool | - | |
-| custom_text_login | bool | - | |
-| lockout_policy | bool | - | |
-| actions | bool | - | |
-| actions_allowed | zitadel.features.v1.ActionsAllowed | - | |
-| max_actions | int32 | - | |
-
-
-
-
-### SetDefaultFeaturesResponse
-
-
-
-| Field | Type | Description | Validation |
-| ----- | ---- | ----------- | ----------- |
-| details | zitadel.v1.ObjectDetails | - | |
-
-
-
-
### SetDefaultInitMessageTextRequest
@@ -3535,53 +3370,6 @@ This is an empty request
-### SetOrgFeaturesRequest
-
-
-
-| Field | Type | Description | Validation |
-| ----- | ---- | ----------- | ----------- |
-| org_id | string | - | string.min_len: 1
string.max_len: 200
|
-| tier_name | string | - | string.max_len: 200
|
-| description | string | - | string.max_len: 200
|
-| state | zitadel.features.v1.FeaturesState | - | |
-| state_description | string | - | string.max_len: 200
|
-| audit_log_retention | google.protobuf.Duration | - | duration.gte.seconds: 0
duration.gte.nanos: 0
|
-| login_policy_username_login | bool | - | |
-| login_policy_registration | bool | - | |
-| login_policy_idp | bool | - | |
-| login_policy_factors | bool | - | |
-| login_policy_passwordless | bool | - | |
-| password_complexity_policy | bool | - | |
-| label_policy | bool | - | |
-| custom_domain | bool | - | |
-| login_policy_password_reset | bool | - | |
-| label_policy_private_label | bool | - | |
-| label_policy_watermark | bool | - | |
-| custom_text | bool | - | |
-| privacy_policy | bool | - | |
-| metadata_user | bool | - | |
-| custom_text_message | bool | - | |
-| custom_text_login | bool | - | |
-| lockout_policy | bool | - | |
-| actions | bool | - | |
-| actions_allowed | zitadel.features.v1.ActionsAllowed | - | |
-| max_actions | int32 | - | |
-
-
-
-
-### SetOrgFeaturesResponse
-
-
-
-| Field | Type | Description | Validation |
-| ----- | ---- | ----------- | ----------- |
-| details | zitadel.v1.ObjectDetails | - | |
-
-
-
-
### SetUpOrgRequest
diff --git a/docs/docs/apis/proto/auth.md b/docs/docs/apis/proto/auth.md
index 5d576d0a9..6a580b2e1 100644
--- a/docs/docs/apis/proto/auth.md
+++ b/docs/docs/apis/proto/auth.md
@@ -533,18 +533,6 @@ Returns a list of organisations where the authorized user has a user grant (auth
POST: /global/projectorgs/_search
-### ListMyZitadelFeatures
-
-> **rpc** ListMyZitadelFeatures([ListMyZitadelFeaturesRequest](#listmyzitadelfeaturesrequest))
-[ListMyZitadelFeaturesResponse](#listmyzitadelfeaturesresponse)
-
-Returns a list of features, which are allowed on these organisation based on the subscription of the organisation
-
-
-
- POST: /features/zitadel/me/_search
-
-
### ListMyZitadelPermissions
> **rpc** ListMyZitadelPermissions([ListMyZitadelPermissionsRequest](#listmyzitadelpermissionsrequest))
@@ -1087,23 +1075,6 @@ This is an empty request
-### ListMyZitadelFeaturesRequest
-This is an empty request
-
-
-
-
-### ListMyZitadelFeaturesResponse
-
-
-
-| Field | Type | Description | Validation |
-| ----- | ---- | ----------- | ----------- |
-| result | repeated string | - | |
-
-
-
-
### ListMyZitadelPermissionsRequest
This is an empty request
diff --git a/docs/docs/apis/proto/features.md b/docs/docs/apis/proto/features.md
deleted file mode 100644
index 8970ca333..000000000
--- a/docs/docs/apis/proto/features.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: zitadel/features.proto
----
-
-
-
-
-
-
-## Enums
-
-
-### FeaturesState {#featuresstate}
-
-
-| Name | Number | Description |
-| ---- | ------ | ----------- |
-| FEATURES_STATE_ACTIVE | 0 | - |
-| FEATURES_STATE_ACTION_REQUIRED | 1 | - |
-| FEATURES_STATE_CANCELED | 2 | - |
-| FEATURES_STATE_GRANDFATHERED | 3 | - |
-
-
-
-
diff --git a/docs/docs/apis/proto/management.md b/docs/docs/apis/proto/management.md
index a49e8fd68..f9cd9b7b0 100644
--- a/docs/docs/apis/proto/management.md
+++ b/docs/docs/apis/proto/management.md
@@ -1680,18 +1680,6 @@ remove a list of user grants in one request
DELETE: /user_grants/_bulk
-### GetFeatures
-
-> **rpc** GetFeatures([GetFeaturesRequest](#getfeaturesrequest))
-[GetFeaturesResponse](#getfeaturesresponse)
-
-
-
-
-
- GET: /features
-
-
### GetOrgIAMPolicy
> **rpc** GetOrgIAMPolicy([GetOrgIAMPolicyRequest](#getorgiampolicyrequest))
@@ -4570,23 +4558,6 @@ This is an empty request
-### GetFeaturesRequest
-
-
-
-
-
-### GetFeaturesResponse
-
-
-
-| Field | Type | Description | Validation |
-| ----- | ---- | ----------- | ----------- |
-| features | zitadel.features.v1.Features | - | |
-
-
-
-
### GetFlowRequest
diff --git a/docs/docs/apis/proto/options.md b/docs/docs/apis/proto/options.md
index c175a172b..4270bc94d 100644
--- a/docs/docs/apis/proto/options.md
+++ b/docs/docs/apis/proto/options.md
@@ -17,7 +17,6 @@ title: zitadel/options.proto
| ----- | ---- | ----------- | ----------- |
| permission | string | - | |
| check_field_name | string | - | |
-| feature | string | - | |
diff --git a/internal/api/assets/generator/asset.yaml b/internal/api/assets/generator/asset.yaml
index cefb90d20..6076882b1 100644
--- a/internal/api/assets/generator/asset.yaml
+++ b/internal/api/assets/generator/asset.yaml
@@ -54,7 +54,6 @@ Services:
Methods:
OrgLabelPolicyLogo:
Path: "/policy/label/logo"
- Feature: "label_policy.private_label"
HasDarkMode: true
Handlers:
- Name: Upload
@@ -71,7 +70,6 @@ Services:
Permission: policy.read
OrgLabelPolicyIcon:
Path: "/policy/label/icon"
- Feature: "label_policy.private_label"
HasDarkMode: true
Handlers:
- Name: Upload
@@ -88,7 +86,6 @@ Services:
Permission: policy.read
OrgLabelPolicyFont:
Path: "/policy/label/font"
- Feature: "label_policy.private_label"
Handlers:
- Name: Upload
Comment:
@@ -107,7 +104,6 @@ Services:
Methods:
MyUserAvatar:
Path: "/me/avatar"
- Features: "label_policy.private_label"
Handlers:
- Name: Upload
Comment:
diff --git a/internal/api/assets/generator/asset_generator.go b/internal/api/assets/generator/asset_generator.go
index 867e194bb..a30112a82 100644
--- a/internal/api/assets/generator/asset_generator.go
+++ b/internal/api/assets/generator/asset_generator.go
@@ -31,7 +31,6 @@ func main() {
type Method struct {
Path string
- Feature string
HasDarkMode bool
Handlers []Handler
}
@@ -144,15 +143,13 @@ var {{.Name}}_AuthMethods = authz.MethodMapping {
{{ range $service := .Services}}
{{ range $method := .Methods}}
{{ range $handler := .Handlers}}
- {{ if (or $method.Feature $handler.Permission) }}
+ {{ if $handler.Permission }}
"{{$handler.Method}}:{{$prefix}}{{$service.Prefix}}{{$method.Path}}{{$handler.PathSuffix}}": authz.Option{
Permission: "{{$handler.Permission}}",
- Feature: "{{$method.Feature}}",
},
{{ if $method.HasDarkMode }}
"{{$handler.Method}}:{{$prefix}}{{$service.Prefix}}{{$method.Path}}/dark{{$handler.PathSuffix}}": authz.Option{
Permission: "{{$handler.Permission}}",
- Feature: "{{$method.Feature}}",
},
{{end}}
{{end}}
diff --git a/internal/api/authz/authorization.go b/internal/api/authz/authorization.go
index 349522d3b..c3c6d55d4 100644
--- a/internal/api/authz/authorization.go
+++ b/internal/api/authz/authorization.go
@@ -23,13 +23,6 @@ func CheckUserAuthorization(ctx context.Context, req interface{}, token, orgID s
return nil, err
}
- if requiredAuthOption.Feature != "" {
- err = CheckOrgFeatures(ctx, verifier, ctxData.OrgID, requiredAuthOption.Feature)
- if err != nil {
- return nil, err
- }
- }
-
if requiredAuthOption.Permission == authenticated {
return func(parent context.Context) context.Context {
return context.WithValue(parent, dataKey, ctxData)
@@ -56,10 +49,6 @@ func CheckUserAuthorization(ctx context.Context, req interface{}, token, orgID s
}, nil
}
-func CheckOrgFeatures(ctx context.Context, t *TokenVerifier, orgID string, requiredFeatures ...string) error {
- return t.authZRepo.CheckOrgFeatures(ctx, orgID, requiredFeatures...)
-}
-
func checkUserPermissions(req interface{}, userPerms []string, authOpt Option) error {
if len(userPerms) == 0 {
return errors.ThrowPermissionDenied(nil, "AUTH-5mWD2", "No matching permissions found")
diff --git a/internal/api/authz/permissions_test.go b/internal/api/authz/permissions_test.go
index 35a6615da..74b9d50ff 100644
--- a/internal/api/authz/permissions_test.go
+++ b/internal/api/authz/permissions_test.go
@@ -34,10 +34,6 @@ func (v *testVerifier) VerifierClientID(ctx context.Context, appName string) (st
return "clientID", "projectID", nil
}
-func (v *testVerifier) CheckOrgFeatures(context.Context, string, ...string) error {
- return nil
-}
-
func equalStringArray(a, b []string) bool {
if len(a) != len(b) {
return false
diff --git a/internal/api/authz/token.go b/internal/api/authz/token.go
index fdc7aced3..eae35b52e 100644
--- a/internal/api/authz/token.go
+++ b/internal/api/authz/token.go
@@ -25,7 +25,6 @@ type authZRepo interface {
SearchMyMemberships(ctx context.Context) ([]*Membership, error)
ProjectIDAndOriginsByClientID(ctx context.Context, clientID string) (projectID string, origins []string, err error)
ExistsOrg(ctx context.Context, orgID string) error
- CheckOrgFeatures(ctx context.Context, orgID string, requiredFeatures ...string) error
}
func Start(authZRepo authZRepo) (v *TokenVerifier) {
diff --git a/internal/api/grpc/admin/features.go b/internal/api/grpc/admin/features.go
deleted file mode 100644
index 7a6f0c8e5..000000000
--- a/internal/api/grpc/admin/features.go
+++ /dev/null
@@ -1,120 +0,0 @@
-package admin
-
-import (
- "context"
-
- features_grpc "github.com/zitadel/zitadel/internal/api/grpc/features"
- object_grpc "github.com/zitadel/zitadel/internal/api/grpc/object"
- "github.com/zitadel/zitadel/internal/domain"
- admin_pb "github.com/zitadel/zitadel/pkg/grpc/admin"
-)
-
-func (s *Server) GetDefaultFeatures(ctx context.Context, _ *admin_pb.GetDefaultFeaturesRequest) (*admin_pb.GetDefaultFeaturesResponse, error) {
- features, err := s.query.DefaultFeatures(ctx)
- if err != nil {
- return nil, err
- }
- return &admin_pb.GetDefaultFeaturesResponse{
- Features: features_grpc.ModelFeaturesToPb(features),
- }, nil
-}
-
-func (s *Server) SetDefaultFeatures(ctx context.Context, req *admin_pb.SetDefaultFeaturesRequest) (*admin_pb.SetDefaultFeaturesResponse, error) {
- details, err := s.command.SetDefaultFeatures(ctx, setDefaultFeaturesRequestToDomain(req))
- if err != nil {
- return nil, err
- }
- return &admin_pb.SetDefaultFeaturesResponse{
- Details: object_grpc.DomainToChangeDetailsPb(details),
- }, nil
-}
-
-func (s *Server) GetOrgFeatures(ctx context.Context, req *admin_pb.GetOrgFeaturesRequest) (*admin_pb.GetOrgFeaturesResponse, error) {
- features, err := s.query.FeaturesByOrgID(ctx, req.OrgId)
- if err != nil {
- return nil, err
- }
- return &admin_pb.GetOrgFeaturesResponse{
- Features: features_grpc.ModelFeaturesToPb(features),
- }, nil
-}
-
-func (s *Server) SetOrgFeatures(ctx context.Context, req *admin_pb.SetOrgFeaturesRequest) (*admin_pb.SetOrgFeaturesResponse, error) {
- details, err := s.command.SetOrgFeatures(ctx, req.OrgId, setOrgFeaturesRequestToDomain(req))
- if err != nil {
- return nil, err
- }
- return &admin_pb.SetOrgFeaturesResponse{
- Details: object_grpc.DomainToChangeDetailsPb(details),
- }, nil
-}
-
-func (s *Server) ResetOrgFeatures(ctx context.Context, req *admin_pb.ResetOrgFeaturesRequest) (*admin_pb.ResetOrgFeaturesResponse, error) {
- details, err := s.command.RemoveOrgFeatures(ctx, req.OrgId)
- if err != nil {
- return nil, err
- }
- return &admin_pb.ResetOrgFeaturesResponse{
- Details: object_grpc.DomainToChangeDetailsPb(details),
- }, nil
-}
-
-func setDefaultFeaturesRequestToDomain(req *admin_pb.SetDefaultFeaturesRequest) *domain.Features {
- actionsAllowed := features_grpc.ActionsAllowedToDomain(req.ActionsAllowed)
- if req.Actions {
- actionsAllowed = domain.ActionsAllowedUnlimited
- }
- return &domain.Features{
- TierName: req.TierName,
- TierDescription: req.Description,
- AuditLogRetention: req.AuditLogRetention.AsDuration(),
- LoginPolicyFactors: req.LoginPolicyFactors,
- LoginPolicyIDP: req.LoginPolicyIdp,
- LoginPolicyPasswordless: req.LoginPolicyPasswordless,
- LoginPolicyRegistration: req.LoginPolicyRegistration,
- LoginPolicyUsernameLogin: req.LoginPolicyUsernameLogin,
- LoginPolicyPasswordReset: req.LoginPolicyPasswordReset,
- PasswordComplexityPolicy: req.PasswordComplexityPolicy,
- LabelPolicyPrivateLabel: req.LabelPolicy || req.LabelPolicyPrivateLabel,
- LabelPolicyWatermark: req.LabelPolicyWatermark,
- CustomDomain: req.CustomDomain,
- PrivacyPolicy: req.PrivacyPolicy,
- MetadataUser: req.MetadataUser,
- CustomTextLogin: req.CustomTextLogin || req.CustomText,
- CustomTextMessage: req.CustomTextMessage,
- LockoutPolicy: req.LockoutPolicy,
- ActionsAllowed: actionsAllowed,
- MaxActions: int(req.MaxActions),
- }
-}
-
-func setOrgFeaturesRequestToDomain(req *admin_pb.SetOrgFeaturesRequest) *domain.Features {
- actionsAllowed := features_grpc.ActionsAllowedToDomain(req.ActionsAllowed)
- if req.Actions {
- actionsAllowed = domain.ActionsAllowedUnlimited
- }
- return &domain.Features{
- TierName: req.TierName,
- TierDescription: req.Description,
- State: features_grpc.FeaturesStateToDomain(req.State),
- StateDescription: req.StateDescription,
- AuditLogRetention: req.AuditLogRetention.AsDuration(),
- LoginPolicyFactors: req.LoginPolicyFactors,
- LoginPolicyIDP: req.LoginPolicyIdp,
- LoginPolicyPasswordless: req.LoginPolicyPasswordless,
- LoginPolicyRegistration: req.LoginPolicyRegistration,
- LoginPolicyUsernameLogin: req.LoginPolicyUsernameLogin,
- LoginPolicyPasswordReset: req.LoginPolicyPasswordReset,
- PasswordComplexityPolicy: req.PasswordComplexityPolicy,
- LabelPolicyPrivateLabel: req.LabelPolicy || req.LabelPolicyPrivateLabel,
- LabelPolicyWatermark: req.LabelPolicyWatermark,
- CustomDomain: req.CustomDomain,
- PrivacyPolicy: req.PrivacyPolicy,
- MetadataUser: req.MetadataUser,
- CustomTextLogin: req.CustomTextLogin || req.CustomText,
- CustomTextMessage: req.CustomTextMessage,
- LockoutPolicy: req.LockoutPolicy,
- ActionsAllowed: actionsAllowed,
- MaxActions: int(req.MaxActions),
- }
-}
diff --git a/internal/api/grpc/auth/features.go b/internal/api/grpc/auth/features.go
deleted file mode 100644
index 86beea81f..000000000
--- a/internal/api/grpc/auth/features.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package auth
-
-import (
- "context"
-
- "github.com/zitadel/zitadel/internal/api/authz"
- auth_pb "github.com/zitadel/zitadel/pkg/grpc/auth"
-)
-
-func (s *Server) ListMyZitadelFeatures(ctx context.Context, _ *auth_pb.ListMyZitadelFeaturesRequest) (*auth_pb.ListMyZitadelFeaturesResponse, error) {
- features, err := s.query.FeaturesByOrgID(ctx, authz.GetCtxData(ctx).OrgID)
- if err != nil {
- return nil, err
- }
- return &auth_pb.ListMyZitadelFeaturesResponse{
- Result: features.EnabledFeatureTypes(),
- }, nil
-}
diff --git a/internal/api/grpc/auth/server.go b/internal/api/grpc/auth/server.go
index 6d7aaf6e7..40697a825 100644
--- a/internal/api/grpc/auth/server.go
+++ b/internal/api/grpc/auth/server.go
@@ -1,6 +1,8 @@
package auth
import (
+ "time"
+
"google.golang.org/grpc"
"github.com/zitadel/zitadel/internal/api/authz"
@@ -22,13 +24,14 @@ const (
type Server struct {
auth.UnimplementedAuthServiceServer
- command *command.Commands
- query *query.Queries
- repo repository.Repository
- defaults systemdefaults.SystemDefaults
- assetsAPIDomain string
- userCodeAlg crypto.EncryptionAlgorithm
- externalSecure bool
+ command *command.Commands
+ query *query.Queries
+ repo repository.Repository
+ defaults systemdefaults.SystemDefaults
+ assetsAPIDomain string
+ userCodeAlg crypto.EncryptionAlgorithm
+ externalSecure bool
+ auditLogRetention time.Duration
}
type Config struct {
@@ -42,15 +45,17 @@ func CreateServer(command *command.Commands,
assetsAPIDomain string,
userCodeAlg crypto.EncryptionAlgorithm,
externalSecure bool,
+ auditLogRetention time.Duration,
) *Server {
return &Server{
- command: command,
- query: query,
- repo: authRepo,
- defaults: defaults,
- assetsAPIDomain: assetsAPIDomain,
- userCodeAlg: userCodeAlg,
- externalSecure: externalSecure,
+ command: command,
+ query: query,
+ repo: authRepo,
+ defaults: defaults,
+ assetsAPIDomain: assetsAPIDomain,
+ userCodeAlg: userCodeAlg,
+ externalSecure: externalSecure,
+ auditLogRetention: auditLogRetention,
}
}
diff --git a/internal/api/grpc/auth/user.go b/internal/api/grpc/auth/user.go
index cb343d512..849dd5bd0 100644
--- a/internal/api/grpc/auth/user.go
+++ b/internal/api/grpc/auth/user.go
@@ -56,11 +56,7 @@ func (s *Server) RemoveMyUser(ctx context.Context, _ *auth_pb.RemoveMyUserReques
func (s *Server) ListMyUserChanges(ctx context.Context, req *auth_pb.ListMyUserChangesRequest) (*auth_pb.ListMyUserChangesResponse, error) {
sequence, limit, asc := change.ChangeQueryToQuery(req.Query)
- features, err := s.query.FeaturesByOrgID(ctx, authz.GetCtxData(ctx).ResourceOwner)
- if err != nil {
- return nil, err
- }
- changes, err := s.query.UserChanges(ctx, authz.GetCtxData(ctx).UserID, sequence, limit, asc, features.AuditLogRetention)
+ changes, err := s.query.UserChanges(ctx, authz.GetCtxData(ctx).UserID, sequence, limit, asc, s.auditLogRetention)
if err != nil {
return nil, err
}
diff --git a/internal/api/grpc/features/features.go b/internal/api/grpc/features/features.go
deleted file mode 100644
index c0fca629f..000000000
--- a/internal/api/grpc/features/features.go
+++ /dev/null
@@ -1,108 +0,0 @@
-package features
-
-import (
- "google.golang.org/protobuf/types/known/durationpb"
-
- object_grpc "github.com/zitadel/zitadel/internal/api/grpc/object"
- "github.com/zitadel/zitadel/internal/domain"
- "github.com/zitadel/zitadel/internal/query"
- features_pb "github.com/zitadel/zitadel/pkg/grpc/features"
-)
-
-func ModelFeaturesToPb(features *query.Features) *features_pb.Features {
- return &features_pb.Features{
- IsDefault: features.IsDefault,
- Tier: FeatureTierToPb(features.TierName, features.TierDescription, features.State, features.StateDescription),
- AuditLogRetention: durationpb.New(features.AuditLogRetention),
- LoginPolicyFactors: features.LoginPolicyFactors,
- LoginPolicyIdp: features.LoginPolicyIDP,
- LoginPolicyPasswordless: features.LoginPolicyPasswordless,
- LoginPolicyRegistration: features.LoginPolicyRegistration,
- LoginPolicyUsernameLogin: features.LoginPolicyUsernameLogin,
- LoginPolicyPasswordReset: features.LoginPolicyPasswordReset,
- PasswordComplexityPolicy: features.PasswordComplexityPolicy,
- LabelPolicy: features.LabelPolicyPrivateLabel,
- CustomDomain: features.CustomDomain,
- LabelPolicyPrivateLabel: features.LabelPolicyPrivateLabel,
- LabelPolicyWatermark: features.LabelPolicyWatermark,
- PrivacyPolicy: features.PrivacyPolicy,
- CustomText: features.CustomTextMessage,
- CustomTextMessage: features.CustomTextMessage,
- CustomTextLogin: features.CustomTextLogin,
- MetadataUser: features.MetadataUser,
- LockoutPolicy: features.LockoutPolicy,
- Actions: features.ActionsAllowed != domain.ActionsNotAllowed,
- ActionsAllowed: ActionsAllowedToPb(features.ActionsAllowed),
- MaxActions: features.MaxActions,
- Details: object_grpc.ChangeToDetailsPb(
- features.Sequence,
- features.ChangeDate,
- features.AggregateID,
- ),
- }
-}
-
-func FeatureTierToPb(name, description string, status domain.FeaturesState, statusDescription string) *features_pb.FeatureTier {
- return &features_pb.FeatureTier{
- Name: name,
- Description: description,
- State: FeaturesStateToPb(status),
- StatusInfo: statusDescription,
- }
-}
-
-func FeaturesStateToPb(status domain.FeaturesState) features_pb.FeaturesState {
- switch status {
- case domain.FeaturesStateActive:
- return features_pb.FeaturesState_FEATURES_STATE_ACTIVE
- case domain.FeaturesStateActionRequired:
- return features_pb.FeaturesState_FEATURES_STATE_ACTION_REQUIRED
- case domain.FeaturesStateCanceled:
- return features_pb.FeaturesState_FEATURES_STATE_CANCELED
- case domain.FeaturesStateGrandfathered:
- return features_pb.FeaturesState_FEATURES_STATE_GRANDFATHERED
- default:
- return features_pb.FeaturesState_FEATURES_STATE_ACTIVE
- }
-}
-
-func FeaturesStateToDomain(status features_pb.FeaturesState) domain.FeaturesState {
- switch status {
- case features_pb.FeaturesState_FEATURES_STATE_ACTIVE:
- return domain.FeaturesStateActive
- case features_pb.FeaturesState_FEATURES_STATE_ACTION_REQUIRED:
- return domain.FeaturesStateActionRequired
- case features_pb.FeaturesState_FEATURES_STATE_CANCELED:
- return domain.FeaturesStateCanceled
- case features_pb.FeaturesState_FEATURES_STATE_GRANDFATHERED:
- return domain.FeaturesStateGrandfathered
- default:
- return -1
- }
-}
-
-func ActionsAllowedToDomain(allowed features_pb.ActionsAllowed) domain.ActionsAllowed {
- switch allowed {
- case features_pb.ActionsAllowed_ACTIONS_ALLOWED_NOT_ALLOWED:
- return domain.ActionsNotAllowed
- case features_pb.ActionsAllowed_ACTIONS_ALLOWED_MAX:
- return domain.ActionsMaxAllowed
- case features_pb.ActionsAllowed_ACTIONS_ALLOWED_UNLIMITED:
- return domain.ActionsAllowedUnlimited
- default:
- return domain.ActionsNotAllowed
- }
-}
-
-func ActionsAllowedToPb(allowed domain.ActionsAllowed) features_pb.ActionsAllowed {
- switch allowed {
- case domain.ActionsNotAllowed:
- return features_pb.ActionsAllowed_ACTIONS_ALLOWED_NOT_ALLOWED
- case domain.ActionsMaxAllowed:
- return features_pb.ActionsAllowed_ACTIONS_ALLOWED_MAX
- case domain.ActionsAllowedUnlimited:
- return features_pb.ActionsAllowed_ACTIONS_ALLOWED_UNLIMITED
- default:
- return features_pb.ActionsAllowed_ACTIONS_ALLOWED_NOT_ALLOWED
- }
-}
diff --git a/internal/api/grpc/management/features.go b/internal/api/grpc/management/features.go
deleted file mode 100644
index 57e2568de..000000000
--- a/internal/api/grpc/management/features.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package management
-
-import (
- "context"
-
- "github.com/zitadel/zitadel/internal/api/authz"
- features_grpc "github.com/zitadel/zitadel/internal/api/grpc/features"
- mgmt_pb "github.com/zitadel/zitadel/pkg/grpc/management"
-)
-
-func (s *Server) GetFeatures(ctx context.Context, req *mgmt_pb.GetFeaturesRequest) (*mgmt_pb.GetFeaturesResponse, error) {
- features, err := s.query.FeaturesByOrgID(ctx, authz.GetCtxData(ctx).OrgID)
- if err != nil {
- return nil, err
- }
- return &mgmt_pb.GetFeaturesResponse{
- Features: features_grpc.ModelFeaturesToPb(features),
- }, nil
-}
diff --git a/internal/api/grpc/management/org.go b/internal/api/grpc/management/org.go
index 976d63f9e..6637e9835 100644
--- a/internal/api/grpc/management/org.go
+++ b/internal/api/grpc/management/org.go
@@ -34,11 +34,7 @@ func (s *Server) GetOrgByDomainGlobal(ctx context.Context, req *mgmt_pb.GetOrgBy
func (s *Server) ListOrgChanges(ctx context.Context, req *mgmt_pb.ListOrgChangesRequest) (*mgmt_pb.ListOrgChangesResponse, error) {
sequence, limit, asc := change_grpc.ChangeQueryToQuery(req.Query)
- features, err := s.query.FeaturesByOrgID(ctx, authz.GetCtxData(ctx).OrgID)
- if err != nil {
- return nil, err
- }
- response, err := s.query.OrgChanges(ctx, authz.GetCtxData(ctx).OrgID, sequence, limit, asc, features.AuditLogRetention)
+ response, err := s.query.OrgChanges(ctx, authz.GetCtxData(ctx).OrgID, sequence, limit, asc, s.auditLogRetention)
if err != nil {
return nil, err
}
diff --git a/internal/api/grpc/management/project.go b/internal/api/grpc/management/project.go
index f214aa205..a17be02ef 100644
--- a/internal/api/grpc/management/project.go
+++ b/internal/api/grpc/management/project.go
@@ -111,11 +111,7 @@ func (s *Server) ListGrantedProjectRoles(ctx context.Context, req *mgmt_pb.ListG
func (s *Server) ListProjectChanges(ctx context.Context, req *mgmt_pb.ListProjectChangesRequest) (*mgmt_pb.ListProjectChangesResponse, error) {
sequence, limit, asc := change_grpc.ChangeQueryToQuery(req.Query)
- features, err := s.query.FeaturesByOrgID(ctx, authz.GetCtxData(ctx).OrgID)
- if err != nil {
- return nil, err
- }
- res, err := s.query.ProjectChanges(ctx, req.ProjectId, sequence, limit, asc, features.AuditLogRetention)
+ res, err := s.query.ProjectChanges(ctx, req.ProjectId, sequence, limit, asc, s.auditLogRetention)
if err != nil {
return nil, err
}
diff --git a/internal/api/grpc/management/project_application.go b/internal/api/grpc/management/project_application.go
index 28e9b96bf..4e2d26990 100644
--- a/internal/api/grpc/management/project_application.go
+++ b/internal/api/grpc/management/project_application.go
@@ -44,11 +44,7 @@ func (s *Server) ListApps(ctx context.Context, req *mgmt_pb.ListAppsRequest) (*m
func (s *Server) ListAppChanges(ctx context.Context, req *mgmt_pb.ListAppChangesRequest) (*mgmt_pb.ListAppChangesResponse, error) {
sequence, limit, asc := change_grpc.ChangeQueryToQuery(req.Query)
- features, err := s.query.FeaturesByOrgID(ctx, authz.GetCtxData(ctx).OrgID)
- if err != nil {
- return nil, err
- }
- res, err := s.query.ApplicationChanges(ctx, req.ProjectId, req.AppId, sequence, limit, asc, features.AuditLogRetention)
+ res, err := s.query.ApplicationChanges(ctx, req.ProjectId, req.AppId, sequence, limit, asc, s.auditLogRetention)
if err != nil {
return nil, err
}
diff --git a/internal/api/grpc/management/server.go b/internal/api/grpc/management/server.go
index 46de35795..d3593b3d2 100644
--- a/internal/api/grpc/management/server.go
+++ b/internal/api/grpc/management/server.go
@@ -1,6 +1,8 @@
package management
import (
+ "time"
+
"google.golang.org/grpc"
"github.com/zitadel/zitadel/internal/api/authz"
@@ -20,14 +22,15 @@ var _ management.ManagementServiceServer = (*Server)(nil)
type Server struct {
management.UnimplementedManagementServiceServer
- command *command.Commands
- query *query.Queries
- systemDefaults systemdefaults.SystemDefaults
- assetAPIPrefix string
- passwordHashAlg crypto.HashAlgorithm
- userCodeAlg crypto.EncryptionAlgorithm
- externalSecure bool
- issuerPath string
+ command *command.Commands
+ query *query.Queries
+ systemDefaults systemdefaults.SystemDefaults
+ assetAPIPrefix string
+ passwordHashAlg crypto.HashAlgorithm
+ userCodeAlg crypto.EncryptionAlgorithm
+ externalSecure bool
+ issuerPath string
+ auditLogRetention time.Duration
}
func CreateServer(
@@ -38,16 +41,18 @@ func CreateServer(
userCodeAlg crypto.EncryptionAlgorithm,
externalSecure bool,
issuerPath string,
+ auditLogRetention time.Duration,
) *Server {
return &Server{
- command: command,
- query: query,
- systemDefaults: sd,
- assetAPIPrefix: assetAPIPrefix,
- passwordHashAlg: crypto.NewBCrypt(sd.SecretGenerators.PasswordSaltCost),
- userCodeAlg: userCodeAlg,
- externalSecure: externalSecure,
- issuerPath: issuerPath,
+ command: command,
+ query: query,
+ systemDefaults: sd,
+ assetAPIPrefix: assetAPIPrefix,
+ passwordHashAlg: crypto.NewBCrypt(sd.SecretGenerators.PasswordSaltCost),
+ userCodeAlg: userCodeAlg,
+ externalSecure: externalSecure,
+ issuerPath: issuerPath,
+ auditLogRetention: auditLogRetention,
}
}
diff --git a/internal/api/grpc/management/user.go b/internal/api/grpc/management/user.go
index a4dfd5943..b9fceb954 100644
--- a/internal/api/grpc/management/user.go
+++ b/internal/api/grpc/management/user.go
@@ -79,11 +79,7 @@ func (s *Server) ListUsers(ctx context.Context, req *mgmt_pb.ListUsersRequest) (
func (s *Server) ListUserChanges(ctx context.Context, req *mgmt_pb.ListUserChangesRequest) (*mgmt_pb.ListUserChangesResponse, error) {
sequence, limit, asc := change_grpc.ChangeQueryToQuery(req.Query)
- features, err := s.query.FeaturesByOrgID(ctx, authz.GetCtxData(ctx).OrgID)
- if err != nil {
- return nil, err
- }
- res, err := s.query.UserChanges(ctx, req.UserId, sequence, limit, asc, features.AuditLogRetention)
+ res, err := s.query.UserChanges(ctx, req.UserId, sequence, limit, asc, s.auditLogRetention)
if err != nil {
return nil, err
}
diff --git a/internal/api/grpc/server/middleware/auth_interceptor_test.go b/internal/api/grpc/server/middleware/auth_interceptor_test.go
index 3ab740989..cce501895 100644
--- a/internal/api/grpc/server/middleware/auth_interceptor_test.go
+++ b/internal/api/grpc/server/middleware/auth_interceptor_test.go
@@ -37,9 +37,6 @@ func (v *verifierMock) ExistsOrg(ctx context.Context, orgID string) error {
func (v *verifierMock) VerifierClientID(ctx context.Context, appName string) (string, string, error) {
return "", "", nil
}
-func (v *verifierMock) CheckOrgFeatures(context.Context, string, ...string) error {
- return nil
-}
func Test_authorize(t *testing.T) {
type args struct {
diff --git a/internal/authz/repository/eventsourcing/eventstore/token_verifier.go b/internal/authz/repository/eventsourcing/eventstore/token_verifier.go
index b4f35e570..60a50b6ed 100644
--- a/internal/authz/repository/eventsourcing/eventstore/token_verifier.go
+++ b/internal/authz/repository/eventsourcing/eventstore/token_verifier.go
@@ -11,7 +11,6 @@ import (
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/authz/repository/eventsourcing/view"
"github.com/zitadel/zitadel/internal/crypto"
- "github.com/zitadel/zitadel/internal/domain"
caos_errs "github.com/zitadel/zitadel/internal/errors"
v1 "github.com/zitadel/zitadel/internal/eventstore/v1"
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
@@ -105,133 +104,6 @@ func (repo *TokenVerifierRepo) ProjectIDAndOriginsByClientID(ctx context.Context
return app.ProjectID, app.OIDCConfig.AllowedOrigins, nil
}
-func (repo *TokenVerifierRepo) CheckOrgFeatures(ctx context.Context, orgID string, requiredFeatures ...string) error {
- features, err := repo.Query.FeaturesByOrgID(ctx, orgID)
- if err != nil {
- return err
- }
- return checkFeatures(features, requiredFeatures...)
-}
-
-func checkFeatures(features *query.Features, requiredFeatures ...string) error {
- for _, requiredFeature := range requiredFeatures {
- if strings.HasPrefix(requiredFeature, domain.FeatureLoginPolicy) {
- if err := checkLoginPolicyFeatures(features, requiredFeature); err != nil {
- return err
- }
- continue
- }
- if requiredFeature == domain.FeaturePasswordComplexityPolicy {
- if !features.PasswordComplexityPolicy {
- return MissingFeatureErr(requiredFeature)
- }
- continue
- }
- if strings.HasPrefix(requiredFeature, domain.FeatureLabelPolicy) {
- if err := checkLabelPolicyFeatures(features, requiredFeature); err != nil {
- return err
- }
- continue
- }
- if requiredFeature == domain.FeatureCustomDomain {
- if !features.CustomDomain {
- return MissingFeatureErr(requiredFeature)
- }
- continue
- }
- if requiredFeature == domain.FeatureCustomTextMessage {
- if !features.CustomTextMessage {
- return MissingFeatureErr(requiredFeature)
- }
- continue
- }
- if requiredFeature == domain.FeatureCustomTextLogin {
- if !features.CustomTextLogin {
- return MissingFeatureErr(requiredFeature)
- }
- continue
- }
- if requiredFeature == domain.FeaturePrivacyPolicy {
- if !features.PrivacyPolicy {
- return MissingFeatureErr(requiredFeature)
- }
- continue
- }
- if requiredFeature == domain.FeatureLockoutPolicy {
- if !features.LockoutPolicy {
- return MissingFeatureErr(requiredFeature)
- }
- continue
- }
- if requiredFeature == domain.FeatureMetadataUser {
- if !features.MetadataUser {
- return MissingFeatureErr(requiredFeature)
- }
- continue
- }
- if requiredFeature == domain.FeatureActions {
- if features.ActionsAllowed == domain.ActionsNotAllowed {
- return MissingFeatureErr(requiredFeature)
- }
- continue
- }
- return MissingFeatureErr(requiredFeature)
- }
- return nil
-}
-
-func checkLoginPolicyFeatures(features *query.Features, requiredFeature string) error {
- switch requiredFeature {
- case domain.FeatureLoginPolicyFactors:
- if !features.LoginPolicyFactors {
- return MissingFeatureErr(requiredFeature)
- }
- case domain.FeatureLoginPolicyIDP:
- if !features.LoginPolicyIDP {
- return MissingFeatureErr(requiredFeature)
- }
- case domain.FeatureLoginPolicyPasswordless:
- if !features.LoginPolicyPasswordless {
- return MissingFeatureErr(requiredFeature)
- }
- case domain.FeatureLoginPolicyRegistration:
- if !features.LoginPolicyRegistration {
- return MissingFeatureErr(requiredFeature)
- }
- case domain.FeatureLoginPolicyUsernameLogin:
- if !features.LoginPolicyUsernameLogin {
- return MissingFeatureErr(requiredFeature)
- }
- case domain.FeatureLoginPolicyPasswordReset:
- if !features.LoginPolicyPasswordReset {
- return MissingFeatureErr(requiredFeature)
- }
- default:
- if !features.LoginPolicyFactors && !features.LoginPolicyIDP && !features.LoginPolicyPasswordless && !features.LoginPolicyRegistration && !features.LoginPolicyUsernameLogin {
- return MissingFeatureErr(requiredFeature)
- }
- }
- return nil
-}
-
-func checkLabelPolicyFeatures(features *query.Features, requiredFeature string) error {
- switch requiredFeature {
- case domain.FeatureLabelPolicyPrivateLabel:
- if !features.LabelPolicyPrivateLabel {
- return MissingFeatureErr(requiredFeature)
- }
- case domain.FeatureLabelPolicyWatermark:
- if !features.LabelPolicyWatermark {
- return MissingFeatureErr(requiredFeature)
- }
- }
- return nil
-}
-
-func MissingFeatureErr(feature string) error {
- return caos_errs.ThrowPermissionDeniedf(nil, "AUTH-Dvgsf", "missing feature %v", feature)
-}
-
func (repo *TokenVerifierRepo) VerifierClientID(ctx context.Context, appName string) (clientID, projectID string, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
diff --git a/internal/authz/repository/token_verifier.go b/internal/authz/repository/token_verifier.go
index c9bcf30a1..c62c75427 100644
--- a/internal/authz/repository/token_verifier.go
+++ b/internal/authz/repository/token_verifier.go
@@ -7,6 +7,5 @@ import (
type TokenVerifierRepository interface {
VerifyAccessToken(ctx context.Context, tokenString, verifierClientID, projectID string) (userID string, agentID string, clientID, prefLang, resourceOwner string, err error)
ProjectIDAndOriginsByClientID(ctx context.Context, clientID string) (projectID string, origins []string, err error)
- CheckOrgFeatures(ctx context.Context, orgID string, requiredFeatures ...string) error
VerifierClientID(ctx context.Context, appName string) (clientID, projectID string, err error)
}
diff --git a/internal/command/command.go b/internal/command/command.go
index 43749b64e..911fef0be 100644
--- a/internal/command/command.go
+++ b/internal/command/command.go
@@ -1,12 +1,10 @@
package command
import (
- "context"
"time"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/api/http"
- authz_repo "github.com/zitadel/zitadel/internal/authz/repository"
sd "github.com/zitadel/zitadel/internal/config/systemdefaults"
"github.com/zitadel/zitadel/internal/crypto"
"github.com/zitadel/zitadel/internal/domain"
@@ -50,19 +48,12 @@ type Commands struct {
keyAlgorithm crypto.EncryptionAlgorithm
privateKeyLifetime time.Duration
publicKeyLifetime time.Duration
-
- tokenVerifier orgFeatureChecker
-}
-
-type orgFeatureChecker interface {
- CheckOrgFeatures(ctx context.Context, orgID string, requiredFeatures ...string) error
}
func StartCommands(es *eventstore.Eventstore,
defaults sd.SystemDefaults,
zitadelRoles []authz.RoleMapping,
staticStore static.Storage,
- authZRepo authz_repo.Repository,
webAuthN *webauthn_helper.Config,
externalDomain string,
externalSecure bool,
@@ -119,8 +110,6 @@ func StartCommands(es *eventstore.Eventstore,
repo.domainVerificationGenerator = crypto.NewEncryptionGenerator(defaults.DomainVerification.VerificationGenerator, repo.domainVerificationAlg)
repo.domainVerificationValidator = http.ValidateDomain
-
- repo.tokenVerifier = authZRepo
return repo, nil
}
diff --git a/internal/command/features_model.go b/internal/command/features_model.go
deleted file mode 100644
index 1b7e6029b..000000000
--- a/internal/command/features_model.go
+++ /dev/null
@@ -1,123 +0,0 @@
-package command
-
-import (
- "time"
-
- "github.com/zitadel/zitadel/internal/domain"
- "github.com/zitadel/zitadel/internal/eventstore"
- "github.com/zitadel/zitadel/internal/repository/features"
-)
-
-type FeaturesWriteModel struct {
- eventstore.WriteModel
-
- TierName string
- TierDescription string
- State domain.FeaturesState
- StateDescription string
- AuditLogRetention time.Duration
- LoginPolicyFactors bool
- LoginPolicyIDP bool
- LoginPolicyPasswordless bool
- LoginPolicyRegistration bool
- LoginPolicyUsernameLogin bool
- LoginPolicyPasswordReset bool
- PasswordComplexityPolicy bool
- LabelPolicyPrivateLabel bool
- LabelPolicyWatermark bool
- CustomDomain bool
- PrivacyPolicy bool
- MetadataUser bool
- CustomTextMessage bool
- CustomTextLogin bool
- LockoutPolicy bool
- ActionsAllowed domain.ActionsAllowed
- MaxActions int
-}
-
-func (wm *FeaturesWriteModel) Reduce() error {
- for _, event := range wm.Events {
- switch e := event.(type) {
- case *features.FeaturesSetEvent:
- if e.TierName != nil {
- wm.TierName = *e.TierName
- }
- if e.TierDescription != nil {
- wm.TierDescription = *e.TierDescription
- }
- wm.State = domain.FeaturesStateActive
- if e.State != nil {
- wm.State = *e.State
- }
- if e.StateDescription != nil {
- wm.StateDescription = *e.StateDescription
- }
- if e.AuditLogRetention != nil {
- wm.AuditLogRetention = *e.AuditLogRetention
- }
- if e.LoginPolicyFactors != nil {
- wm.LoginPolicyFactors = *e.LoginPolicyFactors
- }
- if e.LoginPolicyIDP != nil {
- wm.LoginPolicyIDP = *e.LoginPolicyIDP
- }
- if e.LoginPolicyPasswordless != nil {
- wm.LoginPolicyPasswordless = *e.LoginPolicyPasswordless
- }
- if e.LoginPolicyRegistration != nil {
- wm.LoginPolicyRegistration = *e.LoginPolicyRegistration
- }
- if e.LoginPolicyUsernameLogin != nil {
- wm.LoginPolicyUsernameLogin = *e.LoginPolicyUsernameLogin
- }
- if e.LoginPolicyPasswordReset != nil {
- wm.LoginPolicyPasswordReset = *e.LoginPolicyPasswordReset
- }
- if e.PasswordComplexityPolicy != nil {
- wm.PasswordComplexityPolicy = *e.PasswordComplexityPolicy
- }
- if e.LabelPolicy != nil {
- wm.LabelPolicyPrivateLabel = *e.LabelPolicy
- }
- if e.LabelPolicyPrivateLabel != nil {
- wm.LabelPolicyPrivateLabel = *e.LabelPolicyPrivateLabel
- }
- if e.LabelPolicyWatermark != nil {
- wm.LabelPolicyWatermark = *e.LabelPolicyWatermark
- }
- if e.CustomDomain != nil {
- wm.CustomDomain = *e.CustomDomain
- }
- if e.PrivacyPolicy != nil {
- wm.PrivacyPolicy = *e.PrivacyPolicy
- }
- if e.MetadataUser != nil {
- wm.MetadataUser = *e.MetadataUser
- }
- if e.CustomTextMessage != nil {
- wm.CustomTextMessage = *e.CustomTextMessage
- }
- if e.CustomTextLogin != nil {
- wm.CustomTextLogin = *e.CustomTextLogin
- }
- if e.LockoutPolicy != nil {
- wm.LockoutPolicy = *e.LockoutPolicy
- }
- if e.Actions != nil {
- wm.ActionsAllowed = domain.ActionsNotAllowed
- if *e.Actions {
- wm.ActionsAllowed = domain.ActionsAllowedUnlimited
- }
- }
- if e.ActionsAllowed != nil {
- wm.ActionsAllowed = *e.ActionsAllowed
- }
- if e.MaxActions != nil {
- wm.MaxActions = *e.MaxActions
- }
- case *features.FeaturesRemovedEvent:
- wm.State = domain.FeaturesStateRemoved
- }
- }
- return wm.WriteModel.Reduce()
-}
diff --git a/internal/command/instance.go b/internal/command/instance.go
index ebe82c2d0..a1239bc6d 100644
--- a/internal/command/instance.go
+++ b/internal/command/instance.go
@@ -29,34 +29,10 @@ const (
)
type InstanceSetup struct {
- zitadel ZitadelConfig
- InstanceName string
- CustomDomain string
- Org OrgSetup
- Features struct {
- TierName string
- TierDescription string
- Retention time.Duration
- State domain.FeaturesState
- StateDescription string
- LoginPolicyFactors bool
- LoginPolicyIDP bool
- LoginPolicyPasswordless bool
- LoginPolicyRegistration bool
- LoginPolicyUsernameLogin bool
- LoginPolicyPasswordReset bool
- PasswordComplexityPolicy bool
- LabelPolicyPrivateLabel bool
- LabelPolicyWatermark bool
- CustomDomain bool
- PrivacyPolicy bool
- MetadataUser bool
- CustomTextMessage bool
- CustomTextLogin bool
- LockoutPolicy bool
- ActionsAllowed domain.ActionsAllowed
- MaxActions int
- }
+ zitadel ZitadelConfig
+ InstanceName string
+ CustomDomain string
+ Org OrgSetup
SecretGenerators struct {
PasswordSaltCost uint
ClientSecret *crypto.GeneratorConfig
@@ -191,31 +167,6 @@ func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (str
validations := []preparation.Validation{
addInstance(instanceAgg, setup.InstanceName),
- SetDefaultFeatures(
- instanceAgg,
- setup.Features.TierName,
- setup.Features.TierDescription,
- setup.Features.State,
- setup.Features.StateDescription,
- setup.Features.Retention,
- setup.Features.LoginPolicyFactors,
- setup.Features.LoginPolicyIDP,
- setup.Features.LoginPolicyPasswordless,
- setup.Features.LoginPolicyRegistration,
- setup.Features.LoginPolicyUsernameLogin,
- setup.Features.LoginPolicyPasswordReset,
- setup.Features.PasswordComplexityPolicy,
- setup.Features.LabelPolicyPrivateLabel,
- setup.Features.LabelPolicyWatermark,
- setup.Features.CustomDomain,
- setup.Features.PrivacyPolicy,
- setup.Features.MetadataUser,
- setup.Features.CustomTextMessage,
- setup.Features.CustomTextLogin,
- setup.Features.LockoutPolicy,
- setup.Features.ActionsAllowed,
- setup.Features.MaxActions,
- ),
addSecretGeneratorConfig(instanceAgg, domain.SecretGeneratorTypeAppSecret, setup.SecretGenerators.ClientSecret),
addSecretGeneratorConfig(instanceAgg, domain.SecretGeneratorTypeInitCode, setup.SecretGenerators.InitializeUserCode),
addSecretGeneratorConfig(instanceAgg, domain.SecretGeneratorTypeVerifyEmailCode, setup.SecretGenerators.EmailVerificationCode),
diff --git a/internal/command/instance_converter.go b/internal/command/instance_converter.go
index 90c6e60dc..75320bdcb 100644
--- a/internal/command/instance_converter.go
+++ b/internal/command/instance_converter.go
@@ -169,31 +169,3 @@ func writeModelToIDPProvider(wm *IdentityProviderWriteModel) *domain.IDPProvider
Type: wm.IDPProviderType,
}
}
-
-func writeModelToFeatures(wm *FeaturesWriteModel) *domain.Features {
- return &domain.Features{
- ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
- TierName: wm.TierName,
- TierDescription: wm.TierDescription,
- State: wm.State,
- StateDescription: wm.StateDescription,
- AuditLogRetention: wm.AuditLogRetention,
- LoginPolicyFactors: wm.LoginPolicyFactors,
- LoginPolicyIDP: wm.LoginPolicyIDP,
- LoginPolicyPasswordless: wm.LoginPolicyPasswordless,
- LoginPolicyRegistration: wm.LoginPolicyRegistration,
- LoginPolicyUsernameLogin: wm.LoginPolicyUsernameLogin,
- LoginPolicyPasswordReset: wm.LoginPolicyPasswordReset,
- PasswordComplexityPolicy: wm.PasswordComplexityPolicy,
- LabelPolicyPrivateLabel: wm.LabelPolicyPrivateLabel,
- LabelPolicyWatermark: wm.LabelPolicyWatermark,
- CustomDomain: wm.CustomDomain,
- PrivacyPolicy: wm.PrivacyPolicy,
- MetadataUser: wm.MetadataUser,
- CustomTextMessage: wm.CustomTextMessage,
- CustomTextLogin: wm.CustomTextLogin,
- LockoutPolicy: wm.LockoutPolicy,
- ActionsAllowed: wm.ActionsAllowed,
- MaxActions: wm.MaxActions,
- }
-}
diff --git a/internal/command/instance_features.go b/internal/command/instance_features.go
deleted file mode 100644
index a2ef29bca..000000000
--- a/internal/command/instance_features.go
+++ /dev/null
@@ -1,160 +0,0 @@
-package command
-
-import (
- "context"
- "time"
-
- "github.com/zitadel/zitadel/internal/command/preparation"
- "github.com/zitadel/zitadel/internal/domain"
- "github.com/zitadel/zitadel/internal/errors"
- "github.com/zitadel/zitadel/internal/eventstore"
- "github.com/zitadel/zitadel/internal/repository/instance"
-)
-
-func SetDefaultFeatures(
- a *instance.Aggregate,
- tierName,
- tierDescription string,
- state domain.FeaturesState,
- stateDescription string,
- retention time.Duration,
- loginPolicyFactors,
- loginPolicyIDP,
- loginPolicyPasswordless,
- loginPolicyRegistration,
- loginPolicyUsernameLogin,
- loginPolicyPasswordReset,
- passwordComplexityPolicy,
- labelPolicyPrivateLabel,
- labelPolicyWatermark,
- customDomain,
- privacyPolicy,
- metadataUser,
- customTextMessage,
- customTextLogin,
- lockoutPolicy bool,
- actionsAllowed domain.ActionsAllowed,
- maxActions int,
-) preparation.Validation {
- return func() (preparation.CreateCommands, error) {
- if !state.Valid() || state == domain.FeaturesStateUnspecified || state == domain.FeaturesStateRemoved {
- return nil, errors.ThrowInvalidArgument(nil, "INSTA-d3r1s", "Errors.Invalid.Argument")
- }
- return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
- writeModel, err := defaultFeatures(ctx, filter)
- if err != nil {
- return nil, err
- }
- event, hasChanged := writeModel.NewSetEvent(ctx, &a.Aggregate,
- tierName,
- tierDescription,
- state,
- stateDescription,
- retention,
- loginPolicyFactors,
- loginPolicyIDP,
- loginPolicyPasswordless,
- loginPolicyRegistration,
- loginPolicyUsernameLogin,
- loginPolicyPasswordReset,
- passwordComplexityPolicy,
- labelPolicyPrivateLabel,
- labelPolicyWatermark,
- customDomain,
- privacyPolicy,
- metadataUser,
- customTextMessage,
- customTextLogin,
- lockoutPolicy,
- actionsAllowed,
- maxActions,
- )
- if !hasChanged {
- return nil, errors.ThrowPreconditionFailed(nil, "INSTA-GE4h2", "Errors.Features.NotChanged")
- }
- return []eventstore.Command{
- event,
- }, nil
- }, nil
- }
-}
-
-func defaultFeatures(ctx context.Context, filter preparation.FilterToQueryReducer) (*InstanceFeaturesWriteModel, error) {
- features := NewInstanceFeaturesWriteModel(ctx)
- events, err := filter(ctx, features.Query())
- if err != nil {
- return nil, err
- }
- if len(events) == 0 {
- return features, nil
- }
- features.AppendEvents(events...)
- err = features.Reduce()
- return features, err
-}
-
-func (c *Commands) SetDefaultFeatures(ctx context.Context, features *domain.Features) (*domain.ObjectDetails, error) {
- existingFeatures := NewInstanceFeaturesWriteModel(ctx)
- setEvent, err := c.setDefaultFeatures(ctx, existingFeatures, features)
- if err != nil {
- return nil, err
- }
-
- pushedEvents, err := c.eventstore.Push(ctx, setEvent)
- if err != nil {
- return nil, err
- }
- err = AppendAndReduce(existingFeatures, pushedEvents...)
- if err != nil {
- return nil, err
- }
- return writeModelToObjectDetails(&existingFeatures.WriteModel), nil
-}
-
-func (c *Commands) setDefaultFeatures(ctx context.Context, existingFeatures *InstanceFeaturesWriteModel, features *domain.Features) (*instance.FeaturesSetEvent, error) {
- err := c.eventstore.FilterToQueryReducer(ctx, existingFeatures)
- if err != nil {
- return nil, err
- }
- setEvent, hasChanged := existingFeatures.NewSetEvent(
- ctx,
- InstanceAggregateFromWriteModel(&existingFeatures.FeaturesWriteModel.WriteModel),
- features.TierName,
- features.TierDescription,
- features.State,
- features.StateDescription,
- features.AuditLogRetention,
- features.LoginPolicyFactors,
- features.LoginPolicyIDP,
- features.LoginPolicyPasswordless,
- features.LoginPolicyRegistration,
- features.LoginPolicyUsernameLogin,
- features.LoginPolicyPasswordReset,
- features.PasswordComplexityPolicy,
- features.LabelPolicyPrivateLabel,
- features.LabelPolicyWatermark,
- features.CustomDomain,
- features.PrivacyPolicy,
- features.MetadataUser,
- features.CustomTextMessage,
- features.CustomTextLogin,
- features.LockoutPolicy,
- features.ActionsAllowed,
- features.MaxActions,
- )
- if !hasChanged {
- return nil, errors.ThrowPreconditionFailed(nil, "Features-GE4h2", "Errors.Features.NotChanged")
- }
- return setEvent, nil
-}
-
-func (c *Commands) getDefaultFeatures(ctx context.Context) (*domain.Features, error) {
- existingFeatures := NewInstanceFeaturesWriteModel(ctx)
- err := c.eventstore.FilterToQueryReducer(ctx, existingFeatures)
- if err != nil {
- return nil, err
- }
- features := writeModelToFeatures(&existingFeatures.FeaturesWriteModel)
- features.IsDefault = true
- return features, nil
-}
diff --git a/internal/command/instance_features_model.go b/internal/command/instance_features_model.go
deleted file mode 100644
index d91e4b743..000000000
--- a/internal/command/instance_features_model.go
+++ /dev/null
@@ -1,157 +0,0 @@
-package command
-
-import (
- "context"
- "time"
-
- "github.com/zitadel/zitadel/internal/api/authz"
- "github.com/zitadel/zitadel/internal/domain"
- "github.com/zitadel/zitadel/internal/eventstore"
- "github.com/zitadel/zitadel/internal/repository/features"
- "github.com/zitadel/zitadel/internal/repository/instance"
-)
-
-type InstanceFeaturesWriteModel struct {
- FeaturesWriteModel
-}
-
-func NewInstanceFeaturesWriteModel(ctx context.Context) *InstanceFeaturesWriteModel {
- return &InstanceFeaturesWriteModel{
- FeaturesWriteModel{
- WriteModel: eventstore.WriteModel{
- AggregateID: authz.GetInstance(ctx).InstanceID(),
- ResourceOwner: authz.GetInstance(ctx).InstanceID(),
- },
- },
- }
-}
-
-func (wm *InstanceFeaturesWriteModel) AppendEvents(events ...eventstore.Event) {
- for _, event := range events {
- switch e := event.(type) {
- case *instance.FeaturesSetEvent:
- wm.FeaturesWriteModel.AppendEvents(&e.FeaturesSetEvent)
- }
- }
-}
-
-func (wm *InstanceFeaturesWriteModel) IsValid() bool {
- return wm.AggregateID != ""
-}
-
-func (wm *InstanceFeaturesWriteModel) Reduce() error {
- return wm.FeaturesWriteModel.Reduce()
-}
-
-func (wm *InstanceFeaturesWriteModel) Query() *eventstore.SearchQueryBuilder {
- return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
- ResourceOwner(wm.ResourceOwner).
- AddQuery().
- EventTypes(instance.FeaturesSetEventType).
- AggregateTypes(instance.AggregateType).
- Builder()
-}
-
-func (wm *InstanceFeaturesWriteModel) NewSetEvent(
- ctx context.Context,
- aggregate *eventstore.Aggregate,
- tierName, tierDescription string,
- state domain.FeaturesState,
- stateDescription string,
- auditLogRetention time.Duration,
- loginPolicyFactors,
- loginPolicyIDP,
- loginPolicyPasswordless,
- loginPolicyRegistration,
- loginPolicyUsernameLogin,
- loginPolicyPasswordReset,
- passwordComplexityPolicy,
- labelPolicyPrivateLabel,
- labelPolicyWatermark,
- customDomain,
- privacyPolicy,
- metadataUser,
- customTextMessage,
- customTextLogin,
- lockoutPolicy bool,
- actionsAllowed domain.ActionsAllowed,
- maxActions int,
-) (*instance.FeaturesSetEvent, bool) {
-
- changes := make([]features.FeaturesChanges, 0)
-
- if tierName != "" && wm.TierName != tierName {
- changes = append(changes, features.ChangeTierName(tierName))
- }
- if wm.TierDescription != tierDescription {
- changes = append(changes, features.ChangeTierDescription(tierDescription))
- }
- if wm.State != state {
- changes = append(changes, features.ChangeState(state))
- }
- if wm.StateDescription != stateDescription {
- changes = append(changes, features.ChangeStateDescription(stateDescription))
- }
- if auditLogRetention != 0 && wm.AuditLogRetention != auditLogRetention {
- changes = append(changes, features.ChangeAuditLogRetention(auditLogRetention))
- }
- if wm.LoginPolicyFactors != loginPolicyFactors {
- changes = append(changes, features.ChangeLoginPolicyFactors(loginPolicyFactors))
- }
- if wm.LoginPolicyIDP != loginPolicyIDP {
- changes = append(changes, features.ChangeLoginPolicyIDP(loginPolicyIDP))
- }
- if wm.LoginPolicyPasswordless != loginPolicyPasswordless {
- changes = append(changes, features.ChangeLoginPolicyPasswordless(loginPolicyPasswordless))
- }
- if wm.LoginPolicyRegistration != loginPolicyRegistration {
- changes = append(changes, features.ChangeLoginPolicyRegistration(loginPolicyRegistration))
- }
- if wm.LoginPolicyUsernameLogin != loginPolicyUsernameLogin {
- changes = append(changes, features.ChangeLoginPolicyUsernameLogin(loginPolicyUsernameLogin))
- }
- if wm.LoginPolicyPasswordReset != loginPolicyPasswordReset {
- changes = append(changes, features.ChangeLoginPolicyPasswordReset(loginPolicyPasswordReset))
- }
- if wm.PasswordComplexityPolicy != passwordComplexityPolicy {
- changes = append(changes, features.ChangePasswordComplexityPolicy(passwordComplexityPolicy))
- }
- if wm.LabelPolicyPrivateLabel != labelPolicyPrivateLabel {
- changes = append(changes, features.ChangeLabelPolicyPrivateLabel(labelPolicyPrivateLabel))
- }
- if wm.LabelPolicyWatermark != labelPolicyWatermark {
- changes = append(changes, features.ChangeLabelPolicyWatermark(labelPolicyWatermark))
- }
- if wm.CustomDomain != customDomain {
- changes = append(changes, features.ChangeCustomDomain(customDomain))
- }
- if wm.PrivacyPolicy != privacyPolicy {
- changes = append(changes, features.ChangePrivacyPolicy(privacyPolicy))
- }
- if wm.MetadataUser != metadataUser {
- changes = append(changes, features.ChangeMetadataUser(metadataUser))
- }
- if wm.CustomTextMessage != customTextMessage {
- changes = append(changes, features.ChangeCustomTextMessage(customTextMessage))
- }
- if wm.CustomTextLogin != customTextLogin {
- changes = append(changes, features.ChangeCustomTextLogin(customTextLogin))
- }
- if wm.LockoutPolicy != lockoutPolicy {
- changes = append(changes, features.ChangeLockoutPolicy(lockoutPolicy))
- }
- if wm.ActionsAllowed != actionsAllowed {
- changes = append(changes, features.ChangeActionsAllowed(actionsAllowed))
- }
- if wm.MaxActions != maxActions {
- changes = append(changes, features.ChangeMaxActions(maxActions))
- }
- if len(changes) == 0 {
- return nil, false
- }
- changedEvent, err := instance.NewFeaturesSetEvent(ctx, aggregate, changes)
- if err != nil {
- return nil, false
- }
- return changedEvent, true
-}
diff --git a/internal/command/instance_features_test.go b/internal/command/instance_features_test.go
deleted file mode 100644
index a86432583..000000000
--- a/internal/command/instance_features_test.go
+++ /dev/null
@@ -1,152 +0,0 @@
-package command
-
-import (
- "context"
- "testing"
- "time"
-
- "github.com/zitadel/zitadel/internal/domain"
- "github.com/zitadel/zitadel/internal/errors"
- "github.com/zitadel/zitadel/internal/eventstore"
- "github.com/zitadel/zitadel/internal/repository/features"
- "github.com/zitadel/zitadel/internal/repository/instance"
-)
-
-func TestSetDefaultFeatures(t *testing.T) {
- type args struct {
- a *instance.Aggregate
- tierName string
- tierDescription string
- state domain.FeaturesState
- stateDescription string
- retention time.Duration
- loginPolicyFactors bool
- loginPolicyIDP bool
- loginPolicyPasswordless bool
- loginPolicyRegistration bool
- loginPolicyUsernameLogin bool
- loginPolicyPasswordReset bool
- passwordComplexityPolicy bool
- labelPolicyPrivateLabel bool
- labelPolicyWatermark bool
- customDomain bool
- privacyPolicy bool
- metadataUser bool
- customTextMessage bool
- customTextLogin bool
- lockoutPolicy bool
- actionsAllowed domain.ActionsAllowed
- maxActions int
- }
- tests := []struct {
- name string
- args args
- want Want
- }{
- {
- name: "invalid state",
- args: args{
- a: instance.NewAggregate("INSTANCE"),
- tierName: "",
- tierDescription: "",
- state: 0,
- stateDescription: "",
- retention: 0,
- loginPolicyFactors: false,
- loginPolicyIDP: false,
- loginPolicyPasswordless: false,
- loginPolicyRegistration: false,
- loginPolicyUsernameLogin: false,
- loginPolicyPasswordReset: false,
- passwordComplexityPolicy: false,
- labelPolicyPrivateLabel: false,
- labelPolicyWatermark: false,
- customDomain: false,
- privacyPolicy: false,
- metadataUser: false,
- customTextMessage: false,
- customTextLogin: false,
- lockoutPolicy: false,
- actionsAllowed: 0,
- maxActions: 0,
- },
- want: Want{
- ValidationErr: errors.ThrowInvalidArgument(nil, "INSTA-d3r1s", "Errors.Invalid.Argument"),
- },
- },
- {
- name: "correct",
- args: args{
- a: instance.NewAggregate("INSTANCE"),
- tierName: "",
- tierDescription: "",
- state: domain.FeaturesStateActive,
- stateDescription: "",
- retention: 0,
- loginPolicyFactors: false,
- loginPolicyIDP: false,
- loginPolicyPasswordless: false,
- loginPolicyRegistration: false,
- loginPolicyUsernameLogin: false,
- loginPolicyPasswordReset: false,
- passwordComplexityPolicy: false,
- labelPolicyPrivateLabel: false,
- labelPolicyWatermark: false,
- customDomain: false,
- privacyPolicy: false,
- metadataUser: false,
- customTextMessage: false,
- customTextLogin: false,
- lockoutPolicy: false,
- actionsAllowed: 0,
- maxActions: 0,
- },
- want: Want{
- Commands: []eventstore.Command{
- func() *instance.FeaturesSetEvent {
- event, _ := instance.NewFeaturesSetEvent(context.Background(), &instance.NewAggregate("INSTANCE").Aggregate,
- []features.FeaturesChanges{
- features.ChangeState(domain.FeaturesStateActive),
- },
- )
- return event
- }(),
- },
- },
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- AssertValidation(t, SetDefaultFeatures(
- tt.args.a,
- tt.args.tierName,
- tt.args.tierDescription,
- tt.args.state,
- tt.args.stateDescription,
- tt.args.retention,
- tt.args.loginPolicyFactors,
- tt.args.loginPolicyIDP,
- tt.args.loginPolicyPasswordless,
- tt.args.loginPolicyRegistration,
- tt.args.loginPolicyUsernameLogin,
- tt.args.loginPolicyPasswordReset,
- tt.args.passwordComplexityPolicy,
- tt.args.labelPolicyPrivateLabel,
- tt.args.labelPolicyWatermark,
- tt.args.customDomain,
- tt.args.privacyPolicy,
- tt.args.metadataUser,
- tt.args.customTextMessage,
- tt.args.customTextLogin,
- tt.args.lockoutPolicy,
- tt.args.actionsAllowed,
- tt.args.maxActions,
- ), NewMultiFilter().
- Append(func(ctx context.Context, queryFactory *eventstore.SearchQueryBuilder) ([]eventstore.Event, error) {
- return nil, nil
- }).
- Filter(),
- tt.want)
- })
- }
-}
diff --git a/internal/command/main_test.go b/internal/command/main_test.go
index aa45f1c7d..06391db01 100644
--- a/internal/command/main_test.go
+++ b/internal/command/main_test.go
@@ -9,9 +9,7 @@ import (
"github.com/golang/mock/gomock"
"golang.org/x/text/language"
- "github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/crypto"
- "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/eventstore/repository/mock"
@@ -213,51 +211,6 @@ func GetMockSecretGenerator(t *testing.T) crypto.Generator {
return generator
}
-func GetMockVerifier(t *testing.T, features ...string) *testVerifier {
- return &testVerifier{
- features: features,
- }
-}
-
-type testVerifier struct {
- features []string
-}
-
-func (v *testVerifier) VerifyAccessToken(ctx context.Context, token, clientID string) (string, string, string, string, string, error) {
- return "userID", "agentID", "clientID", "de", "orgID", nil
-}
-func (v *testVerifier) SearchMyMemberships(ctx context.Context) ([]*authz.Membership, error) {
- return nil, nil
-}
-
-func (v *testVerifier) ProjectIDAndOriginsByClientID(ctx context.Context, clientID string) (string, []string, error) {
- return "", nil, nil
-}
-
-func (v *testVerifier) ExistsOrg(ctx context.Context, orgID string) error {
- return nil
-}
-
-func (v *testVerifier) VerifierClientID(ctx context.Context, appName string) (string, error) {
- return "clientID", nil
-}
-
-func (v *testVerifier) CheckOrgFeatures(ctx context.Context, orgID string, requiredFeatures ...string) error {
- for _, feature := range requiredFeatures {
- hasFeature := false
- for _, f := range v.features {
- if f == feature {
- hasFeature = true
- break
- }
- }
- if !hasFeature {
- return errors.ThrowPermissionDenied(nil, "id", "missing feature")
- }
- }
- return nil
-}
-
type mockInstance struct{}
func (m *mockInstance) InstanceID() string {
diff --git a/internal/command/org_action.go b/internal/command/org_action.go
index fe1971bba..aeeb5f587 100644
--- a/internal/command/org_action.go
+++ b/internal/command/org_action.go
@@ -15,10 +15,6 @@ func (c *Commands) AddAction(ctx context.Context, addAction *domain.Action, reso
if !addAction.IsValid() {
return "", nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-eg2gf", "Errors.Action.Invalid")
}
- err = c.checkAdditionalActionAllowed(ctx, resourceOwner)
- if err != nil {
- return "", nil, err
- }
addAction.AggregateID, err = c.idGenerator.Next()
if err != nil {
return "", nil, err
@@ -44,27 +40,6 @@ func (c *Commands) AddAction(ctx context.Context, addAction *domain.Action, reso
return actionModel.AggregateID, writeModelToObjectDetails(&actionModel.WriteModel), nil
}
-func (c *Commands) checkAdditionalActionAllowed(ctx context.Context, resourceOwner string) error {
- features, err := c.getOrgFeaturesOrDefault(ctx, resourceOwner)
- if err != nil {
- return err
- }
- existingActions, err := c.getActionsByOrgWriteModelByID(ctx, resourceOwner)
- if err != nil {
- return err
- }
- activeActions := make([]*ActionWriteModel, 0, len(existingActions.Actions))
- for _, existingAction := range existingActions.Actions {
- if existingAction.State == domain.ActionStateActive {
- activeActions = append(activeActions, existingAction)
- }
- }
- if features.ActionsAllowed == domain.ActionsAllowedUnlimited || len(activeActions) < features.MaxActions {
- return nil
- }
- return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-dfwg2", "Errors.Action.MaxAllowed")
-}
-
func (c *Commands) ChangeAction(ctx context.Context, actionChange *domain.Action, resourceOwner string) (*domain.ObjectDetails, error) {
if !actionChange.IsValid() || actionChange.AggregateID == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-Df2f3", "Errors.Action.Invalid")
@@ -145,10 +120,6 @@ func (c *Commands) ReactivateAction(ctx context.Context, actionID string, resour
if existingAction.State != domain.ActionStateInactive {
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-J53zh", "Errors.Action.NotInactive")
}
- err = c.checkAdditionalActionAllowed(ctx, resourceOwner)
- if err != nil {
- return nil, err
- }
actionAgg := ActionAggregateFromWriteModel(&existingAction.WriteModel)
events := []eventstore.Command{
diff --git a/internal/command/org_action_test.go b/internal/command/org_action_test.go
index 350ae0078..dadb64261 100644
--- a/internal/command/org_action_test.go
+++ b/internal/command/org_action_test.go
@@ -6,8 +6,6 @@ import (
"github.com/stretchr/testify/assert"
- "github.com/zitadel/zitadel/internal/repository/features"
-
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
@@ -56,76 +54,10 @@ func TestCommands_AddAction(t *testing.T) {
err: errors.IsErrorInvalidArgument,
},
},
- {
- "no additional allowed, error",
- fields{
- eventstore: eventstoreExpect(t,
- expectFilter(
- eventFromEventPusher(
- func() eventstore.Command {
- e, _ := org.NewFeaturesSetEvent(context.Background(),
- &org.NewAggregate("org1").Aggregate,
- []features.FeaturesChanges{
- features.ChangeMaxActions(1),
- },
- )
- return e
- }(),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- action.NewAddedEvent(context.Background(),
- &action.NewAggregate("id1", "org1").Aggregate,
- "name",
- "name() {};",
- 0,
- false,
- ),
- ),
- ),
- ),
- },
- args{
- ctx: context.Background(),
- addAction: &domain.Action{
- Name: "name",
- Script: "name() {};",
- },
- resourceOwner: "org1",
- },
- res{
- err: errors.IsPreconditionFailed,
- },
- },
{
"unique constraint failed, error",
fields{
eventstore: eventstoreExpect(t,
- expectFilter(
- eventFromEventPusher(
- func() eventstore.Command {
- e, _ := org.NewFeaturesSetEvent(context.Background(),
- &org.NewAggregate("org1").Aggregate,
- []features.FeaturesChanges{
- features.ChangeMaxActions(2),
- },
- )
- return e
- }(),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- action.NewAddedEvent(context.Background(),
- &action.NewAggregate("id1", "org1").Aggregate,
- "name",
- "name() {};",
- 0,
- false,
- ),
- ),
- ),
expectPushFailed(
errors.ThrowPreconditionFailed(nil, "id", "name already exists"),
[]*repository.Event{
@@ -160,30 +92,6 @@ func TestCommands_AddAction(t *testing.T) {
"push ok",
fields{
eventstore: eventstoreExpect(t,
- expectFilter(
- eventFromEventPusher(
- func() eventstore.Command {
- e, _ := org.NewFeaturesSetEvent(context.Background(),
- &org.NewAggregate("org1").Aggregate,
- []features.FeaturesChanges{
- features.ChangeMaxActions(2),
- },
- )
- return e
- }(),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- action.NewAddedEvent(context.Background(),
- &action.NewAggregate("id1", "org1").Aggregate,
- "name",
- "name() {};",
- 0,
- false,
- ),
- ),
- ),
expectPush(
[]*repository.Event{
eventFromEventPusher(
@@ -663,94 +571,10 @@ func TestCommands_ReactivateAction(t *testing.T) {
err: errors.IsPreconditionFailed,
},
},
- {
- "no additional allowed, error",
- fields{
- eventstore: eventstoreExpect(t,
- expectFilter(
- eventFromEventPusher(
- action.NewAddedEvent(context.Background(),
- &action.NewAggregate("id1", "org1").Aggregate,
- "name",
- "name() {};",
- 0,
- false,
- ),
- ),
- eventFromEventPusher(
- action.NewDeactivatedEvent(context.Background(),
- &action.NewAggregate("id1", "org1").Aggregate,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- func() eventstore.Command {
- e, _ := org.NewFeaturesSetEvent(context.Background(),
- &org.NewAggregate("org1").Aggregate,
- []features.FeaturesChanges{
- features.ChangeMaxActions(1),
- },
- )
- return e
- }(),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- action.NewAddedEvent(context.Background(),
- &action.NewAggregate("id2", "org1").Aggregate,
- "name2",
- "name2() {};",
- 0,
- false,
- ),
- ),
- ),
- ),
- },
- args{
- ctx: context.Background(),
- actionID: "id1",
- resourceOwner: "org1",
- },
- res{
- err: errors.IsPreconditionFailed,
- },
- },
{
"reactivate ok",
fields{
eventstore: eventstoreExpect(t,
- expectFilter(
- eventFromEventPusher(
- action.NewAddedEvent(context.Background(),
- &action.NewAggregate("id1", "org1").Aggregate,
- "name",
- "name() {};",
- 0,
- false,
- ),
- ),
- eventFromEventPusher(
- action.NewDeactivatedEvent(context.Background(),
- &action.NewAggregate("id1", "org1").Aggregate,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- func() eventstore.Command {
- e, _ := org.NewFeaturesSetEvent(context.Background(),
- &org.NewAggregate("org1").Aggregate,
- []features.FeaturesChanges{
- features.ChangeMaxActions(1),
- },
- )
- return e
- }(),
- ),
- ),
expectFilter(
eventFromEventPusher(
action.NewAddedEvent(context.Background(),
diff --git a/internal/command/org_features.go b/internal/command/org_features.go
deleted file mode 100644
index bbc4a0551..000000000
--- a/internal/command/org_features.go
+++ /dev/null
@@ -1,393 +0,0 @@
-package command
-
-import (
- "context"
-
- "github.com/zitadel/zitadel/internal/domain"
- caos_errs "github.com/zitadel/zitadel/internal/errors"
- "github.com/zitadel/zitadel/internal/eventstore"
- "github.com/zitadel/zitadel/internal/repository/org"
-)
-
-func (c *Commands) SetOrgFeatures(ctx context.Context, resourceOwner string, features *domain.Features) (*domain.ObjectDetails, error) {
- if resourceOwner == "" {
- return nil, caos_errs.ThrowInvalidArgument(nil, "Features-G5tg", "Errors.ResourceOwnerMissing")
- }
- err := c.checkOrgExists(ctx, resourceOwner)
- if err != nil {
- return nil, err
- }
- existingFeatures := NewOrgFeaturesWriteModel(resourceOwner)
- err = c.eventstore.FilterToQueryReducer(ctx, existingFeatures)
- if err != nil {
- return nil, err
- }
- setEvent, hasChanged := existingFeatures.NewSetEvent(
- ctx,
- OrgAggregateFromWriteModel(&existingFeatures.FeaturesWriteModel.WriteModel),
- features.TierName,
- features.TierDescription,
- features.State,
- features.StateDescription,
- features.AuditLogRetention,
- features.LoginPolicyFactors,
- features.LoginPolicyIDP,
- features.LoginPolicyPasswordless,
- features.LoginPolicyRegistration,
- features.LoginPolicyUsernameLogin,
- features.LoginPolicyPasswordReset,
- features.PasswordComplexityPolicy,
- features.LabelPolicyPrivateLabel,
- features.LabelPolicyWatermark,
- features.CustomDomain,
- features.PrivacyPolicy,
- features.MetadataUser,
- features.CustomTextMessage,
- features.CustomTextLogin,
- features.LockoutPolicy,
- features.ActionsAllowed,
- features.MaxActions,
- )
- if !hasChanged {
- return nil, caos_errs.ThrowPreconditionFailed(nil, "Features-GE4h2", "Errors.Features.NotChanged")
- }
-
- events, err := c.ensureOrgSettingsToFeatures(ctx, resourceOwner, features)
- if err != nil {
- return nil, err
- }
- events = append(events, setEvent)
-
- pushedEvents, err := c.eventstore.Push(ctx, events...)
- if err != nil {
- return nil, err
- }
- err = AppendAndReduce(existingFeatures, pushedEvents...)
- if err != nil {
- return nil, err
- }
- return writeModelToObjectDetails(&existingFeatures.WriteModel), nil
-}
-
-func (c *Commands) RemoveOrgFeatures(ctx context.Context, orgID string) (*domain.ObjectDetails, error) {
- if orgID == "" {
- return nil, caos_errs.ThrowInvalidArgument(nil, "Features-G5tg", "Errors.ResourceOwnerMissing")
- }
- existingFeatures := NewOrgFeaturesWriteModel(orgID)
- err := c.eventstore.FilterToQueryReducer(ctx, existingFeatures)
- if err != nil {
- return nil, err
- }
- if existingFeatures.State == domain.FeaturesStateUnspecified || existingFeatures.State == domain.FeaturesStateRemoved {
- return nil, caos_errs.ThrowNotFound(nil, "Features-Bg32G", "Errors.Features.NotFound")
- }
- removedEvent := org.NewFeaturesRemovedEvent(ctx, OrgAggregateFromWriteModel(&existingFeatures.FeaturesWriteModel.WriteModel))
-
- features, err := c.getDefaultFeatures(ctx)
- if err != nil {
- return nil, err
- }
- events, err := c.ensureOrgSettingsToFeatures(ctx, orgID, features)
- if err != nil {
- return nil, err
- }
-
- events = append(events, removedEvent)
- pushedEvents, err := c.eventstore.Push(ctx, events...)
- if err != nil {
- return nil, err
- }
- err = AppendAndReduce(existingFeatures, pushedEvents...)
- if err != nil {
- return nil, err
- }
- return writeModelToObjectDetails(&existingFeatures.WriteModel), nil
-}
-
-func (c *Commands) ensureOrgSettingsToFeatures(ctx context.Context, orgID string, features *domain.Features) ([]eventstore.Command, error) {
- events, err := c.setAllowedLoginPolicy(ctx, orgID, features)
- if err != nil {
- return nil, err
- }
- if !features.PasswordComplexityPolicy {
- removePasswordComplexityEvent, err := c.removePasswordComplexityPolicyIfExists(ctx, orgID)
- if err != nil {
- return nil, err
- }
- if removePasswordComplexityEvent != nil {
- events = append(events, removePasswordComplexityEvent)
- }
- }
- labelPolicyEvents, err := c.setAllowedLabelPolicy(ctx, orgID, features)
- if err != nil {
- return nil, err
- }
- events = append(events, labelPolicyEvents...)
-
- if !features.CustomDomain {
- removeCustomDomainsEvents, err := c.removeCustomDomains(ctx, orgID)
- if err != nil {
- return nil, err
- }
- if removeCustomDomainsEvents != nil {
- events = append(events, removeCustomDomainsEvents...)
- }
- }
- if !features.CustomTextMessage {
- removeCustomMessageTextEvents, err := c.removeOrgMessageTextsIfExists(ctx, orgID)
- if err != nil {
- return nil, err
- }
- if removeCustomMessageTextEvents != nil {
- events = append(events, removeCustomMessageTextEvents...)
- }
- }
- if !features.CustomTextLogin {
- removeCustomLoginTextEvents, err := c.removeOrgLoginTextsIfExists(ctx, orgID)
- if err != nil {
- return nil, err
- }
- if removeCustomLoginTextEvents != nil {
- events = append(events, removeCustomLoginTextEvents...)
- }
- }
- if !features.PrivacyPolicy {
- removePrivacyPolicyEvent, err := c.removePrivacyPolicyIfExists(ctx, orgID)
- if err != nil {
- return nil, err
- }
- if removePrivacyPolicyEvent != nil {
- events = append(events, removePrivacyPolicyEvent)
- }
- }
- if !features.LockoutPolicy {
- removeLockoutPolicyEvent, err := c.removeLockoutPolicyIfExists(ctx, orgID)
- if err != nil {
- return nil, err
- }
- if removeLockoutPolicyEvent != nil {
- events = append(events, removeLockoutPolicyEvent)
- }
- }
- if !features.MetadataUser {
- removeOrgUserMetadatas, err := c.removeUserMetadataFromOrg(ctx, orgID)
- if err != nil {
- return nil, err
- }
- if len(removeOrgUserMetadatas) > 0 {
- events = append(events, removeOrgUserMetadatas...)
- }
- }
- if features.ActionsAllowed == domain.ActionsNotAllowed {
- removeOrgActions, err := c.removeActionsFromOrg(ctx, orgID)
- if err != nil {
- return nil, err
- }
- if len(removeOrgActions) > 0 {
- events = append(events, removeOrgActions...)
- }
- }
- if features.ActionsAllowed == domain.ActionsMaxAllowed {
- deactivateActions, err := c.deactivateNotAllowedActionsFromOrg(ctx, orgID, features.MaxActions)
- if err != nil {
- return nil, err
- }
- if len(deactivateActions) > 0 {
- events = append(events, deactivateActions...)
- }
- }
- return events, nil
-}
-
-func (c *Commands) setAllowedLoginPolicy(ctx context.Context, orgID string, features *domain.Features) ([]eventstore.Command, error) {
- events := make([]eventstore.Command, 0)
- existingPolicy, err := c.orgLoginPolicyWriteModelByID(ctx, orgID)
- if err != nil {
- return nil, err
- }
- if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
- return nil, nil
- }
- defaultPolicy, err := c.getDefaultLoginPolicy(ctx)
- if err != nil {
- return nil, err
- }
- policy := *existingPolicy
- if !features.LoginPolicyFactors {
- if defaultPolicy.ForceMFA != existingPolicy.ForceMFA {
- policy.ForceMFA = defaultPolicy.ForceMFA
- }
- authFactorsEvents, err := c.setDefaultAuthFactorsInCustomLoginPolicy(ctx, orgID)
- if err != nil {
- return nil, err
- }
- events = append(events, authFactorsEvents...)
- }
- if !features.LoginPolicyIDP {
- if defaultPolicy.AllowExternalIDP != existingPolicy.AllowExternalIDP {
- policy.AllowExternalIDP = defaultPolicy.AllowExternalIDP
- }
- //TODO: handle idps
- }
- if !features.LoginPolicyRegistration && defaultPolicy.AllowRegister != existingPolicy.AllowRegister {
- policy.AllowRegister = defaultPolicy.AllowRegister
- }
- if !features.LoginPolicyPasswordless && defaultPolicy.PasswordlessType != existingPolicy.PasswordlessType {
- policy.PasswordlessType = defaultPolicy.PasswordlessType
- }
- if !features.LoginPolicyUsernameLogin && defaultPolicy.AllowUsernamePassword != existingPolicy.AllowUserNamePassword {
- policy.AllowUserNamePassword = defaultPolicy.AllowUsernamePassword
- }
- if !features.LoginPolicyPasswordReset && defaultPolicy.HidePasswordReset != existingPolicy.HidePasswordReset {
- policy.HidePasswordReset = defaultPolicy.HidePasswordReset
- }
- changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx,
- OrgAggregateFromWriteModel(&existingPolicy.WriteModel),
- policy.AllowUserNamePassword,
- policy.AllowRegister,
- policy.AllowExternalIDP,
- policy.ForceMFA,
- policy.HidePasswordReset,
- policy.PasswordlessType,
- policy.PasswordCheckLifetime,
- policy.ExternalLoginCheckLifetime,
- policy.MFAInitSkipLifetime,
- policy.SecondFactorCheckLifetime,
- policy.MultiFactorCheckLifetime)
- if hasChanged {
- events = append(events, changedEvent)
- }
- return events, nil
-}
-
-func (c *Commands) setDefaultAuthFactorsInCustomLoginPolicy(ctx context.Context, orgID string) ([]eventstore.Command, error) {
- orgAuthFactors, err := c.orgLoginPolicyAuthFactorsWriteModel(ctx, orgID)
- if err != nil {
- return nil, err
- }
- events := make([]eventstore.Command, 0)
- for _, factor := range domain.SecondFactorTypes() {
- state := orgAuthFactors.SecondFactors[factor]
- if state == nil || state.IAM == state.Org {
- continue
- }
- secondFactorWriteModel := orgAuthFactors.ToSecondFactorWriteModel(factor)
- if state.IAM == domain.FactorStateActive {
- event, err := c.addSecondFactorToLoginPolicy(ctx, secondFactorWriteModel, factor)
- if err != nil {
- return nil, err
- }
- if event != nil {
- events = append(events, event)
- }
- continue
- }
- event, err := c.removeSecondFactorFromLoginPolicy(ctx, secondFactorWriteModel, factor)
- if err != nil {
- return nil, err
- }
- if event != nil {
- events = append(events, event)
- }
- }
-
- for _, factor := range domain.MultiFactorTypes() {
- state := orgAuthFactors.MultiFactors[factor]
- if state == nil || state.IAM == state.Org {
- continue
- }
- multiFactorWriteModel := orgAuthFactors.ToMultiFactorWriteModel(factor)
- if state.IAM == domain.FactorStateActive {
- event, err := c.addMultiFactorToLoginPolicy(ctx, multiFactorWriteModel, factor)
- if err != nil {
- return nil, err
- }
- if event != nil {
- events = append(events, event)
- }
- continue
- }
- event, err := c.removeMultiFactorFromLoginPolicy(ctx, multiFactorWriteModel, factor)
- if err != nil {
- return nil, err
- }
- if event != nil {
- events = append(events, event)
- }
- }
- return events, nil
-}
-
-func (c *Commands) setAllowedLabelPolicy(ctx context.Context, orgID string, features *domain.Features) ([]eventstore.Command, error) {
- events := make([]eventstore.Command, 0)
- existingPolicy, err := c.orgLabelPolicyWriteModelByID(ctx, orgID)
- if err != nil {
- return nil, err
- }
- if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
- return nil, nil
- }
- if !features.LabelPolicyPrivateLabel && !features.LabelPolicyWatermark {
- removeEvent, err := c.removeLabelPolicy(ctx, existingPolicy)
- if err != nil {
- return nil, err
- }
- return append(events, removeEvent), nil
- }
- defaultPolicy, err := c.getDefaultLabelPolicy(ctx)
- if err != nil {
- return nil, err
- }
- policy := *existingPolicy
- if !features.LabelPolicyWatermark && defaultPolicy.DisableWatermark != existingPolicy.DisableWatermark {
- policy.DisableWatermark = defaultPolicy.DisableWatermark
- }
- if !features.LabelPolicyPrivateLabel {
- if defaultPolicy.HideLoginNameSuffix != existingPolicy.HideLoginNameSuffix {
- policy.HideLoginNameSuffix = defaultPolicy.HideLoginNameSuffix
- }
- policy.PrimaryColor = ""
- policy.BackgroundColor = ""
- policy.WarnColor = ""
- policy.FontColor = ""
- policy.PrimaryColorDark = ""
- policy.BackgroundColorDark = ""
- policy.WarnColorDark = ""
- policy.FontColorDark = ""
-
- assetsEvent, err := c.removeLabelPolicyAssets(ctx, existingPolicy)
- if err != nil {
- return nil, err
- }
- events = append(events, assetsEvent)
- }
- changedEvent, hasChangedEvent := existingPolicy.NewChangedEvent(ctx, OrgAggregateFromWriteModel(&existingPolicy.WriteModel),
- policy.PrimaryColor, policy.BackgroundColor, policy.WarnColor, policy.FontColor,
- policy.PrimaryColorDark, policy.BackgroundColorDark, policy.WarnColorDark, policy.FontColorDark,
- policy.HideLoginNameSuffix, policy.ErrorMsgPopup, policy.HideLoginNameSuffix)
- if hasChangedEvent {
- events = append(events, changedEvent)
- }
- if len(events) > 0 {
- events = append(events, org.NewLabelPolicyActivatedEvent(ctx, OrgAggregateFromWriteModel(&existingPolicy.WriteModel)))
- }
- return events, nil
-}
-
-func (c *Commands) getOrgFeaturesOrDefault(ctx context.Context, orgID string) (*domain.Features, error) {
- existingFeatures := NewOrgFeaturesWriteModel(orgID)
- err := c.eventstore.FilterToQueryReducer(ctx, existingFeatures)
- if err != nil {
- return nil, err
- }
- if existingFeatures.State != domain.FeaturesStateUnspecified && existingFeatures.State != domain.FeaturesStateRemoved {
- return writeModelToFeatures(&existingFeatures.FeaturesWriteModel), nil
- }
-
- existingIAMFeatures := NewInstanceFeaturesWriteModel(ctx)
- err = c.eventstore.FilterToQueryReducer(ctx, existingIAMFeatures)
- if err != nil {
- return nil, err
- }
- return writeModelToFeatures(&existingIAMFeatures.FeaturesWriteModel), nil
-}
diff --git a/internal/command/org_features_model.go b/internal/command/org_features_model.go
deleted file mode 100644
index 0b6e0b7db..000000000
--- a/internal/command/org_features_model.go
+++ /dev/null
@@ -1,163 +0,0 @@
-package command
-
-import (
- "context"
- "time"
-
- "github.com/zitadel/zitadel/internal/domain"
- "github.com/zitadel/zitadel/internal/eventstore"
- "github.com/zitadel/zitadel/internal/repository/features"
- "github.com/zitadel/zitadel/internal/repository/org"
-)
-
-type OrgFeaturesWriteModel struct {
- FeaturesWriteModel
-}
-
-func NewOrgFeaturesWriteModel(orgID string) *OrgFeaturesWriteModel {
- return &OrgFeaturesWriteModel{
- FeaturesWriteModel{
- WriteModel: eventstore.WriteModel{
- AggregateID: orgID,
- ResourceOwner: orgID,
- },
- },
- }
-}
-
-func (wm *OrgFeaturesWriteModel) AppendEvents(events ...eventstore.Event) {
- for _, event := range events {
- switch e := event.(type) {
- case *org.FeaturesSetEvent:
- wm.FeaturesWriteModel.AppendEvents(&e.FeaturesSetEvent)
- case *org.FeaturesRemovedEvent:
- wm.FeaturesWriteModel.AppendEvents(&e.FeaturesRemovedEvent)
- }
- }
-}
-
-func (wm *OrgFeaturesWriteModel) IsValid() bool {
- return wm.AggregateID != ""
-}
-
-func (wm *OrgFeaturesWriteModel) Reduce() error {
- return wm.FeaturesWriteModel.Reduce()
-}
-
-func (wm *OrgFeaturesWriteModel) Query() *eventstore.SearchQueryBuilder {
- return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
- ResourceOwner(wm.ResourceOwner).
- AddQuery().
- AggregateTypes(org.AggregateType).
- AggregateIDs(wm.FeaturesWriteModel.AggregateID).
- EventTypes(
- org.FeaturesSetEventType,
- org.FeaturesRemovedEventType).
- Builder()
-}
-
-func (wm *OrgFeaturesWriteModel) NewSetEvent(
- ctx context.Context,
- aggregate *eventstore.Aggregate,
- tierName,
- tierDescription string,
- state domain.FeaturesState,
- stateDescription string,
- auditLogRetention time.Duration,
- loginPolicyFactors,
- loginPolicyIDP,
- loginPolicyPasswordless,
- loginPolicyRegistration,
- loginPolicyUsernameLogin,
- loginPolicyPasswordReset,
- passwordComplexityPolicy,
- labelPolicyPrivateLabel,
- labelPolicyWatermark,
- customDomain,
- privacyPolicy,
- metadataUser,
- customTextMessage,
- customTextLogin,
- lockoutPolicy bool,
- actionsAllowed domain.ActionsAllowed,
- maxActions int,
-) (*org.FeaturesSetEvent, bool) {
-
- changes := make([]features.FeaturesChanges, 0)
-
- if tierName != "" && wm.TierName != tierName {
- changes = append(changes, features.ChangeTierName(tierName))
- }
- if wm.TierDescription != tierDescription {
- changes = append(changes, features.ChangeTierDescription(tierDescription))
- }
- if wm.State != state {
- changes = append(changes, features.ChangeState(state))
- }
- if stateDescription != "" && wm.StateDescription != stateDescription {
- changes = append(changes, features.ChangeStateDescription(stateDescription))
- }
- if auditLogRetention != 0 && wm.AuditLogRetention != auditLogRetention {
- changes = append(changes, features.ChangeAuditLogRetention(auditLogRetention))
- }
- if wm.LoginPolicyFactors != loginPolicyFactors {
- changes = append(changes, features.ChangeLoginPolicyFactors(loginPolicyFactors))
- }
- if wm.LoginPolicyIDP != loginPolicyIDP {
- changes = append(changes, features.ChangeLoginPolicyIDP(loginPolicyIDP))
- }
- if wm.LoginPolicyPasswordless != loginPolicyPasswordless {
- changes = append(changes, features.ChangeLoginPolicyPasswordless(loginPolicyPasswordless))
- }
- if wm.LoginPolicyRegistration != loginPolicyRegistration {
- changes = append(changes, features.ChangeLoginPolicyRegistration(loginPolicyRegistration))
- }
- if wm.LoginPolicyUsernameLogin != loginPolicyUsernameLogin {
- changes = append(changes, features.ChangeLoginPolicyUsernameLogin(loginPolicyUsernameLogin))
- }
- if wm.LoginPolicyPasswordReset != loginPolicyPasswordReset {
- changes = append(changes, features.ChangeLoginPolicyPasswordReset(loginPolicyPasswordReset))
- }
- if wm.PasswordComplexityPolicy != passwordComplexityPolicy {
- changes = append(changes, features.ChangePasswordComplexityPolicy(passwordComplexityPolicy))
- }
- if wm.LabelPolicyPrivateLabel != labelPolicyPrivateLabel {
- changes = append(changes, features.ChangeLabelPolicyPrivateLabel(labelPolicyPrivateLabel))
- }
- if wm.LabelPolicyWatermark != labelPolicyWatermark {
- changes = append(changes, features.ChangeLabelPolicyWatermark(labelPolicyWatermark))
- }
- if wm.CustomDomain != customDomain {
- changes = append(changes, features.ChangeCustomDomain(customDomain))
- }
- if wm.PrivacyPolicy != privacyPolicy {
- changes = append(changes, features.ChangePrivacyPolicy(privacyPolicy))
- }
- if wm.MetadataUser != metadataUser {
- changes = append(changes, features.ChangeMetadataUser(metadataUser))
- }
- if wm.CustomTextMessage != customTextMessage {
- changes = append(changes, features.ChangeCustomTextMessage(customTextMessage))
- }
- if wm.CustomTextLogin != customTextLogin {
- changes = append(changes, features.ChangeCustomTextLogin(customTextLogin))
- }
- if wm.LockoutPolicy != lockoutPolicy {
- changes = append(changes, features.ChangeLockoutPolicy(lockoutPolicy))
- }
- if wm.ActionsAllowed != actionsAllowed {
- changes = append(changes, features.ChangeActionsAllowed(actionsAllowed))
- }
- if wm.MaxActions != maxActions {
- changes = append(changes, features.ChangeMaxActions(maxActions))
- }
-
- if len(changes) == 0 {
- return nil, false
- }
- changedEvent, err := org.NewFeaturesSetEvent(ctx, aggregate, changes)
- if err != nil {
- return nil, false
- }
- return changedEvent, true
-}
diff --git a/internal/command/org_features_test.go b/internal/command/org_features_test.go
deleted file mode 100644
index 4aaccf098..000000000
--- a/internal/command/org_features_test.go
+++ /dev/null
@@ -1,1764 +0,0 @@
-package command
-
-import (
- "context"
- "testing"
- "time"
-
- "github.com/golang/mock/gomock"
- "github.com/stretchr/testify/assert"
- "golang.org/x/text/language"
-
- "github.com/zitadel/zitadel/internal/api/authz"
- "github.com/zitadel/zitadel/internal/domain"
- caos_errs "github.com/zitadel/zitadel/internal/errors"
- "github.com/zitadel/zitadel/internal/eventstore"
- "github.com/zitadel/zitadel/internal/eventstore/repository"
- "github.com/zitadel/zitadel/internal/repository/features"
- "github.com/zitadel/zitadel/internal/repository/instance"
- "github.com/zitadel/zitadel/internal/repository/org"
- "github.com/zitadel/zitadel/internal/repository/user"
- "github.com/zitadel/zitadel/internal/static"
- "github.com/zitadel/zitadel/internal/static/mock"
-)
-
-func TestCommandSide_SetOrgFeatures(t *testing.T) {
- type fields struct {
- eventstore *eventstore.Eventstore
- static static.Storage
- }
- type args struct {
- ctx context.Context
- resourceOwner string
- features *domain.Features
- }
- type res struct {
- want *domain.ObjectDetails
- err func(error) bool
- }
- tests := []struct {
- name string
- fields fields
- args args
- res res
- }{
- {
- name: "resourceowner missing, error",
- fields: fields{
- eventstore: eventstoreExpect(
- t,
- ),
- },
- args: args{
- ctx: context.Background(),
- features: &domain.Features{
- TierName: "Test",
- State: domain.FeaturesStateActive,
- AuditLogRetention: time.Hour,
- LoginPolicyFactors: false,
- LoginPolicyIDP: false,
- LoginPolicyPasswordless: false,
- LoginPolicyRegistration: false,
- LoginPolicyUsernameLogin: false,
- LoginPolicyPasswordReset: false,
- PasswordComplexityPolicy: false,
- LabelPolicyPrivateLabel: false,
- LabelPolicyWatermark: false,
- CustomDomain: false,
- },
- },
- res: res{
- err: caos_errs.IsErrorInvalidArgument,
- },
- },
- {
- name: "no change, error",
- fields: fields{
- eventstore: eventstoreExpect(
- t,
- expectFilter(
- eventFromEventPusher(
- newFeaturesSetEvent(context.Background(), "org1", "Test", domain.FeaturesStateActive, time.Hour),
- ),
- ),
- ),
- },
- args: args{
- ctx: context.Background(),
- resourceOwner: "org1",
- features: &domain.Features{
- TierName: "Test",
- State: domain.FeaturesStateActive,
- AuditLogRetention: time.Hour,
- LoginPolicyFactors: false,
- LoginPolicyIDP: false,
- LoginPolicyPasswordless: false,
- LoginPolicyRegistration: false,
- LoginPolicyUsernameLogin: false,
- LoginPolicyPasswordReset: false,
- PasswordComplexityPolicy: false,
- LabelPolicyPrivateLabel: false,
- LabelPolicyWatermark: false,
- CustomDomain: false,
- MetadataUser: false,
- },
- },
- res: res{
- err: caos_errs.IsPreconditionFailed,
- },
- },
- {
- name: "org does not exist, error",
- fields: fields{
- eventstore: eventstoreExpect(
- t,
- expectFilter(),
- ),
- },
- args: args{
- ctx: context.Background(),
- resourceOwner: "org1",
- features: &domain.Features{
- TierName: "Test",
- State: domain.FeaturesStateActive,
- AuditLogRetention: time.Hour,
- LoginPolicyFactors: false,
- LoginPolicyIDP: false,
- LoginPolicyPasswordless: false,
- LoginPolicyRegistration: false,
- LoginPolicyUsernameLogin: false,
- LoginPolicyPasswordReset: false,
- PasswordComplexityPolicy: false,
- LabelPolicyPrivateLabel: false,
- LabelPolicyWatermark: false,
- CustomDomain: false,
- MetadataUser: false,
- },
- },
- res: res{
- err: caos_errs.IsPreconditionFailed,
- },
- },
- {
- name: "set with default policies, ok",
- fields: fields{
- eventstore: eventstoreExpect(
- t,
- expectFilter(
- eventFromEventPusher(
- org.NewOrgAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1",
- ),
- ),
- ),
- expectFilter(),
- expectFilter(
- eventFromEventPusher(
- instance.NewLoginPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- false,
- false,
- false,
- false,
- false,
- domain.PasswordlessTypeAllowed,
- time.Hour*1,
- time.Hour*2,
- time.Hour*3,
- time.Hour*4,
- time.Hour*5,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewPasswordComplexityPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- 8,
- false,
- false,
- false,
- false,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewLabelPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "primary",
- "secondary",
- "warn",
- "font",
- "primary-dark",
- "secondary-dark",
- "warn-dark",
- "font-dark",
- false,
- false,
- false,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- org.NewOrgAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainVerifiedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainPrimarySetEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewCustomTextSetEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- domain.InitCodeMessageType,
- domain.MessageSubject,
- "text",
- language.English,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewCustomTextSetEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- domain.LoginCustomText,
- domain.LoginKeyExternalRegistrationUserOverviewTitle,
- "text",
- language.English,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewPrivacyPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "toslink",
- "privacylink",
- "helpLink",
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewLockoutPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- 5,
- false,
- ),
- ),
- ),
- expectFilter(),
- expectFilter(),
- expectPush(
- []*repository.Event{
- eventFromEventPusher(
- newFeaturesSetEvent(context.Background(), "org1", "Test", domain.FeaturesStateActive, time.Hour),
- ),
- },
- ),
- ),
- },
- args: args{
- ctx: authz.WithRequestedDomain(context.Background(), "iam-domain"),
- resourceOwner: "org1",
- features: &domain.Features{
- TierName: "Test",
- State: domain.FeaturesStateActive,
- AuditLogRetention: time.Hour,
- LoginPolicyFactors: false,
- LoginPolicyIDP: false,
- LoginPolicyPasswordless: false,
- LoginPolicyRegistration: false,
- LoginPolicyUsernameLogin: false,
- LoginPolicyPasswordReset: false,
- PasswordComplexityPolicy: false,
- LabelPolicyPrivateLabel: false,
- LabelPolicyWatermark: false,
- CustomDomain: false,
- CustomTextMessage: false,
- CustomTextLogin: false,
- PrivacyPolicy: false,
- MetadataUser: false,
- LockoutPolicy: false,
- ActionsAllowed: domain.ActionsNotAllowed,
- },
- },
- res: res{
- want: &domain.ObjectDetails{
- ResourceOwner: "org1",
- },
- },
- },
- {
- name: "set with default policies, custom domains, ok",
- fields: fields{
- eventstore: eventstoreExpect(
- t,
- expectFilter(
- eventFromEventPusher(
- org.NewOrgAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1",
- ),
- ),
- ),
- expectFilter(),
- expectFilter(
- eventFromEventPusher(
- instance.NewLoginPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- false,
- false,
- false,
- false,
- false,
- domain.PasswordlessTypeAllowed,
- time.Hour*1,
- time.Hour*2,
- time.Hour*3,
- time.Hour*4,
- time.Hour*5,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewPasswordComplexityPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- 8,
- false,
- false,
- false,
- false,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewLabelPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "primary",
- "secondary",
- "warn",
- "font",
- "primary-dark",
- "secondary-dark",
- "warn-dark",
- "font-dark",
- false,
- false,
- false,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- org.NewOrgAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainVerifiedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainPrimarySetEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "test1",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainVerifiedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "test1",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "test2",
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewCustomTextSetEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- domain.InitCodeMessageType,
- domain.MessageSubject,
- "text",
- language.English,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewCustomTextSetEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- domain.LoginCustomText,
- domain.LoginKeyExternalRegistrationUserOverviewTitle,
- "text",
- language.English,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewPrivacyPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "toslink",
- "privacylink",
- "helplink",
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewLockoutPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- 5,
- false,
- ),
- ),
- ),
- expectFilter(),
- expectFilter(),
- expectPush(
- []*repository.Event{
- eventFromEventPusher(
- org.NewDomainRemovedEvent(context.Background(), &org.NewAggregate("org1").Aggregate, "test1", true),
- ),
- eventFromEventPusher(
- org.NewDomainRemovedEvent(context.Background(), &org.NewAggregate("org1").Aggregate, "test2", false),
- ),
- eventFromEventPusher(
- newFeaturesSetEvent(context.Background(), "org1", "Test", domain.FeaturesStateActive, time.Hour),
- ),
- },
- uniqueConstraintsFromEventConstraint(org.NewRemoveOrgDomainUniqueConstraint("test1")),
- ),
- ),
- },
- args: args{
- ctx: authz.WithRequestedDomain(context.Background(), "iam-domain"),
- resourceOwner: "org1",
- features: &domain.Features{
- TierName: "Test",
- State: domain.FeaturesStateActive,
- AuditLogRetention: time.Hour,
- LoginPolicyFactors: false,
- LoginPolicyIDP: false,
- LoginPolicyPasswordless: false,
- LoginPolicyRegistration: false,
- LoginPolicyUsernameLogin: false,
- LoginPolicyPasswordReset: false,
- PasswordComplexityPolicy: false,
- LabelPolicyPrivateLabel: false,
- LabelPolicyWatermark: false,
- CustomDomain: false,
- MetadataUser: false,
- PrivacyPolicy: false,
- LockoutPolicy: false,
- ActionsAllowed: domain.ActionsNotAllowed,
- },
- },
- res: res{
- want: &domain.ObjectDetails{
- ResourceOwner: "org1",
- },
- },
- },
- {
- name: "set with default policies, custom domains, default not primary, ok",
- fields: fields{
- eventstore: eventstoreExpect(
- t,
- expectFilter(
- eventFromEventPusher(
- org.NewOrgAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1",
- ),
- ),
- ),
- expectFilter(),
- expectFilter(
- eventFromEventPusher(
- instance.NewLoginPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- false,
- false,
- false,
- false,
- false,
- domain.PasswordlessTypeAllowed,
- time.Hour*1,
- time.Hour*2,
- time.Hour*3,
- time.Hour*4,
- time.Hour*5,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewPasswordComplexityPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- 8,
- false,
- false,
- false,
- false,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewLabelPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "primary",
- "secondary",
- "warn",
- "font",
- "primary-dark",
- "secondary-dark",
- "warn-dark",
- "font-dark",
- false,
- false,
- false,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- org.NewOrgAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainVerifiedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainPrimarySetEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "test1",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainVerifiedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "test1",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainPrimarySetEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "test1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "test2",
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewCustomTextSetEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- domain.InitCodeMessageType,
- domain.MessageSubject,
- "text",
- language.English,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewCustomTextSetEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- domain.LoginCustomText,
- domain.LoginKeyExternalRegistrationUserOverviewTitle,
- "text",
- language.English,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewPrivacyPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "toslink",
- "privacylink",
- "helplink",
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewLockoutPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- 5,
- false,
- ),
- ),
- ),
- expectFilter(),
- expectFilter(),
- expectPush(
- []*repository.Event{
- eventFromEventPusher(
- org.NewDomainPrimarySetEvent(context.Background(), &org.NewAggregate("org1").Aggregate, "org1.iam-domain"),
- ),
- eventFromEventPusher(
- org.NewDomainRemovedEvent(context.Background(), &org.NewAggregate("org1").Aggregate, "test1", true),
- ),
- eventFromEventPusher(
- org.NewDomainRemovedEvent(context.Background(), &org.NewAggregate("org1").Aggregate, "test2", false),
- ),
- eventFromEventPusher(
- newFeaturesSetEvent(context.Background(), "org1", "Test", domain.FeaturesStateActive, time.Hour),
- ),
- },
- uniqueConstraintsFromEventConstraint(org.NewRemoveOrgDomainUniqueConstraint("test1")),
- ),
- ),
- },
- args: args{
- ctx: authz.WithRequestedDomain(context.Background(), "iam-domain"),
- resourceOwner: "org1",
- features: &domain.Features{
- TierName: "Test",
- State: domain.FeaturesStateActive,
- AuditLogRetention: time.Hour,
- LoginPolicyFactors: false,
- LoginPolicyIDP: false,
- LoginPolicyPasswordless: false,
- LoginPolicyRegistration: false,
- LoginPolicyUsernameLogin: false,
- LoginPolicyPasswordReset: false,
- PasswordComplexityPolicy: false,
- LabelPolicyPrivateLabel: false,
- LabelPolicyWatermark: false,
- CustomDomain: false,
- MetadataUser: false,
- PrivacyPolicy: false,
- LockoutPolicy: false,
- ActionsAllowed: domain.ActionsNotAllowed,
- },
- },
- res: res{
- want: &domain.ObjectDetails{
- ResourceOwner: "org1",
- },
- },
- },
- {
- name: "set with default policies, custom domains, default not existing, ok",
- fields: fields{
- eventstore: eventstoreExpect(
- t,
- expectFilter(
- eventFromEventPusher(
- org.NewOrgAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1",
- ),
- ),
- ),
- expectFilter(),
- expectFilter(
- eventFromEventPusher(
- instance.NewLoginPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- false,
- false,
- false,
- false,
- false,
- domain.PasswordlessTypeAllowed,
- time.Hour*1,
- time.Hour*2,
- time.Hour*3,
- time.Hour*4,
- time.Hour*5,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewPasswordComplexityPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- 8,
- false,
- false,
- false,
- false,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewLabelPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "primary",
- "secondary",
- "warn",
- "font",
- "primary-dark",
- "secondary-dark",
- "warn-dark",
- "font-dark",
- false,
- false,
- false,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- org.NewOrgAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainVerifiedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainPrimarySetEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "test1",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainVerifiedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "test1",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainPrimarySetEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "test1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "test2",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainRemovedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain", true,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewCustomTextSetEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- domain.InitCodeMessageType,
- domain.MessageSubject,
- "text",
- language.English,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewCustomTextSetEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- domain.LoginCustomText,
- domain.LoginKeyExternalRegistrationUserOverviewTitle,
- "text",
- language.English,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewPrivacyPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "toslink",
- "privacylink",
- "helplink",
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewLockoutPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- 5,
- false,
- ),
- ),
- ),
- expectFilter(),
- expectFilter(),
- expectPush(
- []*repository.Event{
- eventFromEventPusher(
- org.NewDomainAddedEvent(context.Background(), &org.NewAggregate("org1").Aggregate, "org1.iam-domain"),
- ),
- eventFromEventPusher(
- org.NewDomainPrimarySetEvent(context.Background(), &org.NewAggregate("org1").Aggregate, "org1.iam-domain"),
- ),
- eventFromEventPusher(
- org.NewDomainRemovedEvent(context.Background(), &org.NewAggregate("org1").Aggregate, "test1", true),
- ),
- eventFromEventPusher(
- org.NewDomainRemovedEvent(context.Background(), &org.NewAggregate("org1").Aggregate, "test2", false),
- ),
- eventFromEventPusher(
- newFeaturesSetEvent(context.Background(), "org1", "Test", domain.FeaturesStateActive, time.Hour),
- ),
- },
- uniqueConstraintsFromEventConstraint(org.NewRemoveOrgDomainUniqueConstraint("test1")),
- ),
- ),
- },
- args: args{
- ctx: authz.WithRequestedDomain(context.Background(), "iam-domain"),
- resourceOwner: "org1",
- features: &domain.Features{
- TierName: "Test",
- State: domain.FeaturesStateActive,
- AuditLogRetention: time.Hour,
- LoginPolicyFactors: false,
- LoginPolicyIDP: false,
- LoginPolicyPasswordless: false,
- LoginPolicyRegistration: false,
- LoginPolicyUsernameLogin: false,
- LoginPolicyPasswordReset: false,
- PasswordComplexityPolicy: false,
- LabelPolicyPrivateLabel: false,
- LabelPolicyWatermark: false,
- CustomDomain: false,
- MetadataUser: false,
- PrivacyPolicy: false,
- LockoutPolicy: false,
- ActionsAllowed: domain.ActionsNotAllowed,
- },
- },
- res: res{
- want: &domain.ObjectDetails{
- ResourceOwner: "org1",
- },
- },
- },
- {
- name: "set with custom policies, ok",
- fields: fields{
- eventstore: eventstoreExpect(
- t,
- //checkOrgExists
- expectFilter(
- eventFromEventPusher(
- org.NewOrgAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1",
- ),
- ),
- ),
- //NewOrgFeaturesWriteModel
- expectFilter(),
- //begin ensureOrgSettingsToFeatures
- //begin setAllowedLoginPolicy
- //orgLoginPolicyWriteModelByID
- expectFilter(
- eventFromEventPusher(
- instance.NewLoginPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- true,
- true,
- true,
- true,
- true,
- domain.PasswordlessTypeAllowed,
- time.Hour*1,
- time.Hour*2,
- time.Hour*3,
- time.Hour*4,
- time.Hour*5,
- ),
- ),
- eventFromEventPusher(
- org.NewLoginPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- false,
- false,
- false,
- false,
- false,
- domain.PasswordlessTypeNotAllowed,
- time.Hour*10,
- time.Hour*20,
- time.Hour*30,
- time.Hour*40,
- time.Hour*50,
- ),
- ),
- ),
- //getDefaultLoginPolicy
- expectFilter(
- eventFromEventPusher(
- instance.NewLoginPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- true,
- true,
- true,
- true,
- true,
- domain.PasswordlessTypeAllowed,
- time.Hour*1,
- time.Hour*2,
- time.Hour*3,
- time.Hour*4,
- time.Hour*5,
- ),
- ),
- ),
- //begin setDefaultAuthFactorsInCustomLoginPolicy
- //orgLoginPolicyAuthFactorsWriteModel
- expectFilter(
- eventFromEventPusher(
- instance.NewLoginPolicySecondFactorAddedEvent(context.Background(), &instance.NewAggregate("INSTANCE").Aggregate, domain.SecondFactorTypeU2F),
- ),
- eventFromEventPusher(
- instance.NewLoginPolicyMultiFactorAddedEvent(context.Background(), &instance.NewAggregate("INSTANCE").Aggregate, domain.MultiFactorTypeU2FWithPIN),
- ),
- eventFromEventPusher(
- org.NewLoginPolicySecondFactorAddedEvent(context.Background(), &org.NewAggregate("org1").Aggregate, domain.SecondFactorTypeOTP),
- ),
- ),
- //addSecondFactorToLoginPolicy
- expectFilter(),
- //removeSecondFactorFromLoginPolicy
- expectFilter(),
- //addMultiFactorToLoginPolicy
- expectFilter(),
- //end setDefaultAuthFactorsInCustomLoginPolicy
- //orgPasswordComplexityPolicyWriteModelByID
- expectFilter(
- eventFromEventPusher(
- instance.NewPasswordComplexityPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- 8,
- false,
- false,
- false,
- false,
- ),
- ),
- eventFromEventPusher(
- org.NewPasswordComplexityPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- 7,
- false,
- false,
- false,
- false,
- ),
- ),
- ),
- //begin setDefaultAuthFactorsInCustomLoginPolicy
- //orgLabelPolicyWriteModelByID
- expectFilter(
- eventFromEventPusher(
- instance.NewLabelPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "primary",
- "secondary",
- "warn",
- "font",
- "primary-dark",
- "secondary-dark",
- "warn-dark",
- "font-dark",
- false,
- false,
- false,
- ),
- ),
- eventFromEventPusher(
- org.NewLabelPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "custom",
- "secondary",
- "warn",
- "font",
- "primary-dark",
- "secondary-dark",
- "warn-dark",
- "font-dark",
- false,
- false,
- false,
- ),
- ),
- ),
- //removeLabelPolicy
- expectFilter(),
- //end setDefaultAuthFactorsInCustomLoginPolicy
- //removeCustomDomains
- expectFilter(
- eventFromEventPusher(
- org.NewOrgAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainVerifiedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainPrimarySetEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- org.NewCustomTextSetEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- domain.InitCodeMessageType,
- domain.MessageSubject,
- "text",
- language.English,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- org.NewCustomTextSetEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- domain.LoginCustomText,
- domain.LoginKeyExternalRegistrationUserOverviewTitle,
- "text",
- language.English,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- org.NewPrivacyPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "toslink",
- "privacylink",
- "helplink",
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- org.NewLockoutPolicyAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- 5,
- false,
- ),
- ),
- ),
- expectFilter(),
- expectFilter(),
- expectPush(
- []*repository.Event{
- eventFromEventPusher(
- org.NewLoginPolicySecondFactorRemovedEvent(context.Background(), &org.NewAggregate("org1").Aggregate, domain.SecondFactorTypeOTP),
- ),
- eventFromEventPusher(
- org.NewLoginPolicySecondFactorAddedEvent(context.Background(), &org.NewAggregate("org1").Aggregate, domain.SecondFactorTypeU2F),
- ),
- eventFromEventPusher(
- org.NewLoginPolicyMultiFactorAddedEvent(context.Background(), &org.NewAggregate("org1").Aggregate, domain.MultiFactorTypeU2FWithPIN),
- ),
- eventFromEventPusher(
- newLoginPolicyChangedEvent(context.Background(), "org1",
- true, true, true, true, true, domain.PasswordlessTypeAllowed,
- nil,
- nil,
- nil,
- nil,
- nil),
- ),
- eventFromEventPusher(
- org.NewPasswordComplexityPolicyRemovedEvent(context.Background(), &org.NewAggregate("org1").Aggregate),
- ),
- eventFromEventPusher(
- org.NewLabelPolicyRemovedEvent(context.Background(), &org.NewAggregate("org1").Aggregate),
- ),
- eventFromEventPusher(
- org.NewCustomTextTemplateRemovedEvent(context.Background(), &org.NewAggregate("org1").Aggregate, domain.InitCodeMessageType, language.English),
- ),
- eventFromEventPusher(
- org.NewCustomTextTemplateRemovedEvent(context.Background(), &org.NewAggregate("org1").Aggregate, domain.LoginCustomText, language.English),
- ),
- eventFromEventPusher(
- org.NewPrivacyPolicyRemovedEvent(context.Background(), &org.NewAggregate("org1").Aggregate),
- ),
- eventFromEventPusher(
- org.NewLockoutPolicyRemovedEvent(context.Background(), &org.NewAggregate("org1").Aggregate),
- ),
- eventFromEventPusher(
- newFeaturesSetEvent(context.Background(), "org1", "Test", domain.FeaturesStateActive, time.Hour),
- ),
- },
- ),
- ),
- static: mock.NewMockStorage(gomock.NewController(t)).ExpectRemoveObjectsNoError(),
- },
- args: args{
- ctx: authz.WithRequestedDomain(context.Background(), "iam-domain"),
- resourceOwner: "org1",
- features: &domain.Features{
- TierName: "Test",
- State: domain.FeaturesStateActive,
- AuditLogRetention: time.Hour,
- LoginPolicyFactors: false,
- LoginPolicyIDP: false,
- LoginPolicyPasswordless: false,
- LoginPolicyRegistration: false,
- LoginPolicyUsernameLogin: false,
- PasswordComplexityPolicy: false,
- LabelPolicyPrivateLabel: false,
- LabelPolicyWatermark: false,
- CustomDomain: false,
- MetadataUser: false,
- PrivacyPolicy: false,
- LockoutPolicy: false,
- ActionsAllowed: domain.ActionsNotAllowed,
- },
- },
- res: res{
- want: &domain.ObjectDetails{
- ResourceOwner: "org1",
- },
- },
- },
- {
- name: "set with default policies, usermetadata, ok",
- fields: fields{
- eventstore: eventstoreExpect(
- t,
- expectFilter(
- eventFromEventPusher(
- org.NewOrgAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1",
- ),
- ),
- ),
- expectFilter(),
- expectFilter(
- eventFromEventPusher(
- instance.NewLoginPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- false,
- false,
- false,
- false,
- false,
- domain.PasswordlessTypeAllowed,
- time.Hour*1,
- time.Hour*2,
- time.Hour*3,
- time.Hour*4,
- time.Hour*5,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewPasswordComplexityPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- 8,
- false,
- false,
- false,
- false,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewLabelPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "primary",
- "secondary",
- "warn",
- "font",
- "primary-dark",
- "secondary-dark",
- "warn-dark",
- "font-dark",
- false,
- false,
- false,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- org.NewOrgAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainVerifiedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainPrimarySetEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewCustomTextSetEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- domain.InitCodeMessageType,
- domain.MessageSubject,
- "text",
- language.English,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewCustomTextSetEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- domain.LoginCustomText,
- domain.LoginKeyExternalRegistrationUserOverviewTitle,
- "text",
- language.English,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewPrivacyPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "toslink",
- "privacylink",
- "helplink",
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewLockoutPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- 5,
- false,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- user.NewMetadataSetEvent(
- context.Background(),
- &user.NewAggregate("user1", "org1").Aggregate,
- "key",
- []byte("value"),
- ),
- ),
- ),
- expectFilter(),
- expectPush(
- []*repository.Event{
- eventFromEventPusher(
- user.NewMetadataRemovedAllEvent(context.Background(), &user.NewAggregate("user1", "org1").Aggregate),
- ),
- eventFromEventPusher(
- newFeaturesSetEvent(context.Background(), "org1", "Test", domain.FeaturesStateActive, time.Hour),
- ),
- },
- ),
- ),
- },
- args: args{
- ctx: authz.WithRequestedDomain(context.Background(), "iam-domain"),
- resourceOwner: "org1",
- features: &domain.Features{
- TierName: "Test",
- State: domain.FeaturesStateActive,
- AuditLogRetention: time.Hour,
- LoginPolicyFactors: false,
- LoginPolicyIDP: false,
- LoginPolicyPasswordless: false,
- LoginPolicyRegistration: false,
- LoginPolicyUsernameLogin: false,
- LoginPolicyPasswordReset: false,
- PasswordComplexityPolicy: false,
- LabelPolicyPrivateLabel: false,
- LabelPolicyWatermark: false,
- CustomDomain: false,
- CustomTextMessage: false,
- CustomTextLogin: false,
- PrivacyPolicy: false,
- MetadataUser: false,
- LockoutPolicy: false,
- ActionsAllowed: domain.ActionsNotAllowed,
- },
- },
- res: res{
- want: &domain.ObjectDetails{
- ResourceOwner: "org1",
- },
- },
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- r := &Commands{
- eventstore: tt.fields.eventstore,
- static: tt.fields.static,
- }
- got, err := r.SetOrgFeatures(tt.args.ctx, tt.args.resourceOwner, tt.args.features)
- if tt.res.err == nil {
- assert.NoError(t, err)
- }
- if tt.res.err != nil && !tt.res.err(err) {
- t.Errorf("got wrong err: %v ", err)
- }
- if tt.res.err == nil {
- assert.Equal(t, tt.res.want, got)
- }
- })
- }
-}
-
-func TestCommandSide_RemoveOrgFeatures(t *testing.T) {
- type fields struct {
- eventstore *eventstore.Eventstore
- }
- type args struct {
- ctx context.Context
- resourceOwner string
- }
- type res struct {
- want *domain.ObjectDetails
- err func(error) bool
- }
- tests := []struct {
- name string
- fields fields
- args args
- res res
- }{
- {
- name: "resourceowner missing, error",
- fields: fields{
- eventstore: eventstoreExpect(
- t,
- ),
- },
- args: args{
- ctx: context.Background(),
- },
- res: res{
- err: caos_errs.IsErrorInvalidArgument,
- },
- },
- {
- name: "no features set, error",
- fields: fields{
- eventstore: eventstoreExpect(
- t,
- expectFilter(),
- ),
- },
- args: args{
- ctx: context.Background(),
- resourceOwner: "org1",
- },
- res: res{
- err: caos_errs.IsNotFound,
- },
- },
- {
- name: "remove with default policies, ok",
- fields: fields{
- eventstore: eventstoreExpect(
- t,
- expectFilter(
- eventFromEventPusher(
- newFeaturesSetEvent(context.Background(), "org1", "Test", domain.FeaturesStateActive, time.Hour)),
- ),
- expectFilter(
- eventFromEventPusher(
- newIAMFeaturesSetEvent(context.Background(), "Default", domain.FeaturesStateActive, time.Hour)),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewLoginPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- false,
- false,
- false,
- false,
- false,
- domain.PasswordlessTypeAllowed,
- time.Hour*1,
- time.Hour*2,
- time.Hour*3,
- time.Hour*4,
- time.Hour*5,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewPasswordComplexityPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- 8,
- false,
- false,
- false,
- false,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewLabelPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "primary",
- "secondary",
- "warn",
- "font",
- "primary-dark",
- "secondary-dark",
- "warn-dark",
- "font-dark",
- false,
- false,
- false,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- org.NewOrgAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainAddedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainVerifiedEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- eventFromEventPusher(
- org.NewDomainPrimarySetEvent(
- context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "org1.iam-domain",
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewCustomTextSetEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- domain.InitCodeMessageType,
- domain.MessageSubject,
- "text",
- language.English,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewCustomTextSetEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- domain.LoginCustomText,
- domain.LoginKeyExternalRegistrationUserOverviewTitle,
- "text",
- language.English,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewPrivacyPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "toslink",
- "privacylink",
- "helplink",
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewLockoutPolicyAddedEvent(
- context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- 5,
- false,
- ),
- ),
- ),
- expectFilter(),
- expectFilter(),
- expectPush(
- []*repository.Event{
- eventFromEventPusher(
- org.NewFeaturesRemovedEvent(context.Background(), &org.NewAggregate("org1").Aggregate),
- ),
- },
- ),
- ),
- },
- args: args{
- ctx: authz.WithRequestedDomain(context.Background(), "iam-domain"),
- resourceOwner: "org1",
- },
- res: res{
- want: &domain.ObjectDetails{
- ResourceOwner: "org1",
- },
- },
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- r := &Commands{
- eventstore: tt.fields.eventstore,
- }
- got, err := r.RemoveOrgFeatures(tt.args.ctx, tt.args.resourceOwner)
- if tt.res.err == nil {
- assert.NoError(t, err)
- }
- if tt.res.err != nil && !tt.res.err(err) {
- t.Errorf("got wrong err: %v ", err)
- }
- if tt.res.err == nil {
- assert.Equal(t, tt.res.want, got)
- }
- })
- }
-}
-
-func newIAMFeaturesSetEvent(ctx context.Context, tierName string, state domain.FeaturesState, auditLog time.Duration) *instance.FeaturesSetEvent {
- event, _ := instance.NewFeaturesSetEvent(
- ctx,
- &instance.NewAggregate("INSTANCE").Aggregate,
- []features.FeaturesChanges{
- features.ChangeTierName(tierName),
- features.ChangeState(state),
- features.ChangeAuditLogRetention(auditLog),
- },
- )
- return event
-}
-
-func newFeaturesSetEvent(ctx context.Context, orgID string, tierName string, state domain.FeaturesState, auditLog time.Duration) *org.FeaturesSetEvent {
- event, _ := org.NewFeaturesSetEvent(
- ctx,
- &org.NewAggregate(orgID).Aggregate,
- []features.FeaturesChanges{
- features.ChangeTierName(tierName),
- features.ChangeState(state),
- features.ChangeAuditLogRetention(auditLog),
- },
- )
- return event
-}
diff --git a/internal/command/org_policy_label.go b/internal/command/org_policy_label.go
index 5663eabf2..83387e043 100644
--- a/internal/command/org_policy_label.go
+++ b/internal/command/org_policy_label.go
@@ -25,10 +25,6 @@ func (c *Commands) AddLabelPolicy(ctx context.Context, resourceOwner string, pol
return nil, caos_errs.ThrowAlreadyExists(nil, "Org-2B0ps", "Errors.Org.LabelPolicy.AlreadyExists")
}
- err = c.checkLabelPolicyAllowed(ctx, resourceOwner, policy)
- if err != nil {
- return nil, err
- }
orgAgg := OrgAggregateFromWriteModel(&addedPolicy.LabelPolicyWriteModel.WriteModel)
pushedEvents, err := c.eventstore.Push(ctx, org.NewLabelPolicyAddedEvent(
ctx,
@@ -70,11 +66,6 @@ func (c *Commands) ChangeLabelPolicy(ctx context.Context, resourceOwner string,
return nil, caos_errs.ThrowNotFound(nil, "Org-0K9dq", "Errors.Org.LabelPolicy.NotFound")
}
- err = c.checkLabelPolicyAllowed(ctx, resourceOwner, policy)
- if err != nil {
- return nil, err
- }
-
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel)
changedEvent, hasChanged := existingPolicy.NewChangedEvent(
ctx,
@@ -105,28 +96,6 @@ func (c *Commands) ChangeLabelPolicy(ctx context.Context, resourceOwner string,
return writeModelToLabelPolicy(&existingPolicy.LabelPolicyWriteModel), nil
}
-func (c *Commands) checkLabelPolicyAllowed(ctx context.Context, resourceOwner string, policy *domain.LabelPolicy) error {
- defaultPolicy, err := c.getDefaultLabelPolicy(ctx)
- if err != nil {
- return err
- }
- requiredFeatures := make([]string, 0)
- if defaultPolicy.PrimaryColor != policy.PrimaryColor || defaultPolicy.PrimaryColorDark != policy.PrimaryColorDark ||
- defaultPolicy.FontColor != policy.FontColor || defaultPolicy.FontColorDark != policy.FontColorDark ||
- defaultPolicy.BackgroundColor != policy.BackgroundColor || defaultPolicy.BackgroundColorDark != policy.BackgroundColorDark ||
- defaultPolicy.WarnColor != defaultPolicy.WarnColor || defaultPolicy.WarnColorDark != defaultPolicy.WarnColorDark ||
- defaultPolicy.LogoURL != policy.LogoURL || defaultPolicy.LogoDarkURL != policy.LogoDarkURL ||
- defaultPolicy.IconURL != policy.IconURL || defaultPolicy.IconDarkURL != policy.IconDarkURL ||
- defaultPolicy.Font != policy.Font ||
- defaultPolicy.HideLoginNameSuffix != policy.HideLoginNameSuffix {
- requiredFeatures = append(requiredFeatures, domain.FeatureLabelPolicyPrivateLabel)
- }
- if defaultPolicy.DisableWatermark != policy.DisableWatermark {
- requiredFeatures = append(requiredFeatures, domain.FeatureLabelPolicyWatermark)
- }
- return c.tokenVerifier.CheckOrgFeatures(ctx, resourceOwner, requiredFeatures...)
-}
-
func (c *Commands) ActivateLabelPolicy(ctx context.Context, orgID string) (*domain.ObjectDetails, error) {
if orgID == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-KKd4X", "Errors.ResourceOwnerMissing")
diff --git a/internal/command/org_policy_label_test.go b/internal/command/org_policy_label_test.go
index 83b1baeb6..c4fc41edf 100644
--- a/internal/command/org_policy_label_test.go
+++ b/internal/command/org_policy_label_test.go
@@ -13,7 +13,6 @@ import (
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
- "github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/policy"
"github.com/zitadel/zitadel/internal/static"
@@ -22,8 +21,7 @@ import (
func TestCommandSide_AddLabelPolicy(t *testing.T) {
type fields struct {
- eventstore *eventstore.Eventstore
- tokenVerifier orgFeatureChecker
+ eventstore *eventstore.Eventstore
}
type args struct {
ctx context.Context
@@ -104,78 +102,12 @@ func TestCommandSide_AddLabelPolicy(t *testing.T) {
err: caos_errs.IsErrorAlreadyExists,
},
},
- {
- name: "add policy, permission denied",
- fields: fields{
- eventstore: eventstoreExpect(
- t,
- expectFilter(),
- expectFilter(
- eventFromEventPusher(
- instance.NewLabelPolicyAddedEvent(context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- true,
- true,
- false,
- ),
- ),
- ),
- ),
- tokenVerifier: GetMockVerifier(t),
- },
- args: args{
- ctx: context.Background(),
- orgID: "org1",
- policy: &domain.LabelPolicy{
- PrimaryColor: "#ffffff",
- BackgroundColor: "#ffffff",
- WarnColor: "#ffffff",
- FontColor: "#ffffff",
- PrimaryColorDark: "#ffffff",
- BackgroundColorDark: "#ffffff",
- WarnColorDark: "#ffffff",
- FontColorDark: "#ffffff",
- HideLoginNameSuffix: true,
- ErrorMsgPopup: true,
- DisableWatermark: true,
- },
- },
- res: res{
- err: caos_errs.IsPermissionDenied,
- },
- },
{
name: "add policy,ok",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(),
- expectFilter(
- eventFromEventPusher(
- instance.NewLabelPolicyAddedEvent(context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- true,
- true,
- false,
- ),
- ),
- ),
expectPush(
[]*repository.Event{
eventFromEventPusher(
@@ -197,7 +129,6 @@ func TestCommandSide_AddLabelPolicy(t *testing.T) {
},
),
),
- tokenVerifier: GetMockVerifier(t, domain.FeatureLabelPolicyPrivateLabel, domain.FeatureLabelPolicyWatermark),
},
args: args{
ctx: context.Background(),
@@ -240,8 +171,7 @@ func TestCommandSide_AddLabelPolicy(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
- eventstore: tt.fields.eventstore,
- tokenVerifier: tt.fields.tokenVerifier,
+ eventstore: tt.fields.eventstore,
}
got, err := r.AddLabelPolicy(tt.args.ctx, tt.args.orgID, tt.args.policy)
if tt.res.err == nil {
@@ -259,8 +189,7 @@ func TestCommandSide_AddLabelPolicy(t *testing.T) {
func TestCommandSide_ChangeLabelPolicy(t *testing.T) {
type fields struct {
- eventstore *eventstore.Eventstore
- tokenVerifier orgFeatureChecker
+ eventstore *eventstore.Eventstore
}
type args struct {
ctx context.Context
@@ -316,71 +245,6 @@ func TestCommandSide_ChangeLabelPolicy(t *testing.T) {
err: caos_errs.IsNotFound,
},
},
- {
- name: "permission denied error",
- fields: fields{
- eventstore: eventstoreExpect(
- t,
- expectFilter(
- eventFromEventPusher(
- org.NewLabelPolicyAddedEvent(context.Background(),
- &org.NewAggregate("org1").Aggregate,
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- true,
- true,
- true,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewLabelPolicyAddedEvent(context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- true,
- true,
- false,
- ),
- ),
- ),
- ),
- tokenVerifier: GetMockVerifier(t),
- },
- args: args{
- ctx: context.Background(),
- orgID: "org1",
- policy: &domain.LabelPolicy{
- PrimaryColor: "#000000",
- BackgroundColor: "#000000",
- WarnColor: "#000000",
- FontColor: "#000000",
- PrimaryColorDark: "#000000",
- BackgroundColorDark: "#000000",
- WarnColorDark: "#000000",
- FontColorDark: "#000000",
- HideLoginNameSuffix: true,
- ErrorMsgPopup: true,
- DisableWatermark: true,
- },
- },
- res: res{
- err: caos_errs.IsPermissionDenied,
- },
- },
{
name: "no changes, precondition error",
fields: fields{
@@ -404,26 +268,7 @@ func TestCommandSide_ChangeLabelPolicy(t *testing.T) {
),
),
),
- expectFilter(
- eventFromEventPusher(
- instance.NewLabelPolicyAddedEvent(context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- true,
- true,
- false,
- ),
- ),
- ),
),
- tokenVerifier: GetMockVerifier(t, domain.FeatureLabelPolicyPrivateLabel, domain.FeatureLabelPolicyWatermark),
},
args: args{
ctx: context.Background(),
@@ -469,24 +314,6 @@ func TestCommandSide_ChangeLabelPolicy(t *testing.T) {
),
),
),
- expectFilter(
- eventFromEventPusher(
- instance.NewLabelPolicyAddedEvent(context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- "#ffffff",
- true,
- true,
- false,
- ),
- ),
- ),
expectPush(
[]*repository.Event{
eventFromEventPusher(
@@ -508,7 +335,6 @@ func TestCommandSide_ChangeLabelPolicy(t *testing.T) {
},
),
),
- tokenVerifier: GetMockVerifier(t, domain.FeatureLabelPolicyPrivateLabel, domain.FeatureLabelPolicyWatermark),
},
args: args{
ctx: context.Background(),
@@ -551,8 +377,7 @@ func TestCommandSide_ChangeLabelPolicy(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
- eventstore: tt.fields.eventstore,
- tokenVerifier: tt.fields.tokenVerifier,
+ eventstore: tt.fields.eventstore,
}
got, err := r.ChangeLabelPolicy(tt.args.ctx, tt.args.orgID, tt.args.policy)
if tt.res.err == nil {
diff --git a/internal/command/org_policy_login.go b/internal/command/org_policy_login.go
index 099712bc7..11cc1ece9 100644
--- a/internal/command/org_policy_login.go
+++ b/internal/command/org_policy_login.go
@@ -2,7 +2,6 @@ package command
import (
"context"
- "reflect"
"github.com/zitadel/logging"
@@ -26,11 +25,6 @@ func (c *Commands) AddLoginPolicy(ctx context.Context, resourceOwner string, pol
return nil, caos_errs.ThrowAlreadyExists(nil, "Org-Dgfb2", "Errors.Org.LoginPolicy.AlreadyExists")
}
- err = c.checkLoginPolicyAllowed(ctx, resourceOwner, policy)
- if err != nil {
- return nil, err
- }
-
orgAgg := OrgAggregateFromWriteModel(&addedPolicy.WriteModel)
pushedEvents, err := c.eventstore.Push(
ctx,
@@ -91,11 +85,6 @@ func (c *Commands) ChangeLoginPolicy(ctx context.Context, resourceOwner string,
return nil, caos_errs.ThrowNotFound(nil, "Org-M0sif", "Errors.Org.LoginPolicy.NotFound")
}
- err = c.checkLoginPolicyAllowed(ctx, resourceOwner, policy)
- if err != nil {
- return nil, err
- }
-
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LoginPolicyWriteModel.WriteModel)
changedEvent, hasChanged := existingPolicy.NewChangedEvent(
ctx,
@@ -127,33 +116,6 @@ func (c *Commands) ChangeLoginPolicy(ctx context.Context, resourceOwner string,
return writeModelToLoginPolicy(&existingPolicy.LoginPolicyWriteModel), nil
}
-func (c *Commands) checkLoginPolicyAllowed(ctx context.Context, resourceOwner string, policy *domain.LoginPolicy) error {
- defaultPolicy, err := c.getDefaultLoginPolicy(ctx)
- if err != nil {
- return err
- }
- requiredFeatures := make([]string, 0)
- if defaultPolicy.ForceMFA != policy.ForceMFA || !reflect.DeepEqual(defaultPolicy.MultiFactors, policy.MultiFactors) || !reflect.DeepEqual(defaultPolicy.SecondFactors, policy.SecondFactors) {
- requiredFeatures = append(requiredFeatures, domain.FeatureLoginPolicyFactors)
- }
- if defaultPolicy.AllowExternalIDP != policy.AllowExternalIDP || !reflect.DeepEqual(defaultPolicy.IDPProviders, policy.IDPProviders) {
- requiredFeatures = append(requiredFeatures, domain.FeatureLoginPolicyIDP)
- }
- if defaultPolicy.AllowRegister != policy.AllowRegister {
- requiredFeatures = append(requiredFeatures, domain.FeatureLoginPolicyRegistration)
- }
- if defaultPolicy.PasswordlessType != policy.PasswordlessType {
- requiredFeatures = append(requiredFeatures, domain.FeatureLoginPolicyPasswordless)
- }
- if defaultPolicy.AllowUsernamePassword != policy.AllowUsernamePassword {
- requiredFeatures = append(requiredFeatures, domain.FeatureLoginPolicyUsernameLogin)
- }
- if defaultPolicy.HidePasswordReset != policy.HidePasswordReset {
- requiredFeatures = append(requiredFeatures, domain.FeatureLoginPolicyPasswordReset)
- }
- return c.tokenVerifier.CheckOrgFeatures(ctx, resourceOwner, requiredFeatures...)
-}
-
func (c *Commands) RemoveLoginPolicy(ctx context.Context, orgID string) (*domain.ObjectDetails, error) {
if orgID == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-55Mg9", "Errors.ResourceOwnerMissing")
diff --git a/internal/command/org_policy_login_test.go b/internal/command/org_policy_login_test.go
index ca7526b38..89d61e8bf 100644
--- a/internal/command/org_policy_login_test.go
+++ b/internal/command/org_policy_login_test.go
@@ -12,7 +12,6 @@ import (
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
- "github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/policy"
"github.com/zitadel/zitadel/internal/repository/user"
@@ -28,8 +27,7 @@ var (
func TestCommandSide_AddLoginPolicy(t *testing.T) {
type fields struct {
- eventstore *eventstore.Eventstore
- tokenVerifier orgFeatureChecker
+ eventstore *eventstore.Eventstore
}
type args struct {
ctx context.Context
@@ -110,77 +108,12 @@ func TestCommandSide_AddLoginPolicy(t *testing.T) {
err: caos_errs.IsErrorAlreadyExists,
},
},
- {
- name: "loginpolicy not allowed, permission denied error",
- fields: fields{
- eventstore: eventstoreExpect(
- t,
- expectFilter(),
- expectFilter(
- eventFromEventPusher(
- instance.NewLoginPolicyAddedEvent(context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- false,
- true,
- true,
- true,
- true,
- domain.PasswordlessTypeAllowed,
- time.Hour*1,
- time.Hour*2,
- time.Hour*3,
- time.Hour*4,
- time.Hour*5,
- ),
- ),
- ),
- ),
- tokenVerifier: GetMockVerifier(t),
- },
- args: args{
- ctx: context.Background(),
- orgID: "org1",
- policy: &domain.LoginPolicy{
- AllowRegister: true,
- AllowUsernamePassword: true,
- AllowExternalIDP: true,
- ForceMFA: true,
- PasswordlessType: domain.PasswordlessTypeAllowed,
- PasswordCheckLifetime: time.Hour * 1,
- ExternalLoginCheckLifetime: time.Hour * 2,
- MFAInitSkipLifetime: time.Hour * 3,
- SecondFactorCheckLifetime: time.Hour * 4,
- MultiFactorCheckLifetime: time.Hour * 5,
- },
- },
- res: res{
- err: caos_errs.IsPermissionDenied,
- },
- },
{
name: "add policy,ok",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(),
- expectFilter(
- eventFromEventPusher(
- instance.NewLoginPolicyAddedEvent(context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- false,
- true,
- true,
- true,
- true,
- domain.PasswordlessTypeAllowed,
- time.Hour*1,
- time.Hour*2,
- time.Hour*3,
- time.Hour*4,
- time.Hour*5,
- ),
- ),
- ),
expectPush(
[]*repository.Event{
eventFromEventPusher(
@@ -202,7 +135,6 @@ func TestCommandSide_AddLoginPolicy(t *testing.T) {
},
),
),
- tokenVerifier: GetMockVerifier(t, domain.FeatureLoginPolicyUsernameLogin),
},
args: args{
ctx: context.Background(),
@@ -245,8 +177,7 @@ func TestCommandSide_AddLoginPolicy(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
- eventstore: tt.fields.eventstore,
- tokenVerifier: tt.fields.tokenVerifier,
+ eventstore: tt.fields.eventstore,
}
got, err := r.AddLoginPolicy(tt.args.ctx, tt.args.orgID, tt.args.policy)
if tt.res.err == nil {
@@ -264,8 +195,7 @@ func TestCommandSide_AddLoginPolicy(t *testing.T) {
func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
type fields struct {
- eventstore *eventstore.Eventstore
- tokenVerifier orgFeatureChecker
+ eventstore *eventstore.Eventstore
}
type args struct {
ctx context.Context
@@ -326,70 +256,6 @@ func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
err: caos_errs.IsNotFound,
},
},
- {
- name: "not allowed, permission denied error",
- fields: fields{
- eventstore: eventstoreExpect(
- t,
- expectFilter(
- eventFromEventPusher(
- org.NewLoginPolicyAddedEvent(context.Background(),
- &org.NewAggregate("org1").Aggregate,
- true,
- true,
- true,
- true,
- true,
- domain.PasswordlessTypeAllowed,
- time.Hour*1,
- time.Hour*2,
- time.Hour*3,
- time.Hour*4,
- time.Hour*5,
- ),
- ),
- ),
- expectFilter(
- eventFromEventPusher(
- instance.NewLoginPolicyAddedEvent(context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- false,
- true,
- true,
- true,
- true,
- domain.PasswordlessTypeAllowed,
- time.Hour*1,
- time.Hour*2,
- time.Hour*3,
- time.Hour*4,
- time.Hour*5,
- ),
- ),
- ),
- ),
- tokenVerifier: GetMockVerifier(t),
- },
- args: args{
- ctx: context.Background(),
- orgID: "org1",
- policy: &domain.LoginPolicy{
- AllowRegister: true,
- AllowUsernamePassword: true,
- AllowExternalIDP: true,
- ForceMFA: true,
- PasswordlessType: domain.PasswordlessTypeAllowed,
- PasswordCheckLifetime: time.Hour * 1,
- ExternalLoginCheckLifetime: time.Hour * 2,
- MFAInitSkipLifetime: time.Hour * 3,
- SecondFactorCheckLifetime: time.Hour * 4,
- MultiFactorCheckLifetime: time.Hour * 5,
- },
- },
- res: res{
- err: caos_errs.IsPermissionDenied,
- },
- },
{
name: "no changes, precondition error",
fields: fields{
@@ -413,26 +279,7 @@ func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
),
),
),
- expectFilter(
- eventFromEventPusher(
- instance.NewLoginPolicyAddedEvent(context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- false,
- true,
- true,
- true,
- true,
- domain.PasswordlessTypeAllowed,
- time.Hour*1,
- time.Hour*2,
- time.Hour*3,
- time.Hour*4,
- time.Hour*5,
- ),
- ),
- ),
),
- tokenVerifier: GetMockVerifier(t, domain.FeatureLoginPolicyUsernameLogin),
},
args: args{
ctx: context.Background(),
@@ -478,24 +325,6 @@ func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
),
),
),
- expectFilter(
- eventFromEventPusher(
- instance.NewLoginPolicyAddedEvent(context.Background(),
- &instance.NewAggregate("INSTANCE").Aggregate,
- false,
- false,
- false,
- false,
- false,
- domain.PasswordlessTypeNotAllowed,
- time.Hour*1,
- time.Hour*2,
- time.Hour*3,
- time.Hour*4,
- time.Hour*5,
- ),
- ),
- ),
expectPush(
[]*repository.Event{
eventFromEventPusher(
@@ -517,7 +346,6 @@ func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
},
),
),
- tokenVerifier: GetMockVerifier(t, domain.FeatureLoginPolicyUsernameLogin),
},
args: args{
ctx: context.Background(),
@@ -559,8 +387,7 @@ func TestCommandSide_ChangeLoginPolicy(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
- eventstore: tt.fields.eventstore,
- tokenVerifier: tt.fields.tokenVerifier,
+ eventstore: tt.fields.eventstore,
}
got, err := r.ChangeLoginPolicy(tt.args.ctx, tt.args.orgID, tt.args.policy)
if tt.res.err == nil {
diff --git a/internal/domain/features.go b/internal/domain/features.go
deleted file mode 100644
index d5bd9098c..000000000
--- a/internal/domain/features.go
+++ /dev/null
@@ -1,76 +0,0 @@
-package domain
-
-import (
- "time"
-
- es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
-)
-
-const (
- FeatureLoginPolicy = "login_policy"
- FeatureLoginPolicyFactors = FeatureLoginPolicy + ".factors"
- FeatureLoginPolicyIDP = FeatureLoginPolicy + ".idp"
- FeatureLoginPolicyPasswordless = FeatureLoginPolicy + ".passwordless"
- FeatureLoginPolicyRegistration = FeatureLoginPolicy + ".registration"
- FeatureLoginPolicyUsernameLogin = FeatureLoginPolicy + ".username_login"
- FeatureLoginPolicyPasswordReset = FeatureLoginPolicy + ".password_reset"
- FeaturePasswordComplexityPolicy = "password_complexity_policy"
- FeatureLabelPolicy = "label_policy"
- FeatureLabelPolicyPrivateLabel = FeatureLabelPolicy + ".private_label"
- FeatureLabelPolicyWatermark = FeatureLabelPolicy + ".watermark"
- FeatureCustomDomain = "custom_domain"
- FeaturePrivacyPolicy = "privacy_policy"
- FeatureLockoutPolicy = "lockout_policy"
- FeatureMetadata = "metadata"
- FeatureCustomText = "custom_text"
- FeatureCustomTextMessage = FeatureCustomText + ".message"
- FeatureCustomTextLogin = FeatureCustomText + ".login"
- FeatureMetadataUser = FeatureMetadata + ".user"
- FeatureActions = "actions"
-)
-
-type Features struct {
- es_models.ObjectRoot
-
- TierName string
- TierDescription string
- State FeaturesState
- StateDescription string
- IsDefault bool
-
- AuditLogRetention time.Duration
- LoginPolicyFactors bool
- LoginPolicyIDP bool
- LoginPolicyPasswordless bool
- LoginPolicyRegistration bool
- LoginPolicyUsernameLogin bool
- LoginPolicyPasswordReset bool
- PasswordComplexityPolicy bool
- LabelPolicyPrivateLabel bool
- LabelPolicyWatermark bool
- CustomDomain bool
- CustomTextMessage bool
- CustomTextLogin bool
- PrivacyPolicy bool
- MetadataUser bool
- LockoutPolicy bool
- ActionsAllowed ActionsAllowed
- MaxActions int
-}
-
-type FeaturesState int32
-
-const (
- FeaturesStateUnspecified FeaturesState = iota
- FeaturesStateActive
- FeaturesStateActionRequired
- FeaturesStateCanceled
- FeaturesStateGrandfathered
- FeaturesStateRemoved
-
- featuresStateCount
-)
-
-func (f FeaturesState) Valid() bool {
- return f >= 0 && f < featuresStateCount
-}
diff --git a/internal/protoc/protoc-gen-authoption/templates/auth_method_mapping.go.tmpl b/internal/protoc/protoc-gen-authoption/templates/auth_method_mapping.go.tmpl
index cfc71fb5c..bd6fe3b88 100644
--- a/internal/protoc/protoc-gen-authoption/templates/auth_method_mapping.go.tmpl
+++ b/internal/protoc/protoc-gen-authoption/templates/auth_method_mapping.go.tmpl
@@ -21,14 +21,13 @@ const {{$s.Name}}_MethodPrefix = "{{$.File.Package}}.{{$s.Name}}"
var {{$s.Name}}_AuthMethods = authz.MethodMapping {
{{ range $m := $s.Method}}
{{ $mAuthOpt := option $m.Options "zitadel.v1.auth_option" }}
- {{ if and $mAuthOpt (or $mAuthOpt.Permission $mAuthOpt.Feature) }}
+ {{ if and $mAuthOpt $mAuthOpt.Permission }}
"/{{$.File.Package}}.{{$s.Name}}/{{.Name}}": authz.Option{
Permission: "{{$mAuthOpt.Permission}}",
CheckParam: "{{$mAuthOpt.CheckFieldName}}",
- Feature: "{{$mAuthOpt.Feature}}",
},
{{end}}
{{ end}}
}
-{{ end }}
\ No newline at end of file
+{{ end }}
diff --git a/internal/query/changes.go b/internal/query/changes.go
index bc455e00f..180dc8ea7 100644
--- a/internal/query/changes.go
+++ b/internal/query/changes.go
@@ -87,7 +87,7 @@ func (q *Queries) changes(ctx context.Context, query func(query *eventstore.Sear
}
changes := make([]*Change, 0, len(events))
for _, event := range events {
- if event.CreationDate().Before(time.Now().Add(-auditLogRetention)) {
+ if auditLogRetention != 0 && event.CreationDate().Before(time.Now().Add(-auditLogRetention)) {
continue
}
change := &Change{
diff --git a/internal/query/features.go b/internal/query/features.go
deleted file mode 100644
index 6e93345af..000000000
--- a/internal/query/features.go
+++ /dev/null
@@ -1,327 +0,0 @@
-package query
-
-import (
- "context"
- "database/sql"
- errs "errors"
- "time"
-
- 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"
-)
-
-type Features struct {
- AggregateID string
- ChangeDate time.Time
- Sequence uint64
- IsDefault bool
- TierName string
- TierDescription string
- State domain.FeaturesState
- StateDescription string
- AuditLogRetention time.Duration
- LoginPolicyFactors bool
- LoginPolicyIDP bool
- LoginPolicyPasswordless bool
- LoginPolicyRegistration bool
- LoginPolicyUsernameLogin bool
- LoginPolicyPasswordReset bool
- PasswordComplexityPolicy bool
- LabelPolicyPrivateLabel bool
- LabelPolicyWatermark bool
- CustomDomain bool
- PrivacyPolicy bool
- MetadataUser bool
- CustomTextMessage bool
- CustomTextLogin bool
- LockoutPolicy bool
- ActionsAllowed domain.ActionsAllowed
- MaxActions int32
-}
-
-var (
- featureTable = table{
- name: projection.FeatureTable,
- }
- FeatureColumnAggregateID = Column{
- name: projection.FeatureAggregateIDCol,
- table: featureTable,
- }
- FeatureColumnInstanceID = Column{
- name: projection.FeatureInstanceIDCol,
- table: featureTable,
- }
- FeatureColumnChangeDate = Column{
- name: projection.FeatureChangeDateCol,
- table: featureTable,
- }
- FeatureColumnSequence = Column{
- name: projection.FeatureSequenceCol,
- table: featureTable,
- }
- FeatureColumnIsDefault = Column{
- name: projection.FeatureIsDefaultCol,
- table: featureTable,
- }
- FeatureTierName = Column{
- name: projection.FeatureTierNameCol,
- table: featureTable,
- }
- FeatureTierDescription = Column{
- name: projection.FeatureTierDescriptionCol,
- table: featureTable,
- }
- FeatureState = Column{
- name: projection.FeatureStateCol,
- table: featureTable,
- }
- FeatureStateDescription = Column{
- name: projection.FeatureStateDescriptionCol,
- table: featureTable,
- }
- FeatureAuditLogRetention = Column{
- name: projection.FeatureAuditLogRetentionCol,
- table: featureTable,
- }
- FeatureLoginPolicyFactors = Column{
- name: projection.FeatureLoginPolicyFactorsCol,
- table: featureTable,
- }
- FeatureLoginPolicyIDP = Column{
- name: projection.FeatureLoginPolicyIDPCol,
- table: featureTable,
- }
- FeatureLoginPolicyPasswordless = Column{
- name: projection.FeatureLoginPolicyPasswordlessCol,
- table: featureTable,
- }
- FeatureLoginPolicyRegistration = Column{
- name: projection.FeatureLoginPolicyRegistrationCol,
- table: featureTable,
- }
- FeatureLoginPolicyUsernameLogin = Column{
- name: projection.FeatureLoginPolicyUsernameLoginCol,
- table: featureTable,
- }
- FeatureLoginPolicyPasswordReset = Column{
- name: projection.FeatureLoginPolicyPasswordResetCol,
- table: featureTable,
- }
- FeaturePasswordComplexityPolicy = Column{
- name: projection.FeaturePasswordComplexityPolicyCol,
- table: featureTable,
- }
- FeatureLabelPolicyPrivateLabel = Column{
- name: projection.FeatureLabelPolicyPrivateLabelCol,
- table: featureTable,
- }
- FeatureLabelPolicyWatermark = Column{
- name: projection.FeatureLabelPolicyWatermarkCol,
- table: featureTable,
- }
- FeatureCustomDomain = Column{
- name: projection.FeatureCustomDomainCol,
- table: featureTable,
- }
- FeaturePrivacyPolicy = Column{
- name: projection.FeaturePrivacyPolicyCol,
- table: featureTable,
- }
- FeatureMetadataUser = Column{
- name: projection.FeatureMetadataUserCol,
- table: featureTable,
- }
- FeatureCustomTextMessage = Column{
- name: projection.FeatureCustomTextMessageCol,
- table: featureTable,
- }
- FeatureCustomTextLogin = Column{
- name: projection.FeatureCustomTextLoginCol,
- table: featureTable,
- }
- FeatureLockoutPolicy = Column{
- name: projection.FeatureLockoutPolicyCol,
- table: featureTable,
- }
- FeatureActionsAllowed = Column{
- name: projection.FeatureActionsAllowedCol,
- table: featureTable,
- }
- FeatureMaxActions = Column{
- name: projection.FeatureMaxActionsCol,
- table: featureTable,
- }
-)
-
-func (q *Queries) FeaturesByOrgID(ctx context.Context, orgID string) (*Features, error) {
- query, scan := prepareFeaturesQuery()
- stmt, args, err := query.Where(
- sq.And{
- sq.Eq{
- FeatureColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
- },
- sq.Or{
- sq.Eq{
- FeatureColumnAggregateID.identifier(): orgID,
- },
- sq.Eq{
- FeatureColumnAggregateID.identifier(): authz.GetInstance(ctx).InstanceID(),
- },
- },
- }).
- OrderBy(FeatureColumnIsDefault.identifier()).
- Limit(1).ToSql()
- if err != nil {
- return nil, errors.ThrowInternal(err, "QUERY-P9gwg", "Errors.Query.SQLStatement")
- }
-
- row := q.client.QueryRowContext(ctx, stmt, args...)
- return scan(row)
-}
-
-func (q *Queries) DefaultFeatures(ctx context.Context) (*Features, error) {
- query, scan := prepareFeaturesQuery()
- stmt, args, err := query.Where(sq.Eq{
- FeatureColumnAggregateID.identifier(): authz.GetInstance(ctx).InstanceID(),
- FeatureColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
- }).ToSql()
- if err != nil {
- return nil, errors.ThrowInternal(err, "QUERY-1Ndlg", "Errors.Query.SQLStatement")
- }
-
- row := q.client.QueryRowContext(ctx, stmt, args...)
- return scan(row)
-}
-
-func prepareFeaturesQuery() (sq.SelectBuilder, func(*sql.Row) (*Features, error)) {
- return sq.Select(
- FeatureColumnAggregateID.identifier(),
- FeatureColumnChangeDate.identifier(),
- FeatureColumnSequence.identifier(),
- FeatureColumnIsDefault.identifier(),
- FeatureTierName.identifier(),
- FeatureTierDescription.identifier(),
- FeatureState.identifier(),
- FeatureStateDescription.identifier(),
- FeatureAuditLogRetention.identifier(),
- FeatureLoginPolicyFactors.identifier(),
- FeatureLoginPolicyIDP.identifier(),
- FeatureLoginPolicyPasswordless.identifier(),
- FeatureLoginPolicyRegistration.identifier(),
- FeatureLoginPolicyUsernameLogin.identifier(),
- FeatureLoginPolicyPasswordReset.identifier(),
- FeaturePasswordComplexityPolicy.identifier(),
- FeatureLabelPolicyPrivateLabel.identifier(),
- FeatureLabelPolicyWatermark.identifier(),
- FeatureCustomDomain.identifier(),
- FeaturePrivacyPolicy.identifier(),
- FeatureMetadataUser.identifier(),
- FeatureCustomTextMessage.identifier(),
- FeatureCustomTextLogin.identifier(),
- FeatureLockoutPolicy.identifier(),
- FeatureActionsAllowed.identifier(),
- FeatureMaxActions.identifier(),
- ).From(featureTable.identifier()).PlaceholderFormat(sq.Dollar),
- func(row *sql.Row) (*Features, error) {
- p := new(Features)
- tierName := sql.NullString{}
- tierDescription := sql.NullString{}
- stateDescription := sql.NullString{}
- err := row.Scan(
- &p.AggregateID,
- &p.ChangeDate,
- &p.Sequence,
- &p.IsDefault,
- &tierName,
- &tierDescription,
- &p.State,
- &stateDescription,
- &p.AuditLogRetention,
- &p.LoginPolicyFactors,
- &p.LoginPolicyIDP,
- &p.LoginPolicyPasswordless,
- &p.LoginPolicyRegistration,
- &p.LoginPolicyUsernameLogin,
- &p.LoginPolicyPasswordReset,
- &p.PasswordComplexityPolicy,
- &p.LabelPolicyPrivateLabel,
- &p.LabelPolicyWatermark,
- &p.CustomDomain,
- &p.PrivacyPolicy,
- &p.MetadataUser,
- &p.CustomTextMessage,
- &p.CustomTextLogin,
- &p.LockoutPolicy,
- &p.ActionsAllowed,
- &p.MaxActions,
- )
- if err != nil {
- if errs.Is(err, sql.ErrNoRows) {
- return nil, errors.ThrowNotFound(err, "QUERY-M9fse", "Errors.Features.NotFound")
- }
- return nil, errors.ThrowInternal(err, "QUERY-3o9gd", "Errors.Internal")
- }
- p.TierName = tierName.String
- p.TierDescription = tierDescription.String
- p.StateDescription = stateDescription.String
- return p, nil
- }
-}
-
-func (f *Features) EnabledFeatureTypes() []string {
- list := make([]string, 0)
- if f.LoginPolicyFactors {
- list = append(list, domain.FeatureLoginPolicyFactors)
- }
- if f.LoginPolicyIDP {
- list = append(list, domain.FeatureLoginPolicyIDP)
- }
- if f.LoginPolicyPasswordless {
- list = append(list, domain.FeatureLoginPolicyPasswordless)
- }
- if f.LoginPolicyRegistration {
- list = append(list, domain.FeatureLoginPolicyRegistration)
- }
- if f.LoginPolicyUsernameLogin {
- list = append(list, domain.FeatureLoginPolicyUsernameLogin)
- }
- if f.LoginPolicyPasswordReset {
- list = append(list, domain.FeatureLoginPolicyPasswordReset)
- }
- if f.PasswordComplexityPolicy {
- list = append(list, domain.FeaturePasswordComplexityPolicy)
- }
- if f.LabelPolicyPrivateLabel {
- list = append(list, domain.FeatureLabelPolicyPrivateLabel)
- }
- if f.LabelPolicyWatermark {
- list = append(list, domain.FeatureLabelPolicyWatermark)
- }
- if f.CustomDomain {
- list = append(list, domain.FeatureCustomDomain)
- }
- if f.PrivacyPolicy {
- list = append(list, domain.FeaturePrivacyPolicy)
- }
- if f.MetadataUser {
- list = append(list, domain.FeatureMetadataUser)
- }
- if f.CustomTextMessage {
- list = append(list, domain.FeatureCustomTextMessage)
- }
- if f.CustomTextLogin {
- list = append(list, domain.FeatureCustomTextLogin)
- }
- if f.LockoutPolicy {
- list = append(list, domain.FeatureLockoutPolicy)
- }
- if f.ActionsAllowed != domain.ActionsNotAllowed {
- list = append(list, domain.FeatureActions)
- }
- return list
-}
diff --git a/internal/query/features_test.go b/internal/query/features_test.go
deleted file mode 100644
index daa11b31e..000000000
--- a/internal/query/features_test.go
+++ /dev/null
@@ -1,358 +0,0 @@
-package query
-
-import (
- "database/sql"
- "database/sql/driver"
- "errors"
- "fmt"
- "regexp"
- "testing"
- "time"
-
- "github.com/zitadel/zitadel/internal/domain"
- errs "github.com/zitadel/zitadel/internal/errors"
-)
-
-func Test_FeaturesPrepares(t *testing.T) {
- type want struct {
- sqlExpectations sqlExpectation
- err checkErr
- }
- tests := []struct {
- name string
- prepare interface{}
- want want
- object interface{}
- }{
- {
- name: "prepareFeaturesQuery no result",
- prepare: prepareFeaturesQuery,
- want: want{
- sqlExpectations: mockQuery(
- regexp.QuoteMeta(`SELECT projections.features.aggregate_id,`+
- ` projections.features.change_date,`+
- ` projections.features.sequence,`+
- ` projections.features.is_default,`+
- ` projections.features.tier_name,`+
- ` projections.features.tier_description,`+
- ` projections.features.state,`+
- ` projections.features.state_description,`+
- ` projections.features.audit_log_retention,`+
- ` projections.features.login_policy_factors,`+
- ` projections.features.login_policy_idp,`+
- ` projections.features.login_policy_passwordless,`+
- ` projections.features.login_policy_registration,`+
- ` projections.features.login_policy_username_login,`+
- ` projections.features.login_policy_password_reset,`+
- ` projections.features.password_complexity_policy,`+
- ` projections.features.label_policy_private_label,`+
- ` projections.features.label_policy_watermark,`+
- ` projections.features.custom_domain,`+
- ` projections.features.privacy_policy,`+
- ` projections.features.metadata_user,`+
- ` projections.features.custom_text_message,`+
- ` projections.features.custom_text_login,`+
- ` projections.features.lockout_policy,`+
- ` projections.features.actions_allowed,`+
- ` projections.features.max_actions`+
- ` FROM projections.features`),
- nil,
- nil,
- ),
- err: func(err error) (error, bool) {
- if !errs.IsNotFound(err) {
- return fmt.Errorf("err should be zitadel.NotFoundError got: %w", err), false
- }
- return nil, true
- },
- },
- object: (*Features)(nil),
- },
- {
- name: "prepareFeaturesQuery found",
- prepare: prepareFeaturesQuery,
- want: want{
- sqlExpectations: mockQuery(
- regexp.QuoteMeta(`SELECT projections.features.aggregate_id,`+
- ` projections.features.change_date,`+
- ` projections.features.sequence,`+
- ` projections.features.is_default,`+
- ` projections.features.tier_name,`+
- ` projections.features.tier_description,`+
- ` projections.features.state,`+
- ` projections.features.state_description,`+
- ` projections.features.audit_log_retention,`+
- ` projections.features.login_policy_factors,`+
- ` projections.features.login_policy_idp,`+
- ` projections.features.login_policy_passwordless,`+
- ` projections.features.login_policy_registration,`+
- ` projections.features.login_policy_username_login,`+
- ` projections.features.login_policy_password_reset,`+
- ` projections.features.password_complexity_policy,`+
- ` projections.features.label_policy_private_label,`+
- ` projections.features.label_policy_watermark,`+
- ` projections.features.custom_domain,`+
- ` projections.features.privacy_policy,`+
- ` projections.features.metadata_user,`+
- ` projections.features.custom_text_message,`+
- ` projections.features.custom_text_login,`+
- ` projections.features.lockout_policy,`+
- ` projections.features.actions_allowed,`+
- ` projections.features.max_actions`+
- ` FROM projections.features`),
- []string{
- "aggregate_id",
- "change_date",
- "sequence",
- "is_default",
- "tier_name",
- "tier_description",
- "state",
- "state_description",
- "audit_log_retention",
- "login_policy_factors",
- "login_policy_idp",
- "login_policy_passwordless",
- "login_policy_registration",
- "login_policy_username_login",
- "login_policy_password_reset",
- "password_complexity_policy",
- "label_policy_private_label",
- "label_policy_watermark",
- "custom_domain",
- "privacy_policy",
- "metadata_user",
- "custom_text_message",
- "custom_text_login",
- "lockout_policy",
- "actions_allowed",
- "max_actions",
- },
- []driver.Value{
- "aggregate-id",
- testNow,
- uint64(20211115),
- true,
- "tier-name",
- "tier-description",
- 1,
- "state-description",
- uint(604800000000000), // 7days in nanoseconds
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- domain.ActionsMaxAllowed,
- 10,
- },
- ),
- },
- object: &Features{
- AggregateID: "aggregate-id",
- ChangeDate: testNow,
- Sequence: 20211115,
- IsDefault: true,
- TierName: "tier-name",
- TierDescription: "tier-description",
- State: domain.FeaturesStateActive,
- StateDescription: "state-description",
- AuditLogRetention: 7 * 24 * time.Hour,
- LoginPolicyFactors: true,
- LoginPolicyIDP: true,
- LoginPolicyPasswordless: true,
- LoginPolicyRegistration: true,
- LoginPolicyUsernameLogin: true,
- LoginPolicyPasswordReset: true,
- PasswordComplexityPolicy: true,
- LabelPolicyPrivateLabel: true,
- LabelPolicyWatermark: true,
- CustomDomain: true,
- PrivacyPolicy: true,
- MetadataUser: true,
- CustomTextMessage: true,
- CustomTextLogin: true,
- LockoutPolicy: true,
- ActionsAllowed: domain.ActionsMaxAllowed,
- MaxActions: 10,
- },
- },
- {
- name: "prepareFeaturesQuery found with empty",
- prepare: prepareFeaturesQuery,
- want: want{
- sqlExpectations: mockQuery(
- regexp.QuoteMeta(`SELECT projections.features.aggregate_id,`+
- ` projections.features.change_date,`+
- ` projections.features.sequence,`+
- ` projections.features.is_default,`+
- ` projections.features.tier_name,`+
- ` projections.features.tier_description,`+
- ` projections.features.state,`+
- ` projections.features.state_description,`+
- ` projections.features.audit_log_retention,`+
- ` projections.features.login_policy_factors,`+
- ` projections.features.login_policy_idp,`+
- ` projections.features.login_policy_passwordless,`+
- ` projections.features.login_policy_registration,`+
- ` projections.features.login_policy_username_login,`+
- ` projections.features.login_policy_password_reset,`+
- ` projections.features.password_complexity_policy,`+
- ` projections.features.label_policy_private_label,`+
- ` projections.features.label_policy_watermark,`+
- ` projections.features.custom_domain,`+
- ` projections.features.privacy_policy,`+
- ` projections.features.metadata_user,`+
- ` projections.features.custom_text_message,`+
- ` projections.features.custom_text_login,`+
- ` projections.features.lockout_policy,`+
- ` projections.features.actions_allowed,`+
- ` projections.features.max_actions`+
- ` FROM projections.features`),
- []string{
- "aggregate_id",
- "change_date",
- "sequence",
- "is_default",
- "tier_name",
- "tier_description",
- "state",
- "state_description",
- "audit_log_retention",
- "login_policy_factors",
- "login_policy_idp",
- "login_policy_passwordless",
- "login_policy_registration",
- "login_policy_username_login",
- "login_policy_password_reset",
- "password_complexity_policy",
- "label_policy_private_label",
- "label_policy_watermark",
- "custom_domain",
- "privacy_policy",
- "metadata_user",
- "custom_text_message",
- "custom_text_login",
- "lockout_policy",
- "actions_allowed",
- "max_actions",
- },
- []driver.Value{
- "aggregate-id",
- testNow,
- uint64(20211115),
- true,
- nil,
- nil,
- 1,
- nil,
- uint(604800000000000), // 7days in nanoseconds
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- domain.ActionsMaxAllowed,
- 10,
- },
- ),
- },
- object: &Features{
- AggregateID: "aggregate-id",
- ChangeDate: testNow,
- Sequence: 20211115,
- IsDefault: true,
- TierName: "",
- TierDescription: "",
- State: domain.FeaturesStateActive,
- StateDescription: "",
- AuditLogRetention: 7 * 24 * time.Hour,
- LoginPolicyFactors: true,
- LoginPolicyIDP: true,
- LoginPolicyPasswordless: true,
- LoginPolicyRegistration: true,
- LoginPolicyUsernameLogin: true,
- LoginPolicyPasswordReset: true,
- PasswordComplexityPolicy: true,
- LabelPolicyPrivateLabel: true,
- LabelPolicyWatermark: true,
- CustomDomain: true,
- PrivacyPolicy: true,
- MetadataUser: true,
- CustomTextMessage: true,
- CustomTextLogin: true,
- LockoutPolicy: true,
- ActionsAllowed: domain.ActionsMaxAllowed,
- MaxActions: 10,
- },
- },
- {
- name: "prepareFeaturesQuery sql err",
- prepare: prepareFeaturesQuery,
- want: want{
- sqlExpectations: mockQueryErr(
- regexp.QuoteMeta(`SELECT projections.features.aggregate_id,`+
- ` projections.features.change_date,`+
- ` projections.features.sequence,`+
- ` projections.features.is_default,`+
- ` projections.features.tier_name,`+
- ` projections.features.tier_description,`+
- ` projections.features.state,`+
- ` projections.features.state_description,`+
- ` projections.features.audit_log_retention,`+
- ` projections.features.login_policy_factors,`+
- ` projections.features.login_policy_idp,`+
- ` projections.features.login_policy_passwordless,`+
- ` projections.features.login_policy_registration,`+
- ` projections.features.login_policy_username_login,`+
- ` projections.features.login_policy_password_reset,`+
- ` projections.features.password_complexity_policy,`+
- ` projections.features.label_policy_private_label,`+
- ` projections.features.label_policy_watermark,`+
- ` projections.features.custom_domain,`+
- ` projections.features.privacy_policy,`+
- ` projections.features.metadata_user,`+
- ` projections.features.custom_text_message,`+
- ` projections.features.custom_text_login,`+
- ` projections.features.lockout_policy,`+
- ` projections.features.actions_allowed,`+
- ` projections.features.max_actions`+
- ` FROM projections.features`),
- sql.ErrConnDone,
- ),
- err: func(err error) (error, bool) {
- if !errors.Is(err, sql.ErrConnDone) {
- return fmt.Errorf("err should be sql.ErrConnDone got: %w", err), false
- }
- return nil, true
- },
- },
- object: nil,
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- assertPrepare(t, tt.prepare, tt.object, tt.want.sqlExpectations, tt.want.err)
- })
- }
-}
diff --git a/internal/query/projection/feature.go b/internal/query/projection/feature.go
deleted file mode 100644
index 7f8ca8638..000000000
--- a/internal/query/projection/feature.go
+++ /dev/null
@@ -1,237 +0,0 @@
-package projection
-
-import (
- "context"
-
- "github.com/zitadel/zitadel/internal/domain"
-
- "github.com/zitadel/zitadel/internal/errors"
- "github.com/zitadel/zitadel/internal/eventstore"
- "github.com/zitadel/zitadel/internal/eventstore/handler"
- "github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
- "github.com/zitadel/zitadel/internal/repository/features"
- "github.com/zitadel/zitadel/internal/repository/instance"
- "github.com/zitadel/zitadel/internal/repository/org"
-)
-
-const (
- FeatureTable = "projections.features"
-
- FeatureAggregateIDCol = "aggregate_id"
- FeatureInstanceIDCol = "instance_id"
- FeatureChangeDateCol = "change_date"
- FeatureSequenceCol = "sequence"
- FeatureIsDefaultCol = "is_default"
- FeatureTierNameCol = "tier_name"
- FeatureTierDescriptionCol = "tier_description"
- FeatureStateCol = "state"
- FeatureStateDescriptionCol = "state_description"
- FeatureAuditLogRetentionCol = "audit_log_retention"
- FeatureLoginPolicyFactorsCol = "login_policy_factors"
- FeatureLoginPolicyIDPCol = "login_policy_idp"
- FeatureLoginPolicyPasswordlessCol = "login_policy_passwordless"
- FeatureLoginPolicyRegistrationCol = "login_policy_registration"
- FeatureLoginPolicyUsernameLoginCol = "login_policy_username_login"
- FeatureLoginPolicyPasswordResetCol = "login_policy_password_reset"
- FeaturePasswordComplexityPolicyCol = "password_complexity_policy"
- FeatureLabelPolicyPrivateLabelCol = "label_policy_private_label"
- FeatureLabelPolicyWatermarkCol = "label_policy_watermark"
- FeatureCustomDomainCol = "custom_domain"
- FeaturePrivacyPolicyCol = "privacy_policy"
- FeatureMetadataUserCol = "metadata_user"
- FeatureCustomTextMessageCol = "custom_text_message"
- FeatureCustomTextLoginCol = "custom_text_login"
- FeatureLockoutPolicyCol = "lockout_policy"
- FeatureActionsAllowedCol = "actions_allowed"
- FeatureMaxActionsCol = "max_actions"
-)
-
-type FeatureProjection struct {
- crdb.StatementHandler
-}
-
-func NewFeatureProjection(ctx context.Context, config crdb.StatementHandlerConfig) *FeatureProjection {
- p := new(FeatureProjection)
- config.ProjectionName = FeatureTable
- config.Reducers = p.reducers()
- config.InitCheck = crdb.NewTableCheck(
- crdb.NewTable([]*crdb.Column{
- crdb.NewColumn(FeatureAggregateIDCol, crdb.ColumnTypeText),
- crdb.NewColumn(FeatureInstanceIDCol, crdb.ColumnTypeText),
- crdb.NewColumn(FeatureChangeDateCol, crdb.ColumnTypeTimestamp),
- crdb.NewColumn(FeatureSequenceCol, crdb.ColumnTypeInt64),
- crdb.NewColumn(FeatureIsDefaultCol, crdb.ColumnTypeBool, crdb.Default(false)),
- crdb.NewColumn(FeatureTierNameCol, crdb.ColumnTypeText),
- crdb.NewColumn(FeatureTierDescriptionCol, crdb.ColumnTypeText, crdb.Nullable()),
- crdb.NewColumn(FeatureStateCol, crdb.ColumnTypeEnum, crdb.Default(0)),
- crdb.NewColumn(FeatureStateDescriptionCol, crdb.ColumnTypeText, crdb.Nullable()),
- crdb.NewColumn(FeatureAuditLogRetentionCol, crdb.ColumnTypeInt64, crdb.Default(0)),
- crdb.NewColumn(FeatureLoginPolicyFactorsCol, crdb.ColumnTypeBool, crdb.Default(false)),
- crdb.NewColumn(FeatureLoginPolicyIDPCol, crdb.ColumnTypeBool, crdb.Default(false)),
- crdb.NewColumn(FeatureLoginPolicyPasswordlessCol, crdb.ColumnTypeBool, crdb.Default(false)),
- crdb.NewColumn(FeatureLoginPolicyRegistrationCol, crdb.ColumnTypeBool, crdb.Default(false)),
- crdb.NewColumn(FeatureLoginPolicyUsernameLoginCol, crdb.ColumnTypeBool, crdb.Default(false)),
- crdb.NewColumn(FeatureLoginPolicyPasswordResetCol, crdb.ColumnTypeBool, crdb.Default(false)),
- crdb.NewColumn(FeaturePasswordComplexityPolicyCol, crdb.ColumnTypeBool, crdb.Default(false)),
- crdb.NewColumn(FeatureLabelPolicyPrivateLabelCol, crdb.ColumnTypeBool, crdb.Default(false)),
- crdb.NewColumn(FeatureLabelPolicyWatermarkCol, crdb.ColumnTypeBool, crdb.Default(false)),
- crdb.NewColumn(FeatureCustomDomainCol, crdb.ColumnTypeBool, crdb.Default(false)),
- crdb.NewColumn(FeaturePrivacyPolicyCol, crdb.ColumnTypeBool, crdb.Default(false)),
- crdb.NewColumn(FeatureMetadataUserCol, crdb.ColumnTypeBool, crdb.Default(false)),
- crdb.NewColumn(FeatureCustomTextMessageCol, crdb.ColumnTypeBool, crdb.Default(false)),
- crdb.NewColumn(FeatureCustomTextLoginCol, crdb.ColumnTypeBool, crdb.Default(false)),
- crdb.NewColumn(FeatureLockoutPolicyCol, crdb.ColumnTypeBool, crdb.Default(false)),
- crdb.NewColumn(FeatureActionsAllowedCol, crdb.ColumnTypeEnum, crdb.Default(0)),
- crdb.NewColumn(FeatureMaxActionsCol, crdb.ColumnTypeInt64, crdb.Default(0)),
- },
- crdb.NewPrimaryKey(FeatureInstanceIDCol, FeatureAggregateIDCol),
- ),
- )
- p.StatementHandler = crdb.NewStatementHandler(ctx, config)
- return p
-}
-
-func (p *FeatureProjection) reducers() []handler.AggregateReducer {
- return []handler.AggregateReducer{
- {
- Aggregate: org.AggregateType,
- EventRedusers: []handler.EventReducer{
- {
- Event: org.FeaturesSetEventType,
- Reduce: p.reduceFeatureSet,
- },
- {
- Event: org.FeaturesRemovedEventType,
- Reduce: p.reduceFeatureRemoved,
- },
- },
- },
- {
- Aggregate: instance.AggregateType,
- EventRedusers: []handler.EventReducer{
- {
- Event: instance.FeaturesSetEventType,
- Reduce: p.reduceFeatureSet,
- },
- },
- },
- }
-}
-
-func (p *FeatureProjection) reduceFeatureSet(event eventstore.Event) (*handler.Statement, error) {
- var featureEvent features.FeaturesSetEvent
- var isDefault bool
- switch e := event.(type) {
- case *instance.FeaturesSetEvent:
- featureEvent = e.FeaturesSetEvent
- isDefault = true
- case *org.FeaturesSetEvent:
- featureEvent = e.FeaturesSetEvent
- isDefault = false
- default:
- return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-K0erf", "reduce.wrong.event.type %v", []eventstore.EventType{org.FeaturesSetEventType, instance.FeaturesSetEventType})
- }
-
- cols := []handler.Column{
- handler.NewCol(FeatureAggregateIDCol, featureEvent.Aggregate().ID),
- handler.NewCol(FeatureInstanceIDCol, featureEvent.Aggregate().InstanceID),
- handler.NewCol(FeatureChangeDateCol, featureEvent.CreationDate()),
- handler.NewCol(FeatureSequenceCol, featureEvent.Sequence()),
- handler.NewCol(FeatureIsDefaultCol, isDefault),
- }
- if featureEvent.TierName != nil {
- cols = append(cols, handler.NewCol(FeatureTierNameCol, *featureEvent.TierName))
- }
- if featureEvent.TierDescription != nil {
- cols = append(cols, handler.NewCol(FeatureTierDescriptionCol, *featureEvent.TierDescription))
- }
- if featureEvent.State != nil {
- cols = append(cols, handler.NewCol(FeatureStateCol, *featureEvent.State))
- }
- if featureEvent.StateDescription != nil {
- cols = append(cols, handler.NewCol(FeatureStateDescriptionCol, *featureEvent.StateDescription))
- }
- if featureEvent.AuditLogRetention != nil {
- cols = append(cols, handler.NewCol(FeatureAuditLogRetentionCol, *featureEvent.AuditLogRetention))
- }
- if featureEvent.LoginPolicyFactors != nil {
- cols = append(cols, handler.NewCol(FeatureLoginPolicyFactorsCol, *featureEvent.LoginPolicyFactors))
- }
- if featureEvent.LoginPolicyIDP != nil {
- cols = append(cols, handler.NewCol(FeatureLoginPolicyIDPCol, *featureEvent.LoginPolicyIDP))
- }
- if featureEvent.LoginPolicyPasswordless != nil {
- cols = append(cols, handler.NewCol(FeatureLoginPolicyPasswordlessCol, *featureEvent.LoginPolicyPasswordless))
- }
- if featureEvent.LoginPolicyRegistration != nil {
- cols = append(cols, handler.NewCol(FeatureLoginPolicyRegistrationCol, *featureEvent.LoginPolicyRegistration))
- }
- if featureEvent.LoginPolicyUsernameLogin != nil {
- cols = append(cols, handler.NewCol(FeatureLoginPolicyUsernameLoginCol, *featureEvent.LoginPolicyUsernameLogin))
- }
- if featureEvent.LoginPolicyPasswordReset != nil {
- cols = append(cols, handler.NewCol(FeatureLoginPolicyPasswordResetCol, *featureEvent.LoginPolicyPasswordReset))
- }
- if featureEvent.PasswordComplexityPolicy != nil {
- cols = append(cols, handler.NewCol(FeaturePasswordComplexityPolicyCol, *featureEvent.PasswordComplexityPolicy))
- }
- if featureEvent.LabelPolicyPrivateLabel != nil || featureEvent.LabelPolicy != nil {
- var value bool
- if featureEvent.LabelPolicyPrivateLabel != nil {
- value = *featureEvent.LabelPolicyPrivateLabel
- } else {
- value = *featureEvent.LabelPolicy
- }
- cols = append(cols, handler.NewCol(FeatureLabelPolicyPrivateLabelCol, value))
- }
- if featureEvent.LabelPolicyWatermark != nil {
- cols = append(cols, handler.NewCol(FeatureLabelPolicyWatermarkCol, *featureEvent.LabelPolicyWatermark))
- }
- if featureEvent.CustomDomain != nil {
- cols = append(cols, handler.NewCol(FeatureCustomDomainCol, *featureEvent.CustomDomain))
- }
- if featureEvent.PrivacyPolicy != nil {
- cols = append(cols, handler.NewCol(FeaturePrivacyPolicyCol, *featureEvent.PrivacyPolicy))
- }
- if featureEvent.MetadataUser != nil {
- cols = append(cols, handler.NewCol(FeatureMetadataUserCol, *featureEvent.MetadataUser))
- }
- if featureEvent.CustomTextMessage != nil {
- cols = append(cols, handler.NewCol(FeatureCustomTextMessageCol, *featureEvent.CustomTextMessage))
- }
- if featureEvent.CustomTextLogin != nil {
- cols = append(cols, handler.NewCol(FeatureCustomTextLoginCol, *featureEvent.CustomTextLogin))
- }
- if featureEvent.LockoutPolicy != nil {
- cols = append(cols, handler.NewCol(FeatureLockoutPolicyCol, *featureEvent.LockoutPolicy))
- }
- if featureEvent.Actions != nil {
- actionsAllowed := domain.ActionsNotAllowed
- if *featureEvent.Actions {
- actionsAllowed = domain.ActionsAllowedUnlimited
- }
- cols = append(cols, handler.NewCol(FeatureActionsAllowedCol, actionsAllowed))
- }
- if featureEvent.ActionsAllowed != nil {
- cols = append(cols, handler.NewCol(FeatureActionsAllowedCol, *featureEvent.ActionsAllowed))
- }
- if featureEvent.MaxActions != nil {
- cols = append(cols, handler.NewCol(FeatureMaxActionsCol, *featureEvent.MaxActions))
- }
- return crdb.NewUpsertStatement(
- &featureEvent,
- cols), nil
-}
-
-func (p *FeatureProjection) reduceFeatureRemoved(event eventstore.Event) (*handler.Statement, error) {
- e, ok := event.(*org.FeaturesRemovedEvent)
- if !ok {
- return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-0p4rf", "reduce.wrong.event.type %s", org.FeaturesRemovedEventType)
- }
- return crdb.NewDeleteStatement(
- e,
- []handler.Condition{
- handler.NewCond(FeatureAggregateIDCol, e.Aggregate().ID),
- },
- ), nil
-}
diff --git a/internal/query/projection/feature_test.go b/internal/query/projection/feature_test.go
deleted file mode 100644
index af758b008..000000000
--- a/internal/query/projection/feature_test.go
+++ /dev/null
@@ -1,398 +0,0 @@
-package projection
-
-import (
- "testing"
- "time"
-
- "github.com/zitadel/zitadel/internal/domain"
- "github.com/zitadel/zitadel/internal/errors"
- "github.com/zitadel/zitadel/internal/eventstore"
- "github.com/zitadel/zitadel/internal/eventstore/handler"
- "github.com/zitadel/zitadel/internal/eventstore/repository"
- "github.com/zitadel/zitadel/internal/repository/instance"
- "github.com/zitadel/zitadel/internal/repository/org"
-)
-
-func TestFeatureProjection_reduces(t *testing.T) {
- type args struct {
- event func(t *testing.T) eventstore.Event
- }
- tests := []struct {
- name string
- args args
- reduce func(event eventstore.Event) (*handler.Statement, error)
- want wantReduce
- }{
- {
- name: "org.reduceFeatureSet new",
- args: args{
- event: getEvent(testEvent(
- repository.EventType(org.FeaturesSetEventType),
- org.AggregateType,
- []byte(`{
- "tierName": "TierName",
- "tierDescription": "TierDescription",
- "state": 1,
- "stateDescription": "StateDescription",
- "auditLogRetention": 1,
- "loginPolicyFactors": true,
- "loginPolicyIDP": true,
- "loginPolicyPasswordless": true,
- "loginPolicyRegistration": true,
- "loginPolicyUsernameLogin": true,
- "loginPolicyPasswordReset": true,
- "passwordComplexityPolicy": true,
- "labelPolicyPrivateLabel": true,
- "labelPolicyWatermark": true,
- "customDomain": true,
- "privacyPolicy": true,
- "metadataUser": true,
- "customTextMessage": true,
- "customTextLogin": true,
- "lockoutPolicy": true,
- "actionsAllowed": 1,
- "maxActions": 10
- }`),
- ), org.FeaturesSetEventMapper),
- },
- reduce: (&FeatureProjection{}).reduceFeatureSet,
- want: wantReduce{
- aggregateType: eventstore.AggregateType("org"),
- sequence: 15,
- previousSequence: 10,
- projection: FeatureTable,
- executer: &testExecuter{
- executions: []execution{
- {
- expectedStmt: "UPSERT INTO projections.features (aggregate_id, instance_id, change_date, sequence, is_default, tier_name, tier_description, state, state_description, audit_log_retention, login_policy_factors, login_policy_idp, login_policy_passwordless, login_policy_registration, login_policy_username_login, login_policy_password_reset, password_complexity_policy, label_policy_private_label, label_policy_watermark, custom_domain, privacy_policy, metadata_user, custom_text_message, custom_text_login, lockout_policy, actions_allowed, max_actions) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27)",
- expectedArgs: []interface{}{
- "agg-id",
- "instance-id",
- anyArg{},
- uint64(15),
- false,
- "TierName",
- "TierDescription",
- domain.FeaturesStateActive,
- "StateDescription",
- time.Nanosecond,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- domain.ActionsMaxAllowed,
- 10,
- },
- },
- },
- },
- },
- },
- {
- name: "org.reduceFeatureSet old",
- args: args{
- event: getEvent(testEvent(
- repository.EventType(org.FeaturesSetEventType),
- org.AggregateType,
- []byte(`{
- "tierName": "TierName",
- "tierDescription": "TierDescription",
- "state": 1,
- "stateDescription": "StateDescription",
- "auditLogRetention": 1,
- "loginPolicyFactors": true,
- "loginPolicyIDP": true,
- "loginPolicyPasswordless": true,
- "loginPolicyRegistration": true,
- "loginPolicyUsernameLogin": true,
- "loginPolicyPasswordReset": true,
- "passwordComplexityPolicy": true,
- "labelPolicy": true,
- "labelPolicyWatermark": true,
- "customDomain": true,
- "privacyPolicy": true,
- "metadataUser": true,
- "customTextMessage": true,
- "customTextLogin": true,
- "lockoutPolicy": true,
- "actions": true
- }`),
- ), org.FeaturesSetEventMapper),
- },
- reduce: (&FeatureProjection{}).reduceFeatureSet,
- want: wantReduce{
- aggregateType: eventstore.AggregateType("org"),
- sequence: 15,
- previousSequence: 10,
- projection: FeatureTable,
- executer: &testExecuter{
- executions: []execution{
- {
- expectedStmt: "UPSERT INTO projections.features (aggregate_id, instance_id, change_date, sequence, is_default, tier_name, tier_description, state, state_description, audit_log_retention, login_policy_factors, login_policy_idp, login_policy_passwordless, login_policy_registration, login_policy_username_login, login_policy_password_reset, password_complexity_policy, label_policy_private_label, label_policy_watermark, custom_domain, privacy_policy, metadata_user, custom_text_message, custom_text_login, lockout_policy, actions_allowed) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26)",
- expectedArgs: []interface{}{
- "agg-id",
- "instance-id",
- anyArg{},
- uint64(15),
- false,
- "TierName",
- "TierDescription",
- domain.FeaturesStateActive,
- "StateDescription",
- time.Nanosecond,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- domain.ActionsAllowedUnlimited,
- },
- },
- },
- },
- },
- },
- {
- name: "org.reduceFeatureSet required values only",
- args: args{
- event: getEvent(testEvent(
- repository.EventType(org.FeaturesSetEventType),
- org.AggregateType,
- []byte(`{}`),
- ), org.FeaturesSetEventMapper),
- },
- reduce: (&FeatureProjection{}).reduceFeatureSet,
- want: wantReduce{
- aggregateType: eventstore.AggregateType("org"),
- sequence: 15,
- previousSequence: 10,
- projection: FeatureTable,
- executer: &testExecuter{
- executions: []execution{
- {
- expectedStmt: "UPSERT INTO projections.features (aggregate_id, instance_id, change_date, sequence, is_default) VALUES ($1, $2, $3, $4, $5)",
- expectedArgs: []interface{}{
- "agg-id",
- "instance-id",
- anyArg{},
- uint64(15),
- false,
- },
- },
- },
- },
- },
- },
- {
- name: "org.reduceFeatureRemoved",
- reduce: (&FeatureProjection{}).reduceFeatureRemoved,
- args: args{
- event: getEvent(testEvent(
- repository.EventType(org.FeaturesRemovedEventType),
- org.AggregateType,
- nil,
- ), org.FeaturesRemovedEventMapper),
- },
- want: wantReduce{
- aggregateType: eventstore.AggregateType("org"),
- sequence: 15,
- previousSequence: 10,
- projection: FeatureTable,
- executer: &testExecuter{
- executions: []execution{
- {
- expectedStmt: "DELETE FROM projections.features WHERE (aggregate_id = $1)",
- expectedArgs: []interface{}{
- "agg-id",
- },
- },
- },
- },
- },
- },
- {
- name: "instance.reduceFeatureSet old",
- reduce: (&FeatureProjection{}).reduceFeatureSet,
- args: args{
- event: getEvent(testEvent(
- repository.EventType(instance.FeaturesSetEventType),
- instance.AggregateType,
- []byte(`{
- "tierName": "TierName",
- "tierDescription": "TierDescription",
- "state": 1,
- "stateDescription": "StateDescription",
- "auditLogRetention": 1,
- "loginPolicyFactors": true,
- "loginPolicyIDP": true,
- "loginPolicyPasswordless": true,
- "loginPolicyRegistration": true,
- "loginPolicyUsernameLogin": true,
- "loginPolicyPasswordReset": true,
- "passwordComplexityPolicy": true,
- "labelPolicy": true,
- "labelPolicyWatermark": true,
- "customDomain": true,
- "privacyPolicy": true,
- "metadataUser": true,
- "customTextMessage": true,
- "customTextLogin": true,
- "lockoutPolicy": true,
- "actions": true
- }`),
- ), instance.FeaturesSetEventMapper),
- },
- want: wantReduce{
- aggregateType: eventstore.AggregateType("instance"),
- sequence: 15,
- previousSequence: 10,
- projection: FeatureTable,
- executer: &testExecuter{
- executions: []execution{
- {
- expectedStmt: "UPSERT INTO projections.features (aggregate_id, instance_id, change_date, sequence, is_default, tier_name, tier_description, state, state_description, audit_log_retention, login_policy_factors, login_policy_idp, login_policy_passwordless, login_policy_registration, login_policy_username_login, login_policy_password_reset, password_complexity_policy, label_policy_private_label, label_policy_watermark, custom_domain, privacy_policy, metadata_user, custom_text_message, custom_text_login, lockout_policy, actions_allowed) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26)",
- expectedArgs: []interface{}{
- "agg-id",
- "instance-id",
- anyArg{},
- uint64(15),
- true,
- "TierName",
- "TierDescription",
- domain.FeaturesStateActive,
- "StateDescription",
- time.Nanosecond,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- domain.ActionsAllowedUnlimited,
- },
- },
- },
- },
- },
- },
- {
- name: "instance.reduceFeatureSet new",
- reduce: (&FeatureProjection{}).reduceFeatureSet,
- args: args{
- event: getEvent(testEvent(
- repository.EventType(instance.FeaturesSetEventType),
- instance.AggregateType,
- []byte(`{
- "tierName": "TierName",
- "tierDescription": "TierDescription",
- "state": 1,
- "stateDescription": "StateDescription",
- "auditLogRetention": 1,
- "loginPolicyFactors": true,
- "loginPolicyIDP": true,
- "loginPolicyPasswordless": true,
- "loginPolicyRegistration": true,
- "loginPolicyUsernameLogin": true,
- "loginPolicyPasswordReset": true,
- "passwordComplexityPolicy": true,
- "labelPolicyPrivateLabel": true,
- "labelPolicyWatermark": true,
- "customDomain": true,
- "privacyPolicy": true,
- "metadataUser": true,
- "customTextMessage": true,
- "customTextLogin": true,
- "lockoutPolicy": true,
- "actionsAllowed": 1,
- "maxActions": 10
- }`),
- ), instance.FeaturesSetEventMapper),
- },
- want: wantReduce{
- aggregateType: eventstore.AggregateType("instance"),
- sequence: 15,
- previousSequence: 10,
- projection: FeatureTable,
- executer: &testExecuter{
- executions: []execution{
- {
- expectedStmt: "UPSERT INTO projections.features (aggregate_id, instance_id, change_date, sequence, is_default, tier_name, tier_description, state, state_description, audit_log_retention, login_policy_factors, login_policy_idp, login_policy_passwordless, login_policy_registration, login_policy_username_login, login_policy_password_reset, password_complexity_policy, label_policy_private_label, label_policy_watermark, custom_domain, privacy_policy, metadata_user, custom_text_message, custom_text_login, lockout_policy, actions_allowed, max_actions) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27)",
- expectedArgs: []interface{}{
- "agg-id",
- "instance-id",
- anyArg{},
- uint64(15),
- true,
- "TierName",
- "TierDescription",
- domain.FeaturesStateActive,
- "StateDescription",
- time.Nanosecond,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- true,
- domain.ActionsMaxAllowed,
- 10,
- },
- },
- },
- },
- },
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- event := baseEvent(t)
- got, err := tt.reduce(event)
- if !errors.IsErrorInvalidArgument(err) {
- t.Errorf("no wrong event mapping: %v, got: %v", err, got)
- }
-
- event = tt.args.event(t)
- got, err = tt.reduce(event)
- assertReduce(t, got, err, tt.want)
- })
- }
-}
diff --git a/internal/query/projection/projection.go b/internal/query/projection/projection.go
index 872a271a3..ac5246f89 100644
--- a/internal/query/projection/projection.go
+++ b/internal/query/projection/projection.go
@@ -55,7 +55,6 @@ func Start(ctx context.Context, sqlClient *sql.DB, es *eventstore.Eventstore, co
NewMailTemplateProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["mail_templates"]))
NewMessageTextProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["message_texts"]))
NewCustomTextProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["custom_texts"]))
- NewFeatureProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["features"]))
NewUserProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["users"]))
NewLoginNameProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["login_names"]))
NewOrgMemberProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["org_members"]))
diff --git a/internal/repository/features/features.go b/internal/repository/features/features.go
deleted file mode 100644
index 0d67cf8a2..000000000
--- a/internal/repository/features/features.go
+++ /dev/null
@@ -1,245 +0,0 @@
-package features
-
-import (
- "encoding/json"
- "time"
-
- "github.com/zitadel/zitadel/internal/domain"
- "github.com/zitadel/zitadel/internal/errors"
- "github.com/zitadel/zitadel/internal/eventstore"
- "github.com/zitadel/zitadel/internal/eventstore/repository"
-)
-
-const (
- featuresPrefix = "features."
- FeaturesSetEventType = featuresPrefix + "set"
- FeaturesRemovedEventType = featuresPrefix + "removed"
-)
-
-type FeaturesSetEvent struct {
- eventstore.BaseEvent `json:"-"`
-
- TierName *string `json:"tierName,omitempty"`
- TierDescription *string `json:"tierDescription,omitempty"`
- State *domain.FeaturesState `json:"state,omitempty"`
- StateDescription *string `json:"stateDescription,omitempty"`
- AuditLogRetention *time.Duration `json:"auditLogRetention,omitempty"`
- LoginPolicyFactors *bool `json:"loginPolicyFactors,omitempty"`
- LoginPolicyIDP *bool `json:"loginPolicyIDP,omitempty"`
- LoginPolicyPasswordless *bool `json:"loginPolicyPasswordless,omitempty"`
- LoginPolicyRegistration *bool `json:"loginPolicyRegistration,omitempty"`
- LoginPolicyUsernameLogin *bool `json:"loginPolicyUsernameLogin,omitempty"`
- LoginPolicyPasswordReset *bool `json:"loginPolicyPasswordReset,omitempty"`
- PasswordComplexityPolicy *bool `json:"passwordComplexityPolicy,omitempty"`
- LabelPolicy *bool `json:"labelPolicy,omitempty"`
- LabelPolicyPrivateLabel *bool `json:"labelPolicyPrivateLabel,omitempty"`
- LabelPolicyWatermark *bool `json:"labelPolicyWatermark,omitempty"`
- CustomDomain *bool `json:"customDomain,omitempty"`
- PrivacyPolicy *bool `json:"privacyPolicy,omitempty"`
- MetadataUser *bool `json:"metadataUser,omitempty"`
- CustomTextMessage *bool `json:"customTextMessage,omitempty"`
- CustomTextLogin *bool `json:"customTextLogin,omitempty"`
- LockoutPolicy *bool `json:"lockoutPolicy,omitempty"`
- Actions *bool `json:"actions,omitempty"`
- ActionsAllowed *domain.ActionsAllowed `json:"actionsAllowed,omitempty"`
- MaxActions *int `json:"maxActions,omitempty"`
-}
-
-func (e *FeaturesSetEvent) Data() interface{} {
- return e
-}
-
-func (e *FeaturesSetEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
- return nil
-}
-
-func NewFeaturesSetEvent(
- base *eventstore.BaseEvent,
- changes []FeaturesChanges,
-) (*FeaturesSetEvent, error) {
- if len(changes) == 0 {
- return nil, errors.ThrowPreconditionFailed(nil, "FEATURES-d34F4", "Errors.NoChangesFound")
- }
- changeEvent := &FeaturesSetEvent{
- BaseEvent: *base,
- }
- for _, change := range changes {
- change(changeEvent)
- }
- return changeEvent, nil
-}
-
-type FeaturesChanges func(*FeaturesSetEvent)
-
-func ChangeTierName(tierName string) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.TierName = &tierName
- }
-}
-
-func ChangeTierDescription(tierDescription string) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.TierDescription = &tierDescription
- }
-}
-
-func ChangeState(State domain.FeaturesState) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.State = &State
- }
-}
-
-func ChangeStateDescription(statusDescription string) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.StateDescription = &statusDescription
- }
-}
-
-func ChangeAuditLogRetention(retention time.Duration) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.AuditLogRetention = &retention
- }
-}
-
-func ChangeLoginPolicyFactors(loginPolicyFactors bool) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.LoginPolicyFactors = &loginPolicyFactors
- }
-}
-
-func ChangeLoginPolicyIDP(loginPolicyIDP bool) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.LoginPolicyIDP = &loginPolicyIDP
- }
-}
-
-func ChangeLoginPolicyPasswordless(loginPolicyPasswordless bool) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.LoginPolicyPasswordless = &loginPolicyPasswordless
- }
-}
-
-func ChangeLoginPolicyRegistration(loginPolicyRegistration bool) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.LoginPolicyRegistration = &loginPolicyRegistration
- }
-}
-
-func ChangeLoginPolicyUsernameLogin(loginPolicyUsernameLogin bool) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.LoginPolicyUsernameLogin = &loginPolicyUsernameLogin
- }
-}
-
-func ChangeLoginPolicyPasswordReset(loginPolicyPasswordReset bool) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.LoginPolicyPasswordReset = &loginPolicyPasswordReset
- }
-}
-
-func ChangePasswordComplexityPolicy(passwordComplexityPolicy bool) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.PasswordComplexityPolicy = &passwordComplexityPolicy
- }
-}
-
-func ChangeLabelPolicyPrivateLabel(labelPolicyPrivateLabel bool) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.LabelPolicyPrivateLabel = &labelPolicyPrivateLabel
- }
-}
-
-func ChangeLabelPolicyWatermark(labelPolicyWatermark bool) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.LabelPolicyWatermark = &labelPolicyWatermark
- }
-}
-
-func ChangeCustomDomain(customDomain bool) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.CustomDomain = &customDomain
- }
-}
-
-func ChangePrivacyPolicy(privacyPolicy bool) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.PrivacyPolicy = &privacyPolicy
- }
-}
-
-func ChangeMetadataUser(metadataUser bool) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.MetadataUser = &metadataUser
- }
-}
-
-func ChangeCustomTextMessage(customTextMessage bool) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.CustomTextMessage = &customTextMessage
- }
-}
-
-func ChangeCustomTextLogin(customTextLogin bool) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.CustomTextLogin = &customTextLogin
- }
-}
-
-func ChangeLockoutPolicy(lockoutPolicy bool) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.LockoutPolicy = &lockoutPolicy
- }
-}
-
-func ChangeActionsAllowed(allowedType domain.ActionsAllowed) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.ActionsAllowed = &allowedType
- }
-}
-
-func ChangeMaxActions(maxActions int) func(event *FeaturesSetEvent) {
- return func(e *FeaturesSetEvent) {
- e.MaxActions = &maxActions
- }
-}
-
-func FeaturesSetEventMapper(event *repository.Event) (eventstore.Event, error) {
- e := &FeaturesSetEvent{
- BaseEvent: *eventstore.BaseEventFromRepo(event),
- }
-
- err := json.Unmarshal(event.Data, e)
- if err != nil {
- return nil, errors.ThrowInternal(err, "FEATURES-fdgDg", "unable to unmarshal features")
- }
-
- return e, nil
-}
-
-type FeaturesRemovedEvent struct {
- eventstore.BaseEvent `json:"-"`
-}
-
-func (e *FeaturesRemovedEvent) Data() interface{} {
- return nil
-}
-
-func (e *FeaturesRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
- return nil
-}
-
-func (e *FeaturesRemovedEvent) Assets() []*eventstore.Asset {
- return nil
-}
-
-func NewFeaturesRemovedEvent(base *eventstore.BaseEvent) *FeaturesRemovedEvent {
- return &FeaturesRemovedEvent{
- BaseEvent: *base,
- }
-}
-
-func FeaturesRemovedEventMapper(event *repository.Event) (eventstore.Event, error) {
- return &FeaturesRemovedEvent{
- BaseEvent: *eventstore.BaseEventFromRepo(event),
- }, nil
-}
diff --git a/internal/repository/instance/eventstore.go b/internal/repository/instance/eventstore.go
index 97a1cb27c..3fe9c4c28 100644
--- a/internal/repository/instance/eventstore.go
+++ b/internal/repository/instance/eventstore.go
@@ -85,7 +85,6 @@ func RegisterEventMappers(es *eventstore.Eventstore) {
RegisterFilterEventMapper(CustomTextSetEventType, CustomTextSetEventMapper).
RegisterFilterEventMapper(CustomTextRemovedEventType, CustomTextRemovedEventMapper).
RegisterFilterEventMapper(CustomTextTemplateRemovedEventType, CustomTextTemplateRemovedEventMapper).
- RegisterFilterEventMapper(FeaturesSetEventType, FeaturesSetEventMapper).
RegisterFilterEventMapper(InstanceDomainAddedEventType, DomainAddedEventMapper).
RegisterFilterEventMapper(InstanceDomainPrimarySetEventType, DomainPrimarySetEventMapper).
RegisterFilterEventMapper(InstanceDomainRemovedEventType, DomainRemovedEventMapper).
diff --git a/internal/repository/instance/features.go b/internal/repository/instance/features.go
deleted file mode 100644
index 6bd6637c2..000000000
--- a/internal/repository/instance/features.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package instance
-
-import (
- "context"
-
- "github.com/zitadel/zitadel/internal/eventstore"
- "github.com/zitadel/zitadel/internal/eventstore/repository"
- "github.com/zitadel/zitadel/internal/repository/features"
-)
-
-var (
- FeaturesSetEventType = instanceEventTypePrefix + features.FeaturesSetEventType
-)
-
-type FeaturesSetEvent struct {
- features.FeaturesSetEvent
-}
-
-func NewFeaturesSetEvent(
- ctx context.Context,
- aggregate *eventstore.Aggregate,
- changes []features.FeaturesChanges,
-) (*FeaturesSetEvent, error) {
- changedEvent, err := features.NewFeaturesSetEvent(
- eventstore.NewBaseEventForPush(
- ctx,
- aggregate,
- FeaturesSetEventType),
- changes,
- )
- if err != nil {
- return nil, err
- }
- return &FeaturesSetEvent{FeaturesSetEvent: *changedEvent}, nil
-}
-
-func FeaturesSetEventMapper(event *repository.Event) (eventstore.Event, error) {
- e, err := features.FeaturesSetEventMapper(event)
- if err != nil {
- return nil, err
- }
-
- return &FeaturesSetEvent{FeaturesSetEvent: *e.(*features.FeaturesSetEvent)}, nil
-}
diff --git a/internal/repository/org/eventstore.go b/internal/repository/org/eventstore.go
index e0b479e3c..6b1bd0da5 100644
--- a/internal/repository/org/eventstore.go
+++ b/internal/repository/org/eventstore.go
@@ -77,8 +77,6 @@ func RegisterEventMappers(es *eventstore.Eventstore) {
RegisterFilterEventMapper(IDPOIDCConfigChangedEventType, IDPOIDCConfigChangedEventMapper).
RegisterFilterEventMapper(IDPJWTConfigAddedEventType, IDPJWTConfigAddedEventMapper).
RegisterFilterEventMapper(IDPJWTConfigChangedEventType, IDPJWTConfigChangedEventMapper).
- RegisterFilterEventMapper(FeaturesSetEventType, FeaturesSetEventMapper).
- RegisterFilterEventMapper(FeaturesRemovedEventType, FeaturesRemovedEventMapper).
RegisterFilterEventMapper(TriggerActionsSetEventType, TriggerActionsSetEventMapper).
RegisterFilterEventMapper(TriggerActionsCascadeRemovedEventType, TriggerActionsCascadeRemovedEventMapper).
RegisterFilterEventMapper(FlowClearedEventType, FlowClearedEventMapper)
diff --git a/internal/repository/org/features.go b/internal/repository/org/features.go
deleted file mode 100644
index 7fbb0c33c..000000000
--- a/internal/repository/org/features.go
+++ /dev/null
@@ -1,72 +0,0 @@
-package org
-
-import (
- "context"
-
- "github.com/zitadel/zitadel/internal/eventstore"
- "github.com/zitadel/zitadel/internal/eventstore/repository"
- "github.com/zitadel/zitadel/internal/repository/features"
-)
-
-var (
- FeaturesSetEventType = orgEventTypePrefix + features.FeaturesSetEventType
- FeaturesRemovedEventType = orgEventTypePrefix + features.FeaturesRemovedEventType
-)
-
-type FeaturesSetEvent struct {
- features.FeaturesSetEvent
-}
-
-func NewFeaturesSetEvent(
- ctx context.Context,
- aggregate *eventstore.Aggregate,
- changes []features.FeaturesChanges,
-) (*FeaturesSetEvent, error) {
- changedEvent, err := features.NewFeaturesSetEvent(
- eventstore.NewBaseEventForPush(
- ctx,
- aggregate,
- FeaturesSetEventType),
- changes,
- )
- if err != nil {
- return nil, err
- }
- return &FeaturesSetEvent{FeaturesSetEvent: *changedEvent}, nil
-}
-
-func FeaturesSetEventMapper(event *repository.Event) (eventstore.Event, error) {
- e, err := features.FeaturesSetEventMapper(event)
- if err != nil {
- return nil, err
- }
-
- return &FeaturesSetEvent{FeaturesSetEvent: *e.(*features.FeaturesSetEvent)}, nil
-}
-
-type FeaturesRemovedEvent struct {
- features.FeaturesRemovedEvent
-}
-
-func NewFeaturesRemovedEvent(
- ctx context.Context,
- aggregate *eventstore.Aggregate,
-) *FeaturesRemovedEvent {
- return &FeaturesRemovedEvent{
- FeaturesRemovedEvent: *features.NewFeaturesRemovedEvent(
- eventstore.NewBaseEventForPush(
- ctx,
- aggregate,
- FeaturesRemovedEventType),
- ),
- }
-}
-
-func FeaturesRemovedEventMapper(event *repository.Event) (eventstore.Event, error) {
- e, err := features.FeaturesRemovedEventMapper(event)
- if err != nil {
- return nil, err
- }
-
- return &FeaturesRemovedEvent{FeaturesRemovedEvent: *e.(*features.FeaturesRemovedEvent)}, nil
-}
diff --git a/internal/static/i18n/de.yaml b/internal/static/i18n/de.yaml
index 01a7fb50e..c739420a4 100644
--- a/internal/static/i18n/de.yaml
+++ b/internal/static/i18n/de.yaml
@@ -379,8 +379,6 @@ Errors:
AlreadyExists: Schritt gestartet existiert bereits
Done:
AlreadyExists: Schritt ausgeführt existiert bereits
- Features:
- NotChanged: Feature hat nicht geändert
CustomText:
AlreadyExists: Kundenspezifischer Text existiert bereits
Invalid: Kundenspezifischer Text ist ungültig
@@ -613,9 +611,6 @@ EventTypes:
set: Primäre Domäne gesetzt
reserved: Domäne reserviert
released: Domäne freigegeben
- features:
- set: Feature hinzugefügt
- removed: Feature entfernt
name:
reserved: Name der Organisation reserviert
released: Name der Organisation freigegeben
diff --git a/internal/static/i18n/en.yaml b/internal/static/i18n/en.yaml
index a905a0610..df4b83772 100644
--- a/internal/static/i18n/en.yaml
+++ b/internal/static/i18n/en.yaml
@@ -379,8 +379,6 @@ Errors:
AlreadyExists: Step started already exists
Done:
AlreadyExists: Step done already exists
- Features:
- NotChanged: Feature hat nicht geändert
CustomText:
AlreadyExists: Custom text already exists
Invalid: Custom text invalid
@@ -613,9 +611,6 @@ EventTypes:
set: Primary domain set
reserved: Domain reserved
released: Domain released
- features:
- set: Feature added
- removed: Feature removed
name:
reserved: Organization name reserved
released: Organization name released
diff --git a/internal/static/i18n/it.yaml b/internal/static/i18n/it.yaml
index 20a927fff..56d5437d2 100644
--- a/internal/static/i18n/it.yaml
+++ b/internal/static/i18n/it.yaml
@@ -377,8 +377,6 @@ Errors:
AlreadyExists: Il passo iniziato già esistente
Done:
AlreadyExists: Il passo fatto già esistente
- Features:
- NotChanged: La caratteristica non è cambiata
CustomText:
AlreadyExists: Il testo personalizzato già esistente
Invalid: Testo personalizzato non valido
@@ -611,9 +609,6 @@ EventTypes:
set: Set di dominio primario
reserved: Dominio riservato
released: Dominio rilasciato
- features:
- set: Caratteristica aggiunta
- removed: Caratteristica rimossa
name:
reserved: Nome dell'organizzazione riservato
released: Nome dell'organizzazione rilasciata
diff --git a/proto/zitadel/admin.proto b/proto/zitadel/admin.proto
index 37e8466e2..a15ca56de 100644
--- a/proto/zitadel/admin.proto
+++ b/proto/zitadel/admin.proto
@@ -10,7 +10,6 @@ import "zitadel/policy.proto";
import "zitadel/settings.proto";
import "zitadel/text.proto";
import "zitadel/member.proto";
-import "zitadel/features.proto";
import "google/api/annotations.proto";
import "google/protobuf/timestamp.proto";
@@ -893,58 +892,6 @@ service AdminService {
};
}
- rpc GetDefaultFeatures(GetDefaultFeaturesRequest) returns (GetDefaultFeaturesResponse) {
- option(google.api.http) = {
- get: "/features"
- };
-
- option (zitadel.v1.auth_option) = {
- permission: "iam.features.read"
- };
- }
-
- rpc SetDefaultFeatures(SetDefaultFeaturesRequest) returns (SetDefaultFeaturesResponse) {
- option(google.api.http) = {
- put: "/features"
- body: "*"
- };
-
- option (zitadel.v1.auth_option) = {
- permission: "iam.features.write"
- };
- }
-
- rpc GetOrgFeatures(GetOrgFeaturesRequest) returns (GetOrgFeaturesResponse) {
- option(google.api.http) = {
- get: "/orgs/{org_id}/features"
- };
-
- option (zitadel.v1.auth_option) = {
- permission: "iam.features.read"
- };
- }
-
- rpc SetOrgFeatures(SetOrgFeaturesRequest) returns (SetOrgFeaturesResponse) {
- option(google.api.http) = {
- put: "/orgs/{org_id}/features"
- body: "*"
- };
-
- option (zitadel.v1.auth_option) = {
- permission: "iam.features.write"
- };
- }
-
- rpc ResetOrgFeatures(ResetOrgFeaturesRequest) returns (ResetOrgFeaturesResponse) {
- option(google.api.http) = {
- delete: "/orgs/{org_id}/features"
- };
-
- option (zitadel.v1.auth_option) = {
- permission: "iam.features.write"
- };
- }
-
//deprecated: please use DomainPolicy instead
//Returns the Org IAM policy defined by the administrators of ZITADEL
rpc GetOrgIAMPolicy(GetOrgIAMPolicyRequest) returns (GetOrgIAMPolicyResponse) {
@@ -3380,92 +3327,6 @@ message UpdateIDPJWTConfigResponse {
zitadel.v1.ObjectDetails details = 1;
}
-message GetDefaultFeaturesRequest {}
-
-message GetDefaultFeaturesResponse {
- zitadel.features.v1.Features features = 1;
-}
-
-message SetDefaultFeaturesRequest {
- string tier_name = 1 [(validate.rules).string = {max_len: 200}];
- string description = 2 [(validate.rules).string = {max_len: 200}];
-
- google.protobuf.Duration audit_log_retention = 5 [(validate.rules).duration = {gte: {seconds: 0}}];
- bool login_policy_username_login = 6;
- bool login_policy_registration = 7;
- bool login_policy_idp = 8;
- bool login_policy_factors = 9;
- bool login_policy_passwordless = 10;
- bool password_complexity_policy = 11;
- bool label_policy = 12;
- bool custom_domain = 13;
- bool login_policy_password_reset = 14;
- bool label_policy_private_label = 15;
- bool label_policy_watermark = 16;
- bool custom_text = 17;
- bool privacy_policy = 18;
- bool metadata_user = 19;
- bool custom_text_message = 20;
- bool custom_text_login = 21;
- bool lockout_policy = 22;
- bool actions = 23;
- zitadel.features.v1.ActionsAllowed actions_allowed = 24;
- int32 max_actions = 25;
-}
-
-message SetDefaultFeaturesResponse {
- zitadel.v1.ObjectDetails details = 1;
-}
-
-message GetOrgFeaturesRequest {
- string org_id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
-}
-
-message GetOrgFeaturesResponse {
- zitadel.features.v1.Features features = 1;
-}
-
-message SetOrgFeaturesRequest {
- string org_id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
- string tier_name = 2 [(validate.rules).string = {max_len: 200}];
- string description = 3 [(validate.rules).string = {max_len: 200}];
- zitadel.features.v1.FeaturesState state = 4;
- string state_description = 5 [(validate.rules).string = {max_len: 200}];
-
- google.protobuf.Duration audit_log_retention = 6 [(validate.rules).duration = {gte: {seconds: 0}}];
- bool login_policy_username_login = 7;
- bool login_policy_registration = 8;
- bool login_policy_idp = 9;
- bool login_policy_factors = 10;
- bool login_policy_passwordless = 11;
- bool password_complexity_policy = 12;
- bool label_policy = 13;
- bool custom_domain = 14;
- bool login_policy_password_reset = 15;
- bool label_policy_private_label = 16;
- bool label_policy_watermark = 17;
- bool custom_text = 18;
- bool privacy_policy = 19;
- bool metadata_user = 20;
- bool custom_text_message = 21;
- bool custom_text_login = 22;
- bool lockout_policy = 23;
- bool actions = 24;
- zitadel.features.v1.ActionsAllowed actions_allowed = 25;
- int32 max_actions = 26;
-}
-
-message SetOrgFeaturesResponse {
- zitadel.v1.ObjectDetails details = 1;
-}
-
-message ResetOrgFeaturesRequest {
- string org_id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
-}
-message ResetOrgFeaturesResponse {
- zitadel.v1.ObjectDetails details = 1;
-}
-
message GetOrgIAMPolicyRequest {}
message GetOrgIAMPolicyResponse {
diff --git a/proto/zitadel/auth.proto b/proto/zitadel/auth.proto
index 152da0df8..a9b7a1d5e 100644
--- a/proto/zitadel/auth.proto
+++ b/proto/zitadel/auth.proto
@@ -551,17 +551,6 @@ service AuthService {
};
}
- // Returns a list of features, which are allowed on these organisation based on the subscription of the organisation
- rpc ListMyZitadelFeatures(ListMyZitadelFeaturesRequest) returns (ListMyZitadelFeaturesResponse) {
- option (google.api.http) = {
- post: "/features/zitadel/me/_search"
- };
-
- option (zitadel.v1.auth_option) = {
- permission: "authenticated"
- };
- }
-
// Returns the permissions the authorized user has in ZITADEL based on his manager roles (e.g ORG_OWNER)
rpc ListMyZitadelPermissions(ListMyZitadelPermissionsRequest) returns (ListMyZitadelPermissionsResponse) {
option (google.api.http) = {
@@ -1003,13 +992,6 @@ message ListMyProjectOrgsResponse {
repeated zitadel.org.v1.Org result = 2;
}
-//This is an empty request
-message ListMyZitadelFeaturesRequest {}
-
-message ListMyZitadelFeaturesResponse {
- repeated string result = 1;
-}
-
//This is an empty request
message ListMyZitadelPermissionsRequest {}
diff --git a/proto/zitadel/features.proto b/proto/zitadel/features.proto
deleted file mode 100644
index 3de7eb80f..000000000
--- a/proto/zitadel/features.proto
+++ /dev/null
@@ -1,57 +0,0 @@
-syntax = "proto3";
-
-import "zitadel/object.proto";
-import "google/protobuf/duration.proto";
-
-package zitadel.features.v1;
-
-option go_package = "github.com/zitadel/zitadel/pkg/grpc/features";
-
-message Features {
- zitadel.v1.ObjectDetails details = 1;
- FeatureTier tier = 2;
- bool is_default = 3;
-
- google.protobuf.Duration audit_log_retention = 4;
- bool login_policy_username_login = 5;
- bool login_policy_registration = 6;
- bool login_policy_idp = 7;
- bool login_policy_factors = 8;
- bool login_policy_passwordless = 9;
- bool password_complexity_policy = 10;
- bool label_policy = 11;
- bool custom_domain = 12;
- bool login_policy_password_reset = 13;
- bool label_policy_private_label = 14;
- bool label_policy_watermark = 15;
- bool custom_text = 16;
- bool privacy_policy = 17;
- bool metadata_user = 18;
- bool custom_text_message = 19;
- bool custom_text_login = 20;
- bool lockout_policy = 21;
- bool actions = 22;
- ActionsAllowed actions_allowed = 23;
- int32 max_actions = 24;
-}
-
-message FeatureTier {
- string name = 1;
- string description = 2;
- FeaturesState state = 3;
- string status_info = 4;
-}
-
-
-enum FeaturesState {
- FEATURES_STATE_ACTIVE = 0;
- FEATURES_STATE_ACTION_REQUIRED = 1;
- FEATURES_STATE_CANCELED = 2;
- FEATURES_STATE_GRANDFATHERED = 3;
-}
-
-enum ActionsAllowed {
- ACTIONS_ALLOWED_NOT_ALLOWED = 0;
- ACTIONS_ALLOWED_MAX = 1;
- ACTIONS_ALLOWED_UNLIMITED = 2;
-}
diff --git a/proto/zitadel/management.proto b/proto/zitadel/management.proto
index b07ccfb4b..31c9ddead 100644
--- a/proto/zitadel/management.proto
+++ b/proto/zitadel/management.proto
@@ -13,7 +13,6 @@ import "zitadel/text.proto";
import "zitadel/message.proto";
import "zitadel/change.proto";
import "zitadel/auth_n_key.proto";
-import "zitadel/features.proto";
import "zitadel/metadata.proto";
import "zitadel/action.proto";
@@ -307,7 +306,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "user.write"
- feature: "metadata.user"
};
}
@@ -320,7 +318,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "user.write"
- feature: "metadata.user"
};
}
@@ -333,7 +330,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "user.read"
- feature: "metadata.user"
};
}
@@ -345,7 +341,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "user.read"
- feature: "metadata.user"
};
}
@@ -357,7 +352,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "user.write"
- feature: "metadata.user"
};
}
@@ -370,7 +364,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "user.write"
- feature: "metadata.user"
};
}
@@ -871,7 +864,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.write"
- feature: "custom_domain"
};
}
@@ -895,7 +887,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.write"
- feature: "custom_domain"
};
}
@@ -909,7 +900,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.write"
- feature: "custom_domain"
};
}
@@ -922,7 +912,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.write"
- feature: "custom_domain"
};
}
@@ -1740,16 +1729,6 @@ service ManagementService {
};
}
- rpc GetFeatures(GetFeaturesRequest) returns (GetFeaturesResponse) {
- option (google.api.http) = {
- get: "/features"
- };
-
- option (zitadel.v1.auth_option) = {
- permission: "features.read"
- };
- }
-
//deprecated: please use DomainPolicy instead
// Returns the domain policy (this policy is managed by the iam administrator)
rpc GetOrgIAMPolicy(GetOrgIAMPolicyRequest) returns (GetOrgIAMPolicyResponse) {
@@ -1806,7 +1785,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "login_policy"
};
}
@@ -1820,7 +1798,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "login_policy"
};
}
@@ -1858,7 +1835,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "login_policy.idp"
};
}
@@ -1870,7 +1846,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "login_policy.idp"
};
}
@@ -1894,7 +1869,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "login_policy.factors"
};
}
@@ -1906,7 +1880,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "login_policy.factors"
};
}
@@ -1930,7 +1903,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "login_policy.factors"
};
}
@@ -1942,7 +1914,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "login_policy.factors"
};
}
@@ -1980,7 +1951,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "password_complexity_policy"
};
}
@@ -1994,7 +1964,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "password_complexity_policy"
};
}
@@ -2154,7 +2123,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "privacy_policy"
};
}
@@ -2169,7 +2137,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "privacy_policy"
};
}
@@ -2218,7 +2185,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.read"
- feature: "label_policy"
};
}
@@ -2232,7 +2198,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "label_policy"
};
}
@@ -2246,7 +2211,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "label_policy"
};
}
@@ -2260,7 +2224,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "label_policy"
};
}
@@ -2272,7 +2235,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "label_policy"
};
}
@@ -2284,7 +2246,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "label_policy"
};
}
@@ -2296,7 +2257,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "label_policy"
};
}
@@ -2308,7 +2268,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "label_policy"
};
}
@@ -2320,7 +2279,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write"
- feature: "label_policy"
};
}
@@ -2369,7 +2327,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write";
- feature: "custom_text.message"
};
}
@@ -2417,7 +2374,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write";
- feature: "custom_text.message"
};
}
@@ -2466,7 +2422,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write";
- feature: "custom_text.message"
};
}
@@ -2515,7 +2470,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write";
- feature: "custom_text.message"
};
}
@@ -2564,7 +2518,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write";
- feature: "custom_text.message"
};
}
@@ -2613,7 +2566,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write";
- feature: "custom_text.message"
};
}
@@ -2661,7 +2613,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "policy.write";
- feature: "custom_text.login"
};
}
@@ -2711,7 +2662,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.idp.write"
- feature: "login_policy.idp"
};
}
@@ -2724,7 +2674,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.idp.write"
- feature: "login_policy.idp"
};
}
@@ -2739,7 +2688,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.idp.write"
- feature: "login_policy.idp"
};
}
@@ -2753,7 +2701,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.idp.write"
- feature: "login_policy.idp"
};
}
@@ -2766,7 +2713,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.idp.write"
- feature: "login_policy.idp"
};
}
@@ -2779,7 +2725,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.idp.write"
- feature: "login_policy.idp"
};
}
@@ -2792,7 +2737,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.idp.write"
- feature: "login_policy.idp"
};
}
@@ -2805,7 +2749,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.idp.write"
- feature: "login_policy.idp"
};
}
@@ -2817,7 +2760,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.action.read"
- feature: "actions"
};
}
@@ -2828,7 +2770,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.action.read"
- feature: "actions"
};
}
@@ -2840,7 +2781,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.action.write"
- feature: "actions"
};
}
@@ -2852,7 +2792,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.action.write"
- feature: "actions"
};
}
@@ -2864,7 +2803,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.action.write"
- feature: "actions"
};
}
@@ -2876,7 +2814,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.action.write"
- feature: "actions"
};
}
@@ -2888,7 +2825,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.action.delete"
- feature: "actions"
};
}
@@ -2899,7 +2835,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.flow.read"
- feature: "actions"
};
}
@@ -2910,7 +2845,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.flow.delete"
- feature: "actions"
};
}
@@ -2922,7 +2856,6 @@ service ManagementService {
option (zitadel.v1.auth_option) = {
permission: "org.flow.write"
- feature: "actions"
};
}
}
@@ -4378,12 +4311,6 @@ message BulkRemoveUserGrantRequest {
message BulkRemoveUserGrantResponse {}
-message GetFeaturesRequest {}
-
-message GetFeaturesResponse {
- zitadel.features.v1.Features features = 1;
-}
-
message GetOrgIAMPolicyRequest {}
message GetOrgIAMPolicyResponse {
diff --git a/proto/zitadel/options.proto b/proto/zitadel/options.proto
index b30904e12..b71082858 100644
--- a/proto/zitadel/options.proto
+++ b/proto/zitadel/options.proto
@@ -14,5 +14,4 @@ extend google.protobuf.MethodOptions {
message AuthOption {
string permission = 1;
string check_field_name = 2;
- string feature = 3;
}
diff --git a/proto/zitadel/settings.proto b/proto/zitadel/settings.proto
index b22e1ce8f..02b98a7e9 100644
--- a/proto/zitadel/settings.proto
+++ b/proto/zitadel/settings.proto
@@ -3,7 +3,6 @@ syntax = "proto3";
import "zitadel/object.proto";
import "validate/validate.proto";
import "google/protobuf/duration.proto";
-import "protoc-gen-openapiv2/options/annotations.proto";
package zitadel.settings.v1;
diff --git a/proto/zitadel/system.proto b/proto/zitadel/system.proto
index baeefec7e..b18e8b466 100644
--- a/proto/zitadel/system.proto
+++ b/proto/zitadel/system.proto
@@ -3,14 +3,10 @@ syntax = "proto3";
import "zitadel/object.proto";
import "zitadel/options.proto";
import "zitadel/instance.proto";
-import "zitadel/text.proto";
import "google/api/annotations.proto";
import "google/protobuf/timestamp.proto";
-import "google/protobuf/duration.proto";
-
import "protoc-gen-openapiv2/options/annotations.proto";
-
import "validate/validate.proto";
package zitadel.system.v1;