mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-07 22:47:41 +00:00
feat: Lockout policy feature (#2341)
* feat: add lockoutpolicy feature * feat: add tests * fix: err handling
This commit is contained in:
parent
257bf90f7e
commit
59e393728e
@ -2507,6 +2507,7 @@ This is an empty request
|
|||||||
| metadata_user | bool | - | |
|
| metadata_user | bool | - | |
|
||||||
| custom_text_message | bool | - | |
|
| custom_text_message | bool | - | |
|
||||||
| custom_text_login | bool | - | |
|
| custom_text_login | bool | - | |
|
||||||
|
| lockout_policy | bool | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -2695,6 +2696,7 @@ This is an empty request
|
|||||||
| metadata_user | bool | - | |
|
| metadata_user | bool | - | |
|
||||||
| custom_text_message | bool | - | |
|
| custom_text_message | bool | - | |
|
||||||
| custom_text_login | bool | - | |
|
| custom_text_login | bool | - | |
|
||||||
|
| lockout_policy | bool | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,6 +78,7 @@ func setDefaultFeaturesRequestToDomain(req *admin_pb.SetDefaultFeaturesRequest)
|
|||||||
MetadataUser: req.MetadataUser,
|
MetadataUser: req.MetadataUser,
|
||||||
CustomTextLogin: req.CustomTextLogin || req.CustomText,
|
CustomTextLogin: req.CustomTextLogin || req.CustomText,
|
||||||
CustomTextMessage: req.CustomTextMessage,
|
CustomTextMessage: req.CustomTextMessage,
|
||||||
|
LockoutPolicy: req.LockoutPolicy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,5 +103,6 @@ func setOrgFeaturesRequestToDomain(req *admin_pb.SetOrgFeaturesRequest) *domain.
|
|||||||
MetadataUser: req.MetadataUser,
|
MetadataUser: req.MetadataUser,
|
||||||
CustomTextLogin: req.CustomTextLogin || req.CustomText,
|
CustomTextLogin: req.CustomTextLogin || req.CustomText,
|
||||||
CustomTextMessage: req.CustomTextMessage,
|
CustomTextMessage: req.CustomTextMessage,
|
||||||
|
LockoutPolicy: req.LockoutPolicy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ func FeaturesFromModel(features *features_model.FeaturesView) *features_pb.Featu
|
|||||||
CustomTextMessage: features.CustomTextMessage,
|
CustomTextMessage: features.CustomTextMessage,
|
||||||
CustomTextLogin: features.CustomTextLogin,
|
CustomTextLogin: features.CustomTextLogin,
|
||||||
MetadataUser: features.MetadataUser,
|
MetadataUser: features.MetadataUser,
|
||||||
|
LockoutPolicy: features.LockoutPolicy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,6 +169,12 @@ func checkFeatures(features *features_view_model.FeaturesView, requiredFeatures
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if requiredFeature == domain.FeatureLockoutPolicy {
|
||||||
|
if !features.LockoutPolicy {
|
||||||
|
return MissingFeatureErr(requiredFeature)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
if requiredFeature == domain.FeatureMetadataUser {
|
if requiredFeature == domain.FeatureMetadataUser {
|
||||||
if !features.MetadataUser {
|
if !features.MetadataUser {
|
||||||
return MissingFeatureErr(requiredFeature)
|
return MissingFeatureErr(requiredFeature)
|
||||||
|
@ -30,6 +30,7 @@ type FeaturesWriteModel struct {
|
|||||||
MetadataUser bool
|
MetadataUser bool
|
||||||
CustomTextMessage bool
|
CustomTextMessage bool
|
||||||
CustomTextLogin bool
|
CustomTextLogin bool
|
||||||
|
LockoutPolicy bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *FeaturesWriteModel) Reduce() error {
|
func (wm *FeaturesWriteModel) Reduce() error {
|
||||||
@ -94,6 +95,9 @@ func (wm *FeaturesWriteModel) Reduce() error {
|
|||||||
if e.CustomTextLogin != nil {
|
if e.CustomTextLogin != nil {
|
||||||
wm.CustomTextLogin = *e.CustomTextLogin
|
wm.CustomTextLogin = *e.CustomTextLogin
|
||||||
}
|
}
|
||||||
|
if e.LockoutPolicy != nil {
|
||||||
|
wm.LockoutPolicy = *e.LockoutPolicy
|
||||||
|
}
|
||||||
case *features.FeaturesRemovedEvent:
|
case *features.FeaturesRemovedEvent:
|
||||||
wm.State = domain.FeaturesStateRemoved
|
wm.State = domain.FeaturesStateRemoved
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ func (c *Commands) setDefaultFeatures(ctx context.Context, existingFeatures *IAM
|
|||||||
features.MetadataUser,
|
features.MetadataUser,
|
||||||
features.CustomTextMessage,
|
features.CustomTextMessage,
|
||||||
features.CustomTextLogin,
|
features.CustomTextLogin,
|
||||||
|
features.LockoutPolicy,
|
||||||
)
|
)
|
||||||
if !hasChanged {
|
if !hasChanged {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "Features-GE4h2", "Errors.Features.NotChanged")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "Features-GE4h2", "Errors.Features.NotChanged")
|
||||||
|
@ -70,7 +70,8 @@ func (wm *IAMFeaturesWriteModel) NewSetEvent(
|
|||||||
privacyPolicy,
|
privacyPolicy,
|
||||||
metadataUser,
|
metadataUser,
|
||||||
customTextMessage,
|
customTextMessage,
|
||||||
customTextLogin bool,
|
customTextLogin,
|
||||||
|
lockoutPolicy bool,
|
||||||
) (*iam.FeaturesSetEvent, bool) {
|
) (*iam.FeaturesSetEvent, bool) {
|
||||||
|
|
||||||
changes := make([]features.FeaturesChanges, 0)
|
changes := make([]features.FeaturesChanges, 0)
|
||||||
@ -129,6 +130,9 @@ func (wm *IAMFeaturesWriteModel) NewSetEvent(
|
|||||||
if wm.CustomTextLogin != customTextLogin {
|
if wm.CustomTextLogin != customTextLogin {
|
||||||
changes = append(changes, features.ChangeCustomTextLogin(customTextLogin))
|
changes = append(changes, features.ChangeCustomTextLogin(customTextLogin))
|
||||||
}
|
}
|
||||||
|
if wm.LockoutPolicy != lockoutPolicy {
|
||||||
|
changes = append(changes, features.ChangeLockoutPolicy(lockoutPolicy))
|
||||||
|
}
|
||||||
if len(changes) == 0 {
|
if len(changes) == 0 {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ func (c *Commands) SetOrgFeatures(ctx context.Context, resourceOwner string, fea
|
|||||||
features.MetadataUser,
|
features.MetadataUser,
|
||||||
features.CustomTextMessage,
|
features.CustomTextMessage,
|
||||||
features.CustomTextLogin,
|
features.CustomTextLogin,
|
||||||
|
features.LockoutPolicy,
|
||||||
)
|
)
|
||||||
if !hasChanged {
|
if !hasChanged {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "Features-GE4h2", "Errors.Features.NotChanged")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "Features-GE4h2", "Errors.Features.NotChanged")
|
||||||
@ -157,6 +158,15 @@ func (c *Commands) ensureOrgSettingsToFeatures(ctx context.Context, orgID string
|
|||||||
events = append(events, removePrivacyPolicyEvent)
|
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 {
|
if !features.MetadataUser {
|
||||||
removeOrgUserMetadatas, err := c.removeUserMetadataFromOrg(ctx, orgID)
|
removeOrgUserMetadatas, err := c.removeUserMetadataFromOrg(ctx, orgID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -77,7 +77,8 @@ func (wm *OrgFeaturesWriteModel) NewSetEvent(
|
|||||||
privacyPolicy,
|
privacyPolicy,
|
||||||
metadataUser,
|
metadataUser,
|
||||||
customTextMessage,
|
customTextMessage,
|
||||||
customTextLogin bool,
|
customTextLogin,
|
||||||
|
lockoutPolicy bool,
|
||||||
) (*org.FeaturesSetEvent, bool) {
|
) (*org.FeaturesSetEvent, bool) {
|
||||||
|
|
||||||
changes := make([]features.FeaturesChanges, 0)
|
changes := make([]features.FeaturesChanges, 0)
|
||||||
@ -139,6 +140,9 @@ func (wm *OrgFeaturesWriteModel) NewSetEvent(
|
|||||||
if wm.CustomTextLogin != customTextLogin {
|
if wm.CustomTextLogin != customTextLogin {
|
||||||
changes = append(changes, features.ChangeCustomTextLogin(customTextLogin))
|
changes = append(changes, features.ChangeCustomTextLogin(customTextLogin))
|
||||||
}
|
}
|
||||||
|
if wm.LockoutPolicy != lockoutPolicy {
|
||||||
|
changes = append(changes, features.ChangeLockoutPolicy(lockoutPolicy))
|
||||||
|
}
|
||||||
|
|
||||||
if len(changes) == 0 {
|
if len(changes) == 0 {
|
||||||
return nil, false
|
return nil, false
|
||||||
|
@ -264,6 +264,16 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
iam.NewLockoutPolicyAddedEvent(
|
||||||
|
context.Background(),
|
||||||
|
&iam.NewAggregate().Aggregate,
|
||||||
|
5,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
expectFilter(),
|
expectFilter(),
|
||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
@ -296,6 +306,7 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
CustomTextLogin: false,
|
CustomTextLogin: false,
|
||||||
PrivacyPolicy: false,
|
PrivacyPolicy: false,
|
||||||
MetadataUser: false,
|
MetadataUser: false,
|
||||||
|
LockoutPolicy: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -450,6 +461,16 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
iam.NewLockoutPolicyAddedEvent(
|
||||||
|
context.Background(),
|
||||||
|
&iam.NewAggregate().Aggregate,
|
||||||
|
5,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
expectFilter(),
|
expectFilter(),
|
||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
@ -486,6 +507,8 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
LabelPolicyWatermark: false,
|
LabelPolicyWatermark: false,
|
||||||
CustomDomain: false,
|
CustomDomain: false,
|
||||||
MetadataUser: false,
|
MetadataUser: false,
|
||||||
|
PrivacyPolicy: false,
|
||||||
|
LockoutPolicy: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -647,6 +670,16 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
iam.NewLockoutPolicyAddedEvent(
|
||||||
|
context.Background(),
|
||||||
|
&iam.NewAggregate().Aggregate,
|
||||||
|
5,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
expectFilter(),
|
expectFilter(),
|
||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
@ -686,6 +719,8 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
LabelPolicyWatermark: false,
|
LabelPolicyWatermark: false,
|
||||||
CustomDomain: false,
|
CustomDomain: false,
|
||||||
MetadataUser: false,
|
MetadataUser: false,
|
||||||
|
PrivacyPolicy: false,
|
||||||
|
LockoutPolicy: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -854,6 +889,16 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
iam.NewLockoutPolicyAddedEvent(
|
||||||
|
context.Background(),
|
||||||
|
&iam.NewAggregate().Aggregate,
|
||||||
|
5,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
expectFilter(),
|
expectFilter(),
|
||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
@ -896,6 +941,8 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
LabelPolicyWatermark: false,
|
LabelPolicyWatermark: false,
|
||||||
CustomDomain: false,
|
CustomDomain: false,
|
||||||
MetadataUser: false,
|
MetadataUser: false,
|
||||||
|
PrivacyPolicy: false,
|
||||||
|
LockoutPolicy: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -1116,6 +1163,16 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
org.NewLockoutPolicyAddedEvent(
|
||||||
|
context.Background(),
|
||||||
|
&org.NewAggregate("org1", "org1").Aggregate,
|
||||||
|
5,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
expectFilter(),
|
expectFilter(),
|
||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
@ -1146,6 +1203,9 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
org.NewPrivacyPolicyRemovedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate),
|
org.NewPrivacyPolicyRemovedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate),
|
||||||
),
|
),
|
||||||
|
eventFromEventPusher(
|
||||||
|
org.NewLockoutPolicyRemovedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate),
|
||||||
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
newFeaturesSetEvent(context.Background(), "org1", "Test", domain.FeaturesStateActive, time.Hour),
|
newFeaturesSetEvent(context.Background(), "org1", "Test", domain.FeaturesStateActive, time.Hour),
|
||||||
),
|
),
|
||||||
@ -1172,6 +1232,8 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
LabelPolicyWatermark: false,
|
LabelPolicyWatermark: false,
|
||||||
CustomDomain: false,
|
CustomDomain: false,
|
||||||
MetadataUser: false,
|
MetadataUser: false,
|
||||||
|
PrivacyPolicy: false,
|
||||||
|
LockoutPolicy: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -1305,6 +1367,16 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
iam.NewLockoutPolicyAddedEvent(
|
||||||
|
context.Background(),
|
||||||
|
&iam.NewAggregate().Aggregate,
|
||||||
|
5,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
user.NewMetadataSetEvent(
|
user.NewMetadataSetEvent(
|
||||||
@ -1349,6 +1421,7 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
|||||||
CustomTextLogin: false,
|
CustomTextLogin: false,
|
||||||
PrivacyPolicy: false,
|
PrivacyPolicy: false,
|
||||||
MetadataUser: false,
|
MetadataUser: false,
|
||||||
|
LockoutPolicy: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -1551,6 +1624,16 @@ func TestCommandSide_RemoveOrgFeatures(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
iam.NewLockoutPolicyAddedEvent(
|
||||||
|
context.Background(),
|
||||||
|
&iam.NewAggregate().Aggregate,
|
||||||
|
5,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
expectFilter(),
|
expectFilter(),
|
||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
|
@ -11,8 +11,7 @@ func (c *Commands) AddLockoutPolicy(ctx context.Context, resourceOwner string, p
|
|||||||
if resourceOwner == "" {
|
if resourceOwner == "" {
|
||||||
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-8fJif", "Errors.ResourceOwnerMissing")
|
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-8fJif", "Errors.ResourceOwnerMissing")
|
||||||
}
|
}
|
||||||
addedPolicy := NewOrgLockoutPolicyWriteModel(resourceOwner)
|
addedPolicy, err := c.orgLockoutPolicyWriteModelByID(ctx, resourceOwner)
|
||||||
err := c.eventstore.FilterToQueryReducer(ctx, addedPolicy)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -36,8 +35,7 @@ func (c *Commands) ChangeLockoutPolicy(ctx context.Context, resourceOwner string
|
|||||||
if resourceOwner == "" {
|
if resourceOwner == "" {
|
||||||
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-3J9fs", "Errors.ResourceOwnerMissing")
|
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-3J9fs", "Errors.ResourceOwnerMissing")
|
||||||
}
|
}
|
||||||
existingPolicy := NewOrgLockoutPolicyWriteModel(resourceOwner)
|
existingPolicy, err := c.orgLockoutPolicyWriteModelByID(ctx, resourceOwner)
|
||||||
err := c.eventstore.FilterToQueryReducer(ctx, existingPolicy)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -66,8 +64,7 @@ func (c *Commands) RemoveLockoutPolicy(ctx context.Context, orgID string) error
|
|||||||
if orgID == "" {
|
if orgID == "" {
|
||||||
return caos_errs.ThrowInvalidArgument(nil, "Org-4J9fs", "Errors.ResourceOwnerMissing")
|
return caos_errs.ThrowInvalidArgument(nil, "Org-4J9fs", "Errors.ResourceOwnerMissing")
|
||||||
}
|
}
|
||||||
existingPolicy := NewOrgLockoutPolicyWriteModel(orgID)
|
existingPolicy, err := c.orgLockoutPolicyWriteModelByID(ctx, orgID)
|
||||||
err := c.eventstore.FilterToQueryReducer(ctx, existingPolicy)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -79,3 +76,24 @@ func (c *Commands) RemoveLockoutPolicy(ctx context.Context, orgID string) error
|
|||||||
_, err = c.eventstore.PushEvents(ctx, org.NewLockoutPolicyRemovedEvent(ctx, orgAgg))
|
_, err = c.eventstore.PushEvents(ctx, org.NewLockoutPolicyRemovedEvent(ctx, orgAgg))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Commands) removeLockoutPolicyIfExists(ctx context.Context, orgID string) (*org.LockoutPolicyRemovedEvent, error) {
|
||||||
|
existingPolicy, err := c.orgLockoutPolicyWriteModelByID(ctx, orgID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if existingPolicy.State != domain.PolicyStateActive {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.WriteModel)
|
||||||
|
return org.NewLockoutPolicyRemovedEvent(ctx, orgAgg), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) orgLockoutPolicyWriteModelByID(ctx context.Context, orgID string) (*OrgLockoutPolicyWriteModel, error) {
|
||||||
|
policy := NewOrgLockoutPolicyWriteModel(orgID)
|
||||||
|
err := c.eventstore.FilterToQueryReducer(ctx, policy)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return policy, nil
|
||||||
|
}
|
@ -20,6 +20,7 @@ const (
|
|||||||
FeatureLabelPolicyWatermark = FeatureLabelPolicy + ".watermark"
|
FeatureLabelPolicyWatermark = FeatureLabelPolicy + ".watermark"
|
||||||
FeatureCustomDomain = "custom_domain"
|
FeatureCustomDomain = "custom_domain"
|
||||||
FeaturePrivacyPolicy = "privacy_policy"
|
FeaturePrivacyPolicy = "privacy_policy"
|
||||||
|
FeatureLockoutPolicy = "lockout_policy"
|
||||||
FeatureMetadata = "metadata"
|
FeatureMetadata = "metadata"
|
||||||
FeatureCustomText = "custom_text"
|
FeatureCustomText = "custom_text"
|
||||||
FeatureCustomTextMessage = FeatureCustomText + ".message"
|
FeatureCustomTextMessage = FeatureCustomText + ".message"
|
||||||
@ -51,6 +52,7 @@ type Features struct {
|
|||||||
CustomTextLogin bool
|
CustomTextLogin bool
|
||||||
PrivacyPolicy bool
|
PrivacyPolicy bool
|
||||||
MetadataUser bool
|
MetadataUser bool
|
||||||
|
LockoutPolicy bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type FeaturesState int32
|
type FeaturesState int32
|
||||||
|
@ -32,6 +32,7 @@ type FeaturesView struct {
|
|||||||
MetadataUser bool
|
MetadataUser bool
|
||||||
CustomTextMessage bool
|
CustomTextMessage bool
|
||||||
CustomTextLogin bool
|
CustomTextLogin bool
|
||||||
|
LockoutPolicy bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FeaturesView) FeatureList() []string {
|
func (f *FeaturesView) FeatureList() []string {
|
||||||
@ -78,6 +79,9 @@ func (f *FeaturesView) FeatureList() []string {
|
|||||||
if f.CustomTextLogin {
|
if f.CustomTextLogin {
|
||||||
list = append(list, domain.FeatureCustomTextLogin)
|
list = append(list, domain.FeatureCustomTextLogin)
|
||||||
}
|
}
|
||||||
|
if f.LockoutPolicy {
|
||||||
|
list = append(list, domain.FeatureLockoutPolicy)
|
||||||
|
}
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ type FeaturesView struct {
|
|||||||
MetadataUser bool `json:"metadataUser" gorm:"column:metadata_user"`
|
MetadataUser bool `json:"metadataUser" gorm:"column:metadata_user"`
|
||||||
CustomTextMessage bool `json:"customTextMessage" gorm:"column:custom_text_message"`
|
CustomTextMessage bool `json:"customTextMessage" gorm:"column:custom_text_message"`
|
||||||
CustomTextLogin bool `json:"customTextLogin" gorm:"column:custom_text_login"`
|
CustomTextLogin bool `json:"customTextLogin" gorm:"column:custom_text_login"`
|
||||||
|
LockoutPolicy bool `json:"lockoutPolicy" gorm:"column:lockout_policy"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func FeaturesToModel(features *FeaturesView) *features_model.FeaturesView {
|
func FeaturesToModel(features *FeaturesView) *features_model.FeaturesView {
|
||||||
@ -74,6 +75,7 @@ func FeaturesToModel(features *FeaturesView) *features_model.FeaturesView {
|
|||||||
MetadataUser: features.MetadataUser,
|
MetadataUser: features.MetadataUser,
|
||||||
CustomTextMessage: features.CustomTextMessage,
|
CustomTextMessage: features.CustomTextMessage,
|
||||||
CustomTextLogin: features.CustomTextLogin,
|
CustomTextLogin: features.CustomTextLogin,
|
||||||
|
LockoutPolicy: features.LockoutPolicy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ type FeaturesSetEvent struct {
|
|||||||
MetadataUser *bool `json:"metadataUser,omitempty"`
|
MetadataUser *bool `json:"metadataUser,omitempty"`
|
||||||
CustomTextMessage *bool `json:"customTextMessage,omitempty"`
|
CustomTextMessage *bool `json:"customTextMessage,omitempty"`
|
||||||
CustomTextLogin *bool `json:"customTextLogin,omitempty"`
|
CustomTextLogin *bool `json:"customTextLogin,omitempty"`
|
||||||
|
LockoutPolicy *bool `json:"lockoutPolicy,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *FeaturesSetEvent) Data() interface{} {
|
func (e *FeaturesSetEvent) Data() interface{} {
|
||||||
@ -181,6 +182,12 @@ func ChangeCustomTextLogin(customTextLogin bool) func(event *FeaturesSetEvent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ChangeLockoutPolicy(lockoutPolicy bool) func(event *FeaturesSetEvent) {
|
||||||
|
return func(e *FeaturesSetEvent) {
|
||||||
|
e.LockoutPolicy = &lockoutPolicy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func FeaturesSetEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
func FeaturesSetEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||||
e := &FeaturesSetEvent{
|
e := &FeaturesSetEvent{
|
||||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||||
|
4
migrations/cockroach/V1.69__lockout_policy_feature.sql
Normal file
4
migrations/cockroach/V1.69__lockout_policy_feature.sql
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
ALTER TABLE adminapi.features ADD COLUMN lockout_policy BOOLEAN;
|
||||||
|
ALTER TABLE auth.features ADD COLUMN lockout_policy BOOLEAN;
|
||||||
|
ALTER TABLE authz.features ADD COLUMN lockout_policy BOOLEAN;
|
||||||
|
ALTER TABLE management.features ADD COLUMN lockout_policy BOOLEAN;
|
@ -2615,6 +2615,7 @@ message SetDefaultFeaturesRequest {
|
|||||||
bool metadata_user = 19;
|
bool metadata_user = 19;
|
||||||
bool custom_text_message = 20;
|
bool custom_text_message = 20;
|
||||||
bool custom_text_login = 21;
|
bool custom_text_login = 21;
|
||||||
|
bool lockout_policy = 22;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SetDefaultFeaturesResponse {
|
message SetDefaultFeaturesResponse {
|
||||||
@ -2653,6 +2654,7 @@ message SetOrgFeaturesRequest {
|
|||||||
bool metadata_user = 20;
|
bool metadata_user = 20;
|
||||||
bool custom_text_message = 21;
|
bool custom_text_message = 21;
|
||||||
bool custom_text_login = 22;
|
bool custom_text_login = 22;
|
||||||
|
bool lockout_policy = 23;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SetOrgFeaturesResponse {
|
message SetOrgFeaturesResponse {
|
||||||
|
@ -29,6 +29,7 @@ message Features {
|
|||||||
bool metadata_user = 18;
|
bool metadata_user = 18;
|
||||||
bool custom_text_message = 19;
|
bool custom_text_message = 19;
|
||||||
bool custom_text_login = 20;
|
bool custom_text_login = 20;
|
||||||
|
bool lockout_policy = 21;
|
||||||
}
|
}
|
||||||
|
|
||||||
message FeatureTier {
|
message FeatureTier {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user