mirror of
https://github.com/zitadel/zitadel.git
synced 2025-04-07 05:24:32 +00:00
feat: Lockout policy (#2121)
* feat: lock users if lockout policy is set * feat: setup * feat: lock user on password failes * feat: render error * feat: lock user on command side * feat: auth_req tests * feat: lockout policy docs * feat: remove show lockout failures from proto * fix: console lockout * feat: tests * fix: tests * unlock function * add unlock button * fix migration version * lockout policy * lint * Update internal/auth/repository/eventsourcing/eventstore/auth_request.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * fix: err message * Update internal/command/setup_step4.go Co-authored-by: Silvan <silvan.reusser@gmail.com> Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Silvan <silvan.reusser@gmail.com>
This commit is contained in:
parent
272e411e27
commit
bc951985ed
@ -202,7 +202,7 @@ func startAPI(ctx context.Context, conf *Config, verifier *internal_authz.TokenV
|
|||||||
for i, role := range conf.InternalAuthZ.RolePermissionMappings {
|
for i, role := range conf.InternalAuthZ.RolePermissionMappings {
|
||||||
roles[i] = role.Role
|
roles[i] = role.Role
|
||||||
}
|
}
|
||||||
repo, err := admin_es.Start(ctx, conf.Admin, conf.SystemDefaults, static, roles, *localDevMode)
|
repo, err := admin_es.Start(ctx, conf.Admin, conf.SystemDefaults, command, static, roles, *localDevMode)
|
||||||
logging.Log("API-D42tq").OnError(err).Fatal("error starting auth repo")
|
logging.Log("API-D42tq").OnError(err).Fatal("error starting auth repo")
|
||||||
|
|
||||||
apis := api.Create(conf.API, conf.InternalAuthZ, authZRepo, authRepo, repo, conf.SystemDefaults)
|
apis := api.Create(conf.API, conf.InternalAuthZ, authZRepo, authRepo, repo, conf.SystemDefaults)
|
||||||
|
@ -74,7 +74,7 @@ SetUp:
|
|||||||
ExpireWarnDays: 0
|
ExpireWarnDays: 0
|
||||||
Step4:
|
Step4:
|
||||||
DefaultPasswordLockoutPolicy:
|
DefaultPasswordLockoutPolicy:
|
||||||
MaxAttempts: 5
|
MaxPasswordAttempts: 5
|
||||||
ShowLockOutFailures: false
|
ShowLockOutFailures: false
|
||||||
Step5:
|
Step5:
|
||||||
DefaultOrgIAMPolicy:
|
DefaultOrgIAMPolicy:
|
||||||
@ -192,4 +192,8 @@ SetUp:
|
|||||||
Step17:
|
Step17:
|
||||||
PrivacyPolicy:
|
PrivacyPolicy:
|
||||||
TOSLink: https://docs.zitadel.ch/docs/legal/terms-of-service
|
TOSLink: https://docs.zitadel.ch/docs/legal/terms-of-service
|
||||||
PrivacyLink: https://docs.zitadel.ch/docs/legal/privacy-policy
|
PrivacyLink: https://docs.zitadel.ch/docs/legal/privacy-policy
|
||||||
|
Step18:
|
||||||
|
LockoutPolicy:
|
||||||
|
MaxPasswordAttempts: 0
|
||||||
|
ShowLockOutFailures: true
|
34
console/package-lock.json
generated
34
console/package-lock.json
generated
@ -35,6 +35,7 @@
|
|||||||
"libphonenumber-js": "^1.9.16",
|
"libphonenumber-js": "^1.9.16",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"ngx-color": "^7.2.0",
|
"ngx-color": "^7.2.0",
|
||||||
|
"ngx-image-cropper": "^3.3.5",
|
||||||
"ngx-quicklink": "^0.2.6",
|
"ngx-quicklink": "^0.2.6",
|
||||||
"rxjs": "~6.6.7",
|
"rxjs": "~6.6.7",
|
||||||
"tinycolor2": "^1.4.2",
|
"tinycolor2": "^1.4.2",
|
||||||
@ -10368,6 +10369,24 @@
|
|||||||
"@angular/core": ">=12.0.0-0"
|
"@angular/core": ">=12.0.0-0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ngx-image-cropper": {
|
||||||
|
"version": "3.3.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/ngx-image-cropper/-/ngx-image-cropper-3.3.5.tgz",
|
||||||
|
"integrity": "sha512-0yRVKG5XAbVo3rOaj/iFDlekGsxEqXKU9iXFbjyvHvRT2DFs+AjwtyvINsHCWw+4ed9yA4Y+wLIUNqzA0bfxLw==",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^1.9.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/common": ">=8.0.0",
|
||||||
|
"@angular/core": ">=8.0.0",
|
||||||
|
"@angular/platform-browser": ">=8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ngx-image-cropper/node_modules/tslib": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
|
},
|
||||||
"node_modules/ngx-quicklink": {
|
"node_modules/ngx-quicklink": {
|
||||||
"version": "0.2.7",
|
"version": "0.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/ngx-quicklink/-/ngx-quicklink-0.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/ngx-quicklink/-/ngx-quicklink-0.2.7.tgz",
|
||||||
@ -27536,6 +27555,21 @@
|
|||||||
"tslib": "^2.1.0"
|
"tslib": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ngx-image-cropper": {
|
||||||
|
"version": "3.3.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/ngx-image-cropper/-/ngx-image-cropper-3.3.5.tgz",
|
||||||
|
"integrity": "sha512-0yRVKG5XAbVo3rOaj/iFDlekGsxEqXKU9iXFbjyvHvRT2DFs+AjwtyvINsHCWw+4ed9yA4Y+wLIUNqzA0bfxLw==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "^1.9.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"ngx-quicklink": {
|
"ngx-quicklink": {
|
||||||
"version": "0.2.7",
|
"version": "0.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/ngx-quicklink/-/ngx-quicklink-0.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/ngx-quicklink/-/ngx-quicklink-0.2.7.tgz",
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<app-detail-layout [backRouterLink]="[ serviceType === PolicyComponentServiceType.ADMIN ? '/iam/policies' : '/org']"
|
<app-detail-layout [backRouterLink]="[ serviceType === PolicyComponentServiceType.ADMIN ? '/iam/policies' : '/org']"
|
||||||
[title]="'POLICY.PWD_LOCKOUT.TITLE' | translate" [description]="'POLICY.PWD_LOCKOUT.DESCRIPTION' | translate">
|
[title]="'POLICY.PWD_LOCKOUT.TITLE' | translate" [description]="'POLICY.PWD_LOCKOUT.DESCRIPTION' | translate">
|
||||||
<p class="default" *ngIf="isDefault"> {{'POLICY.DEFAULTLABEL' | translate}}</p>
|
<cnsl-info-section class="default" *ngIf="isDefault"> {{'POLICY.DEFAULTLABEL' | translate}}</cnsl-info-section>
|
||||||
|
|
||||||
<ng-template appHasRole [appHasRole]="['policy.delete']">
|
<ng-template appHasRole [appHasRole]="['policy.delete']">
|
||||||
<button *ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault"
|
<button *ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault"
|
||||||
matTooltip="{{'POLICY.RESET' | translate}}" color="warn" (click)="removePolicy()" mat-stroked-button>
|
matTooltip="{{'POLICY.RESET' | translate}}" color="warn" (click)="resetPolicy()" mat-stroked-button>
|
||||||
{{'POLICY.RESET' | translate}}
|
{{'POLICY.RESET' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
@ -14,22 +14,15 @@
|
|||||||
<span class="left-desc">{{'POLICY.DATA.MAXATTEMPTS' | translate}}</span>
|
<span class="left-desc">{{'POLICY.DATA.MAXATTEMPTS' | translate}}</span>
|
||||||
<span class="fill-space"></span>
|
<span class="fill-space"></span>
|
||||||
<div class="length-wrapper">
|
<div class="length-wrapper">
|
||||||
<button mat-icon-button (click)="incrementMaxAttempts()">
|
|
||||||
<mat-icon>add</mat-icon>
|
|
||||||
</button>
|
|
||||||
<span>{{lockoutData?.maxAttempts}}</span>
|
|
||||||
<button mat-icon-button (click)="decrementMaxAttempts()">
|
<button mat-icon-button (click)="decrementMaxAttempts()">
|
||||||
<mat-icon>remove</mat-icon>
|
<mat-icon>remove</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
<span>{{lockoutData?.maxPasswordAttempts}}</span>
|
||||||
|
<button mat-icon-button (click)="incrementMaxAttempts()">
|
||||||
|
<mat-icon>add</mat-icon>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
|
||||||
<span class="left-desc">{{'POLICY.DATA.SHOWLOCKOUTFAILURES' | translate}}</span>
|
|
||||||
<span class="fill-space"></span>
|
|
||||||
<mat-slide-toggle color="primary" name="showLockoutFailure" ngDefaultControl
|
|
||||||
[(ngModel)]="lockoutData.showLockoutFailure">
|
|
||||||
</mat-slide-toggle>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn-container">
|
<div class="btn-container">
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
.default {
|
.default {
|
||||||
color: var(--color-main);
|
display: block;
|
||||||
margin-top: 0;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
|
@ -3,13 +3,11 @@ import { FormGroup } from '@angular/forms';
|
|||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { switchMap } from 'rxjs/operators';
|
import { switchMap } from 'rxjs/operators';
|
||||||
|
import { GetLockoutPolicyResponse as AdminGetPasswordLockoutPolicyResponse } from 'src/app/proto/generated/zitadel/admin_pb';
|
||||||
import {
|
import {
|
||||||
GetPasswordLockoutPolicyResponse as AdminGetPasswordLockoutPolicyResponse,
|
GetLockoutPolicyResponse as MgmtGetPasswordLockoutPolicyResponse,
|
||||||
} from 'src/app/proto/generated/zitadel/admin_pb';
|
|
||||||
import {
|
|
||||||
GetPasswordLockoutPolicyResponse as MgmtGetPasswordLockoutPolicyResponse,
|
|
||||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||||
import { PasswordLockoutPolicy } from 'src/app/proto/generated/zitadel/policy_pb';
|
import { LockoutPolicy } from 'src/app/proto/generated/zitadel/policy_pb';
|
||||||
import { AdminService } from 'src/app/services/admin.service';
|
import { AdminService } from 'src/app/services/admin.service';
|
||||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
@ -17,127 +15,124 @@ import { ToastService } from 'src/app/services/toast.service';
|
|||||||
import { PolicyComponentServiceType } from '../policy-component-types.enum';
|
import { PolicyComponentServiceType } from '../policy-component-types.enum';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-password-lockout-policy',
|
selector: 'app-password-lockout-policy',
|
||||||
templateUrl: './password-lockout-policy.component.html',
|
templateUrl: './password-lockout-policy.component.html',
|
||||||
styleUrls: ['./password-lockout-policy.component.scss'],
|
styleUrls: ['./password-lockout-policy.component.scss'],
|
||||||
})
|
})
|
||||||
export class PasswordLockoutPolicyComponent implements OnDestroy {
|
export class PasswordLockoutPolicyComponent implements OnDestroy {
|
||||||
@Input() public service!: ManagementService | AdminService;
|
@Input() public service!: ManagementService | AdminService;
|
||||||
public serviceType: PolicyComponentServiceType = PolicyComponentServiceType.MGMT;
|
public serviceType: PolicyComponentServiceType = PolicyComponentServiceType.MGMT;
|
||||||
|
|
||||||
|
|
||||||
public lockoutForm!: FormGroup;
|
public lockoutForm!: FormGroup;
|
||||||
public lockoutData!: PasswordLockoutPolicy.AsObject;
|
public lockoutData!: LockoutPolicy.AsObject;
|
||||||
private sub: Subscription = new Subscription();
|
private sub: Subscription = new Subscription();
|
||||||
public PolicyComponentServiceType: any = PolicyComponentServiceType;
|
public PolicyComponentServiceType: any = PolicyComponentServiceType;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private toast: ToastService,
|
private toast: ToastService,
|
||||||
private injector: Injector,
|
private injector: Injector,
|
||||||
) {
|
) {
|
||||||
this.sub = this.route.data.pipe(switchMap(data => {
|
this.sub = this.route.data.pipe(switchMap(data => {
|
||||||
this.serviceType = data.serviceType;
|
this.serviceType = data.serviceType;
|
||||||
|
|
||||||
switch (this.serviceType) {
|
switch (this.serviceType) {
|
||||||
case PolicyComponentServiceType.MGMT:
|
case PolicyComponentServiceType.MGMT:
|
||||||
this.service = this.injector.get(ManagementService as Type<ManagementService>);
|
this.service = this.injector.get(ManagementService as Type<ManagementService>);
|
||||||
break;
|
break;
|
||||||
case PolicyComponentServiceType.ADMIN:
|
case PolicyComponentServiceType.ADMIN:
|
||||||
this.service = this.injector.get(AdminService as Type<AdminService>);
|
this.service = this.injector.get(AdminService as Type<AdminService>);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.route.params;
|
return this.route.params;
|
||||||
})).subscribe(() => {
|
})).subscribe(() => {
|
||||||
this.fetchData();
|
this.fetchData();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnDestroy(): void {
|
||||||
|
this.sub.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
private fetchData(): void {
|
||||||
|
this.getData().then(resp => {
|
||||||
|
if (resp.policy) {
|
||||||
|
this.lockoutData = resp.policy;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private getData():
|
||||||
|
Promise<AdminGetPasswordLockoutPolicyResponse.AsObject | MgmtGetPasswordLockoutPolicyResponse.AsObject> {
|
||||||
|
switch (this.serviceType) {
|
||||||
|
case PolicyComponentServiceType.MGMT:
|
||||||
|
return (this.service as ManagementService).getLockoutPolicy();
|
||||||
|
case PolicyComponentServiceType.ADMIN:
|
||||||
|
return (this.service as AdminService).getLockoutPolicy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public resetPolicy(): void {
|
||||||
|
if (this.service instanceof ManagementService) {
|
||||||
|
this.service.resetLockoutPolicyToDefault().then(() => {
|
||||||
|
this.toast.showInfo('POLICY.TOAST.RESETSUCCESS', true);
|
||||||
|
this.fetchData();
|
||||||
|
}).catch(error => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public incrementMaxAttempts(): void {
|
||||||
|
if (this.lockoutData?.maxPasswordAttempts !== undefined) {
|
||||||
|
this.lockoutData.maxPasswordAttempts++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public decrementMaxAttempts(): void {
|
||||||
|
if (this.lockoutData?.maxPasswordAttempts && this.lockoutData?.maxPasswordAttempts > 0) {
|
||||||
|
this.lockoutData.maxPasswordAttempts--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public savePolicy(): void {
|
||||||
|
let promise: Promise<any>;
|
||||||
|
if (this.service instanceof AdminService) {
|
||||||
|
promise = this.service.updateLockoutPolicy(
|
||||||
|
this.lockoutData.maxPasswordAttempts,
|
||||||
|
).then(() => {
|
||||||
|
this.toast.showInfo('POLICY.TOAST.SET', true);
|
||||||
|
}).catch(error => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if ((this.lockoutData as LockoutPolicy.AsObject).isDefault) {
|
||||||
|
promise = this.service.addCustomLockoutPolicy(
|
||||||
|
this.lockoutData.maxPasswordAttempts,
|
||||||
|
).then(() => {
|
||||||
|
this.toast.showInfo('POLICY.TOAST.SET', true);
|
||||||
|
}).catch(error => {
|
||||||
|
this.toast.showError(error);
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
|
promise = this.service.updateCustomLockoutPolicy(
|
||||||
public ngOnDestroy(): void {
|
this.lockoutData.maxPasswordAttempts,
|
||||||
this.sub.unsubscribe();
|
).then(() => {
|
||||||
}
|
this.toast.showInfo('POLICY.TOAST.SET', true);
|
||||||
|
}).catch(error => {
|
||||||
private fetchData(): void {
|
this.toast.showError(error);
|
||||||
this.getData().then(resp => {
|
|
||||||
if (resp.policy) {
|
|
||||||
this.lockoutData = resp.policy;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private getData():
|
public get isDefault(): boolean {
|
||||||
Promise<AdminGetPasswordLockoutPolicyResponse.AsObject | MgmtGetPasswordLockoutPolicyResponse.AsObject> {
|
if (this.lockoutData && this.serviceType === PolicyComponentServiceType.MGMT) {
|
||||||
switch (this.serviceType) {
|
return (this.lockoutData as LockoutPolicy.AsObject).isDefault;
|
||||||
case PolicyComponentServiceType.MGMT:
|
} else {
|
||||||
return (this.service as ManagementService).getPasswordLockoutPolicy();
|
return false;
|
||||||
case PolicyComponentServiceType.ADMIN:
|
|
||||||
return (this.service as AdminService).getPasswordLockoutPolicy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public removePolicy(): void {
|
|
||||||
if (this.service instanceof ManagementService) {
|
|
||||||
this.service.resetPasswordLockoutPolicyToDefault().then(() => {
|
|
||||||
this.toast.showInfo('POLICY.TOAST.RESETSUCCESS', true);
|
|
||||||
this.fetchData();
|
|
||||||
}).catch(error => {
|
|
||||||
this.toast.showError(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public incrementMaxAttempts(): void {
|
|
||||||
if (this.lockoutData?.maxAttempts !== undefined) {
|
|
||||||
this.lockoutData.maxAttempts++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public decrementMaxAttempts(): void {
|
|
||||||
if (this.lockoutData?.maxAttempts && this.lockoutData?.maxAttempts > 0) {
|
|
||||||
this.lockoutData.maxAttempts--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public savePolicy(): void {
|
|
||||||
let promise: Promise<any>;
|
|
||||||
if (this.service instanceof AdminService) {
|
|
||||||
promise = this.service.updatePasswordLockoutPolicy(
|
|
||||||
this.lockoutData.maxAttempts,
|
|
||||||
this.lockoutData.showLockoutFailure,
|
|
||||||
).then(() => {
|
|
||||||
this.toast.showInfo('POLICY.TOAST.SET', true);
|
|
||||||
}).catch(error => {
|
|
||||||
this.toast.showError(error);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
if ((this.lockoutData as PasswordLockoutPolicy.AsObject).isDefault) {
|
|
||||||
promise = this.service.addCustomPasswordLockoutPolicy(
|
|
||||||
this.lockoutData.maxAttempts,
|
|
||||||
this.lockoutData.showLockoutFailure,
|
|
||||||
).then(() => {
|
|
||||||
this.toast.showInfo('POLICY.TOAST.SET', true);
|
|
||||||
}).catch(error => {
|
|
||||||
this.toast.showError(error);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
promise = this.service.updateCustomPasswordLockoutPolicy(
|
|
||||||
this.lockoutData.maxAttempts,
|
|
||||||
this.lockoutData.showLockoutFailure,
|
|
||||||
).then(() => {
|
|
||||||
this.toast.showInfo('POLICY.TOAST.SET', true);
|
|
||||||
}).catch(error => {
|
|
||||||
this.toast.showError(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public get isDefault(): boolean {
|
|
||||||
if (this.lockoutData && this.serviceType === PolicyComponentServiceType.MGMT) {
|
|
||||||
return (this.lockoutData as PasswordLockoutPolicy.AsObject).isDefault;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,25 +9,26 @@ import { TranslateModule } from '@ngx-translate/core';
|
|||||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||||
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
||||||
import { InputModule } from 'src/app/modules/input/input.module';
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
import { LinksModule } from '../../links/links.module';
|
|
||||||
|
|
||||||
|
import { InfoSectionModule } from '../../info-section/info-section.module';
|
||||||
import { PasswordLockoutPolicyRoutingModule } from './password-lockout-policy-routing.module';
|
import { PasswordLockoutPolicyRoutingModule } from './password-lockout-policy-routing.module';
|
||||||
import { PasswordLockoutPolicyComponent } from './password-lockout-policy.component';
|
import { PasswordLockoutPolicyComponent } from './password-lockout-policy.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [PasswordLockoutPolicyComponent],
|
declarations: [PasswordLockoutPolicyComponent],
|
||||||
imports: [
|
imports: [
|
||||||
PasswordLockoutPolicyRoutingModule,
|
PasswordLockoutPolicyRoutingModule,
|
||||||
CommonModule,
|
CommonModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
InputModule,
|
InputModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatSlideToggleModule,
|
MatSlideToggleModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
HasRoleModule,
|
HasRoleModule,
|
||||||
MatTooltipModule,
|
MatTooltipModule,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
DetailLayoutModule,
|
DetailLayoutModule,
|
||||||
],
|
InfoSectionModule,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class PasswordLockoutPolicyModule { }
|
export class PasswordLockoutPolicyModule { }
|
||||||
|
@ -25,6 +25,18 @@ export const COMPLEXITY_POLICY: GridPolicy = {
|
|||||||
color: 'yellow',
|
color: 'yellow',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const LOCKOUT_POLICY: GridPolicy = {
|
||||||
|
i18nTitle: 'POLICY.PWD_LOCKOUT.TITLE',
|
||||||
|
i18nDesc: 'POLICY.PWD_LOCKOUT.DESCRIPTION',
|
||||||
|
iamRouterLink: ['/iam', 'policy', PolicyComponentType.LOCKOUT],
|
||||||
|
orgRouterLink: ['/org', 'policy', PolicyComponentType.LOCKOUT],
|
||||||
|
iamWithRole: ['iam.policy.read'],
|
||||||
|
orgWithRole: ['policy.read'],
|
||||||
|
tags: ['login', 'security'],
|
||||||
|
icon: 'las la-lock',
|
||||||
|
color: 'yellow',
|
||||||
|
};
|
||||||
|
|
||||||
export const IAM_POLICY = {
|
export const IAM_POLICY = {
|
||||||
i18nTitle: 'POLICY.IAM_POLICY.TITLE',
|
i18nTitle: 'POLICY.IAM_POLICY.TITLE',
|
||||||
i18nDesc: 'POLICY.IAM_POLICY.DESCRIPTION',
|
i18nDesc: 'POLICY.IAM_POLICY.DESCRIPTION',
|
||||||
@ -99,6 +111,7 @@ export const LOGIN_TEXTS_POLICY = {
|
|||||||
|
|
||||||
export const POLICIES: GridPolicy[] = [
|
export const POLICIES: GridPolicy[] = [
|
||||||
COMPLEXITY_POLICY,
|
COMPLEXITY_POLICY,
|
||||||
|
LOCKOUT_POLICY,
|
||||||
IAM_POLICY,
|
IAM_POLICY,
|
||||||
LOGIN_POLICY,
|
LOGIN_POLICY,
|
||||||
PRIVATELABEL_POLICY,
|
PRIVATELABEL_POLICY,
|
||||||
|
@ -17,6 +17,7 @@ import { MemberCreateDialogModule } from 'src/app/modules/add-member-dialog/memb
|
|||||||
import { CardModule } from 'src/app/modules/card/card.module';
|
import { CardModule } from 'src/app/modules/card/card.module';
|
||||||
import { ChangesModule } from 'src/app/modules/changes/changes.module';
|
import { ChangesModule } from 'src/app/modules/changes/changes.module';
|
||||||
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
||||||
|
import { InfoSectionModule } from 'src/app/modules/info-section/info-section.module';
|
||||||
import { InputModule } from 'src/app/modules/input/input.module';
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
import { MachineKeysModule } from 'src/app/modules/machine-keys/machine-keys.module';
|
import { MachineKeysModule } from 'src/app/modules/machine-keys/machine-keys.module';
|
||||||
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
||||||
@ -104,6 +105,7 @@ import { UserMfaComponent } from './user-detail/user-mfa/user-mfa.component';
|
|||||||
LocalizedDatePipeModule,
|
LocalizedDatePipeModule,
|
||||||
InputModule,
|
InputModule,
|
||||||
MachineKeysModule,
|
MachineKeysModule,
|
||||||
|
InfoSectionModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class UserDetailModule { }
|
export class UserDetailModule { }
|
||||||
|
@ -14,6 +14,11 @@
|
|||||||
<span class="fill-space"></span>
|
<span class="fill-space"></span>
|
||||||
|
|
||||||
<ng-template appHasRole [appHasRole]="['user.write$', 'user.write:'+user?.id]">
|
<ng-template appHasRole [appHasRole]="['user.write$', 'user.write:'+user?.id]">
|
||||||
|
<button class="unlock-button" mat-stroked-button color="warn"
|
||||||
|
*ngIf="user?.state === UserState.USER_STATE_LOCKED"
|
||||||
|
(click)="unlockUser()">{{'USER.PAGES.UNLOCK' |
|
||||||
|
translate}}</button>
|
||||||
|
|
||||||
<button class="state-button" mat-stroked-button color="warn"
|
<button class="state-button" mat-stroked-button color="warn"
|
||||||
*ngIf="user?.state !== UserState.USER_STATE_INACTIVE"
|
*ngIf="user?.state !== UserState.USER_STATE_INACTIVE"
|
||||||
(click)="changeState(UserState.USER_STATE_INACTIVE)">{{'USER.PAGES.DEACTIVATE' |
|
(click)="changeState(UserState.USER_STATE_INACTIVE)">{{'USER.PAGES.DEACTIVATE' |
|
||||||
@ -26,6 +31,7 @@
|
|||||||
|
|
||||||
<mat-progress-bar *ngIf="loading" color="primary" mode="indeterminate"></mat-progress-bar>
|
<mat-progress-bar *ngIf="loading" color="primary" mode="indeterminate"></mat-progress-bar>
|
||||||
|
|
||||||
|
<cnsl-info-section class="locked" *ngIf="user?.state === UserState.USER_STATE_LOCKED" type="WARN">{{'USER.PAGES.LOCKEDDESCRIPTION' | translate}}</cnsl-info-section>
|
||||||
<span *ngIf="!loading && !user">{{ 'USER.PAGES.NOUSER' | translate }}</span>
|
<span *ngIf="!loading && !user">{{ 'USER.PAGES.NOUSER' | translate }}</span>
|
||||||
|
|
||||||
<app-card title="{{ 'USER.PAGES.LOGINNAMES' | translate }}"
|
<app-card title="{{ 'USER.PAGES.LOGINNAMES' | translate }}"
|
||||||
|
@ -18,11 +18,20 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.unlock-button {
|
||||||
|
margin-left: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.state-button {
|
.state-button {
|
||||||
margin-left: .5rem;
|
margin-left: .5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.locked {
|
||||||
|
display: block;
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
.img-phone-email {
|
.img-phone-email {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import { take } from 'rxjs/operators';
|
|||||||
import { ChangeType } from 'src/app/modules/changes/changes.component';
|
import { ChangeType } from 'src/app/modules/changes/changes.component';
|
||||||
import { UserGrantContext } from 'src/app/modules/user-grants/user-grants-datasource';
|
import { UserGrantContext } from 'src/app/modules/user-grants/user-grants-datasource';
|
||||||
import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
|
import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
|
||||||
import { SendHumanResetPasswordNotificationRequest } from 'src/app/proto/generated/zitadel/management_pb';
|
import { SendHumanResetPasswordNotificationRequest, UnlockUserRequest } from 'src/app/proto/generated/zitadel/management_pb';
|
||||||
import { Email, Gender, Machine, Phone, Profile, User, UserState } from 'src/app/proto/generated/zitadel/user_pb';
|
import { Email, Gender, Machine, Phone, Profile, User, UserState } from 'src/app/proto/generated/zitadel/user_pb';
|
||||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
@ -16,281 +16,292 @@ import { EditDialogComponent, EditDialogType } from '../auth-user-detail/edit-di
|
|||||||
import { ResendEmailDialogComponent } from '../auth-user-detail/resend-email-dialog/resend-email-dialog.component';
|
import { ResendEmailDialogComponent } from '../auth-user-detail/resend-email-dialog/resend-email-dialog.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-user-detail',
|
selector: 'app-user-detail',
|
||||||
templateUrl: './user-detail.component.html',
|
templateUrl: './user-detail.component.html',
|
||||||
styleUrls: ['./user-detail.component.scss'],
|
styleUrls: ['./user-detail.component.scss'],
|
||||||
})
|
})
|
||||||
export class UserDetailComponent implements OnInit {
|
export class UserDetailComponent implements OnInit {
|
||||||
public user!: User.AsObject;
|
public user!: User.AsObject;
|
||||||
public genders: Gender[] = [Gender.GENDER_MALE, Gender.GENDER_FEMALE, Gender.GENDER_DIVERSE];
|
public genders: Gender[] = [Gender.GENDER_MALE, Gender.GENDER_FEMALE, Gender.GENDER_DIVERSE];
|
||||||
public languages: string[] = ['de', 'en'];
|
public languages: string[] = ['de', 'en'];
|
||||||
|
|
||||||
public ChangeType: any = ChangeType;
|
public ChangeType: any = ChangeType;
|
||||||
public loading: boolean = false;
|
public loading: boolean = false;
|
||||||
|
|
||||||
public UserState: any = UserState;
|
public UserState: any = UserState;
|
||||||
public copied: string = '';
|
public copied: string = '';
|
||||||
public USERGRANTCONTEXT: UserGrantContext = UserGrantContext.USER;
|
public USERGRANTCONTEXT: UserGrantContext = UserGrantContext.USER;
|
||||||
|
|
||||||
public EditDialogType: any = EditDialogType;
|
public EditDialogType: any = EditDialogType;
|
||||||
public refreshChanges$: EventEmitter<void> = new EventEmitter();
|
public refreshChanges$: EventEmitter<void> = new EventEmitter();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public translate: TranslateService,
|
public translate: TranslateService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private toast: ToastService,
|
private toast: ToastService,
|
||||||
public mgmtUserService: ManagementService,
|
public mgmtUserService: ManagementService,
|
||||||
private _location: Location,
|
private _location: Location,
|
||||||
private dialog: MatDialog,
|
private dialog: MatDialog,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
refreshUser(): void {
|
refreshUser(): void {
|
||||||
this.refreshChanges$.emit();
|
this.refreshChanges$.emit();
|
||||||
this.route.params.pipe(take(1)).subscribe(params => {
|
this.route.params.pipe(take(1)).subscribe(params => {
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
this.mgmtUserService.getUserByID(id).then(resp => {
|
this.mgmtUserService.getUserByID(id).then(resp => {
|
||||||
if (resp.user) {
|
if (resp.user) {
|
||||||
this.user = resp.user;
|
this.user = resp.user;
|
||||||
}
|
}
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnInit(): void {
|
||||||
|
this.refreshUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
public unlockUser(): void {
|
||||||
|
const req = new UnlockUserRequest();
|
||||||
|
req.setId(this.user.id);
|
||||||
|
this.mgmtUserService.unlockUser(req).then(() => {
|
||||||
|
this.toast.showInfo('USER.TOAST.UNLOCKED', true);
|
||||||
|
this.refreshUser();
|
||||||
|
}).catch(error => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public changeState(newState: UserState): void {
|
||||||
|
if (newState === UserState.USER_STATE_ACTIVE) {
|
||||||
|
this.mgmtUserService.reactivateUser(this.user.id).then(() => {
|
||||||
|
this.toast.showInfo('USER.TOAST.REACTIVATED', true);
|
||||||
|
this.user.state = newState;
|
||||||
|
}).catch(error => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
|
} else if (newState === UserState.USER_STATE_INACTIVE) {
|
||||||
|
this.mgmtUserService.deactivateUser(this.user.id).then(() => {
|
||||||
|
this.toast.showInfo('USER.TOAST.DEACTIVATED', true);
|
||||||
|
this.user.state = newState;
|
||||||
|
}).catch(error => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public saveProfile(profileData: Profile.AsObject): void {
|
||||||
|
if (this.user.human) {
|
||||||
|
this.user.human.profile = profileData;
|
||||||
|
this.mgmtUserService
|
||||||
|
.updateHumanProfile(
|
||||||
|
this.user.id,
|
||||||
|
this.user.human.profile.firstName,
|
||||||
|
this.user.human.profile.lastName,
|
||||||
|
this.user.human.profile.nickName,
|
||||||
|
this.user.human.profile.displayName,
|
||||||
|
this.user.human.profile.preferredLanguage,
|
||||||
|
this.user.human.profile.gender)
|
||||||
|
.then(() => {
|
||||||
|
this.toast.showInfo('USER.TOAST.SAVED', true);
|
||||||
|
this.refreshChanges$.emit();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
this.toast.showError(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public saveMachine(machineData: Machine.AsObject): void {
|
||||||
|
if (this.user.machine) {
|
||||||
|
this.user.machine.name = machineData.name;
|
||||||
|
this.user.machine.description = machineData.description;
|
||||||
|
|
||||||
|
this.mgmtUserService
|
||||||
|
.updateMachine(
|
||||||
|
this.user.id,
|
||||||
|
this.user.machine.name,
|
||||||
|
this.user.machine.description)
|
||||||
|
.then(() => {
|
||||||
|
this.toast.showInfo('USER.TOAST.SAVED', true);
|
||||||
|
this.refreshChanges$.emit();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public resendEmailVerification(): void {
|
||||||
|
this.mgmtUserService.resendHumanEmailVerification(this.user.id).then(() => {
|
||||||
|
this.toast.showInfo('USER.TOAST.EMAILVERIFICATIONSENT', true);
|
||||||
|
this.refreshChanges$.emit();
|
||||||
|
}).catch(error => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public resendPhoneVerification(): void {
|
||||||
|
this.mgmtUserService.resendHumanPhoneVerification(this.user.id).then(() => {
|
||||||
|
this.toast.showInfo('USER.TOAST.PHONEVERIFICATIONSENT', true);
|
||||||
|
this.refreshChanges$.emit();
|
||||||
|
}).catch(error => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public deletePhone(): void {
|
||||||
|
this.mgmtUserService.removeHumanPhone(this.user.id).then(() => {
|
||||||
|
this.toast.showInfo('USER.TOAST.PHONEREMOVED', true);
|
||||||
|
if (this.user.human) {
|
||||||
|
this.user.human.phone = new Phone().setPhone('').toObject();
|
||||||
this.refreshUser();
|
this.refreshUser();
|
||||||
}
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public changeState(newState: UserState): void {
|
public saveEmail(email: string): void {
|
||||||
if (newState === UserState.USER_STATE_ACTIVE) {
|
if (this.user.id && email) {
|
||||||
this.mgmtUserService.reactivateUser(this.user.id).then(() => {
|
this.mgmtUserService.updateHumanEmail(this.user.id, email).then(() => {
|
||||||
this.toast.showInfo('USER.TOAST.REACTIVATED', true);
|
this.toast.showInfo('USER.TOAST.EMAILSAVED', true);
|
||||||
this.user.state = newState;
|
if (this.user.state === UserState.USER_STATE_INITIAL) {
|
||||||
}).catch(error => {
|
this.mgmtUserService.resendHumanInitialization(this.user.id, email ?? '').then(() => {
|
||||||
this.toast.showError(error);
|
this.toast.showInfo('USER.TOAST.INITEMAILSENT', true);
|
||||||
});
|
this.refreshChanges$.emit();
|
||||||
} else if (newState === UserState.USER_STATE_INACTIVE) {
|
}).catch(error => {
|
||||||
this.mgmtUserService.deactivateUser(this.user.id).then(() => {
|
this.toast.showError(error);
|
||||||
this.toast.showInfo('USER.TOAST.DEACTIVATED', true);
|
});
|
||||||
this.user.state = newState;
|
|
||||||
}).catch(error => {
|
|
||||||
this.toast.showError(error);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public saveProfile(profileData: Profile.AsObject): void {
|
|
||||||
if (this.user.human) {
|
if (this.user.human) {
|
||||||
this.user.human.profile = profileData;
|
this.user.human.email = new Email().setEmail(email).toObject();
|
||||||
this.mgmtUserService
|
this.refreshUser();
|
||||||
.updateHumanProfile(
|
|
||||||
this.user.id,
|
|
||||||
this.user.human.profile.firstName,
|
|
||||||
this.user.human.profile.lastName,
|
|
||||||
this.user.human.profile.nickName,
|
|
||||||
this.user.human.profile.displayName,
|
|
||||||
this.user.human.profile.preferredLanguage,
|
|
||||||
this.user.human.profile.gender)
|
|
||||||
.then(() => {
|
|
||||||
this.toast.showInfo('USER.TOAST.SAVED', true);
|
|
||||||
this.refreshChanges$.emit();
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
this.toast.showError(error);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public saveMachine(machineData: Machine.AsObject): void {
|
public savePhone(phone: string): void {
|
||||||
if (this.user.machine) {
|
if (this.user.id && phone) {
|
||||||
this.user.machine.name = machineData.name;
|
this.mgmtUserService
|
||||||
this.user.machine.description = machineData.description;
|
.updateHumanPhone(this.user.id, phone).then(() => {
|
||||||
|
this.toast.showInfo('USER.TOAST.PHONESAVED', true);
|
||||||
this.mgmtUserService
|
if (this.user.human) {
|
||||||
.updateMachine(
|
this.user.human.phone = new Phone().setPhone(phone).toObject();
|
||||||
this.user.id,
|
this.refreshUser();
|
||||||
this.user.machine.name,
|
}
|
||||||
this.user.machine.description)
|
|
||||||
.then(() => {
|
|
||||||
this.toast.showInfo('USER.TOAST.SAVED', true);
|
|
||||||
this.refreshChanges$.emit();
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
this.toast.showError(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public resendEmailVerification(): void {
|
|
||||||
this.mgmtUserService.resendHumanEmailVerification(this.user.id).then(() => {
|
|
||||||
this.toast.showInfo('USER.TOAST.EMAILVERIFICATIONSENT', true);
|
|
||||||
this.refreshChanges$.emit();
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.toast.showError(error);
|
this.toast.showError(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public resendPhoneVerification(): void {
|
public navigateBack(): void {
|
||||||
this.mgmtUserService.resendHumanPhoneVerification(this.user.id).then(() => {
|
this._location.back();
|
||||||
this.toast.showInfo('USER.TOAST.PHONEVERIFICATIONSENT', true);
|
}
|
||||||
this.refreshChanges$.emit();
|
|
||||||
|
public sendSetPasswordNotification(): void {
|
||||||
|
this.mgmtUserService.sendHumanResetPasswordNotification(
|
||||||
|
this.user.id,
|
||||||
|
SendHumanResetPasswordNotificationRequest.Type.TYPE_EMAIL,
|
||||||
|
).then(() => {
|
||||||
|
this.toast.showInfo('USER.TOAST.PASSWORDNOTIFICATIONSENT', true);
|
||||||
|
this.refreshChanges$.emit();
|
||||||
|
}).catch(error => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public deleteUser(): void {
|
||||||
|
const dialogRef = this.dialog.open(WarnDialogComponent, {
|
||||||
|
data: {
|
||||||
|
confirmKey: 'ACTIONS.DELETE',
|
||||||
|
cancelKey: 'ACTIONS.CANCEL',
|
||||||
|
titleKey: 'USER.DIALOG.DELETE_TITLE',
|
||||||
|
descriptionKey: 'USER.DIALOG.DELETE_DESCRIPTION',
|
||||||
|
},
|
||||||
|
width: '400px',
|
||||||
|
});
|
||||||
|
|
||||||
|
dialogRef.afterClosed().subscribe(resp => {
|
||||||
|
if (resp) {
|
||||||
|
this.mgmtUserService.removeUser(this.user.id).then(() => {
|
||||||
|
const params: Params = {
|
||||||
|
'deferredReload': true,
|
||||||
|
};
|
||||||
|
this.router.navigate(['/users/list', this.user.human ? 'humans' : 'machines'], { queryParams: params });
|
||||||
|
this.toast.showInfo('USER.TOAST.DELETED', true);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.toast.showError(error);
|
this.toast.showError(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public deletePhone(): void {
|
public resendInitEmail(): void {
|
||||||
this.mgmtUserService.removeHumanPhone(this.user.id).then(() => {
|
const dialogRef = this.dialog.open(ResendEmailDialogComponent, {
|
||||||
this.toast.showInfo('USER.TOAST.PHONEREMOVED', true);
|
width: '400px',
|
||||||
if (this.user.human) {
|
});
|
||||||
this.user.human.phone = new Phone().setPhone('').toObject();
|
|
||||||
this.refreshUser();
|
dialogRef.afterClosed().subscribe(resp => {
|
||||||
}
|
if (resp.send && this.user.id) {
|
||||||
|
this.mgmtUserService.resendHumanInitialization(this.user.id, resp.email ?? '').then(() => {
|
||||||
|
this.toast.showInfo('USER.TOAST.INITEMAILSENT', true);
|
||||||
|
this.refreshChanges$.emit();
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.toast.showError(error);
|
this.toast.showError(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public saveEmail(email: string): void {
|
public openEditDialog(type: EditDialogType): void {
|
||||||
if (this.user.id && email) {
|
switch (type) {
|
||||||
this.mgmtUserService.updateHumanEmail(this.user.id, email).then(() => {
|
case EditDialogType.PHONE:
|
||||||
this.toast.showInfo('USER.TOAST.EMAILSAVED', true);
|
const dialogRefPhone = this.dialog.open(EditDialogComponent, {
|
||||||
if (this.user.state === UserState.USER_STATE_INITIAL) {
|
data: {
|
||||||
this.mgmtUserService.resendHumanInitialization(this.user.id, email ?? '').then(() => {
|
confirmKey: 'ACTIONS.SAVE',
|
||||||
this.toast.showInfo('USER.TOAST.INITEMAILSENT', true);
|
cancelKey: 'ACTIONS.CANCEL',
|
||||||
this.refreshChanges$.emit();
|
labelKey: 'ACTIONS.NEWVALUE',
|
||||||
}).catch(error => {
|
titleKey: 'USER.LOGINMETHODS.PHONE.EDITTITLE',
|
||||||
this.toast.showError(error);
|
descriptionKey: 'USER.LOGINMETHODS.PHONE.EDITDESC',
|
||||||
});
|
value: this.user.human?.phone?.phone,
|
||||||
}
|
type: EditDialogType.PHONE,
|
||||||
if (this.user.human) {
|
},
|
||||||
this.user.human.email = new Email().setEmail(email).toObject();
|
width: '400px',
|
||||||
this.refreshUser();
|
|
||||||
}
|
|
||||||
}).catch(error => {
|
|
||||||
this.toast.showError(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public savePhone(phone: string): void {
|
|
||||||
if (this.user.id && phone) {
|
|
||||||
this.mgmtUserService
|
|
||||||
.updateHumanPhone(this.user.id, phone).then(() => {
|
|
||||||
this.toast.showInfo('USER.TOAST.PHONESAVED', true);
|
|
||||||
if (this.user.human) {
|
|
||||||
this.user.human.phone = new Phone().setPhone(phone).toObject();
|
|
||||||
this.refreshUser();
|
|
||||||
}
|
|
||||||
}).catch(error => {
|
|
||||||
this.toast.showError(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public navigateBack(): void {
|
|
||||||
this._location.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public sendSetPasswordNotification(): void {
|
|
||||||
this.mgmtUserService.sendHumanResetPasswordNotification(
|
|
||||||
this.user.id,
|
|
||||||
SendHumanResetPasswordNotificationRequest.Type.TYPE_EMAIL,
|
|
||||||
).then(() => {
|
|
||||||
this.toast.showInfo('USER.TOAST.PASSWORDNOTIFICATIONSENT', true);
|
|
||||||
this.refreshChanges$.emit();
|
|
||||||
}).catch(error => {
|
|
||||||
this.toast.showError(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public deleteUser(): void {
|
|
||||||
const dialogRef = this.dialog.open(WarnDialogComponent, {
|
|
||||||
data: {
|
|
||||||
confirmKey: 'ACTIONS.DELETE',
|
|
||||||
cancelKey: 'ACTIONS.CANCEL',
|
|
||||||
titleKey: 'USER.DIALOG.DELETE_TITLE',
|
|
||||||
descriptionKey: 'USER.DIALOG.DELETE_DESCRIPTION',
|
|
||||||
},
|
|
||||||
width: '400px',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe(resp => {
|
dialogRefPhone.afterClosed().subscribe(resp => {
|
||||||
if (resp) {
|
if (resp) {
|
||||||
this.mgmtUserService.removeUser(this.user.id).then(() => {
|
this.savePhone(resp);
|
||||||
const params: Params = {
|
}
|
||||||
'deferredReload': true,
|
|
||||||
};
|
|
||||||
this.router.navigate(['/users/list', this.user.human ? 'humans' : 'machines'], { queryParams: params });
|
|
||||||
this.toast.showInfo('USER.TOAST.DELETED', true);
|
|
||||||
}).catch(error => {
|
|
||||||
this.toast.showError(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
break;
|
||||||
|
case EditDialogType.EMAIL:
|
||||||
public resendInitEmail(): void {
|
const dialogRefEmail = this.dialog.open(EditDialogComponent, {
|
||||||
const dialogRef = this.dialog.open(ResendEmailDialogComponent, {
|
data: {
|
||||||
width: '400px',
|
confirmKey: 'ACTIONS.SAVE',
|
||||||
|
cancelKey: 'ACTIONS.CANCEL',
|
||||||
|
labelKey: 'ACTIONS.NEWVALUE',
|
||||||
|
titleKey: 'USER.LOGINMETHODS.EMAIL.EDITTITLE',
|
||||||
|
descriptionKey: 'USER.LOGINMETHODS.EMAIL.EDITDESC',
|
||||||
|
value: this.user.human?.email?.email,
|
||||||
|
type: EditDialogType.EMAIL,
|
||||||
|
},
|
||||||
|
width: '400px',
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe(resp => {
|
dialogRefEmail.afterClosed().subscribe(resp => {
|
||||||
if (resp.send && this.user.id) {
|
if (resp) {
|
||||||
this.mgmtUserService.resendHumanInitialization(this.user.id, resp.email ?? '').then(() => {
|
this.saveEmail(resp);
|
||||||
this.toast.showInfo('USER.TOAST.INITEMAILSENT', true);
|
}
|
||||||
this.refreshChanges$.emit();
|
|
||||||
}).catch(error => {
|
|
||||||
this.toast.showError(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public openEditDialog(type: EditDialogType): void {
|
|
||||||
switch (type) {
|
|
||||||
case EditDialogType.PHONE:
|
|
||||||
const dialogRefPhone = this.dialog.open(EditDialogComponent, {
|
|
||||||
data: {
|
|
||||||
confirmKey: 'ACTIONS.SAVE',
|
|
||||||
cancelKey: 'ACTIONS.CANCEL',
|
|
||||||
labelKey: 'ACTIONS.NEWVALUE',
|
|
||||||
titleKey: 'USER.LOGINMETHODS.PHONE.EDITTITLE',
|
|
||||||
descriptionKey: 'USER.LOGINMETHODS.PHONE.EDITDESC',
|
|
||||||
value: this.user.human?.phone?.phone,
|
|
||||||
type: EditDialogType.PHONE,
|
|
||||||
},
|
|
||||||
width: '400px',
|
|
||||||
});
|
|
||||||
|
|
||||||
dialogRefPhone.afterClosed().subscribe(resp => {
|
|
||||||
if (resp) {
|
|
||||||
this.savePhone(resp);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case EditDialogType.EMAIL:
|
|
||||||
const dialogRefEmail = this.dialog.open(EditDialogComponent, {
|
|
||||||
data: {
|
|
||||||
confirmKey: 'ACTIONS.SAVE',
|
|
||||||
cancelKey: 'ACTIONS.CANCEL',
|
|
||||||
labelKey: 'ACTIONS.NEWVALUE',
|
|
||||||
titleKey: 'USER.LOGINMETHODS.EMAIL.EDITTITLE',
|
|
||||||
descriptionKey: 'USER.LOGINMETHODS.EMAIL.EDITDESC',
|
|
||||||
value: this.user.human?.email?.email,
|
|
||||||
type: EditDialogType.EMAIL,
|
|
||||||
},
|
|
||||||
width: '400px',
|
|
||||||
});
|
|
||||||
|
|
||||||
dialogRefEmail.afterClosed().subscribe(resp => {
|
|
||||||
if (resp) {
|
|
||||||
this.saveEmail(resp);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,8 @@ import {
|
|||||||
GetIDPByIDResponse,
|
GetIDPByIDResponse,
|
||||||
GetLabelPolicyRequest,
|
GetLabelPolicyRequest,
|
||||||
GetLabelPolicyResponse,
|
GetLabelPolicyResponse,
|
||||||
|
GetLockoutPolicyRequest,
|
||||||
|
GetLockoutPolicyResponse,
|
||||||
GetLoginPolicyRequest,
|
GetLoginPolicyRequest,
|
||||||
GetLoginPolicyResponse,
|
GetLoginPolicyResponse,
|
||||||
GetOrgFeaturesRequest,
|
GetOrgFeaturesRequest,
|
||||||
@ -61,8 +63,6 @@ import {
|
|||||||
GetPasswordAgePolicyResponse,
|
GetPasswordAgePolicyResponse,
|
||||||
GetPasswordComplexityPolicyRequest,
|
GetPasswordComplexityPolicyRequest,
|
||||||
GetPasswordComplexityPolicyResponse,
|
GetPasswordComplexityPolicyResponse,
|
||||||
GetPasswordLockoutPolicyRequest,
|
|
||||||
GetPasswordLockoutPolicyResponse,
|
|
||||||
GetPreviewLabelPolicyRequest,
|
GetPreviewLabelPolicyRequest,
|
||||||
GetPreviewLabelPolicyResponse,
|
GetPreviewLabelPolicyResponse,
|
||||||
GetPrivacyPolicyRequest,
|
GetPrivacyPolicyRequest,
|
||||||
@ -144,6 +144,8 @@ import {
|
|||||||
UpdateIDPResponse,
|
UpdateIDPResponse,
|
||||||
UpdateLabelPolicyRequest,
|
UpdateLabelPolicyRequest,
|
||||||
UpdateLabelPolicyResponse,
|
UpdateLabelPolicyResponse,
|
||||||
|
UpdateLockoutPolicyRequest,
|
||||||
|
UpdateLockoutPolicyResponse,
|
||||||
UpdateLoginPolicyRequest,
|
UpdateLoginPolicyRequest,
|
||||||
UpdateLoginPolicyResponse,
|
UpdateLoginPolicyResponse,
|
||||||
UpdateOrgIAMPolicyRequest,
|
UpdateOrgIAMPolicyRequest,
|
||||||
@ -152,8 +154,6 @@ import {
|
|||||||
UpdatePasswordAgePolicyResponse,
|
UpdatePasswordAgePolicyResponse,
|
||||||
UpdatePasswordComplexityPolicyRequest,
|
UpdatePasswordComplexityPolicyRequest,
|
||||||
UpdatePasswordComplexityPolicyResponse,
|
UpdatePasswordComplexityPolicyResponse,
|
||||||
UpdatePasswordLockoutPolicyRequest,
|
|
||||||
UpdatePasswordLockoutPolicyResponse,
|
|
||||||
UpdatePrivacyPolicyRequest,
|
UpdatePrivacyPolicyRequest,
|
||||||
UpdatePrivacyPolicyResponse,
|
UpdatePrivacyPolicyResponse,
|
||||||
} from '../proto/generated/zitadel/admin_pb';
|
} from '../proto/generated/zitadel/admin_pb';
|
||||||
@ -431,20 +431,18 @@ export class AdminService {
|
|||||||
|
|
||||||
/* lockout */
|
/* lockout */
|
||||||
|
|
||||||
public getPasswordLockoutPolicy(): Promise<GetPasswordLockoutPolicyResponse.AsObject> {
|
public getLockoutPolicy(): Promise<GetLockoutPolicyResponse.AsObject> {
|
||||||
const req = new GetPasswordLockoutPolicyRequest();
|
const req = new GetLockoutPolicyRequest();
|
||||||
return this.grpcService.admin.getPasswordLockoutPolicy(req, null).then(resp => resp.toObject());
|
return this.grpcService.admin.getLockoutPolicy(req, null).then(resp => resp.toObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
public updatePasswordLockoutPolicy(
|
public updateLockoutPolicy(
|
||||||
maxAttempts: number,
|
maxAttempts: number,
|
||||||
showLockoutFailures: boolean,
|
): Promise<UpdateLockoutPolicyResponse.AsObject> {
|
||||||
): Promise<UpdatePasswordLockoutPolicyResponse.AsObject> {
|
const req = new UpdateLockoutPolicyRequest();
|
||||||
const req = new UpdatePasswordLockoutPolicyRequest();
|
req.setMaxPasswordAttempts(maxAttempts);
|
||||||
req.setMaxAttempts(maxAttempts);
|
|
||||||
req.setShowLockoutFailure(showLockoutFailures);
|
|
||||||
|
|
||||||
return this.grpcService.admin.updatePasswordLockoutPolicy(req, null).then(resp => resp.toObject());
|
return this.grpcService.admin.updateLockoutPolicy(req, null).then(resp => resp.toObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* label */
|
/* label */
|
||||||
|
@ -17,14 +17,14 @@ import {
|
|||||||
AddAppKeyResponse,
|
AddAppKeyResponse,
|
||||||
AddCustomLabelPolicyRequest,
|
AddCustomLabelPolicyRequest,
|
||||||
AddCustomLabelPolicyResponse,
|
AddCustomLabelPolicyResponse,
|
||||||
|
AddCustomLockoutPolicyRequest,
|
||||||
|
AddCustomLockoutPolicyResponse,
|
||||||
AddCustomLoginPolicyRequest,
|
AddCustomLoginPolicyRequest,
|
||||||
AddCustomLoginPolicyResponse,
|
AddCustomLoginPolicyResponse,
|
||||||
AddCustomPasswordAgePolicyRequest,
|
AddCustomPasswordAgePolicyRequest,
|
||||||
AddCustomPasswordAgePolicyResponse,
|
AddCustomPasswordAgePolicyResponse,
|
||||||
AddCustomPasswordComplexityPolicyRequest,
|
AddCustomPasswordComplexityPolicyRequest,
|
||||||
AddCustomPasswordComplexityPolicyResponse,
|
AddCustomPasswordComplexityPolicyResponse,
|
||||||
AddCustomPasswordLockoutPolicyRequest,
|
|
||||||
AddCustomPasswordLockoutPolicyResponse,
|
|
||||||
AddCustomPrivacyPolicyRequest,
|
AddCustomPrivacyPolicyRequest,
|
||||||
AddCustomPrivacyPolicyResponse,
|
AddCustomPrivacyPolicyResponse,
|
||||||
AddHumanUserRequest,
|
AddHumanUserRequest,
|
||||||
@ -122,6 +122,8 @@ import {
|
|||||||
GetIAMResponse,
|
GetIAMResponse,
|
||||||
GetLabelPolicyRequest,
|
GetLabelPolicyRequest,
|
||||||
GetLabelPolicyResponse,
|
GetLabelPolicyResponse,
|
||||||
|
GetLockoutPolicyRequest,
|
||||||
|
GetLockoutPolicyResponse,
|
||||||
GetLoginPolicyRequest,
|
GetLoginPolicyRequest,
|
||||||
GetLoginPolicyResponse,
|
GetLoginPolicyResponse,
|
||||||
GetMyOrgRequest,
|
GetMyOrgRequest,
|
||||||
@ -138,8 +140,6 @@ import {
|
|||||||
GetPasswordAgePolicyResponse,
|
GetPasswordAgePolicyResponse,
|
||||||
GetPasswordComplexityPolicyRequest,
|
GetPasswordComplexityPolicyRequest,
|
||||||
GetPasswordComplexityPolicyResponse,
|
GetPasswordComplexityPolicyResponse,
|
||||||
GetPasswordLockoutPolicyRequest,
|
|
||||||
GetPasswordLockoutPolicyResponse,
|
|
||||||
GetPreviewLabelPolicyRequest,
|
GetPreviewLabelPolicyRequest,
|
||||||
GetPreviewLabelPolicyResponse,
|
GetPreviewLabelPolicyResponse,
|
||||||
GetPrivacyPolicyRequest,
|
GetPrivacyPolicyRequest,
|
||||||
@ -298,14 +298,14 @@ import {
|
|||||||
ResetCustomVerifyPhoneMessageTextToDefaultResponse,
|
ResetCustomVerifyPhoneMessageTextToDefaultResponse,
|
||||||
ResetLabelPolicyToDefaultRequest,
|
ResetLabelPolicyToDefaultRequest,
|
||||||
ResetLabelPolicyToDefaultResponse,
|
ResetLabelPolicyToDefaultResponse,
|
||||||
|
ResetLockoutPolicyToDefaultRequest,
|
||||||
|
ResetLockoutPolicyToDefaultResponse,
|
||||||
ResetLoginPolicyToDefaultRequest,
|
ResetLoginPolicyToDefaultRequest,
|
||||||
ResetLoginPolicyToDefaultResponse,
|
ResetLoginPolicyToDefaultResponse,
|
||||||
ResetPasswordAgePolicyToDefaultRequest,
|
ResetPasswordAgePolicyToDefaultRequest,
|
||||||
ResetPasswordAgePolicyToDefaultResponse,
|
ResetPasswordAgePolicyToDefaultResponse,
|
||||||
ResetPasswordComplexityPolicyToDefaultRequest,
|
ResetPasswordComplexityPolicyToDefaultRequest,
|
||||||
ResetPasswordComplexityPolicyToDefaultResponse,
|
ResetPasswordComplexityPolicyToDefaultResponse,
|
||||||
ResetPasswordLockoutPolicyToDefaultRequest,
|
|
||||||
ResetPasswordLockoutPolicyToDefaultResponse,
|
|
||||||
ResetPrivacyPolicyToDefaultRequest,
|
ResetPrivacyPolicyToDefaultRequest,
|
||||||
ResetPrivacyPolicyToDefaultResponse,
|
ResetPrivacyPolicyToDefaultResponse,
|
||||||
SendHumanResetPasswordNotificationRequest,
|
SendHumanResetPasswordNotificationRequest,
|
||||||
@ -324,20 +324,22 @@ import {
|
|||||||
SetHumanInitialPasswordRequest,
|
SetHumanInitialPasswordRequest,
|
||||||
SetPrimaryOrgDomainRequest,
|
SetPrimaryOrgDomainRequest,
|
||||||
SetPrimaryOrgDomainResponse,
|
SetPrimaryOrgDomainResponse,
|
||||||
|
UnlockUserRequest,
|
||||||
|
UnlockUserResponse,
|
||||||
UpdateAPIAppConfigRequest,
|
UpdateAPIAppConfigRequest,
|
||||||
UpdateAPIAppConfigResponse,
|
UpdateAPIAppConfigResponse,
|
||||||
UpdateAppRequest,
|
UpdateAppRequest,
|
||||||
UpdateAppResponse,
|
UpdateAppResponse,
|
||||||
UpdateCustomLabelPolicyRequest,
|
UpdateCustomLabelPolicyRequest,
|
||||||
UpdateCustomLabelPolicyResponse,
|
UpdateCustomLabelPolicyResponse,
|
||||||
|
UpdateCustomLockoutPolicyRequest,
|
||||||
|
UpdateCustomLockoutPolicyResponse,
|
||||||
UpdateCustomLoginPolicyRequest,
|
UpdateCustomLoginPolicyRequest,
|
||||||
UpdateCustomLoginPolicyResponse,
|
UpdateCustomLoginPolicyResponse,
|
||||||
UpdateCustomPasswordAgePolicyRequest,
|
UpdateCustomPasswordAgePolicyRequest,
|
||||||
UpdateCustomPasswordAgePolicyResponse,
|
UpdateCustomPasswordAgePolicyResponse,
|
||||||
UpdateCustomPasswordComplexityPolicyRequest,
|
UpdateCustomPasswordComplexityPolicyRequest,
|
||||||
UpdateCustomPasswordComplexityPolicyResponse,
|
UpdateCustomPasswordComplexityPolicyResponse,
|
||||||
UpdateCustomPasswordLockoutPolicyRequest,
|
|
||||||
UpdateCustomPasswordLockoutPolicyResponse,
|
|
||||||
UpdateCustomPrivacyPolicyRequest,
|
UpdateCustomPrivacyPolicyRequest,
|
||||||
UpdateCustomPrivacyPolicyResponse,
|
UpdateCustomPrivacyPolicyResponse,
|
||||||
UpdateHumanEmailRequest,
|
UpdateHumanEmailRequest,
|
||||||
@ -556,6 +558,11 @@ export class ManagementService {
|
|||||||
return this.grpcService.mgmt.listOrgIDPs(req, null).then(resp => resp.toObject());
|
return this.grpcService.mgmt.listOrgIDPs(req, null).then(resp => resp.toObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public unlockUser(req: UnlockUserRequest):
|
||||||
|
Promise<UnlockUserResponse.AsObject> {
|
||||||
|
return this.grpcService.mgmt.unlockUser(req, null).then(resp => resp.toObject());
|
||||||
|
}
|
||||||
|
|
||||||
public getPrivacyPolicy():
|
public getPrivacyPolicy():
|
||||||
Promise<GetPrivacyPolicyResponse.AsObject> {
|
Promise<GetPrivacyPolicyResponse.AsObject> {
|
||||||
const req = new GetPrivacyPolicyRequest();
|
const req = new GetPrivacyPolicyRequest();
|
||||||
@ -1105,36 +1112,31 @@ export class ManagementService {
|
|||||||
return this.grpcService.mgmt.updateCustomPasswordComplexityPolicy(req, null).then(resp => resp.toObject());
|
return this.grpcService.mgmt.updateCustomPasswordComplexityPolicy(req, null).then(resp => resp.toObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
public getPasswordLockoutPolicy(): Promise<GetPasswordLockoutPolicyResponse.AsObject> {
|
public getLockoutPolicy(): Promise<GetLockoutPolicyResponse.AsObject> {
|
||||||
const req = new GetPasswordLockoutPolicyRequest();
|
const req = new GetLockoutPolicyRequest();
|
||||||
|
return this.grpcService.mgmt.getLockoutPolicy(req, null).then(resp => resp.toObject());
|
||||||
return this.grpcService.mgmt.getPasswordLockoutPolicy(req, null).then(resp => resp.toObject());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public addCustomPasswordLockoutPolicy(
|
public addCustomLockoutPolicy(
|
||||||
maxAttempts: number,
|
maxAttempts: number,
|
||||||
showLockoutFailures: boolean,
|
): Promise<AddCustomLockoutPolicyResponse.AsObject> {
|
||||||
): Promise<AddCustomPasswordLockoutPolicyResponse.AsObject> {
|
const req = new AddCustomLockoutPolicyRequest();
|
||||||
const req = new AddCustomPasswordLockoutPolicyRequest();
|
req.setMaxPasswordAttempts(maxAttempts);
|
||||||
req.setMaxAttempts(maxAttempts);
|
|
||||||
req.setShowLockoutFailure(showLockoutFailures);
|
|
||||||
|
|
||||||
return this.grpcService.mgmt.addCustomPasswordLockoutPolicy(req, null).then(resp => resp.toObject());
|
return this.grpcService.mgmt.addCustomLockoutPolicy(req, null).then(resp => resp.toObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
public resetPasswordLockoutPolicyToDefault(): Promise<ResetPasswordLockoutPolicyToDefaultResponse.AsObject> {
|
public resetLockoutPolicyToDefault(): Promise<ResetLockoutPolicyToDefaultResponse.AsObject> {
|
||||||
const req = new ResetPasswordLockoutPolicyToDefaultRequest();
|
const req = new ResetLockoutPolicyToDefaultRequest();
|
||||||
return this.grpcService.mgmt.resetPasswordLockoutPolicyToDefault(req, null).then(resp => resp.toObject());
|
return this.grpcService.mgmt.resetLockoutPolicyToDefault(req, null).then(resp => resp.toObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateCustomPasswordLockoutPolicy(
|
public updateCustomLockoutPolicy(
|
||||||
maxAttempts: number,
|
maxAttempts: number,
|
||||||
showLockoutFailures: boolean,
|
): Promise<UpdateCustomLockoutPolicyResponse.AsObject> {
|
||||||
): Promise<UpdateCustomPasswordLockoutPolicyResponse.AsObject> {
|
const req = new UpdateCustomLockoutPolicyRequest();
|
||||||
const req = new UpdateCustomPasswordLockoutPolicyRequest();
|
req.setMaxPasswordAttempts(maxAttempts);
|
||||||
req.setMaxAttempts(maxAttempts);
|
return this.grpcService.mgmt.updateCustomLockoutPolicy(req, null).then(resp => resp.toObject());
|
||||||
req.setShowLockoutFailure(showLockoutFailures);
|
|
||||||
return this.grpcService.mgmt.updateCustomPasswordLockoutPolicy(req, null).then(resp => resp.toObject());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public getLocalizedComplexityPolicyPatternErrorString(policy: PasswordComplexityPolicy.AsObject): string {
|
public getLocalizedComplexityPolicyPatternErrorString(policy: PasswordComplexityPolicy.AsObject): string {
|
||||||
|
@ -174,7 +174,9 @@
|
|||||||
"REACTIVATE": "Reaktivieren",
|
"REACTIVATE": "Reaktivieren",
|
||||||
"DEACTIVATE": "Deaktivieren",
|
"DEACTIVATE": "Deaktivieren",
|
||||||
"FILTER": "Filter",
|
"FILTER": "Filter",
|
||||||
"DELETE": "Benutzer löschen"
|
"DELETE": "Benutzer löschen",
|
||||||
|
"UNLOCK": "Benutzer entsperren",
|
||||||
|
"LOCKEDDESCRIPTION":"Dieser Benutzer wurde aufgrund der Überschreitung der maximalen Anmeldeversuche gesperrt und muss zur erneuten Verwendung entsperrt werden."
|
||||||
},
|
},
|
||||||
"DIALOG": {
|
"DIALOG": {
|
||||||
"DELETE_TITLE": "User löschen",
|
"DELETE_TITLE": "User löschen",
|
||||||
@ -421,7 +423,8 @@
|
|||||||
"STATE": {
|
"STATE": {
|
||||||
"0": "Unbekannt",
|
"0": "Unbekannt",
|
||||||
"1": "Aktiv",
|
"1": "Aktiv",
|
||||||
"2": "Abgelaufen"
|
"2": "Abgelaufen",
|
||||||
|
"4": "Gesperrt"
|
||||||
},
|
},
|
||||||
"SEARCH": {
|
"SEARCH": {
|
||||||
"FOUND": "Gefunden"
|
"FOUND": "Gefunden"
|
||||||
@ -460,7 +463,8 @@
|
|||||||
"SELECTEDKEYSDELETED": "Selektierte Schlüssel gelöscht.",
|
"SELECTEDKEYSDELETED": "Selektierte Schlüssel gelöscht.",
|
||||||
"KEYADDED": "Schlüssel hinzugefügt!",
|
"KEYADDED": "Schlüssel hinzugefügt!",
|
||||||
"MACHINEADDED": "Service User erstellt!",
|
"MACHINEADDED": "Service User erstellt!",
|
||||||
"DELETED": "Benutzer erfolgreich gelöscht!"
|
"DELETED": "Benutzer erfolgreich gelöscht!",
|
||||||
|
"UNLOCKED":"Benutzer erfolgreich freigeschaltet!"
|
||||||
},
|
},
|
||||||
"MEMBERSHIPS": {
|
"MEMBERSHIPS": {
|
||||||
"TITLE": "ZITADEL Manager-Rollen",
|
"TITLE": "ZITADEL Manager-Rollen",
|
||||||
@ -688,7 +692,7 @@
|
|||||||
},
|
},
|
||||||
"PWD_LOCKOUT": {
|
"PWD_LOCKOUT": {
|
||||||
"TITLE": "Passwortsperre",
|
"TITLE": "Passwortsperre",
|
||||||
"DESCRIPTION": "Standardmässig sind die Passwortwiederholungen bei Falscheingabe nicht begrenzt. Du musst diese Richtlinie installieren, wenn Du Wiederholungsversuche anzeigen, oder eine maximale Anzahl von wiederholten Passworteingaben festlegen möchtest."
|
"DESCRIPTION": "Lege eine maximale Anzahl an Passwordwiederholungen fest, nachdem Accounts gesperrt werden sollen."
|
||||||
},
|
},
|
||||||
"IAM_POLICY": {
|
"IAM_POLICY": {
|
||||||
"TITLE": "Zugangseinstellungen IAM",
|
"TITLE": "Zugangseinstellungen IAM",
|
||||||
|
@ -174,7 +174,9 @@
|
|||||||
"REACTIVATE": "Reactivate",
|
"REACTIVATE": "Reactivate",
|
||||||
"DEACTIVATE": "Deactivate",
|
"DEACTIVATE": "Deactivate",
|
||||||
"FILTER": "Filter",
|
"FILTER": "Filter",
|
||||||
"DELETE": "Delete User"
|
"DELETE": "Delete User",
|
||||||
|
"UNLOCK": "Unlock User",
|
||||||
|
"LOCKEDDESCRIPTION":"This user has been locked out due to exceeding the maximum login attempts and must be unlocked to be used again."
|
||||||
},
|
},
|
||||||
"DIALOG": {
|
"DIALOG": {
|
||||||
"DELETE_TITLE": "Delete User",
|
"DELETE_TITLE": "Delete User",
|
||||||
@ -421,7 +423,8 @@
|
|||||||
"STATE": {
|
"STATE": {
|
||||||
"0": "Unknown",
|
"0": "Unknown",
|
||||||
"1": "Active",
|
"1": "Active",
|
||||||
"2": "Expired"
|
"2": "Expired",
|
||||||
|
"4": "Locked"
|
||||||
},
|
},
|
||||||
"SEARCH": {
|
"SEARCH": {
|
||||||
"FOUND": "Found"
|
"FOUND": "Found"
|
||||||
@ -460,7 +463,8 @@
|
|||||||
"SELECTEDKEYSDELETED": "Selected keys deleted.",
|
"SELECTEDKEYSDELETED": "Selected keys deleted.",
|
||||||
"KEYADDED": "Key added!",
|
"KEYADDED": "Key added!",
|
||||||
"MACHINEADDED": "Service User created!",
|
"MACHINEADDED": "Service User created!",
|
||||||
"DELETED": "User deleted successfully!"
|
"DELETED": "User deleted successfully!",
|
||||||
|
"UNLOCKED":"User unlocked successfully!"
|
||||||
},
|
},
|
||||||
"MEMBERSHIPS": {
|
"MEMBERSHIPS": {
|
||||||
"TITLE": "ZITADEL Manager Roles",
|
"TITLE": "ZITADEL Manager Roles",
|
||||||
@ -688,7 +692,7 @@
|
|||||||
},
|
},
|
||||||
"PWD_LOCKOUT": {
|
"PWD_LOCKOUT": {
|
||||||
"TITLE": "Password Lockout",
|
"TITLE": "Password Lockout",
|
||||||
"DESCRIPTION": "Password retries are infinite in default mode. You have to apply this policy if you want to show the number of retries, or set a maximum number of retries after which the account will be blocked."
|
"DESCRIPTION": "Set a maximum number of passwordretries, after which accounts will be blocked."
|
||||||
},
|
},
|
||||||
"IAM_POLICY": {
|
"IAM_POLICY": {
|
||||||
"TITLE": "IAM Access Preferences",
|
"TITLE": "IAM Access Preferences",
|
||||||
|
@ -615,24 +615,24 @@ it impacts all organisations without a customised policy
|
|||||||
PUT: /policies/password/age
|
PUT: /policies/password/age
|
||||||
|
|
||||||
|
|
||||||
### GetPasswordLockoutPolicy
|
### GetLockoutPolicy
|
||||||
|
|
||||||
> **rpc** GetPasswordLockoutPolicy([GetPasswordLockoutPolicyRequest](#getpasswordlockoutpolicyrequest))
|
> **rpc** GetLockoutPolicy([GetLockoutPolicyRequest](#getlockoutpolicyrequest))
|
||||||
[GetPasswordLockoutPolicyResponse](#getpasswordlockoutpolicyresponse)
|
[GetLockoutPolicyResponse](#getlockoutpolicyresponse)
|
||||||
|
|
||||||
Returns the password lockout policy defined by the administrators of ZITADEL
|
Returns the lockout policy defined by the administrators of ZITADEL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GET: /policies/password/lockout
|
GET: /policies/lockout
|
||||||
|
|
||||||
|
|
||||||
### UpdatePasswordLockoutPolicy
|
### UpdateLockoutPolicy
|
||||||
|
|
||||||
> **rpc** UpdatePasswordLockoutPolicy([UpdatePasswordLockoutPolicyRequest](#updatepasswordlockoutpolicyrequest))
|
> **rpc** UpdateLockoutPolicy([UpdateLockoutPolicyRequest](#updatelockoutpolicyrequest))
|
||||||
[UpdatePasswordLockoutPolicyResponse](#updatepasswordlockoutpolicyresponse)
|
[UpdateLockoutPolicyResponse](#updatelockoutpolicyresponse)
|
||||||
|
|
||||||
Updates the default password lockout policy of ZITADEL
|
Updates the default lockout policy of ZITADEL
|
||||||
it impacts all organisations without a customised policy
|
it impacts all organisations without a customised policy
|
||||||
|
|
||||||
|
|
||||||
@ -1681,6 +1681,23 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### GetLockoutPolicyRequest
|
||||||
|
This is an empty request
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### GetLockoutPolicyResponse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| policy | zitadel.policy.v1.LockoutPolicy | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### GetLoginPolicyRequest
|
### GetLoginPolicyRequest
|
||||||
This is an empty request
|
This is an empty request
|
||||||
|
|
||||||
@ -1793,23 +1810,6 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### GetPasswordLockoutPolicyRequest
|
|
||||||
This is an empty request
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### GetPasswordLockoutPolicyResponse
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
| Field | Type | Description | Validation |
|
|
||||||
| ----- | ---- | ----------- | ----------- |
|
|
||||||
| policy | zitadel.policy.v1.PasswordLockoutPolicy | - | |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### GetPreviewLabelPolicyRequest
|
### GetPreviewLabelPolicyRequest
|
||||||
This is an empty request
|
This is an empty request
|
||||||
|
|
||||||
@ -2924,6 +2924,28 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### UpdateLockoutPolicyRequest
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| max_password_attempts | uint32 | failed attempts until a user gets locked | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### UpdateLockoutPolicyResponse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| details | zitadel.v1.ObjectDetails | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### UpdateLoginPolicyRequest
|
### UpdateLoginPolicyRequest
|
||||||
|
|
||||||
|
|
||||||
@ -3022,29 +3044,6 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### UpdatePasswordLockoutPolicyRequest
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
| Field | Type | Description | Validation |
|
|
||||||
| ----- | ---- | ----------- | ----------- |
|
|
||||||
| max_attempts | uint32 | failed attempts until a user gets locked | |
|
|
||||||
| show_lockout_failure | bool | If an error should be displayed during a lockout or not | |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### UpdatePasswordLockoutPolicyResponse
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
| Field | Type | Description | Validation |
|
|
||||||
| ----- | ---- | ----------- | ----------- |
|
|
||||||
| details | zitadel.v1.ObjectDetails | - | |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### UpdatePrivacyPolicyRequest
|
### UpdatePrivacyPolicyRequest
|
||||||
|
|
||||||
|
|
||||||
|
@ -1926,64 +1926,64 @@ The password age policy is not used at the moment
|
|||||||
DELETE: /policies/password/age
|
DELETE: /policies/password/age
|
||||||
|
|
||||||
|
|
||||||
### GetPasswordLockoutPolicy
|
### GetLockoutPolicy
|
||||||
|
|
||||||
> **rpc** GetPasswordLockoutPolicy([GetPasswordLockoutPolicyRequest](#getpasswordlockoutpolicyrequest))
|
> **rpc** GetLockoutPolicy([GetLockoutPolicyRequest](#getlockoutpolicyrequest))
|
||||||
[GetPasswordLockoutPolicyResponse](#getpasswordlockoutpolicyresponse)
|
[GetLockoutPolicyResponse](#getlockoutpolicyresponse)
|
||||||
|
|
||||||
The password lockout policy is not used at the moment
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GET: /policies/password/lockout
|
|
||||||
|
|
||||||
|
|
||||||
### GetDefaultPasswordLockoutPolicy
|
GET: /policies/lockout
|
||||||
|
|
||||||
> **rpc** GetDefaultPasswordLockoutPolicy([GetDefaultPasswordLockoutPolicyRequest](#getdefaultpasswordlockoutpolicyrequest))
|
|
||||||
[GetDefaultPasswordLockoutPolicyResponse](#getdefaultpasswordlockoutpolicyresponse)
|
|
||||||
|
|
||||||
The password lockout policy is not used at the moment
|
### GetDefaultLockoutPolicy
|
||||||
|
|
||||||
|
> **rpc** GetDefaultLockoutPolicy([GetDefaultLockoutPolicyRequest](#getdefaultlockoutpolicyrequest))
|
||||||
|
[GetDefaultLockoutPolicyResponse](#getdefaultlockoutpolicyresponse)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GET: /policies/default/password/lockout
|
|
||||||
|
|
||||||
|
|
||||||
### AddCustomPasswordLockoutPolicy
|
GET: /policies/default/lockout
|
||||||
|
|
||||||
> **rpc** AddCustomPasswordLockoutPolicy([AddCustomPasswordLockoutPolicyRequest](#addcustompasswordlockoutpolicyrequest))
|
|
||||||
[AddCustomPasswordLockoutPolicyResponse](#addcustompasswordlockoutpolicyresponse)
|
|
||||||
|
|
||||||
The password lockout policy is not used at the moment
|
### AddCustomLockoutPolicy
|
||||||
|
|
||||||
|
> **rpc** AddCustomLockoutPolicy([AddCustomLockoutPolicyRequest](#addcustomlockoutpolicyrequest))
|
||||||
|
[AddCustomLockoutPolicyResponse](#addcustomlockoutpolicyresponse)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
POST: /policies/password/lockout
|
|
||||||
|
|
||||||
|
|
||||||
### UpdateCustomPasswordLockoutPolicy
|
POST: /policies/lockout
|
||||||
|
|
||||||
> **rpc** UpdateCustomPasswordLockoutPolicy([UpdateCustomPasswordLockoutPolicyRequest](#updatecustompasswordlockoutpolicyrequest))
|
|
||||||
[UpdateCustomPasswordLockoutPolicyResponse](#updatecustompasswordlockoutpolicyresponse)
|
|
||||||
|
|
||||||
The password lockout policy is not used at the moment
|
### UpdateCustomLockoutPolicy
|
||||||
|
|
||||||
|
> **rpc** UpdateCustomLockoutPolicy([UpdateCustomLockoutPolicyRequest](#updatecustomlockoutpolicyrequest))
|
||||||
|
[UpdateCustomLockoutPolicyResponse](#updatecustomlockoutpolicyresponse)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PUT: /policies/password/lockout
|
|
||||||
|
|
||||||
|
|
||||||
### ResetPasswordLockoutPolicyToDefault
|
PUT: /policies/lockout
|
||||||
|
|
||||||
> **rpc** ResetPasswordLockoutPolicyToDefault([ResetPasswordLockoutPolicyToDefaultRequest](#resetpasswordlockoutpolicytodefaultrequest))
|
|
||||||
[ResetPasswordLockoutPolicyToDefaultResponse](#resetpasswordlockoutpolicytodefaultresponse)
|
|
||||||
|
|
||||||
The password lockout policy is not used at the moment
|
### ResetLockoutPolicyToDefault
|
||||||
|
|
||||||
|
> **rpc** ResetLockoutPolicyToDefault([ResetLockoutPolicyToDefaultRequest](#resetlockoutpolicytodefaultrequest))
|
||||||
|
[ResetLockoutPolicyToDefaultResponse](#resetlockoutpolicytodefaultresponse)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DELETE: /policies/password/lockout
|
|
||||||
|
|
||||||
|
DELETE: /policies/lockout
|
||||||
|
|
||||||
|
|
||||||
### GetPrivacyPolicy
|
### GetPrivacyPolicy
|
||||||
@ -2769,6 +2769,28 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### AddCustomLockoutPolicyRequest
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| max_password_attempts | uint32 | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### AddCustomLockoutPolicyResponse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| details | zitadel.v1.ObjectDetails | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### AddCustomLoginPolicyRequest
|
### AddCustomLoginPolicyRequest
|
||||||
|
|
||||||
|
|
||||||
@ -2845,29 +2867,6 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### AddCustomPasswordLockoutPolicyRequest
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
| Field | Type | Description | Validation |
|
|
||||||
| ----- | ---- | ----------- | ----------- |
|
|
||||||
| max_attempts | uint32 | - | |
|
|
||||||
| show_lockout_failure | bool | - | |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### AddCustomPasswordLockoutPolicyResponse
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
| Field | Type | Description | Validation |
|
|
||||||
| ----- | ---- | ----------- | ----------- |
|
|
||||||
| details | zitadel.v1.ObjectDetails | - | |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### AddCustomPrivacyPolicyRequest
|
### AddCustomPrivacyPolicyRequest
|
||||||
|
|
||||||
|
|
||||||
@ -3915,6 +3914,23 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### GetDefaultLockoutPolicyRequest
|
||||||
|
This is an empty request
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### GetDefaultLockoutPolicyResponse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| policy | zitadel.policy.v1.LockoutPolicy | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### GetDefaultLoginPolicyRequest
|
### GetDefaultLoginPolicyRequest
|
||||||
|
|
||||||
|
|
||||||
@ -3988,23 +4004,6 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### GetDefaultPasswordLockoutPolicyRequest
|
|
||||||
This is an empty request
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### GetDefaultPasswordLockoutPolicyResponse
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
| Field | Type | Description | Validation |
|
|
||||||
| ----- | ---- | ----------- | ----------- |
|
|
||||||
| policy | zitadel.policy.v1.PasswordLockoutPolicy | - | |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### GetDefaultPasswordResetMessageTextRequest
|
### GetDefaultPasswordResetMessageTextRequest
|
||||||
|
|
||||||
|
|
||||||
@ -4255,6 +4254,24 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### GetLockoutPolicyRequest
|
||||||
|
This is an empty request
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### GetLockoutPolicyResponse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| policy | zitadel.policy.v1.LockoutPolicy | - | |
|
||||||
|
| is_default | bool | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### GetLoginPolicyRequest
|
### GetLoginPolicyRequest
|
||||||
|
|
||||||
|
|
||||||
@ -4428,24 +4445,6 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### GetPasswordLockoutPolicyRequest
|
|
||||||
This is an empty request
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### GetPasswordLockoutPolicyResponse
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
| Field | Type | Description | Validation |
|
|
||||||
| ----- | ---- | ----------- | ----------- |
|
|
||||||
| policy | zitadel.policy.v1.PasswordLockoutPolicy | - | |
|
|
||||||
| is_default | bool | - | |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### GetPreviewLabelPolicyRequest
|
### GetPreviewLabelPolicyRequest
|
||||||
This is an empty request
|
This is an empty request
|
||||||
|
|
||||||
@ -6529,6 +6528,23 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### ResetLockoutPolicyToDefaultRequest
|
||||||
|
This is an empty request
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### ResetLockoutPolicyToDefaultResponse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| details | zitadel.v1.ObjectDetails | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### ResetLoginPolicyToDefaultRequest
|
### ResetLoginPolicyToDefaultRequest
|
||||||
|
|
||||||
|
|
||||||
@ -6580,23 +6596,6 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### ResetPasswordLockoutPolicyToDefaultRequest
|
|
||||||
This is an empty request
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### ResetPasswordLockoutPolicyToDefaultResponse
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
| Field | Type | Description | Validation |
|
|
||||||
| ----- | ---- | ----------- | ----------- |
|
|
||||||
| details | zitadel.v1.ObjectDetails | - | |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### ResetPrivacyPolicyToDefaultRequest
|
### ResetPrivacyPolicyToDefaultRequest
|
||||||
This is an empty request
|
This is an empty request
|
||||||
|
|
||||||
@ -7083,6 +7082,28 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### UpdateCustomLockoutPolicyRequest
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| max_password_attempts | uint32 | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### UpdateCustomLockoutPolicyResponse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| details | zitadel.v1.ObjectDetails | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### UpdateCustomLoginPolicyRequest
|
### UpdateCustomLoginPolicyRequest
|
||||||
|
|
||||||
|
|
||||||
@ -7159,29 +7180,6 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### UpdateCustomPasswordLockoutPolicyRequest
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
| Field | Type | Description | Validation |
|
|
||||||
| ----- | ---- | ----------- | ----------- |
|
|
||||||
| max_attempts | uint32 | - | |
|
|
||||||
| show_lockout_failure | bool | - | |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### UpdateCustomPasswordLockoutPolicyResponse
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
| Field | Type | Description | Validation |
|
|
||||||
| ----- | ---- | ----------- | ----------- |
|
|
||||||
| details | zitadel.v1.ObjectDetails | - | |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### UpdateCustomPrivacyPolicyRequest
|
### UpdateCustomPrivacyPolicyRequest
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,6 +36,19 @@ title: zitadel/policy.proto
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### LockoutPolicy
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| details | zitadel.v1.ObjectDetails | - | |
|
||||||
|
| max_password_attempts | uint64 | - | |
|
||||||
|
| is_default | bool | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### LoginPolicy
|
### LoginPolicy
|
||||||
|
|
||||||
|
|
||||||
@ -98,20 +111,6 @@ title: zitadel/policy.proto
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### PasswordLockoutPolicy
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
| Field | Type | Description | Validation |
|
|
||||||
| ----- | ---- | ----------- | ----------- |
|
|
||||||
| details | zitadel.v1.ObjectDetails | - | |
|
|
||||||
| max_attempts | uint64 | - | |
|
|
||||||
| show_lockout_failure | bool | - | |
|
|
||||||
| is_default | bool | - | |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### PrivacyPolicy
|
### PrivacyPolicy
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,6 +37,16 @@ The Login Policy defines how the login process should look like and which authen
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
## Lockout Policy
|
||||||
|
|
||||||
|
Define when a user should be blocked.
|
||||||
|
|
||||||
|
The following properties are possible:
|
||||||
|
- Maximum Password Attempts: When the user has reached the maximum password attempts the user will be locked
|
||||||
|
|
||||||
|
If a user is locked, an administrator has to unlock it in the ZITADEL console
|
||||||
|
|
||||||
|
|
||||||
### Multifactors / Second Factors
|
### Multifactors / Second Factors
|
||||||
|
|
||||||
In the multifactors section you can configure what kind of multifactors should be allowed. For passwordless to work, it's required to enable U2F (Universial Second Factor) with PIN. There is no other option at the moment.
|
In the multifactors section you can configure what kind of multifactors should be allowed. For passwordless to work, it's required to enable U2F (Universial Second Factor) with PIN. There is no other option at the moment.
|
||||||
|
@ -282,30 +282,30 @@ func (repo *IAMRepository) GetDefaultPasswordAgePolicy(ctx context.Context) (*ia
|
|||||||
return iam_es_model.PasswordAgeViewToModel(policy), nil
|
return iam_es_model.PasswordAgeViewToModel(policy), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IAMRepository) GetDefaultPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error) {
|
func (repo *IAMRepository) GetDefaultLockoutPolicy(ctx context.Context) (*iam_model.LockoutPolicyView, error) {
|
||||||
policy, viewErr := repo.View.PasswordLockoutPolicyByAggregateID(repo.SystemDefaults.IamID)
|
policy, viewErr := repo.View.LockoutPolicyByAggregateID(repo.SystemDefaults.IamID)
|
||||||
if viewErr != nil && !caos_errs.IsNotFound(viewErr) {
|
if viewErr != nil && !caos_errs.IsNotFound(viewErr) {
|
||||||
return nil, viewErr
|
return nil, viewErr
|
||||||
}
|
}
|
||||||
if caos_errs.IsNotFound(viewErr) {
|
if caos_errs.IsNotFound(viewErr) {
|
||||||
policy = new(iam_es_model.PasswordLockoutPolicyView)
|
policy = new(iam_es_model.LockoutPolicyView)
|
||||||
}
|
}
|
||||||
|
|
||||||
events, esErr := repo.getIAMEvents(ctx, policy.Sequence)
|
events, esErr := repo.getIAMEvents(ctx, policy.Sequence)
|
||||||
if caos_errs.IsNotFound(viewErr) && len(events) == 0 {
|
if caos_errs.IsNotFound(viewErr) && len(events) == 0 {
|
||||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-2M9oP", "Errors.IAM.PasswordLockoutPolicy.NotFound")
|
return nil, caos_errs.ThrowNotFound(nil, "EVENT-2M9oP", "Errors.IAM.LockoutPolicy.NotFound")
|
||||||
}
|
}
|
||||||
if esErr != nil {
|
if esErr != nil {
|
||||||
logging.Log("EVENT-3M0xs").WithError(esErr).Debug("error retrieving new events")
|
logging.Log("EVENT-3M0xs").WithError(esErr).Debug("error retrieving new events")
|
||||||
return iam_es_model.PasswordLockoutViewToModel(policy), nil
|
return iam_es_model.LockoutViewToModel(policy), nil
|
||||||
}
|
}
|
||||||
policyCopy := *policy
|
policyCopy := *policy
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
if err := policyCopy.AppendEvent(event); err != nil {
|
if err := policyCopy.AppendEvent(event); err != nil {
|
||||||
return iam_es_model.PasswordLockoutViewToModel(policy), nil
|
return iam_es_model.LockoutViewToModel(policy), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return iam_es_model.PasswordLockoutViewToModel(policy), nil
|
return iam_es_model.LockoutViewToModel(policy), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IAMRepository) GetOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicyView, error) {
|
func (repo *IAMRepository) GetOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicyView, error) {
|
||||||
|
@ -3,6 +3,7 @@ package handler
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/command"
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||||
"github.com/caos/zitadel/internal/static"
|
"github.com/caos/zitadel/internal/static"
|
||||||
|
|
||||||
@ -31,7 +32,7 @@ func (h *handler) Eventstore() v1.Eventstore {
|
|||||||
return h.es
|
return h.es
|
||||||
}
|
}
|
||||||
|
|
||||||
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es v1.Eventstore, defaults systemdefaults.SystemDefaults, static static.Storage, localDevMode bool) []query.Handler {
|
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es v1.Eventstore, defaults systemdefaults.SystemDefaults, command *command.Commands, static static.Storage, localDevMode bool) []query.Handler {
|
||||||
handlers := []query.Handler{
|
handlers := []query.Handler{
|
||||||
newOrg(
|
newOrg(
|
||||||
handler{view, bulkLimit, configs.cycleDuration("Org"), errorCount, es}),
|
handler{view, bulkLimit, configs.cycleDuration("Org"), errorCount, es}),
|
||||||
@ -53,8 +54,8 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es
|
|||||||
handler{view, bulkLimit, configs.cycleDuration("PasswordComplexityPolicy"), errorCount, es}),
|
handler{view, bulkLimit, configs.cycleDuration("PasswordComplexityPolicy"), errorCount, es}),
|
||||||
newPasswordAgePolicy(
|
newPasswordAgePolicy(
|
||||||
handler{view, bulkLimit, configs.cycleDuration("PasswordAgePolicy"), errorCount, es}),
|
handler{view, bulkLimit, configs.cycleDuration("PasswordAgePolicy"), errorCount, es}),
|
||||||
newPasswordLockoutPolicy(
|
newLockoutPolicy(
|
||||||
handler{view, bulkLimit, configs.cycleDuration("PasswordLockoutPolicy"), errorCount, es}),
|
handler{view, bulkLimit, configs.cycleDuration("LockoutPolicy"), errorCount, es}),
|
||||||
newOrgIAMPolicy(
|
newOrgIAMPolicy(
|
||||||
handler{view, bulkLimit, configs.cycleDuration("OrgIAMPolicy"), errorCount, es}),
|
handler{view, bulkLimit, configs.cycleDuration("OrgIAMPolicy"), errorCount, es}),
|
||||||
newExternalIDP(
|
newExternalIDP(
|
||||||
|
@ -13,16 +13,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
passwordLockoutPolicyTable = "adminapi.password_lockout_policies"
|
lockoutPolicyTable = "adminapi.lockout_policies"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PasswordLockoutPolicy struct {
|
type LockoutPolicy struct {
|
||||||
handler
|
handler
|
||||||
subscription *v1.Subscription
|
subscription *v1.Subscription
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPasswordLockoutPolicy(handler handler) *PasswordLockoutPolicy {
|
func newLockoutPolicy(handler handler) *LockoutPolicy {
|
||||||
h := &PasswordLockoutPolicy{
|
h := &LockoutPolicy{
|
||||||
handler: handler,
|
handler: handler,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ func newPasswordLockoutPolicy(handler handler) *PasswordLockoutPolicy {
|
|||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) subscribe() {
|
func (p *LockoutPolicy) subscribe() {
|
||||||
p.subscription = p.es.Subscribe(p.AggregateTypes()...)
|
p.subscription = p.es.Subscribe(p.AggregateTypes()...)
|
||||||
go func() {
|
go func() {
|
||||||
for event := range p.subscription.Events {
|
for event := range p.subscription.Events {
|
||||||
@ -40,28 +40,28 @@ func (p *PasswordLockoutPolicy) subscribe() {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) ViewModel() string {
|
func (p *LockoutPolicy) ViewModel() string {
|
||||||
return passwordLockoutPolicyTable
|
return lockoutPolicyTable
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *PasswordLockoutPolicy) Subscription() *v1.Subscription {
|
func (m *LockoutPolicy) Subscription() *v1.Subscription {
|
||||||
return m.subscription
|
return m.subscription
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) AggregateTypes() []es_models.AggregateType {
|
func (p *LockoutPolicy) AggregateTypes() []es_models.AggregateType {
|
||||||
return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate}
|
return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) CurrentSequence() (uint64, error) {
|
func (p *LockoutPolicy) CurrentSequence() (uint64, error) {
|
||||||
sequence, err := p.view.GetLatestPasswordLockoutPolicySequence()
|
sequence, err := p.view.GetLatestLockoutPolicySequence()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return sequence.CurrentSequence, nil
|
return sequence.CurrentSequence, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) EventQuery() (*es_models.SearchQuery, error) {
|
func (p *LockoutPolicy) EventQuery() (*es_models.SearchQuery, error) {
|
||||||
sequence, err := p.view.GetLatestPasswordLockoutPolicySequence()
|
sequence, err := p.view.GetLatestLockoutPolicySequence()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -70,41 +70,41 @@ func (p *PasswordLockoutPolicy) EventQuery() (*es_models.SearchQuery, error) {
|
|||||||
LatestSequenceFilter(sequence.CurrentSequence), nil
|
LatestSequenceFilter(sequence.CurrentSequence), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) Reduce(event *es_models.Event) (err error) {
|
func (p *LockoutPolicy) Reduce(event *es_models.Event) (err error) {
|
||||||
switch event.AggregateType {
|
switch event.AggregateType {
|
||||||
case model.OrgAggregate, iam_es_model.IAMAggregate:
|
case model.OrgAggregate, iam_es_model.IAMAggregate:
|
||||||
err = p.processPasswordLockoutPolicy(event)
|
err = p.processLockoutPolicy(event)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) processPasswordLockoutPolicy(event *es_models.Event) (err error) {
|
func (p *LockoutPolicy) processLockoutPolicy(event *es_models.Event) (err error) {
|
||||||
policy := new(iam_model.PasswordLockoutPolicyView)
|
policy := new(iam_model.LockoutPolicyView)
|
||||||
switch event.Type {
|
switch event.Type {
|
||||||
case iam_es_model.PasswordLockoutPolicyAdded, model.PasswordLockoutPolicyAdded:
|
case iam_es_model.LockoutPolicyAdded, model.LockoutPolicyAdded:
|
||||||
err = policy.AppendEvent(event)
|
err = policy.AppendEvent(event)
|
||||||
case iam_es_model.PasswordLockoutPolicyChanged, model.PasswordLockoutPolicyChanged:
|
case iam_es_model.LockoutPolicyChanged, model.LockoutPolicyChanged:
|
||||||
policy, err = p.view.PasswordLockoutPolicyByAggregateID(event.AggregateID)
|
policy, err = p.view.LockoutPolicyByAggregateID(event.AggregateID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = policy.AppendEvent(event)
|
err = policy.AppendEvent(event)
|
||||||
case model.PasswordLockoutPolicyRemoved:
|
case model.LockoutPolicyRemoved:
|
||||||
return p.view.DeletePasswordLockoutPolicy(event.AggregateID, event)
|
return p.view.DeleteLockoutPolicy(event.AggregateID, event)
|
||||||
default:
|
default:
|
||||||
return p.view.ProcessedPasswordLockoutPolicySequence(event)
|
return p.view.ProcessedLockoutPolicySequence(event)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return p.view.PutPasswordLockoutPolicy(policy, event)
|
return p.view.PutLockoutPolicy(policy, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) OnError(event *es_models.Event, err error) error {
|
func (p *LockoutPolicy) OnError(event *es_models.Event, err error) error {
|
||||||
logging.LogWithFields("SPOOL-nD8sie", "id", event.AggregateID).WithError(err).Warn("something went wrong in passwordLockout policy handler")
|
logging.LogWithFields("SPOOL-nD8sie", "id", event.AggregateID).WithError(err).Warn("something went wrong in Lockout policy handler")
|
||||||
return spooler.HandleError(event, err, p.view.GetLatestPasswordLockoutPolicyFailedEvent, p.view.ProcessedPasswordLockoutPolicyFailedEvent, p.view.ProcessedPasswordLockoutPolicySequence, p.errorCountUntilSkip)
|
return spooler.HandleError(event, err, p.view.GetLatestLockoutPolicyFailedEvent, p.view.ProcessedLockoutPolicyFailedEvent, p.view.ProcessedLockoutPolicySequence, p.errorCountUntilSkip)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) OnSuccess() error {
|
func (p *LockoutPolicy) OnSuccess() error {
|
||||||
return spooler.HandleSuccess(p.view.UpdatePasswordLockoutPolicySpoolerRunTimestamp)
|
return spooler.HandleSuccess(p.view.UpdateLockoutPolicySpoolerRunTimestamp)
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/eventstore"
|
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/eventstore"
|
||||||
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/spooler"
|
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/spooler"
|
||||||
admin_view "github.com/caos/zitadel/internal/admin/repository/eventsourcing/view"
|
admin_view "github.com/caos/zitadel/internal/admin/repository/eventsourcing/view"
|
||||||
|
"github.com/caos/zitadel/internal/command"
|
||||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||||
"github.com/caos/zitadel/internal/config/types"
|
"github.com/caos/zitadel/internal/config/types"
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||||
@ -34,7 +35,7 @@ type EsRepository struct {
|
|||||||
eventstore.UserRepo
|
eventstore.UserRepo
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, static static.Storage, roles []string, localDevMode bool) (*EsRepository, error) {
|
func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, command *command.Commands, static static.Storage, roles []string, localDevMode bool) (*EsRepository, error) {
|
||||||
es, err := v1.Start(conf.Eventstore)
|
es, err := v1.Start(conf.Eventstore)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -48,7 +49,7 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, s
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, systemDefaults, static, localDevMode)
|
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, systemDefaults, command, static, localDevMode)
|
||||||
assetsAPI := conf.APIDomain + "/assets/v1/"
|
assetsAPI := conf.APIDomain + "/assets/v1/"
|
||||||
|
|
||||||
statikLoginFS, err := fs.NewWithNamespace("login")
|
statikLoginFS, err := fs.NewWithNamespace("login")
|
||||||
|
@ -2,6 +2,7 @@ package spooler
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"github.com/caos/zitadel/internal/command"
|
||||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||||
"github.com/caos/zitadel/internal/static"
|
"github.com/caos/zitadel/internal/static"
|
||||||
@ -18,12 +19,12 @@ type SpoolerConfig struct {
|
|||||||
Handlers handler.Configs
|
Handlers handler.Configs
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartSpooler(c SpoolerConfig, es v1.Eventstore, view *view.View, sql *sql.DB, defaults systemdefaults.SystemDefaults, static static.Storage, localDevMode bool) *spooler.Spooler {
|
func StartSpooler(c SpoolerConfig, es v1.Eventstore, view *view.View, sql *sql.DB, defaults systemdefaults.SystemDefaults, command *command.Commands, static static.Storage, localDevMode bool) *spooler.Spooler {
|
||||||
spoolerConfig := spooler.Config{
|
spoolerConfig := spooler.Config{
|
||||||
Eventstore: es,
|
Eventstore: es,
|
||||||
Locker: &locker{dbClient: sql},
|
Locker: &locker{dbClient: sql},
|
||||||
ConcurrentWorkers: c.ConcurrentWorkers,
|
ConcurrentWorkers: c.ConcurrentWorkers,
|
||||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, defaults, static, localDevMode),
|
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, defaults, command, static, localDevMode),
|
||||||
}
|
}
|
||||||
spool := spoolerConfig.New()
|
spool := spoolerConfig.New()
|
||||||
spool.Start()
|
spool.Start()
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
package view
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/caos/zitadel/internal/errors"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||||
|
"github.com/caos/zitadel/internal/iam/repository/view"
|
||||||
|
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||||
|
global_view "github.com/caos/zitadel/internal/view/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
lockoutPolicyTable = "adminapi.lockout_policies"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (v *View) LockoutPolicyByAggregateID(aggregateID string) (*model.LockoutPolicyView, error) {
|
||||||
|
return view.GetLockoutPolicyByAggregateID(v.Db, lockoutPolicyTable, aggregateID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) PutLockoutPolicy(policy *model.LockoutPolicyView, event *models.Event) error {
|
||||||
|
err := view.PutLockoutPolicy(v.Db, lockoutPolicyTable, policy)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return v.ProcessedLockoutPolicySequence(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) DeleteLockoutPolicy(aggregateID string, event *models.Event) error {
|
||||||
|
err := view.DeleteLockoutPolicy(v.Db, lockoutPolicyTable, aggregateID)
|
||||||
|
if err != nil && !errors.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return v.ProcessedLockoutPolicySequence(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) GetLatestLockoutPolicySequence() (*global_view.CurrentSequence, error) {
|
||||||
|
return v.latestSequence(lockoutPolicyTable)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) ProcessedLockoutPolicySequence(event *models.Event) error {
|
||||||
|
return v.saveCurrentSequence(lockoutPolicyTable, event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) UpdateLockoutPolicySpoolerRunTimestamp() error {
|
||||||
|
return v.updateSpoolerRunSequence(lockoutPolicyTable)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) GetLatestLockoutPolicyFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
|
||||||
|
return v.latestFailedEvent(lockoutPolicyTable, sequence)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) ProcessedLockoutPolicyFailedEvent(failedEvent *global_view.FailedEvent) error {
|
||||||
|
return v.saveFailedEvent(failedEvent)
|
||||||
|
}
|
@ -1,53 +0,0 @@
|
|||||||
package view
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/zitadel/internal/errors"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
global_view "github.com/caos/zitadel/internal/view/repository"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
passwordLockoutPolicyTable = "adminapi.password_lockout_policies"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (v *View) PasswordLockoutPolicyByAggregateID(aggregateID string) (*model.PasswordLockoutPolicyView, error) {
|
|
||||||
return view.GetPasswordLockoutPolicyByAggregateID(v.Db, passwordLockoutPolicyTable, aggregateID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) PutPasswordLockoutPolicy(policy *model.PasswordLockoutPolicyView, event *models.Event) error {
|
|
||||||
err := view.PutPasswordLockoutPolicy(v.Db, passwordLockoutPolicyTable, policy)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedPasswordLockoutPolicySequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) DeletePasswordLockoutPolicy(aggregateID string, event *models.Event) error {
|
|
||||||
err := view.DeletePasswordLockoutPolicy(v.Db, passwordLockoutPolicyTable, aggregateID)
|
|
||||||
if err != nil && !errors.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedPasswordLockoutPolicySequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestPasswordLockoutPolicySequence() (*global_view.CurrentSequence, error) {
|
|
||||||
return v.latestSequence(passwordLockoutPolicyTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedPasswordLockoutPolicySequence(event *models.Event) error {
|
|
||||||
return v.saveCurrentSequence(passwordLockoutPolicyTable, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) UpdatePasswordLockoutPolicySpoolerRunTimestamp() error {
|
|
||||||
return v.updateSpoolerRunSequence(passwordLockoutPolicyTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestPasswordLockoutPolicyFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
|
|
||||||
return v.latestFailedEvent(passwordLockoutPolicyTable, sequence)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedPasswordLockoutPolicyFailedEvent(failedEvent *global_view.FailedEvent) error {
|
|
||||||
return v.saveFailedEvent(failedEvent)
|
|
||||||
}
|
|
@ -43,7 +43,7 @@ type IAMRepository interface {
|
|||||||
|
|
||||||
GetDefaultPasswordAgePolicy(ctx context.Context) (*iam_model.PasswordAgePolicyView, error)
|
GetDefaultPasswordAgePolicy(ctx context.Context) (*iam_model.PasswordAgePolicyView, error)
|
||||||
|
|
||||||
GetDefaultPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error)
|
GetDefaultLockoutPolicy(ctx context.Context) (*iam_model.LockoutPolicyView, error)
|
||||||
|
|
||||||
GetDefaultPrivacyPolicy(ctx context.Context) (*iam_model.PrivacyPolicyView, error)
|
GetDefaultPrivacyPolicy(ctx context.Context) (*iam_model.PrivacyPolicyView, error)
|
||||||
|
|
||||||
|
31
internal/api/grpc/admin/lockout.go
Normal file
31
internal/api/grpc/admin/lockout.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package admin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/api/grpc/object"
|
||||||
|
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
|
||||||
|
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Server) GetLockoutPolicy(ctx context.Context, req *admin_pb.GetLockoutPolicyRequest) (*admin_pb.GetLockoutPolicyResponse, error) {
|
||||||
|
policy, err := s.iam.GetDefaultLockoutPolicy(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &admin_pb.GetLockoutPolicyResponse{Policy: policy_grpc.ModelLockoutPolicyToPb(policy)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) UpdateLockoutPolicy(ctx context.Context, req *admin_pb.UpdateLockoutPolicyRequest) (*admin_pb.UpdateLockoutPolicyResponse, error) {
|
||||||
|
policy, err := s.command.ChangeDefaultLockoutPolicy(ctx, UpdateLockoutPolicyToDomain(req))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &admin_pb.UpdateLockoutPolicyResponse{
|
||||||
|
Details: object.ChangeToDetailsPb(
|
||||||
|
policy.Sequence,
|
||||||
|
policy.ChangeDate,
|
||||||
|
policy.ResourceOwner,
|
||||||
|
),
|
||||||
|
}, nil
|
||||||
|
}
|
12
internal/api/grpc/admin/lockout_converter.go
Normal file
12
internal/api/grpc/admin/lockout_converter.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package admin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/caos/zitadel/internal/domain"
|
||||||
|
"github.com/caos/zitadel/pkg/grpc/admin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func UpdateLockoutPolicyToDomain(p *admin.UpdateLockoutPolicyRequest) *domain.LockoutPolicy {
|
||||||
|
return &domain.LockoutPolicy{
|
||||||
|
MaxPasswordAttempts: uint64(p.MaxPasswordAttempts),
|
||||||
|
}
|
||||||
|
}
|
@ -1,31 +0,0 @@
|
|||||||
package admin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/api/grpc/object"
|
|
||||||
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
|
|
||||||
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s *Server) GetPasswordLockoutPolicy(ctx context.Context, req *admin_pb.GetPasswordLockoutPolicyRequest) (*admin_pb.GetPasswordLockoutPolicyResponse, error) {
|
|
||||||
policy, err := s.iam.GetDefaultPasswordLockoutPolicy(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &admin_pb.GetPasswordLockoutPolicyResponse{Policy: policy_grpc.ModelPasswordLockoutPolicyToPb(policy)}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) UpdatePasswordLockoutPolicy(ctx context.Context, req *admin_pb.UpdatePasswordLockoutPolicyRequest) (*admin_pb.UpdatePasswordLockoutPolicyResponse, error) {
|
|
||||||
policy, err := s.command.ChangeDefaultPasswordLockoutPolicy(ctx, UpdatePasswordLockoutPolicyToDomain(req))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &admin_pb.UpdatePasswordLockoutPolicyResponse{
|
|
||||||
Details: object.ChangeToDetailsPb(
|
|
||||||
policy.Sequence,
|
|
||||||
policy.ChangeDate,
|
|
||||||
policy.ResourceOwner,
|
|
||||||
),
|
|
||||||
}, nil
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package admin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/zitadel/internal/domain"
|
|
||||||
"github.com/caos/zitadel/pkg/grpc/admin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func UpdatePasswordLockoutPolicyToDomain(p *admin.UpdatePasswordLockoutPolicyRequest) *domain.PasswordLockoutPolicy {
|
|
||||||
return &domain.PasswordLockoutPolicy{
|
|
||||||
MaxAttempts: uint64(p.MaxAttempts),
|
|
||||||
ShowLockOutFailures: p.ShowLockoutFailure,
|
|
||||||
}
|
|
||||||
}
|
|
63
internal/api/grpc/management/policy_lockout.go
Normal file
63
internal/api/grpc/management/policy_lockout.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package management
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/caos/zitadel/internal/api/authz"
|
||||||
|
"github.com/caos/zitadel/internal/api/grpc/object"
|
||||||
|
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
|
||||||
|
mgmt_pb "github.com/caos/zitadel/pkg/grpc/management"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Server) GetLockoutPolicy(ctx context.Context, req *mgmt_pb.GetLockoutPolicyRequest) (*mgmt_pb.GetLockoutPolicyResponse, error) {
|
||||||
|
policy, err := s.org.GetLockoutPolicy(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &mgmt_pb.GetLockoutPolicyResponse{Policy: policy_grpc.ModelLockoutPolicyToPb(policy), IsDefault: policy.Default}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) GetDefaultLockoutPolicy(ctx context.Context, req *mgmt_pb.GetDefaultLockoutPolicyRequest) (*mgmt_pb.GetDefaultLockoutPolicyResponse, error) {
|
||||||
|
policy, err := s.org.GetDefaultLockoutPolicy(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &mgmt_pb.GetDefaultLockoutPolicyResponse{Policy: policy_grpc.ModelLockoutPolicyToPb(policy)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) AddCustomLockoutPolicy(ctx context.Context, req *mgmt_pb.AddCustomLockoutPolicyRequest) (*mgmt_pb.AddCustomLockoutPolicyResponse, error) {
|
||||||
|
policy, err := s.command.AddLockoutPolicy(ctx, authz.GetCtxData(ctx).OrgID, AddLockoutPolicyToDomain(req))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &mgmt_pb.AddCustomLockoutPolicyResponse{
|
||||||
|
Details: object.AddToDetailsPb(
|
||||||
|
policy.Sequence,
|
||||||
|
policy.ChangeDate,
|
||||||
|
policy.ResourceOwner,
|
||||||
|
),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) UpdateCustomLockoutPolicy(ctx context.Context, req *mgmt_pb.UpdateCustomLockoutPolicyRequest) (*mgmt_pb.UpdateCustomLockoutPolicyResponse, error) {
|
||||||
|
policy, err := s.command.ChangeLockoutPolicy(ctx, authz.GetCtxData(ctx).OrgID, UpdateLockoutPolicyToDomain(req))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &mgmt_pb.UpdateCustomLockoutPolicyResponse{
|
||||||
|
Details: object.ChangeToDetailsPb(
|
||||||
|
policy.Sequence,
|
||||||
|
policy.ChangeDate,
|
||||||
|
policy.ResourceOwner,
|
||||||
|
),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) ResetLockoutPolicyToDefault(ctx context.Context, req *mgmt_pb.ResetLockoutPolicyToDefaultRequest) (*mgmt_pb.ResetLockoutPolicyToDefaultResponse, error) {
|
||||||
|
objectDetails, err := s.command.RemovePasswordComplexityPolicy(ctx, authz.GetCtxData(ctx).OrgID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &mgmt_pb.ResetLockoutPolicyToDefaultResponse{
|
||||||
|
Details: object.DomainToChangeDetailsPb(objectDetails),
|
||||||
|
}, nil
|
||||||
|
}
|
18
internal/api/grpc/management/policy_lockout_converter.go
Normal file
18
internal/api/grpc/management/policy_lockout_converter.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package management
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/caos/zitadel/internal/domain"
|
||||||
|
mgmt "github.com/caos/zitadel/pkg/grpc/management"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AddLockoutPolicyToDomain(p *mgmt.AddCustomLockoutPolicyRequest) *domain.LockoutPolicy {
|
||||||
|
return &domain.LockoutPolicy{
|
||||||
|
MaxPasswordAttempts: uint64(p.MaxPasswordAttempts),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateLockoutPolicyToDomain(p *mgmt.UpdateCustomLockoutPolicyRequest) *domain.LockoutPolicy {
|
||||||
|
return &domain.LockoutPolicy{
|
||||||
|
MaxPasswordAttempts: uint64(p.MaxPasswordAttempts),
|
||||||
|
}
|
||||||
|
}
|
@ -1,63 +0,0 @@
|
|||||||
package management
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/caos/zitadel/internal/api/authz"
|
|
||||||
"github.com/caos/zitadel/internal/api/grpc/object"
|
|
||||||
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
|
|
||||||
mgmt_pb "github.com/caos/zitadel/pkg/grpc/management"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s *Server) GetPasswordLockoutPolicy(ctx context.Context, req *mgmt_pb.GetPasswordLockoutPolicyRequest) (*mgmt_pb.GetPasswordLockoutPolicyResponse, error) {
|
|
||||||
policy, err := s.org.GetPasswordLockoutPolicy(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &mgmt_pb.GetPasswordLockoutPolicyResponse{Policy: policy_grpc.ModelPasswordLockoutPolicyToPb(policy), IsDefault: policy.Default}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) GetDefaultPasswordLockoutPolicy(ctx context.Context, req *mgmt_pb.GetDefaultPasswordLockoutPolicyRequest) (*mgmt_pb.GetDefaultPasswordLockoutPolicyResponse, error) {
|
|
||||||
policy, err := s.org.GetDefaultPasswordLockoutPolicy(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &mgmt_pb.GetDefaultPasswordLockoutPolicyResponse{Policy: policy_grpc.ModelPasswordLockoutPolicyToPb(policy)}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) AddCustomPasswordLockoutPolicy(ctx context.Context, req *mgmt_pb.AddCustomPasswordLockoutPolicyRequest) (*mgmt_pb.AddCustomPasswordLockoutPolicyResponse, error) {
|
|
||||||
policy, err := s.command.AddPasswordLockoutPolicy(ctx, authz.GetCtxData(ctx).OrgID, AddPasswordLockoutPolicyToDomain(req))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &mgmt_pb.AddCustomPasswordLockoutPolicyResponse{
|
|
||||||
Details: object.AddToDetailsPb(
|
|
||||||
policy.Sequence,
|
|
||||||
policy.ChangeDate,
|
|
||||||
policy.ResourceOwner,
|
|
||||||
),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) UpdateCustomPasswordLockoutPolicy(ctx context.Context, req *mgmt_pb.UpdateCustomPasswordLockoutPolicyRequest) (*mgmt_pb.UpdateCustomPasswordLockoutPolicyResponse, error) {
|
|
||||||
policy, err := s.command.ChangePasswordLockoutPolicy(ctx, authz.GetCtxData(ctx).OrgID, UpdatePasswordLockoutPolicyToDomain(req))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &mgmt_pb.UpdateCustomPasswordLockoutPolicyResponse{
|
|
||||||
Details: object.ChangeToDetailsPb(
|
|
||||||
policy.Sequence,
|
|
||||||
policy.ChangeDate,
|
|
||||||
policy.ResourceOwner,
|
|
||||||
),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) ResetPasswordLockoutPolicyToDefault(ctx context.Context, req *mgmt_pb.ResetPasswordLockoutPolicyToDefaultRequest) (*mgmt_pb.ResetPasswordLockoutPolicyToDefaultResponse, error) {
|
|
||||||
objectDetails, err := s.command.RemovePasswordComplexityPolicy(ctx, authz.GetCtxData(ctx).OrgID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &mgmt_pb.ResetPasswordLockoutPolicyToDefaultResponse{
|
|
||||||
Details: object.DomainToChangeDetailsPb(objectDetails),
|
|
||||||
}, nil
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package management
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/zitadel/internal/domain"
|
|
||||||
mgmt "github.com/caos/zitadel/pkg/grpc/management"
|
|
||||||
)
|
|
||||||
|
|
||||||
func AddPasswordLockoutPolicyToDomain(p *mgmt.AddCustomPasswordLockoutPolicyRequest) *domain.PasswordLockoutPolicy {
|
|
||||||
return &domain.PasswordLockoutPolicy{
|
|
||||||
MaxAttempts: uint64(p.MaxAttempts),
|
|
||||||
ShowLockOutFailures: p.ShowLockoutFailure,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdatePasswordLockoutPolicyToDomain(p *mgmt.UpdateCustomPasswordLockoutPolicyRequest) *domain.PasswordLockoutPolicy {
|
|
||||||
return &domain.PasswordLockoutPolicy{
|
|
||||||
MaxAttempts: uint64(p.MaxAttempts),
|
|
||||||
ShowLockOutFailures: p.ShowLockoutFailure,
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,11 +6,10 @@ import (
|
|||||||
policy_pb "github.com/caos/zitadel/pkg/grpc/policy"
|
policy_pb "github.com/caos/zitadel/pkg/grpc/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ModelPasswordLockoutPolicyToPb(policy *model.PasswordLockoutPolicyView) *policy_pb.PasswordLockoutPolicy {
|
func ModelLockoutPolicyToPb(policy *model.LockoutPolicyView) *policy_pb.LockoutPolicy {
|
||||||
return &policy_pb.PasswordLockoutPolicy{
|
return &policy_pb.LockoutPolicy{
|
||||||
IsDefault: policy.Default,
|
IsDefault: policy.Default,
|
||||||
MaxAttempts: policy.MaxAttempts,
|
MaxPasswordAttempts: policy.MaxPasswordAttempts,
|
||||||
ShowLockoutFailure: policy.ShowLockOutFailures,
|
|
||||||
Details: object.ToViewDetailsPb(
|
Details: object.ToViewDetailsPb(
|
||||||
policy.Sequence,
|
policy.Sequence,
|
||||||
policy.CreationDate,
|
policy.CreationDate,
|
||||||
|
@ -35,14 +35,15 @@ type AuthRequestRepo struct {
|
|||||||
View *view.View
|
View *view.View
|
||||||
Eventstore v1.Eventstore
|
Eventstore v1.Eventstore
|
||||||
|
|
||||||
UserSessionViewProvider userSessionViewProvider
|
UserSessionViewProvider userSessionViewProvider
|
||||||
UserViewProvider userViewProvider
|
UserViewProvider userViewProvider
|
||||||
UserCommandProvider userCommandProvider
|
UserCommandProvider userCommandProvider
|
||||||
UserEventProvider userEventProvider
|
UserEventProvider userEventProvider
|
||||||
OrgViewProvider orgViewProvider
|
OrgViewProvider orgViewProvider
|
||||||
LoginPolicyViewProvider loginPolicyViewProvider
|
LoginPolicyViewProvider loginPolicyViewProvider
|
||||||
IDPProviderViewProvider idpProviderViewProvider
|
LockoutPolicyViewProvider lockoutPolicyViewProvider
|
||||||
UserGrantProvider userGrantProvider
|
IDPProviderViewProvider idpProviderViewProvider
|
||||||
|
UserGrantProvider userGrantProvider
|
||||||
|
|
||||||
IdGenerator id.Generator
|
IdGenerator id.Generator
|
||||||
|
|
||||||
@ -69,6 +70,10 @@ type loginPolicyViewProvider interface {
|
|||||||
LoginPolicyByAggregateID(string) (*iam_view_model.LoginPolicyView, error)
|
LoginPolicyByAggregateID(string) (*iam_view_model.LoginPolicyView, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type lockoutPolicyViewProvider interface {
|
||||||
|
LockoutPolicyByAggregateID(string) (*iam_view_model.LockoutPolicyView, error)
|
||||||
|
}
|
||||||
|
|
||||||
type idpProviderViewProvider interface {
|
type idpProviderViewProvider interface {
|
||||||
IDPProvidersByAggregateIDAndState(string, iam_model.IDPConfigState) ([]*iam_view_model.IDPProviderView, error)
|
IDPProvidersByAggregateIDAndState(string, iam_model.IDPConfigState) ([]*iam_view_model.IDPProviderView, error)
|
||||||
}
|
}
|
||||||
@ -240,7 +245,7 @@ func (repo *AuthRequestRepo) SelectUser(ctx context.Context, id, userID, userAge
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
user, err := activeUserByID(ctx, repo.UserViewProvider, repo.UserEventProvider, repo.OrgViewProvider, userID)
|
user, err := activeUserByID(ctx, repo.UserViewProvider, repo.UserEventProvider, repo.OrgViewProvider, repo.LockoutPolicyViewProvider, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -262,7 +267,11 @@ func (repo *AuthRequestRepo) VerifyPassword(ctx context.Context, id, userID, res
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return repo.Command.HumanCheckPassword(ctx, resourceOwner, userID, password, request.WithCurrentInfo(info))
|
policy, err := repo.getLockoutPolicy(ctx, resourceOwner)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return repo.Command.HumanCheckPassword(ctx, resourceOwner, userID, password, request.WithCurrentInfo(info), policy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *AuthRequestRepo) VerifyMFAOTP(ctx context.Context, authRequestID, userID, resourceOwner, code, userAgentID string, info *domain.BrowserInfo) (err error) {
|
func (repo *AuthRequestRepo) VerifyMFAOTP(ctx context.Context, authRequestID, userID, resourceOwner, code, userAgentID string, info *domain.BrowserInfo) (err error) {
|
||||||
@ -414,6 +423,10 @@ func (repo *AuthRequestRepo) getAuthRequestEnsureUser(ctx context.Context, authR
|
|||||||
if request.UserID != userID {
|
if request.UserID != userID {
|
||||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-GBH32", "Errors.User.NotMatchingUserID")
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-GBH32", "Errors.User.NotMatchingUserID")
|
||||||
}
|
}
|
||||||
|
_, err = activeUserByID(ctx, repo.UserViewProvider, repo.UserEventProvider, repo.OrgViewProvider, repo.LockoutPolicyViewProvider, request.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return request, nil
|
return request, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,6 +479,11 @@ func (repo *AuthRequestRepo) fillPolicies(ctx context.Context, request *domain.A
|
|||||||
if idpProviders != nil {
|
if idpProviders != nil {
|
||||||
request.AllowedExternalIDPs = idpProviders
|
request.AllowedExternalIDPs = idpProviders
|
||||||
}
|
}
|
||||||
|
lockoutPolicy, err := repo.getLockoutPolicy(ctx, orgID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
request.LockoutPolicy = lockoutPolicy
|
||||||
privacyPolicy, err := repo.getPrivacyPolicy(ctx, orgID)
|
privacyPolicy, err := repo.getPrivacyPolicy(ctx, orgID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -587,7 +605,7 @@ func (repo *AuthRequestRepo) nextSteps(ctx context.Context, request *domain.Auth
|
|||||||
}
|
}
|
||||||
return steps, nil
|
return steps, nil
|
||||||
}
|
}
|
||||||
user, err := activeUserByID(ctx, repo.UserViewProvider, repo.UserEventProvider, repo.OrgViewProvider, request.UserID)
|
user, err := activeUserByID(ctx, repo.UserViewProvider, repo.UserEventProvider, repo.OrgViewProvider, repo.LockoutPolicyViewProvider, request.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -795,6 +813,21 @@ func (repo *AuthRequestRepo) getPrivacyPolicy(ctx context.Context, orgID string)
|
|||||||
return policy.ToDomain(), err
|
return policy.ToDomain(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repo *AuthRequestRepo) getLockoutPolicy(ctx context.Context, orgID string) (*domain.LockoutPolicy, error) {
|
||||||
|
policy, err := repo.View.LockoutPolicyByAggregateID(orgID)
|
||||||
|
if errors.IsNotFound(err) {
|
||||||
|
policy, err = repo.View.LockoutPolicyByAggregateID(repo.IAMID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
policy.Default = true
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return policy.ToDomain(), err
|
||||||
|
}
|
||||||
|
|
||||||
func (repo *AuthRequestRepo) getLabelPolicy(ctx context.Context, orgID string) (*domain.LabelPolicy, error) {
|
func (repo *AuthRequestRepo) getLabelPolicy(ctx context.Context, orgID string) (*domain.LabelPolicy, error) {
|
||||||
policy, err := repo.View.LabelPolicyByAggregateIDAndState(orgID, int32(domain.LabelPolicyStateActive))
|
policy, err := repo.View.LabelPolicyByAggregateIDAndState(orgID, int32(domain.LabelPolicyStateActive))
|
||||||
if errors.IsNotFound(err) {
|
if errors.IsNotFound(err) {
|
||||||
@ -921,7 +954,8 @@ func userSessionByIDs(ctx context.Context, provider userSessionViewProvider, eve
|
|||||||
return user_view_model.UserSessionToModel(&sessionCopy, provider.PrefixAvatarURL()), nil
|
return user_view_model.UserSessionToModel(&sessionCopy, provider.PrefixAvatarURL()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func activeUserByID(ctx context.Context, userViewProvider userViewProvider, userEventProvider userEventProvider, orgViewProvider orgViewProvider, userID string) (*user_model.UserView, error) {
|
func activeUserByID(ctx context.Context, userViewProvider userViewProvider, userEventProvider userEventProvider, orgViewProvider orgViewProvider, lockoutPolicyProvider lockoutPolicyViewProvider, userID string) (*user_model.UserView, error) {
|
||||||
|
// PLANNED: Check LockoutPolicy
|
||||||
user, err := userByID(ctx, userViewProvider, userEventProvider, userID)
|
user, err := userByID(ctx, userViewProvider, userEventProvider, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -930,7 +964,6 @@ func activeUserByID(ctx context.Context, userViewProvider userViewProvider, user
|
|||||||
if user.HumanView == nil {
|
if user.HumanView == nil {
|
||||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Lm69x", "Errors.User.NotHuman")
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Lm69x", "Errors.User.NotHuman")
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.State == user_model.UserStateLocked || user.State == user_model.UserStateSuspend {
|
if user.State == user_model.UserStateLocked || user.State == user_model.UserStateSuspend {
|
||||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-FJ262", "Errors.User.Locked")
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-FJ262", "Errors.User.Locked")
|
||||||
}
|
}
|
||||||
|
@ -152,6 +152,14 @@ func (m *mockLoginPolicy) LoginPolicyByAggregateID(id string) (*iam_view_model.L
|
|||||||
return m.policy, nil
|
return m.policy, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type mockLockoutPolicy struct {
|
||||||
|
policy *iam_view_model.LockoutPolicyView
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockLockoutPolicy) LockoutPolicyByAggregateID(id string) (*iam_view_model.LockoutPolicyView, error) {
|
||||||
|
return m.policy, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *mockViewUser) UserByID(string) (*user_view_model.UserView, error) {
|
func (m *mockViewUser) UserByID(string) (*user_view_model.UserView, error) {
|
||||||
return &user_view_model.UserView{
|
return &user_view_model.UserView{
|
||||||
State: int32(user_model.UserStateActive),
|
State: int32(user_model.UserStateActive),
|
||||||
@ -229,6 +237,7 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
orgViewProvider orgViewProvider
|
orgViewProvider orgViewProvider
|
||||||
userGrantProvider userGrantProvider
|
userGrantProvider userGrantProvider
|
||||||
loginPolicyProvider loginPolicyViewProvider
|
loginPolicyProvider loginPolicyViewProvider
|
||||||
|
lockoutPolicyProvider lockoutPolicyViewProvider
|
||||||
PasswordCheckLifeTime time.Duration
|
PasswordCheckLifeTime time.Duration
|
||||||
ExternalLoginCheckLifeTime time.Duration
|
ExternalLoginCheckLifeTime time.Duration
|
||||||
MFAInitSkippedLifeTime time.Duration
|
MFAInitSkippedLifeTime time.Duration
|
||||||
@ -404,6 +413,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
args{&domain.AuthRequest{UserID: "UserID"}, false},
|
args{&domain.AuthRequest{UserID: "UserID"}, false},
|
||||||
nil,
|
nil,
|
||||||
@ -420,6 +434,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
args{&domain.AuthRequest{UserID: "UserID"}, false},
|
args{&domain.AuthRequest{UserID: "UserID"}, false},
|
||||||
nil,
|
nil,
|
||||||
@ -431,6 +450,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
userViewProvider: &mockViewUser{},
|
userViewProvider: &mockViewUser{},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewErrOrg{},
|
orgViewProvider: &mockViewErrOrg{},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
args{&domain.AuthRequest{UserID: "UserID"}, false},
|
args{&domain.AuthRequest{UserID: "UserID"}, false},
|
||||||
nil,
|
nil,
|
||||||
@ -442,6 +466,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
userViewProvider: &mockViewUser{},
|
userViewProvider: &mockViewUser{},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateInactive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateInactive},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
args{&domain.AuthRequest{UserID: "UserID"}, false},
|
args{&domain.AuthRequest{UserID: "UserID"}, false},
|
||||||
nil,
|
nil,
|
||||||
@ -456,6 +485,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
},
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
args{&domain.AuthRequest{UserID: "UserID", LoginPolicy: &domain.LoginPolicy{}}, false},
|
args{&domain.AuthRequest{UserID: "UserID", LoginPolicy: &domain.LoginPolicy{}}, false},
|
||||||
[]domain.NextStep{&domain.PasswordStep{}},
|
[]domain.NextStep{&domain.PasswordStep{}},
|
||||||
@ -468,6 +502,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
userViewProvider: &mockViewUser{},
|
userViewProvider: &mockViewUser{},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
args{&domain.AuthRequest{UserID: "UserID"}, false},
|
args{&domain.AuthRequest{UserID: "UserID"}, false},
|
||||||
nil,
|
nil,
|
||||||
@ -483,6 +522,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
},
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
args{&domain.AuthRequest{UserID: "UserID"}, false},
|
args{&domain.AuthRequest{UserID: "UserID"}, false},
|
||||||
[]domain.NextStep{&domain.InitUserStep{
|
[]domain.NextStep{&domain.InitUserStep{
|
||||||
@ -500,6 +544,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
MultiFactorCheckLifeTime: 10 * time.Hour,
|
MultiFactorCheckLifeTime: 10 * time.Hour,
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
args{&domain.AuthRequest{UserID: "UserID", LoginPolicy: &domain.LoginPolicy{PasswordlessType: domain.PasswordlessTypeAllowed}}, false},
|
args{&domain.AuthRequest{UserID: "UserID", LoginPolicy: &domain.LoginPolicy{PasswordlessType: domain.PasswordlessTypeAllowed}}, false},
|
||||||
[]domain.NextStep{&domain.PasswordlessRegistrationPromptStep{}},
|
[]domain.NextStep{&domain.PasswordlessRegistrationPromptStep{}},
|
||||||
@ -512,8 +561,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
userViewProvider: &mockViewUser{
|
userViewProvider: &mockViewUser{
|
||||||
PasswordlessTokens: user_view_model.WebAuthNTokens{&user_view_model.WebAuthNView{ID: "id", State: int32(user_model.MFAStateReady)}},
|
PasswordlessTokens: user_view_model.WebAuthNTokens{&user_view_model.WebAuthNView{ID: "id", State: int32(user_model.MFAStateReady)}},
|
||||||
},
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
MultiFactorCheckLifeTime: 10 * time.Hour,
|
MultiFactorCheckLifeTime: 10 * time.Hour,
|
||||||
},
|
},
|
||||||
args{&domain.AuthRequest{UserID: "UserID", LoginPolicy: &domain.LoginPolicy{PasswordlessType: domain.PasswordlessTypeAllowed}}, false},
|
args{&domain.AuthRequest{UserID: "UserID", LoginPolicy: &domain.LoginPolicy{PasswordlessType: domain.PasswordlessTypeAllowed}}, false},
|
||||||
@ -528,8 +582,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
PasswordSet: true,
|
PasswordSet: true,
|
||||||
PasswordlessTokens: user_view_model.WebAuthNTokens{&user_view_model.WebAuthNView{ID: "id", State: int32(user_model.MFAStateReady)}},
|
PasswordlessTokens: user_view_model.WebAuthNTokens{&user_view_model.WebAuthNView{ID: "id", State: int32(user_model.MFAStateReady)}},
|
||||||
},
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
MultiFactorCheckLifeTime: 10 * time.Hour,
|
MultiFactorCheckLifeTime: 10 * time.Hour,
|
||||||
},
|
},
|
||||||
args{&domain.AuthRequest{UserID: "UserID", LoginPolicy: &domain.LoginPolicy{PasswordlessType: domain.PasswordlessTypeAllowed}}, false},
|
args{&domain.AuthRequest{UserID: "UserID", LoginPolicy: &domain.LoginPolicy{PasswordlessType: domain.PasswordlessTypeAllowed}}, false},
|
||||||
@ -550,7 +609,12 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
IsEmailVerified: false,
|
IsEmailVerified: false,
|
||||||
MFAMaxSetUp: int32(model.MFALevelMultiFactor),
|
MFAMaxSetUp: int32(model.MFALevelMultiFactor),
|
||||||
},
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
MultiFactorCheckLifeTime: 10 * time.Hour,
|
MultiFactorCheckLifeTime: 10 * time.Hour,
|
||||||
},
|
},
|
||||||
@ -572,7 +636,12 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
PasswordInitRequired: true,
|
PasswordInitRequired: true,
|
||||||
},
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
},
|
},
|
||||||
args{&domain.AuthRequest{UserID: "UserID", LoginPolicy: &domain.LoginPolicy{}}, false},
|
args{&domain.AuthRequest{UserID: "UserID", LoginPolicy: &domain.LoginPolicy{}}, false},
|
||||||
[]domain.NextStep{&domain.InitPasswordStep{}},
|
[]domain.NextStep{&domain.InitPasswordStep{}},
|
||||||
@ -588,7 +657,12 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
IsEmailVerified: true,
|
IsEmailVerified: true,
|
||||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||||
},
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||||
},
|
},
|
||||||
@ -613,6 +687,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
loginPolicyProvider: &mockLoginPolicy{
|
loginPolicyProvider: &mockLoginPolicy{
|
||||||
policy: &iam_view_model.LoginPolicyView{},
|
policy: &iam_view_model.LoginPolicyView{},
|
||||||
},
|
},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
ExternalLoginCheckLifeTime: 10 * 24 * time.Hour,
|
ExternalLoginCheckLifeTime: 10 * 24 * time.Hour,
|
||||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||||
},
|
},
|
||||||
@ -634,8 +713,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
userViewProvider: &mockViewUser{
|
userViewProvider: &mockViewUser{
|
||||||
PasswordSet: true,
|
PasswordSet: true,
|
||||||
},
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||||
},
|
},
|
||||||
args{&domain.AuthRequest{UserID: "UserID", LoginPolicy: &domain.LoginPolicy{}}, false},
|
args{&domain.AuthRequest{UserID: "UserID", LoginPolicy: &domain.LoginPolicy{}}, false},
|
||||||
@ -654,9 +738,14 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
IsEmailVerified: true,
|
IsEmailVerified: true,
|
||||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||||
},
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
userGrantProvider: &mockUserGrants{},
|
userGrantProvider: &mockUserGrants{},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||||
ExternalLoginCheckLifeTime: 10 * 24 * time.Hour,
|
ExternalLoginCheckLifeTime: 10 * 24 * time.Hour,
|
||||||
},
|
},
|
||||||
@ -682,8 +771,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
OTPState: int32(user_model.MFAStateReady),
|
OTPState: int32(user_model.MFAStateReady),
|
||||||
MFAMaxSetUp: int32(model.MFALevelMultiFactor),
|
MFAMaxSetUp: int32(model.MFALevelMultiFactor),
|
||||||
},
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||||
},
|
},
|
||||||
@ -710,8 +804,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
OTPState: int32(user_model.MFAStateReady),
|
OTPState: int32(user_model.MFAStateReady),
|
||||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||||
},
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||||
},
|
},
|
||||||
@ -739,8 +838,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
OTPState: int32(user_model.MFAStateReady),
|
OTPState: int32(user_model.MFAStateReady),
|
||||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||||
},
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||||
ExternalLoginCheckLifeTime: 10 * 24 * time.Hour,
|
ExternalLoginCheckLifeTime: 10 * 24 * time.Hour,
|
||||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||||
@ -771,8 +875,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
IsEmailVerified: true,
|
IsEmailVerified: true,
|
||||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||||
},
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||||
},
|
},
|
||||||
@ -797,8 +906,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
PasswordSet: true,
|
PasswordSet: true,
|
||||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||||
},
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||||
},
|
},
|
||||||
@ -823,8 +937,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
PasswordChangeRequired: true,
|
PasswordChangeRequired: true,
|
||||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||||
},
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||||
},
|
},
|
||||||
@ -849,9 +968,14 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
IsEmailVerified: true,
|
IsEmailVerified: true,
|
||||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||||
},
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
userGrantProvider: &mockUserGrants{},
|
userGrantProvider: &mockUserGrants{},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||||
},
|
},
|
||||||
@ -877,9 +1001,14 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
IsEmailVerified: true,
|
IsEmailVerified: true,
|
||||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||||
},
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
userGrantProvider: &mockUserGrants{},
|
userGrantProvider: &mockUserGrants{},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||||
},
|
},
|
||||||
@ -912,6 +1041,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
roleCheck: true,
|
roleCheck: true,
|
||||||
userGrants: 0,
|
userGrants: 0,
|
||||||
},
|
},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||||
},
|
},
|
||||||
@ -944,6 +1078,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
roleCheck: true,
|
roleCheck: true,
|
||||||
userGrants: 2,
|
userGrants: 2,
|
||||||
},
|
},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||||
},
|
},
|
||||||
@ -969,6 +1108,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
IsEmailVerified: true,
|
IsEmailVerified: true,
|
||||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||||
},
|
},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||||
@ -995,8 +1139,13 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
IsEmailVerified: true,
|
IsEmailVerified: true,
|
||||||
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
MFAMaxSetUp: int32(model.MFALevelSecondFactor),
|
||||||
},
|
},
|
||||||
userEventProvider: &mockEventUser{},
|
userEventProvider: &mockEventUser{},
|
||||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||||
|
lockoutPolicyProvider: &mockLockoutPolicy{
|
||||||
|
policy: &iam_view_model.LockoutPolicyView{
|
||||||
|
ShowLockOutFailures: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
SecondFactorCheckLifeTime: 18 * time.Hour,
|
SecondFactorCheckLifeTime: 18 * time.Hour,
|
||||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||||
},
|
},
|
||||||
@ -1024,6 +1173,7 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
OrgViewProvider: tt.fields.orgViewProvider,
|
OrgViewProvider: tt.fields.orgViewProvider,
|
||||||
UserGrantProvider: tt.fields.userGrantProvider,
|
UserGrantProvider: tt.fields.userGrantProvider,
|
||||||
LoginPolicyViewProvider: tt.fields.loginPolicyProvider,
|
LoginPolicyViewProvider: tt.fields.loginPolicyProvider,
|
||||||
|
LockoutPolicyViewProvider: tt.fields.lockoutPolicyProvider,
|
||||||
PasswordCheckLifeTime: tt.fields.PasswordCheckLifeTime,
|
PasswordCheckLifeTime: tt.fields.PasswordCheckLifeTime,
|
||||||
ExternalLoginCheckLifeTime: tt.fields.ExternalLoginCheckLifeTime,
|
ExternalLoginCheckLifeTime: tt.fields.ExternalLoginCheckLifeTime,
|
||||||
MFAInitSkippedLifeTime: tt.fields.MFAInitSkippedLifeTime,
|
MFAInitSkippedLifeTime: tt.fields.MFAInitSkippedLifeTime,
|
||||||
|
@ -73,6 +73,7 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es
|
|||||||
newPrivacyPolicy(handler{view, bulkLimit, configs.cycleDuration("PrivacyPolicy"), errorCount, es}),
|
newPrivacyPolicy(handler{view, bulkLimit, configs.cycleDuration("PrivacyPolicy"), errorCount, es}),
|
||||||
newCustomText(handler{view, bulkLimit, configs.cycleDuration("CustomTexts"), errorCount, es}),
|
newCustomText(handler{view, bulkLimit, configs.cycleDuration("CustomTexts"), errorCount, es}),
|
||||||
newMetadata(handler{view, bulkLimit, configs.cycleDuration("Metadata"), errorCount, es}),
|
newMetadata(handler{view, bulkLimit, configs.cycleDuration("Metadata"), errorCount, es}),
|
||||||
|
newLockoutPolicy(handler{view, bulkLimit, configs.cycleDuration("LockoutPolicy"), errorCount, es}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
110
internal/auth/repository/eventsourcing/handler/lockout_policy.go
Normal file
110
internal/auth/repository/eventsourcing/handler/lockout_policy.go
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/caos/logging"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||||
|
|
||||||
|
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
||||||
|
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||||
|
iam_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||||
|
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
lockoutPolicyTable = "auth.lockout_policies"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LockoutPolicy struct {
|
||||||
|
handler
|
||||||
|
subscription *v1.Subscription
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLockoutPolicy(handler handler) *LockoutPolicy {
|
||||||
|
h := &LockoutPolicy{
|
||||||
|
handler: handler,
|
||||||
|
}
|
||||||
|
|
||||||
|
h.subscribe()
|
||||||
|
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *LockoutPolicy) subscribe() {
|
||||||
|
p.subscription = p.es.Subscribe(p.AggregateTypes()...)
|
||||||
|
go func() {
|
||||||
|
for event := range p.subscription.Events {
|
||||||
|
query.ReduceEvent(p, event)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *LockoutPolicy) ViewModel() string {
|
||||||
|
return lockoutPolicyTable
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *LockoutPolicy) Subscription() *v1.Subscription {
|
||||||
|
return p.subscription
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ *LockoutPolicy) AggregateTypes() []es_models.AggregateType {
|
||||||
|
return []es_models.AggregateType{org_es_model.OrgAggregate, iam_es_model.IAMAggregate}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *LockoutPolicy) CurrentSequence() (uint64, error) {
|
||||||
|
sequence, err := p.view.GetLatestLockoutPolicySequence()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return sequence.CurrentSequence, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *LockoutPolicy) EventQuery() (*es_models.SearchQuery, error) {
|
||||||
|
sequence, err := p.view.GetLatestLockoutPolicySequence()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return es_models.NewSearchQuery().
|
||||||
|
AggregateTypeFilter(p.AggregateTypes()...).
|
||||||
|
LatestSequenceFilter(sequence.CurrentSequence), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *LockoutPolicy) Reduce(event *es_models.Event) (err error) {
|
||||||
|
switch event.AggregateType {
|
||||||
|
case org_es_model.OrgAggregate, iam_es_model.IAMAggregate:
|
||||||
|
err = p.processLockoutPolicy(event)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *LockoutPolicy) processLockoutPolicy(event *es_models.Event) (err error) {
|
||||||
|
policy := new(iam_model.LockoutPolicyView)
|
||||||
|
switch event.Type {
|
||||||
|
case iam_es_model.LockoutPolicyAdded, org_es_model.LockoutPolicyAdded:
|
||||||
|
err = policy.AppendEvent(event)
|
||||||
|
case iam_es_model.LockoutPolicyChanged, org_es_model.LockoutPolicyChanged:
|
||||||
|
policy, err = p.view.LockoutPolicyByAggregateID(event.AggregateID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = policy.AppendEvent(event)
|
||||||
|
case org_es_model.LockoutPolicyRemoved:
|
||||||
|
return p.view.DeleteLockoutPolicy(event.AggregateID, event)
|
||||||
|
default:
|
||||||
|
return p.view.ProcessedLockoutPolicySequence(event)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return p.view.PutLockoutPolicy(policy, event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *LockoutPolicy) OnError(event *es_models.Event, err error) error {
|
||||||
|
logging.LogWithFields("SPOOL-0pos2", "id", event.AggregateID).WithError(err).Warn("something went wrong in passwordLockout policy handler")
|
||||||
|
return spooler.HandleError(event, err, p.view.GetLatestLockoutPolicyFailedEvent, p.view.ProcessedLockoutPolicyFailedEvent, p.view.ProcessedLockoutPolicySequence, p.errorCountUntilSkip)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *LockoutPolicy) OnSuccess() error {
|
||||||
|
return spooler.HandleSuccess(p.view.UpdateLockoutPolicySpoolerRunTimestamp)
|
||||||
|
}
|
@ -109,6 +109,7 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, co
|
|||||||
OrgViewProvider: view,
|
OrgViewProvider: view,
|
||||||
IDPProviderViewProvider: view,
|
IDPProviderViewProvider: view,
|
||||||
LoginPolicyViewProvider: view,
|
LoginPolicyViewProvider: view,
|
||||||
|
LockoutPolicyViewProvider: view,
|
||||||
UserGrantProvider: view,
|
UserGrantProvider: view,
|
||||||
IdGenerator: idGenerator,
|
IdGenerator: idGenerator,
|
||||||
PasswordCheckLifeTime: systemDefaults.VerificationLifetimes.PasswordCheck.Duration,
|
PasswordCheckLifeTime: systemDefaults.VerificationLifetimes.PasswordCheck.Duration,
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
package view
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/caos/zitadel/internal/errors"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||||
|
"github.com/caos/zitadel/internal/iam/repository/view"
|
||||||
|
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||||
|
global_view "github.com/caos/zitadel/internal/view/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
passwordLockoutPolicyTable = "auth.lockout_policies"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (v *View) LockoutPolicyByAggregateID(aggregateID string) (*model.LockoutPolicyView, error) {
|
||||||
|
return view.GetLockoutPolicyByAggregateID(v.Db, passwordLockoutPolicyTable, aggregateID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) PutLockoutPolicy(policy *model.LockoutPolicyView, event *models.Event) error {
|
||||||
|
err := view.PutLockoutPolicy(v.Db, passwordLockoutPolicyTable, policy)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return v.ProcessedLockoutPolicySequence(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) DeleteLockoutPolicy(aggregateID string, event *models.Event) error {
|
||||||
|
err := view.DeleteLockoutPolicy(v.Db, passwordLockoutPolicyTable, aggregateID)
|
||||||
|
if err != nil && !errors.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return v.ProcessedLockoutPolicySequence(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) GetLatestLockoutPolicySequence() (*global_view.CurrentSequence, error) {
|
||||||
|
return v.latestSequence(passwordLockoutPolicyTable)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) ProcessedLockoutPolicySequence(event *models.Event) error {
|
||||||
|
return v.saveCurrentSequence(passwordLockoutPolicyTable, event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) UpdateLockoutPolicySpoolerRunTimestamp() error {
|
||||||
|
return v.updateSpoolerRunSequence(passwordLockoutPolicyTable)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) GetLatestLockoutPolicyFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
|
||||||
|
return v.latestFailedEvent(passwordLockoutPolicyTable, sequence)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) ProcessedLockoutPolicyFailedEvent(failedEvent *global_view.FailedEvent) error {
|
||||||
|
return v.saveFailedEvent(failedEvent)
|
||||||
|
}
|
@ -112,10 +112,10 @@ func writeModelToPasswordComplexityPolicy(wm *PasswordComplexityPolicyWriteModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeModelToPasswordLockoutPolicy(wm *PasswordLockoutPolicyWriteModel) *domain.PasswordLockoutPolicy {
|
func writeModelToLockoutPolicy(wm *LockoutPolicyWriteModel) *domain.LockoutPolicy {
|
||||||
return &domain.PasswordLockoutPolicy{
|
return &domain.LockoutPolicy{
|
||||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
||||||
MaxAttempts: wm.MaxAttempts,
|
MaxPasswordAttempts: wm.MaxPasswordAttempts,
|
||||||
ShowLockOutFailures: wm.ShowLockOutFailures,
|
ShowLockOutFailures: wm.ShowLockOutFailures,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,10 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Commands) AddDefaultPasswordLockoutPolicy(ctx context.Context, policy *domain.PasswordLockoutPolicy) (*domain.PasswordLockoutPolicy, error) {
|
func (c *Commands) AddDefaultLockoutPolicy(ctx context.Context, policy *domain.LockoutPolicy) (*domain.LockoutPolicy, error) {
|
||||||
addedPolicy := NewIAMPasswordLockoutPolicyWriteModel()
|
addedPolicy := NewIAMLockoutPolicyWriteModel()
|
||||||
iamAgg := IAMAggregateFromWriteModel(&addedPolicy.WriteModel)
|
iamAgg := IAMAggregateFromWriteModel(&addedPolicy.WriteModel)
|
||||||
event, err := c.addDefaultPasswordLockoutPolicy(ctx, iamAgg, addedPolicy, policy)
|
event, err := c.addDefaultLockoutPolicy(ctx, iamAgg, addedPolicy, policy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -25,34 +25,34 @@ func (c *Commands) AddDefaultPasswordLockoutPolicy(ctx context.Context, policy *
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return writeModelToPasswordLockoutPolicy(&addedPolicy.PasswordLockoutPolicyWriteModel), nil
|
return writeModelToLockoutPolicy(&addedPolicy.LockoutPolicyWriteModel), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) addDefaultPasswordLockoutPolicy(ctx context.Context, iamAgg *eventstore.Aggregate, addedPolicy *IAMPasswordLockoutPolicyWriteModel, policy *domain.PasswordLockoutPolicy) (eventstore.EventPusher, error) {
|
func (c *Commands) addDefaultLockoutPolicy(ctx context.Context, iamAgg *eventstore.Aggregate, addedPolicy *IAMLockoutPolicyWriteModel, policy *domain.LockoutPolicy) (eventstore.EventPusher, error) {
|
||||||
err := c.eventstore.FilterToQueryReducer(ctx, addedPolicy)
|
err := c.eventstore.FilterToQueryReducer(ctx, addedPolicy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if addedPolicy.State == domain.PolicyStateActive {
|
if addedPolicy.State == domain.PolicyStateActive {
|
||||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0olDf", "Errors.IAM.PasswordLockoutPolicy.AlreadyExists")
|
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0olDf", "Errors.IAM.LockoutPolicy.AlreadyExists")
|
||||||
}
|
}
|
||||||
|
|
||||||
return iam_repo.NewPasswordLockoutPolicyAddedEvent(ctx, iamAgg, policy.MaxAttempts, policy.ShowLockOutFailures), nil
|
return iam_repo.NewLockoutPolicyAddedEvent(ctx, iamAgg, policy.MaxPasswordAttempts, policy.ShowLockOutFailures), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) ChangeDefaultPasswordLockoutPolicy(ctx context.Context, policy *domain.PasswordLockoutPolicy) (*domain.PasswordLockoutPolicy, error) {
|
func (c *Commands) ChangeDefaultLockoutPolicy(ctx context.Context, policy *domain.LockoutPolicy) (*domain.LockoutPolicy, error) {
|
||||||
existingPolicy, err := c.defaultPasswordLockoutPolicyWriteModelByID(ctx)
|
existingPolicy, err := c.defaultLockoutPolicyWriteModelByID(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
|
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
|
||||||
return nil, caos_errs.ThrowNotFound(nil, "IAM-0oPew", "Errors.IAM.PasswordLockoutPolicy.NotFound")
|
return nil, caos_errs.ThrowNotFound(nil, "IAM-0oPew", "Errors.IAM.LockoutPolicy.NotFound")
|
||||||
}
|
}
|
||||||
|
|
||||||
iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PasswordLockoutPolicyWriteModel.WriteModel)
|
iamAgg := IAMAggregateFromWriteModel(&existingPolicy.LockoutPolicyWriteModel.WriteModel)
|
||||||
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, iamAgg, policy.MaxAttempts, policy.ShowLockOutFailures)
|
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, iamAgg, policy.MaxPasswordAttempts, policy.ShowLockOutFailures)
|
||||||
if !hasChanged {
|
if !hasChanged {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9vs", "Errors.IAM.PasswordLockoutPolicy.NotChanged")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9vs", "Errors.IAM.LockoutPolicy.NotChanged")
|
||||||
}
|
}
|
||||||
|
|
||||||
pushedEvents, err := c.eventstore.PushEvents(ctx, changedEvent)
|
pushedEvents, err := c.eventstore.PushEvents(ctx, changedEvent)
|
||||||
@ -63,14 +63,14 @@ func (c *Commands) ChangeDefaultPasswordLockoutPolicy(ctx context.Context, polic
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return writeModelToPasswordLockoutPolicy(&existingPolicy.PasswordLockoutPolicyWriteModel), nil
|
return writeModelToLockoutPolicy(&existingPolicy.LockoutPolicyWriteModel), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) defaultPasswordLockoutPolicyWriteModelByID(ctx context.Context) (policy *IAMPasswordLockoutPolicyWriteModel, err error) {
|
func (c *Commands) defaultLockoutPolicyWriteModelByID(ctx context.Context) (policy *IAMLockoutPolicyWriteModel, err error) {
|
||||||
ctx, span := tracing.NewSpan(ctx)
|
ctx, span := tracing.NewSpan(ctx)
|
||||||
defer func() { span.EndWithError(err) }()
|
defer func() { span.EndWithError(err) }()
|
||||||
|
|
||||||
writeModel := NewIAMPasswordLockoutPolicyWriteModel()
|
writeModel := NewIAMLockoutPolicyWriteModel()
|
||||||
err = c.eventstore.FilterToQueryReducer(ctx, writeModel)
|
err = c.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -10,13 +10,13 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/repository/policy"
|
"github.com/caos/zitadel/internal/repository/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
type IAMPasswordLockoutPolicyWriteModel struct {
|
type IAMLockoutPolicyWriteModel struct {
|
||||||
PasswordLockoutPolicyWriteModel
|
LockoutPolicyWriteModel
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIAMPasswordLockoutPolicyWriteModel() *IAMPasswordLockoutPolicyWriteModel {
|
func NewIAMLockoutPolicyWriteModel() *IAMLockoutPolicyWriteModel {
|
||||||
return &IAMPasswordLockoutPolicyWriteModel{
|
return &IAMLockoutPolicyWriteModel{
|
||||||
PasswordLockoutPolicyWriteModel{
|
LockoutPolicyWriteModel{
|
||||||
WriteModel: eventstore.WriteModel{
|
WriteModel: eventstore.WriteModel{
|
||||||
AggregateID: domain.IAMID,
|
AggregateID: domain.IAMID,
|
||||||
ResourceOwner: domain.IAMID,
|
ResourceOwner: domain.IAMID,
|
||||||
@ -25,40 +25,40 @@ func NewIAMPasswordLockoutPolicyWriteModel() *IAMPasswordLockoutPolicyWriteModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *IAMPasswordLockoutPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
func (wm *IAMLockoutPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *iam.PasswordLockoutPolicyAddedEvent:
|
case *iam.LockoutPolicyAddedEvent:
|
||||||
wm.PasswordLockoutPolicyWriteModel.AppendEvents(&e.PasswordLockoutPolicyAddedEvent)
|
wm.LockoutPolicyWriteModel.AppendEvents(&e.LockoutPolicyAddedEvent)
|
||||||
case *iam.PasswordLockoutPolicyChangedEvent:
|
case *iam.LockoutPolicyChangedEvent:
|
||||||
wm.PasswordLockoutPolicyWriteModel.AppendEvents(&e.PasswordLockoutPolicyChangedEvent)
|
wm.LockoutPolicyWriteModel.AppendEvents(&e.LockoutPolicyChangedEvent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *IAMPasswordLockoutPolicyWriteModel) Reduce() error {
|
func (wm *IAMLockoutPolicyWriteModel) Reduce() error {
|
||||||
return wm.PasswordLockoutPolicyWriteModel.Reduce()
|
return wm.LockoutPolicyWriteModel.Reduce()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *IAMPasswordLockoutPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
|
func (wm *IAMLockoutPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||||
ResourceOwner(wm.ResourceOwner).
|
ResourceOwner(wm.ResourceOwner).
|
||||||
AddQuery().
|
AddQuery().
|
||||||
AggregateTypes(iam.AggregateType).
|
AggregateTypes(iam.AggregateType).
|
||||||
AggregateIDs(wm.PasswordLockoutPolicyWriteModel.AggregateID).
|
AggregateIDs(wm.LockoutPolicyWriteModel.AggregateID).
|
||||||
EventTypes(
|
EventTypes(
|
||||||
iam.PasswordLockoutPolicyAddedEventType,
|
iam.LockoutPolicyAddedEventType,
|
||||||
iam.PasswordLockoutPolicyChangedEventType).
|
iam.LockoutPolicyChangedEventType).
|
||||||
Builder()
|
Builder()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *IAMPasswordLockoutPolicyWriteModel) NewChangedEvent(
|
func (wm *IAMLockoutPolicyWriteModel) NewChangedEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
aggregate *eventstore.Aggregate,
|
aggregate *eventstore.Aggregate,
|
||||||
maxAttempts uint64,
|
maxAttempts uint64,
|
||||||
showLockoutFailure bool) (*iam.PasswordLockoutPolicyChangedEvent, bool) {
|
showLockoutFailure bool) (*iam.LockoutPolicyChangedEvent, bool) {
|
||||||
changes := make([]policy.PasswordLockoutPolicyChanges, 0)
|
changes := make([]policy.LockoutPolicyChanges, 0)
|
||||||
if wm.MaxAttempts != maxAttempts {
|
if wm.MaxPasswordAttempts != maxAttempts {
|
||||||
changes = append(changes, policy.ChangeMaxAttempts(maxAttempts))
|
changes = append(changes, policy.ChangeMaxAttempts(maxAttempts))
|
||||||
}
|
}
|
||||||
if wm.ShowLockOutFailures != showLockoutFailure {
|
if wm.ShowLockOutFailures != showLockoutFailure {
|
||||||
@ -67,7 +67,7 @@ func (wm *IAMPasswordLockoutPolicyWriteModel) NewChangedEvent(
|
|||||||
if len(changes) == 0 {
|
if len(changes) == 0 {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
changedEvent, err := iam.NewPasswordLockoutPolicyChangedEvent(ctx, aggregate, changes)
|
changedEvent, err := iam.NewLockoutPolicyChangedEvent(ctx, aggregate, changes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
@ -13,16 +13,16 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCommandSide_AddDefaultPasswordLockoutPolicy(t *testing.T) {
|
func TestCommandSide_AddDefaultLockoutPolicy(t *testing.T) {
|
||||||
type fields struct {
|
type fields struct {
|
||||||
eventstore *eventstore.Eventstore
|
eventstore *eventstore.Eventstore
|
||||||
}
|
}
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
policy *domain.PasswordLockoutPolicy
|
policy *domain.LockoutPolicy
|
||||||
}
|
}
|
||||||
type res struct {
|
type res struct {
|
||||||
want *domain.PasswordLockoutPolicy
|
want *domain.LockoutPolicy
|
||||||
err func(error) bool
|
err func(error) bool
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
@ -32,13 +32,13 @@ func TestCommandSide_AddDefaultPasswordLockoutPolicy(t *testing.T) {
|
|||||||
res res
|
res res
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "password lockout policy already existing, already exists error",
|
name: "lockout policy already existing, already exists error",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
eventstore: eventstoreExpect(
|
eventstore: eventstoreExpect(
|
||||||
t,
|
t,
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
iam.NewPasswordLockoutPolicyAddedEvent(context.Background(),
|
iam.NewLockoutPolicyAddedEvent(context.Background(),
|
||||||
&iam.NewAggregate().Aggregate,
|
&iam.NewAggregate().Aggregate,
|
||||||
10,
|
10,
|
||||||
true,
|
true,
|
||||||
@ -49,8 +49,8 @@ func TestCommandSide_AddDefaultPasswordLockoutPolicy(t *testing.T) {
|
|||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
policy: &domain.PasswordLockoutPolicy{
|
policy: &domain.LockoutPolicy{
|
||||||
MaxAttempts: 10,
|
MaxPasswordAttempts: 10,
|
||||||
ShowLockOutFailures: true,
|
ShowLockOutFailures: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -67,7 +67,7 @@ func TestCommandSide_AddDefaultPasswordLockoutPolicy(t *testing.T) {
|
|||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
iam.NewPasswordLockoutPolicyAddedEvent(context.Background(),
|
iam.NewLockoutPolicyAddedEvent(context.Background(),
|
||||||
&iam.NewAggregate().Aggregate,
|
&iam.NewAggregate().Aggregate,
|
||||||
10,
|
10,
|
||||||
true,
|
true,
|
||||||
@ -79,18 +79,18 @@ func TestCommandSide_AddDefaultPasswordLockoutPolicy(t *testing.T) {
|
|||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
policy: &domain.PasswordLockoutPolicy{
|
policy: &domain.LockoutPolicy{
|
||||||
MaxAttempts: 10,
|
MaxPasswordAttempts: 10,
|
||||||
ShowLockOutFailures: true,
|
ShowLockOutFailures: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
want: &domain.PasswordLockoutPolicy{
|
want: &domain.LockoutPolicy{
|
||||||
ObjectRoot: models.ObjectRoot{
|
ObjectRoot: models.ObjectRoot{
|
||||||
AggregateID: "IAM",
|
AggregateID: "IAM",
|
||||||
ResourceOwner: "IAM",
|
ResourceOwner: "IAM",
|
||||||
},
|
},
|
||||||
MaxAttempts: 10,
|
MaxPasswordAttempts: 10,
|
||||||
ShowLockOutFailures: true,
|
ShowLockOutFailures: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -101,7 +101,7 @@ func TestCommandSide_AddDefaultPasswordLockoutPolicy(t *testing.T) {
|
|||||||
r := &Commands{
|
r := &Commands{
|
||||||
eventstore: tt.fields.eventstore,
|
eventstore: tt.fields.eventstore,
|
||||||
}
|
}
|
||||||
got, err := r.AddDefaultPasswordLockoutPolicy(tt.args.ctx, tt.args.policy)
|
got, err := r.AddDefaultLockoutPolicy(tt.args.ctx, tt.args.policy)
|
||||||
if tt.res.err == nil {
|
if tt.res.err == nil {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
@ -115,16 +115,16 @@ func TestCommandSide_AddDefaultPasswordLockoutPolicy(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
|
func TestCommandSide_ChangeDefaultLockoutPolicy(t *testing.T) {
|
||||||
type fields struct {
|
type fields struct {
|
||||||
eventstore *eventstore.Eventstore
|
eventstore *eventstore.Eventstore
|
||||||
}
|
}
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
policy *domain.PasswordLockoutPolicy
|
policy *domain.LockoutPolicy
|
||||||
}
|
}
|
||||||
type res struct {
|
type res struct {
|
||||||
want *domain.PasswordLockoutPolicy
|
want *domain.LockoutPolicy
|
||||||
err func(error) bool
|
err func(error) bool
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
@ -134,7 +134,7 @@ func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
|
|||||||
res res
|
res res
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "password lockout policy not existing, not found error",
|
name: "lockout policy not existing, not found error",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
eventstore: eventstoreExpect(
|
eventstore: eventstoreExpect(
|
||||||
t,
|
t,
|
||||||
@ -143,8 +143,8 @@ func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
|
|||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
policy: &domain.PasswordLockoutPolicy{
|
policy: &domain.LockoutPolicy{
|
||||||
MaxAttempts: 10,
|
MaxPasswordAttempts: 10,
|
||||||
ShowLockOutFailures: true,
|
ShowLockOutFailures: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -159,7 +159,7 @@ func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
|
|||||||
t,
|
t,
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
iam.NewPasswordLockoutPolicyAddedEvent(context.Background(),
|
iam.NewLockoutPolicyAddedEvent(context.Background(),
|
||||||
&iam.NewAggregate().Aggregate,
|
&iam.NewAggregate().Aggregate,
|
||||||
10,
|
10,
|
||||||
true,
|
true,
|
||||||
@ -170,8 +170,8 @@ func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
|
|||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
policy: &domain.PasswordLockoutPolicy{
|
policy: &domain.LockoutPolicy{
|
||||||
MaxAttempts: 10,
|
MaxPasswordAttempts: 10,
|
||||||
ShowLockOutFailures: true,
|
ShowLockOutFailures: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -186,7 +186,7 @@ func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
|
|||||||
t,
|
t,
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
iam.NewPasswordLockoutPolicyAddedEvent(context.Background(),
|
iam.NewLockoutPolicyAddedEvent(context.Background(),
|
||||||
&iam.NewAggregate().Aggregate,
|
&iam.NewAggregate().Aggregate,
|
||||||
10,
|
10,
|
||||||
true,
|
true,
|
||||||
@ -196,7 +196,7 @@ func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
|
|||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
newDefaultPasswordLockoutPolicyChangedEvent(context.Background(), 20, false),
|
newDefaultLockoutPolicyChangedEvent(context.Background(), 20, false),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -204,18 +204,18 @@ func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
|
|||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
policy: &domain.PasswordLockoutPolicy{
|
policy: &domain.LockoutPolicy{
|
||||||
MaxAttempts: 20,
|
MaxPasswordAttempts: 20,
|
||||||
ShowLockOutFailures: false,
|
ShowLockOutFailures: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
want: &domain.PasswordLockoutPolicy{
|
want: &domain.LockoutPolicy{
|
||||||
ObjectRoot: models.ObjectRoot{
|
ObjectRoot: models.ObjectRoot{
|
||||||
AggregateID: "IAM",
|
AggregateID: "IAM",
|
||||||
ResourceOwner: "IAM",
|
ResourceOwner: "IAM",
|
||||||
},
|
},
|
||||||
MaxAttempts: 20,
|
MaxPasswordAttempts: 20,
|
||||||
ShowLockOutFailures: false,
|
ShowLockOutFailures: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -226,7 +226,7 @@ func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
|
|||||||
r := &Commands{
|
r := &Commands{
|
||||||
eventstore: tt.fields.eventstore,
|
eventstore: tt.fields.eventstore,
|
||||||
}
|
}
|
||||||
got, err := r.ChangeDefaultPasswordLockoutPolicy(tt.args.ctx, tt.args.policy)
|
got, err := r.ChangeDefaultLockoutPolicy(tt.args.ctx, tt.args.policy)
|
||||||
if tt.res.err == nil {
|
if tt.res.err == nil {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
@ -240,10 +240,10 @@ func TestCommandSide_ChangeDefaultPasswordLockoutPolicy(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDefaultPasswordLockoutPolicyChangedEvent(ctx context.Context, maxAttempts uint64, showLockoutFailure bool) *iam.PasswordLockoutPolicyChangedEvent {
|
func newDefaultLockoutPolicyChangedEvent(ctx context.Context, maxAttempts uint64, showLockoutFailure bool) *iam.LockoutPolicyChangedEvent {
|
||||||
event, _ := iam.NewPasswordLockoutPolicyChangedEvent(ctx,
|
event, _ := iam.NewLockoutPolicyChangedEvent(ctx,
|
||||||
&iam.NewAggregate().Aggregate,
|
&iam.NewAggregate().Aggregate,
|
||||||
[]policy.PasswordLockoutPolicyChanges{
|
[]policy.LockoutPolicyChanges{
|
||||||
policy.ChangeMaxAttempts(maxAttempts),
|
policy.ChangeMaxAttempts(maxAttempts),
|
||||||
policy.ChangeShowLockOutFailures(showLockoutFailure),
|
policy.ChangeShowLockOutFailures(showLockoutFailure),
|
||||||
},
|
},
|
||||||
|
@ -7,21 +7,21 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/repository/org"
|
"github.com/caos/zitadel/internal/repository/org"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Commands) AddPasswordLockoutPolicy(ctx context.Context, resourceOwner string, policy *domain.PasswordLockoutPolicy) (*domain.PasswordLockoutPolicy, error) {
|
func (c *Commands) AddLockoutPolicy(ctx context.Context, resourceOwner string, policy *domain.LockoutPolicy) (*domain.LockoutPolicy, error) {
|
||||||
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 := NewOrgPasswordLockoutPolicyWriteModel(resourceOwner)
|
addedPolicy := NewOrgLockoutPolicyWriteModel(resourceOwner)
|
||||||
err := c.eventstore.FilterToQueryReducer(ctx, addedPolicy)
|
err := c.eventstore.FilterToQueryReducer(ctx, addedPolicy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if addedPolicy.State == domain.PolicyStateActive {
|
if addedPolicy.State == domain.PolicyStateActive {
|
||||||
return nil, caos_errs.ThrowAlreadyExists(nil, "ORG-0olDf", "Errors.ORG.PasswordLockoutPolicy.AlreadyExists")
|
return nil, caos_errs.ThrowAlreadyExists(nil, "ORG-0olDf", "Errors.ORG.LockoutPolicy.AlreadyExists")
|
||||||
}
|
}
|
||||||
|
|
||||||
orgAgg := OrgAggregateFromWriteModel(&addedPolicy.WriteModel)
|
orgAgg := OrgAggregateFromWriteModel(&addedPolicy.WriteModel)
|
||||||
pushedEvents, err := c.eventstore.PushEvents(ctx, org.NewPasswordLockoutPolicyAddedEvent(ctx, orgAgg, policy.MaxAttempts, policy.ShowLockOutFailures))
|
pushedEvents, err := c.eventstore.PushEvents(ctx, org.NewLockoutPolicyAddedEvent(ctx, orgAgg, policy.MaxPasswordAttempts, policy.ShowLockOutFailures))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -29,26 +29,26 @@ func (c *Commands) AddPasswordLockoutPolicy(ctx context.Context, resourceOwner s
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return writeModelToPasswordLockoutPolicy(&addedPolicy.PasswordLockoutPolicyWriteModel), nil
|
return writeModelToLockoutPolicy(&addedPolicy.LockoutPolicyWriteModel), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) ChangePasswordLockoutPolicy(ctx context.Context, resourceOwner string, policy *domain.PasswordLockoutPolicy) (*domain.PasswordLockoutPolicy, error) {
|
func (c *Commands) ChangeLockoutPolicy(ctx context.Context, resourceOwner string, policy *domain.LockoutPolicy) (*domain.LockoutPolicy, error) {
|
||||||
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 := NewOrgPasswordLockoutPolicyWriteModel(resourceOwner)
|
existingPolicy := NewOrgLockoutPolicyWriteModel(resourceOwner)
|
||||||
err := c.eventstore.FilterToQueryReducer(ctx, existingPolicy)
|
err := c.eventstore.FilterToQueryReducer(ctx, existingPolicy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
|
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
|
||||||
return nil, caos_errs.ThrowNotFound(nil, "ORG-ADfs1", "Errors.Org.PasswordLockoutPolicy.NotFound")
|
return nil, caos_errs.ThrowNotFound(nil, "ORG-ADfs1", "Errors.Org.LockoutPolicy.NotFound")
|
||||||
}
|
}
|
||||||
|
|
||||||
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PasswordLockoutPolicyWriteModel.WriteModel)
|
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LockoutPolicyWriteModel.WriteModel)
|
||||||
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.MaxAttempts, policy.ShowLockOutFailures)
|
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.MaxPasswordAttempts, policy.ShowLockOutFailures)
|
||||||
if !hasChanged {
|
if !hasChanged {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "ORG-4M9vs", "Errors.Org.PasswordLockoutPolicy.NotChanged")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "ORG-4M9vs", "Errors.Org.LockoutPolicy.NotChanged")
|
||||||
}
|
}
|
||||||
|
|
||||||
pushedEvents, err := c.eventstore.PushEvents(ctx, changedEvent)
|
pushedEvents, err := c.eventstore.PushEvents(ctx, changedEvent)
|
||||||
@ -59,23 +59,23 @@ func (c *Commands) ChangePasswordLockoutPolicy(ctx context.Context, resourceOwne
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return writeModelToPasswordLockoutPolicy(&existingPolicy.PasswordLockoutPolicyWriteModel), nil
|
return writeModelToLockoutPolicy(&existingPolicy.LockoutPolicyWriteModel), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) RemovePasswordLockoutPolicy(ctx context.Context, orgID string) error {
|
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 := NewOrgPasswordLockoutPolicyWriteModel(orgID)
|
existingPolicy := NewOrgLockoutPolicyWriteModel(orgID)
|
||||||
err := c.eventstore.FilterToQueryReducer(ctx, existingPolicy)
|
err := c.eventstore.FilterToQueryReducer(ctx, existingPolicy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
|
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
|
||||||
return caos_errs.ThrowNotFound(nil, "ORG-D4zuz", "Errors.Org.PasswordLockoutPolicy.NotFound")
|
return caos_errs.ThrowNotFound(nil, "ORG-D4zuz", "Errors.Org.LockoutPolicy.NotFound")
|
||||||
}
|
}
|
||||||
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.WriteModel)
|
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.WriteModel)
|
||||||
|
|
||||||
_, err = c.eventstore.PushEvents(ctx, org.NewPasswordLockoutPolicyRemovedEvent(ctx, orgAgg))
|
_, err = c.eventstore.PushEvents(ctx, org.NewLockoutPolicyRemovedEvent(ctx, orgAgg))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,13 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/repository/policy"
|
"github.com/caos/zitadel/internal/repository/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
type OrgPasswordLockoutPolicyWriteModel struct {
|
type OrgLockoutPolicyWriteModel struct {
|
||||||
PasswordLockoutPolicyWriteModel
|
LockoutPolicyWriteModel
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOrgPasswordLockoutPolicyWriteModel(orgID string) *OrgPasswordLockoutPolicyWriteModel {
|
func NewOrgLockoutPolicyWriteModel(orgID string) *OrgLockoutPolicyWriteModel {
|
||||||
return &OrgPasswordLockoutPolicyWriteModel{
|
return &OrgLockoutPolicyWriteModel{
|
||||||
PasswordLockoutPolicyWriteModel{
|
LockoutPolicyWriteModel{
|
||||||
WriteModel: eventstore.WriteModel{
|
WriteModel: eventstore.WriteModel{
|
||||||
AggregateID: orgID,
|
AggregateID: orgID,
|
||||||
ResourceOwner: orgID,
|
ResourceOwner: orgID,
|
||||||
@ -24,42 +24,42 @@ func NewOrgPasswordLockoutPolicyWriteModel(orgID string) *OrgPasswordLockoutPoli
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *OrgPasswordLockoutPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
func (wm *OrgLockoutPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *org.PasswordLockoutPolicyAddedEvent:
|
case *org.LockoutPolicyAddedEvent:
|
||||||
wm.PasswordLockoutPolicyWriteModel.AppendEvents(&e.PasswordLockoutPolicyAddedEvent)
|
wm.LockoutPolicyWriteModel.AppendEvents(&e.LockoutPolicyAddedEvent)
|
||||||
case *org.PasswordLockoutPolicyChangedEvent:
|
case *org.LockoutPolicyChangedEvent:
|
||||||
wm.PasswordLockoutPolicyWriteModel.AppendEvents(&e.PasswordLockoutPolicyChangedEvent)
|
wm.LockoutPolicyWriteModel.AppendEvents(&e.LockoutPolicyChangedEvent)
|
||||||
case *org.PasswordLockoutPolicyRemovedEvent:
|
case *org.LockoutPolicyRemovedEvent:
|
||||||
wm.PasswordLockoutPolicyWriteModel.AppendEvents(&e.PasswordLockoutPolicyRemovedEvent)
|
wm.LockoutPolicyWriteModel.AppendEvents(&e.LockoutPolicyRemovedEvent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *OrgPasswordLockoutPolicyWriteModel) Reduce() error {
|
func (wm *OrgLockoutPolicyWriteModel) Reduce() error {
|
||||||
return wm.PasswordLockoutPolicyWriteModel.Reduce()
|
return wm.LockoutPolicyWriteModel.Reduce()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *OrgPasswordLockoutPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
|
func (wm *OrgLockoutPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||||
ResourceOwner(wm.ResourceOwner).
|
ResourceOwner(wm.ResourceOwner).
|
||||||
AddQuery().
|
AddQuery().
|
||||||
AggregateTypes(org.AggregateType).
|
AggregateTypes(org.AggregateType).
|
||||||
AggregateIDs(wm.PasswordLockoutPolicyWriteModel.AggregateID).
|
AggregateIDs(wm.LockoutPolicyWriteModel.AggregateID).
|
||||||
EventTypes(org.PasswordLockoutPolicyAddedEventType,
|
EventTypes(org.LockoutPolicyAddedEventType,
|
||||||
org.PasswordLockoutPolicyChangedEventType,
|
org.LockoutPolicyChangedEventType,
|
||||||
org.PasswordLockoutPolicyRemovedEventType).
|
org.LockoutPolicyRemovedEventType).
|
||||||
Builder()
|
Builder()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *OrgPasswordLockoutPolicyWriteModel) NewChangedEvent(
|
func (wm *OrgLockoutPolicyWriteModel) NewChangedEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
aggregate *eventstore.Aggregate,
|
aggregate *eventstore.Aggregate,
|
||||||
maxAttempts uint64,
|
maxAttempts uint64,
|
||||||
showLockoutFailure bool) (*org.PasswordLockoutPolicyChangedEvent, bool) {
|
showLockoutFailure bool) (*org.LockoutPolicyChangedEvent, bool) {
|
||||||
changes := make([]policy.PasswordLockoutPolicyChanges, 0)
|
changes := make([]policy.LockoutPolicyChanges, 0)
|
||||||
if wm.MaxAttempts != maxAttempts {
|
if wm.MaxPasswordAttempts != maxAttempts {
|
||||||
changes = append(changes, policy.ChangeMaxAttempts(maxAttempts))
|
changes = append(changes, policy.ChangeMaxAttempts(maxAttempts))
|
||||||
}
|
}
|
||||||
if wm.ShowLockOutFailures != showLockoutFailure {
|
if wm.ShowLockOutFailures != showLockoutFailure {
|
||||||
@ -68,7 +68,7 @@ func (wm *OrgPasswordLockoutPolicyWriteModel) NewChangedEvent(
|
|||||||
if len(changes) == 0 {
|
if len(changes) == 0 {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
changedEvent, err := org.NewPasswordLockoutPolicyChangedEvent(ctx, aggregate, changes)
|
changedEvent, err := org.NewLockoutPolicyChangedEvent(ctx, aggregate, changes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,10 @@ func TestCommandSide_AddPasswordLockoutPolicy(t *testing.T) {
|
|||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
orgID string
|
orgID string
|
||||||
policy *domain.PasswordLockoutPolicy
|
policy *domain.LockoutPolicy
|
||||||
}
|
}
|
||||||
type res struct {
|
type res struct {
|
||||||
want *domain.PasswordLockoutPolicy
|
want *domain.LockoutPolicy
|
||||||
err func(error) bool
|
err func(error) bool
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
@ -43,8 +43,8 @@ func TestCommandSide_AddPasswordLockoutPolicy(t *testing.T) {
|
|||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
policy: &domain.PasswordLockoutPolicy{
|
policy: &domain.LockoutPolicy{
|
||||||
MaxAttempts: 10,
|
MaxPasswordAttempts: 10,
|
||||||
ShowLockOutFailures: true,
|
ShowLockOutFailures: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -59,7 +59,7 @@ func TestCommandSide_AddPasswordLockoutPolicy(t *testing.T) {
|
|||||||
t,
|
t,
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
org.NewPasswordLockoutPolicyAddedEvent(context.Background(),
|
org.NewLockoutPolicyAddedEvent(context.Background(),
|
||||||
&org.NewAggregate("org1", "org1").Aggregate,
|
&org.NewAggregate("org1", "org1").Aggregate,
|
||||||
10,
|
10,
|
||||||
true,
|
true,
|
||||||
@ -71,8 +71,8 @@ func TestCommandSide_AddPasswordLockoutPolicy(t *testing.T) {
|
|||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
orgID: "org1",
|
orgID: "org1",
|
||||||
policy: &domain.PasswordLockoutPolicy{
|
policy: &domain.LockoutPolicy{
|
||||||
MaxAttempts: 10,
|
MaxPasswordAttempts: 10,
|
||||||
ShowLockOutFailures: true,
|
ShowLockOutFailures: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -89,7 +89,7 @@ func TestCommandSide_AddPasswordLockoutPolicy(t *testing.T) {
|
|||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
org.NewPasswordLockoutPolicyAddedEvent(context.Background(),
|
org.NewLockoutPolicyAddedEvent(context.Background(),
|
||||||
&org.NewAggregate("org1", "org1").Aggregate,
|
&org.NewAggregate("org1", "org1").Aggregate,
|
||||||
10,
|
10,
|
||||||
true,
|
true,
|
||||||
@ -102,18 +102,18 @@ func TestCommandSide_AddPasswordLockoutPolicy(t *testing.T) {
|
|||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
orgID: "org1",
|
orgID: "org1",
|
||||||
policy: &domain.PasswordLockoutPolicy{
|
policy: &domain.LockoutPolicy{
|
||||||
MaxAttempts: 10,
|
MaxPasswordAttempts: 10,
|
||||||
ShowLockOutFailures: true,
|
ShowLockOutFailures: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
want: &domain.PasswordLockoutPolicy{
|
want: &domain.LockoutPolicy{
|
||||||
ObjectRoot: models.ObjectRoot{
|
ObjectRoot: models.ObjectRoot{
|
||||||
AggregateID: "org1",
|
AggregateID: "org1",
|
||||||
ResourceOwner: "org1",
|
ResourceOwner: "org1",
|
||||||
},
|
},
|
||||||
MaxAttempts: 10,
|
MaxPasswordAttempts: 10,
|
||||||
ShowLockOutFailures: true,
|
ShowLockOutFailures: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -124,7 +124,7 @@ func TestCommandSide_AddPasswordLockoutPolicy(t *testing.T) {
|
|||||||
r := &Commands{
|
r := &Commands{
|
||||||
eventstore: tt.fields.eventstore,
|
eventstore: tt.fields.eventstore,
|
||||||
}
|
}
|
||||||
got, err := r.AddPasswordLockoutPolicy(tt.args.ctx, tt.args.orgID, tt.args.policy)
|
got, err := r.AddLockoutPolicy(tt.args.ctx, tt.args.orgID, tt.args.policy)
|
||||||
if tt.res.err == nil {
|
if tt.res.err == nil {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
@ -145,10 +145,10 @@ func TestCommandSide_ChangePasswordLockoutPolicy(t *testing.T) {
|
|||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
orgID string
|
orgID string
|
||||||
policy *domain.PasswordLockoutPolicy
|
policy *domain.LockoutPolicy
|
||||||
}
|
}
|
||||||
type res struct {
|
type res struct {
|
||||||
want *domain.PasswordLockoutPolicy
|
want *domain.LockoutPolicy
|
||||||
err func(error) bool
|
err func(error) bool
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
@ -166,8 +166,8 @@ func TestCommandSide_ChangePasswordLockoutPolicy(t *testing.T) {
|
|||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
policy: &domain.PasswordLockoutPolicy{
|
policy: &domain.LockoutPolicy{
|
||||||
MaxAttempts: 10,
|
MaxPasswordAttempts: 10,
|
||||||
ShowLockOutFailures: true,
|
ShowLockOutFailures: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -186,8 +186,8 @@ func TestCommandSide_ChangePasswordLockoutPolicy(t *testing.T) {
|
|||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
orgID: "org1",
|
orgID: "org1",
|
||||||
policy: &domain.PasswordLockoutPolicy{
|
policy: &domain.LockoutPolicy{
|
||||||
MaxAttempts: 10,
|
MaxPasswordAttempts: 10,
|
||||||
ShowLockOutFailures: true,
|
ShowLockOutFailures: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -202,7 +202,7 @@ func TestCommandSide_ChangePasswordLockoutPolicy(t *testing.T) {
|
|||||||
t,
|
t,
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
org.NewPasswordLockoutPolicyAddedEvent(context.Background(),
|
org.NewLockoutPolicyAddedEvent(context.Background(),
|
||||||
&org.NewAggregate("org1", "org1").Aggregate,
|
&org.NewAggregate("org1", "org1").Aggregate,
|
||||||
10,
|
10,
|
||||||
true,
|
true,
|
||||||
@ -214,8 +214,8 @@ func TestCommandSide_ChangePasswordLockoutPolicy(t *testing.T) {
|
|||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
orgID: "org1",
|
orgID: "org1",
|
||||||
policy: &domain.PasswordLockoutPolicy{
|
policy: &domain.LockoutPolicy{
|
||||||
MaxAttempts: 10,
|
MaxPasswordAttempts: 10,
|
||||||
ShowLockOutFailures: true,
|
ShowLockOutFailures: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -230,7 +230,7 @@ func TestCommandSide_ChangePasswordLockoutPolicy(t *testing.T) {
|
|||||||
t,
|
t,
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
org.NewPasswordLockoutPolicyAddedEvent(context.Background(),
|
org.NewLockoutPolicyAddedEvent(context.Background(),
|
||||||
&org.NewAggregate("org1", "org1").Aggregate,
|
&org.NewAggregate("org1", "org1").Aggregate,
|
||||||
10,
|
10,
|
||||||
true,
|
true,
|
||||||
@ -249,18 +249,18 @@ func TestCommandSide_ChangePasswordLockoutPolicy(t *testing.T) {
|
|||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
orgID: "org1",
|
orgID: "org1",
|
||||||
policy: &domain.PasswordLockoutPolicy{
|
policy: &domain.LockoutPolicy{
|
||||||
MaxAttempts: 5,
|
MaxPasswordAttempts: 5,
|
||||||
ShowLockOutFailures: false,
|
ShowLockOutFailures: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
want: &domain.PasswordLockoutPolicy{
|
want: &domain.LockoutPolicy{
|
||||||
ObjectRoot: models.ObjectRoot{
|
ObjectRoot: models.ObjectRoot{
|
||||||
AggregateID: "org1",
|
AggregateID: "org1",
|
||||||
ResourceOwner: "org1",
|
ResourceOwner: "org1",
|
||||||
},
|
},
|
||||||
MaxAttempts: 5,
|
MaxPasswordAttempts: 5,
|
||||||
ShowLockOutFailures: false,
|
ShowLockOutFailures: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -271,7 +271,7 @@ func TestCommandSide_ChangePasswordLockoutPolicy(t *testing.T) {
|
|||||||
r := &Commands{
|
r := &Commands{
|
||||||
eventstore: tt.fields.eventstore,
|
eventstore: tt.fields.eventstore,
|
||||||
}
|
}
|
||||||
got, err := r.ChangePasswordLockoutPolicy(tt.args.ctx, tt.args.orgID, tt.args.policy)
|
got, err := r.ChangeLockoutPolicy(tt.args.ctx, tt.args.orgID, tt.args.policy)
|
||||||
if tt.res.err == nil {
|
if tt.res.err == nil {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
@ -340,7 +340,7 @@ func TestCommandSide_RemovePasswordLockoutPolicy(t *testing.T) {
|
|||||||
t,
|
t,
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
org.NewPasswordLockoutPolicyAddedEvent(context.Background(),
|
org.NewLockoutPolicyAddedEvent(context.Background(),
|
||||||
&org.NewAggregate("org1", "org1").Aggregate,
|
&org.NewAggregate("org1", "org1").Aggregate,
|
||||||
10,
|
10,
|
||||||
true,
|
true,
|
||||||
@ -350,7 +350,7 @@ func TestCommandSide_RemovePasswordLockoutPolicy(t *testing.T) {
|
|||||||
expectPush(
|
expectPush(
|
||||||
[]*repository.Event{
|
[]*repository.Event{
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
org.NewPasswordLockoutPolicyRemovedEvent(context.Background(),
|
org.NewLockoutPolicyRemovedEvent(context.Background(),
|
||||||
&org.NewAggregate("org1", "org1").Aggregate),
|
&org.NewAggregate("org1", "org1").Aggregate),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -373,7 +373,7 @@ func TestCommandSide_RemovePasswordLockoutPolicy(t *testing.T) {
|
|||||||
r := &Commands{
|
r := &Commands{
|
||||||
eventstore: tt.fields.eventstore,
|
eventstore: tt.fields.eventstore,
|
||||||
}
|
}
|
||||||
err := r.RemovePasswordLockoutPolicy(tt.args.ctx, tt.args.orgID)
|
err := r.RemoveLockoutPolicy(tt.args.ctx, tt.args.orgID)
|
||||||
if tt.res.err == nil {
|
if tt.res.err == nil {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
@ -384,10 +384,10 @@ func TestCommandSide_RemovePasswordLockoutPolicy(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPasswordLockoutPolicyChangedEvent(ctx context.Context, orgID string, maxAttempts uint64, showLockoutFailure bool) *org.PasswordLockoutPolicyChangedEvent {
|
func newPasswordLockoutPolicyChangedEvent(ctx context.Context, orgID string, maxAttempts uint64, showLockoutFailure bool) *org.LockoutPolicyChangedEvent {
|
||||||
event, _ := org.NewPasswordLockoutPolicyChangedEvent(ctx,
|
event, _ := org.NewLockoutPolicyChangedEvent(ctx,
|
||||||
&org.NewAggregate(orgID, orgID).Aggregate,
|
&org.NewAggregate(orgID, orgID).Aggregate,
|
||||||
[]policy.PasswordLockoutPolicyChanges{
|
[]policy.LockoutPolicyChanges{
|
||||||
policy.ChangeMaxAttempts(maxAttempts),
|
policy.ChangeMaxAttempts(maxAttempts),
|
||||||
policy.ChangeShowLockOutFailures(showLockoutFailure),
|
policy.ChangeShowLockOutFailures(showLockoutFailure),
|
||||||
},
|
},
|
||||||
|
@ -6,29 +6,29 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/repository/policy"
|
"github.com/caos/zitadel/internal/repository/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PasswordLockoutPolicyWriteModel struct {
|
type LockoutPolicyWriteModel struct {
|
||||||
eventstore.WriteModel
|
eventstore.WriteModel
|
||||||
|
|
||||||
MaxAttempts uint64
|
MaxPasswordAttempts uint64
|
||||||
ShowLockOutFailures bool
|
ShowLockOutFailures bool
|
||||||
State domain.PolicyState
|
State domain.PolicyState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *PasswordLockoutPolicyWriteModel) Reduce() error {
|
func (wm *LockoutPolicyWriteModel) Reduce() error {
|
||||||
for _, event := range wm.Events {
|
for _, event := range wm.Events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *policy.PasswordLockoutPolicyAddedEvent:
|
case *policy.LockoutPolicyAddedEvent:
|
||||||
wm.MaxAttempts = e.MaxAttempts
|
wm.MaxPasswordAttempts = e.MaxPasswordAttempts
|
||||||
wm.ShowLockOutFailures = e.ShowLockOutFailures
|
wm.ShowLockOutFailures = e.ShowLockOutFailures
|
||||||
wm.State = domain.PolicyStateActive
|
wm.State = domain.PolicyStateActive
|
||||||
case *policy.PasswordLockoutPolicyChangedEvent:
|
case *policy.LockoutPolicyChangedEvent:
|
||||||
if e.MaxAttempts != nil {
|
if e.MaxPasswordAttempts != nil {
|
||||||
wm.MaxAttempts = *e.MaxAttempts
|
wm.MaxPasswordAttempts = *e.MaxPasswordAttempts
|
||||||
}
|
}
|
||||||
if e.ShowLockOutFailures != nil {
|
if e.ShowLockOutFailures != nil {
|
||||||
wm.ShowLockOutFailures = *e.ShowLockOutFailures
|
wm.ShowLockOutFailures = *e.ShowLockOutFailures
|
||||||
}
|
}
|
||||||
case *policy.PasswordLockoutPolicyRemovedEvent:
|
case *policy.LockoutPolicyRemovedEvent:
|
||||||
wm.State = domain.PolicyStateRemoved
|
wm.State = domain.PolicyStateRemoved
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
35
internal/command/setup_step18.go
Normal file
35
internal/command/setup_step18.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/caos/logging"
|
||||||
|
"github.com/caos/zitadel/internal/domain"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Step18 struct {
|
||||||
|
LockoutPolicy domain.LockoutPolicy
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Step18) Step() domain.Step {
|
||||||
|
return domain.Step18
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Step18) execute(ctx context.Context, commandSide *Commands) error {
|
||||||
|
return commandSide.SetupStep18(ctx, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) SetupStep18(ctx context.Context, step *Step18) error {
|
||||||
|
fn := func(iam *IAMWriteModel) ([]eventstore.EventPusher, error) {
|
||||||
|
iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel)
|
||||||
|
addedPolicy := NewIAMLockoutPolicyWriteModel()
|
||||||
|
events, err := c.addDefaultLockoutPolicy(ctx, iamAgg, addedPolicy, &step.LockoutPolicy)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
logging.Log("SETUP-3m99ds").Info("default lockout policy set up")
|
||||||
|
return []eventstore.EventPusher{events}, nil
|
||||||
|
}
|
||||||
|
return c.setup(ctx, step, fn)
|
||||||
|
}
|
@ -3,15 +3,13 @@ package command
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/caos/logging"
|
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/eventstore"
|
"github.com/caos/zitadel/internal/eventstore"
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/domain"
|
"github.com/caos/zitadel/internal/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Step4 struct {
|
type Step4 struct {
|
||||||
DefaultPasswordLockoutPolicy domain.PasswordLockoutPolicy
|
DefaultPasswordLockoutPolicy domain.LockoutPolicy
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Step4) Step() domain.Step {
|
func (s *Step4) Step() domain.Step {
|
||||||
@ -21,19 +19,12 @@ func (s *Step4) Step() domain.Step {
|
|||||||
func (s *Step4) execute(ctx context.Context, commandSide *Commands) error {
|
func (s *Step4) execute(ctx context.Context, commandSide *Commands) error {
|
||||||
return commandSide.SetupStep4(ctx, s)
|
return commandSide.SetupStep4(ctx, s)
|
||||||
}
|
}
|
||||||
|
//This step should not be executed when a new instance is setup, because its not used anymore
|
||||||
|
//SetupStep4 is no op in favour of step 18.
|
||||||
|
//Password lockout policy is replaced by lockout policy
|
||||||
func (c *Commands) SetupStep4(ctx context.Context, step *Step4) error {
|
func (c *Commands) SetupStep4(ctx context.Context, step *Step4) error {
|
||||||
fn := func(iam *IAMWriteModel) ([]eventstore.EventPusher, error) {
|
fn := func(iam *IAMWriteModel) ([]eventstore.EventPusher, error) {
|
||||||
iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel)
|
return nil, nil
|
||||||
event, err := c.addDefaultPasswordLockoutPolicy(ctx, iamAgg, NewIAMPasswordLockoutPolicyWriteModel(), &domain.PasswordLockoutPolicy{
|
|
||||||
MaxAttempts: step.DefaultPasswordLockoutPolicy.MaxAttempts,
|
|
||||||
ShowLockOutFailures: step.DefaultPasswordLockoutPolicy.ShowLockOutFailures,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
logging.Log("SETUP-Bfnge").Info("default password lockout policy set up")
|
|
||||||
return []eventstore.EventPusher{event}, nil
|
|
||||||
}
|
}
|
||||||
return c.setup(ctx, step, fn)
|
return c.setup(ctx, step, fn)
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,7 @@ func (c *Commands) PasswordCodeSent(ctx context.Context, orgID, userID string) (
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) HumanCheckPassword(ctx context.Context, orgID, userID, password string, authRequest *domain.AuthRequest) (err error) {
|
func (c *Commands) HumanCheckPassword(ctx context.Context, orgID, userID, password string, authRequest *domain.AuthRequest, lockoutPolicy *domain.LockoutPolicy) (err error) {
|
||||||
ctx, span := tracing.NewSpan(ctx)
|
ctx, span := tracing.NewSpan(ctx)
|
||||||
defer func() { span.EndWithError(err) }()
|
defer func() { span.EndWithError(err) }()
|
||||||
|
|
||||||
@ -225,7 +225,15 @@ func (c *Commands) HumanCheckPassword(ctx context.Context, orgID, userID, passwo
|
|||||||
_, err = c.eventstore.PushEvents(ctx, user.NewHumanPasswordCheckSucceededEvent(ctx, userAgg, authRequestDomainToAuthRequestInfo(authRequest)))
|
_, err = c.eventstore.PushEvents(ctx, user.NewHumanPasswordCheckSucceededEvent(ctx, userAgg, authRequestDomainToAuthRequestInfo(authRequest)))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = c.eventstore.PushEvents(ctx, user.NewHumanPasswordCheckFailedEvent(ctx, userAgg, authRequestDomainToAuthRequestInfo(authRequest)))
|
events := make([]eventstore.EventPusher, 0)
|
||||||
|
events = append(events, user.NewHumanPasswordCheckFailedEvent(ctx, userAgg, authRequestDomainToAuthRequestInfo(authRequest)))
|
||||||
|
if lockoutPolicy != nil && lockoutPolicy.MaxPasswordAttempts > 0 {
|
||||||
|
if existingPassword.PasswordCheckFailedCount+1 >= lockoutPolicy.MaxPasswordAttempts {
|
||||||
|
events = append(events, user.NewUserLockedEvent(ctx, userAgg))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
_, err = c.eventstore.PushEvents(ctx, events...)
|
||||||
logging.Log("COMMAND-9fj7s").OnError(err).Error("error create password check failed event")
|
logging.Log("COMMAND-9fj7s").OnError(err).Error("error create password check failed event")
|
||||||
return caos_errs.ThrowInvalidArgument(nil, "COMMAND-452ad", "Errors.User.Password.Invalid")
|
return caos_errs.ThrowInvalidArgument(nil, "COMMAND-452ad", "Errors.User.Password.Invalid")
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,10 @@ type HumanPasswordWriteModel struct {
|
|||||||
Secret *crypto.CryptoValue
|
Secret *crypto.CryptoValue
|
||||||
SecretChangeRequired bool
|
SecretChangeRequired bool
|
||||||
|
|
||||||
Code *crypto.CryptoValue
|
Code *crypto.CryptoValue
|
||||||
CodeCreationDate time.Time
|
CodeCreationDate time.Time
|
||||||
CodeExpiry time.Duration
|
CodeExpiry time.Duration
|
||||||
|
PasswordCheckFailedCount uint64
|
||||||
|
|
||||||
UserState domain.UserState
|
UserState domain.UserState
|
||||||
}
|
}
|
||||||
@ -51,6 +52,7 @@ func (wm *HumanPasswordWriteModel) Reduce() error {
|
|||||||
wm.Secret = e.Secret
|
wm.Secret = e.Secret
|
||||||
wm.SecretChangeRequired = e.ChangeRequired
|
wm.SecretChangeRequired = e.ChangeRequired
|
||||||
wm.Code = nil
|
wm.Code = nil
|
||||||
|
wm.PasswordCheckFailedCount = 0
|
||||||
case *user.HumanPasswordCodeAddedEvent:
|
case *user.HumanPasswordCodeAddedEvent:
|
||||||
wm.Code = e.Code
|
wm.Code = e.Code
|
||||||
wm.CodeCreationDate = e.CreationDate()
|
wm.CodeCreationDate = e.CreationDate()
|
||||||
@ -59,6 +61,12 @@ func (wm *HumanPasswordWriteModel) Reduce() error {
|
|||||||
if wm.UserState == domain.UserStateInitial {
|
if wm.UserState == domain.UserStateInitial {
|
||||||
wm.UserState = domain.UserStateActive
|
wm.UserState = domain.UserStateActive
|
||||||
}
|
}
|
||||||
|
case *user.HumanPasswordCheckFailedEvent:
|
||||||
|
wm.PasswordCheckFailedCount += 1
|
||||||
|
case *user.HumanPasswordCheckSucceededEvent:
|
||||||
|
wm.PasswordCheckFailedCount = 0
|
||||||
|
case *user.UserUnlockedEvent:
|
||||||
|
wm.PasswordCheckFailedCount = 0
|
||||||
case *user.UserRemovedEvent:
|
case *user.UserRemovedEvent:
|
||||||
wm.UserState = domain.UserStateDeleted
|
wm.UserState = domain.UserStateDeleted
|
||||||
}
|
}
|
||||||
@ -78,14 +86,19 @@ func (wm *HumanPasswordWriteModel) Query() *eventstore.SearchQueryBuilder {
|
|||||||
user.HumanPasswordChangedType,
|
user.HumanPasswordChangedType,
|
||||||
user.HumanPasswordCodeAddedType,
|
user.HumanPasswordCodeAddedType,
|
||||||
user.HumanEmailVerifiedType,
|
user.HumanEmailVerifiedType,
|
||||||
|
user.HumanPasswordCheckFailedType,
|
||||||
|
user.HumanPasswordCheckSucceededType,
|
||||||
user.UserRemovedType,
|
user.UserRemovedType,
|
||||||
|
user.UserUnlockedType,
|
||||||
user.UserV1AddedType,
|
user.UserV1AddedType,
|
||||||
user.UserV1RegisteredType,
|
user.UserV1RegisteredType,
|
||||||
user.UserV1InitialCodeAddedType,
|
user.UserV1InitialCodeAddedType,
|
||||||
user.UserV1InitializedCheckSucceededType,
|
user.UserV1InitializedCheckSucceededType,
|
||||||
user.UserV1PasswordChangedType,
|
user.UserV1PasswordChangedType,
|
||||||
user.UserV1PasswordCodeAddedType,
|
user.UserV1PasswordCodeAddedType,
|
||||||
user.UserV1EmailVerifiedType).
|
user.UserV1EmailVerifiedType,
|
||||||
|
user.UserV1PasswordCheckFailedType,
|
||||||
|
user.UserV1PasswordCheckSucceededType).
|
||||||
Builder()
|
Builder()
|
||||||
|
|
||||||
if wm.ResourceOwner != "" {
|
if wm.ResourceOwner != "" {
|
||||||
|
@ -1082,6 +1082,7 @@ func TestCommandSide_CheckPassword(t *testing.T) {
|
|||||||
resourceOwner string
|
resourceOwner string
|
||||||
password string
|
password string
|
||||||
authReq *domain.AuthRequest
|
authReq *domain.AuthRequest
|
||||||
|
lockoutPolicy *domain.LockoutPolicy
|
||||||
}
|
}
|
||||||
type res struct {
|
type res struct {
|
||||||
err func(error) bool
|
err func(error) bool
|
||||||
@ -1177,7 +1178,7 @@ func TestCommandSide_CheckPassword(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "password not matching, precondition error",
|
name: "password not matching lockout policy not relevant, precondition error",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
eventstore: eventstoreExpect(
|
eventstore: eventstoreExpect(
|
||||||
t,
|
t,
|
||||||
@ -1238,6 +1239,82 @@ func TestCommandSide_CheckPassword(t *testing.T) {
|
|||||||
ID: "request1",
|
ID: "request1",
|
||||||
AgentID: "agent1",
|
AgentID: "agent1",
|
||||||
},
|
},
|
||||||
|
lockoutPolicy: &domain.LockoutPolicy{},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
err: caos_errs.IsErrorInvalidArgument,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "password not matching, max password attempts reached - user locked, precondition error",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(
|
||||||
|
t,
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
user.NewHumanAddedEvent(context.Background(),
|
||||||
|
&user.NewAggregate("user1", "org1").Aggregate,
|
||||||
|
"username",
|
||||||
|
"firstname",
|
||||||
|
"lastname",
|
||||||
|
"nickname",
|
||||||
|
"displayname",
|
||||||
|
language.German,
|
||||||
|
domain.GenderUnspecified,
|
||||||
|
"email@test.ch",
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
eventFromEventPusher(
|
||||||
|
user.NewHumanEmailVerifiedEvent(context.Background(),
|
||||||
|
&user.NewAggregate("user1", "org1").Aggregate,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
eventFromEventPusher(
|
||||||
|
user.NewHumanPasswordChangedEvent(context.Background(),
|
||||||
|
&user.NewAggregate("user1", "org1").Aggregate,
|
||||||
|
&crypto.CryptoValue{
|
||||||
|
CryptoType: crypto.TypeHash,
|
||||||
|
Algorithm: "hash",
|
||||||
|
KeyID: "",
|
||||||
|
Crypted: []byte("password"),
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
"")),
|
||||||
|
),
|
||||||
|
expectPush(
|
||||||
|
[]*repository.Event{
|
||||||
|
eventFromEventPusher(
|
||||||
|
user.NewHumanPasswordCheckFailedEvent(context.Background(),
|
||||||
|
&user.NewAggregate("user1", "org1").Aggregate,
|
||||||
|
&user.AuthRequestInfo{
|
||||||
|
ID: "request1",
|
||||||
|
UserAgentID: "agent1",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
eventFromEventPusher(
|
||||||
|
user.NewUserLockedEvent(context.Background(),
|
||||||
|
&user.NewAggregate("user1", "org1").Aggregate,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
userPasswordAlg: crypto.CreateMockHashAlg(gomock.NewController(t)),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
userID: "user1",
|
||||||
|
password: "password1",
|
||||||
|
resourceOwner: "org1",
|
||||||
|
authReq: &domain.AuthRequest{
|
||||||
|
ID: "request1",
|
||||||
|
AgentID: "agent1",
|
||||||
|
},
|
||||||
|
lockoutPolicy: &domain.LockoutPolicy{
|
||||||
|
MaxPasswordAttempts: 1,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
err: caos_errs.IsErrorInvalidArgument,
|
err: caos_errs.IsErrorInvalidArgument,
|
||||||
@ -1315,7 +1392,7 @@ func TestCommandSide_CheckPassword(t *testing.T) {
|
|||||||
eventstore: tt.fields.eventstore,
|
eventstore: tt.fields.eventstore,
|
||||||
userPasswordAlg: tt.fields.userPasswordAlg,
|
userPasswordAlg: tt.fields.userPasswordAlg,
|
||||||
}
|
}
|
||||||
err := r.HumanCheckPassword(tt.args.ctx, tt.args.resourceOwner, tt.args.userID, tt.args.password, tt.args.authReq)
|
err := r.HumanCheckPassword(tt.args.ctx, tt.args.resourceOwner, tt.args.userID, tt.args.password, tt.args.authReq, tt.args.lockoutPolicy)
|
||||||
if tt.res.err == nil {
|
if tt.res.err == nil {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ type AuthRequest struct {
|
|||||||
AllowedExternalIDPs []*IDPProvider
|
AllowedExternalIDPs []*IDPProvider
|
||||||
LabelPolicy *LabelPolicy
|
LabelPolicy *LabelPolicy
|
||||||
PrivacyPolicy *PrivacyPolicy
|
PrivacyPolicy *PrivacyPolicy
|
||||||
|
LockoutPolicy *LockoutPolicy
|
||||||
DefaultTranslations []*CustomText
|
DefaultTranslations []*CustomText
|
||||||
OrgTranslations []*CustomText
|
OrgTranslations []*CustomText
|
||||||
}
|
}
|
||||||
|
@ -22,5 +22,5 @@ type IAM struct {
|
|||||||
DefaultOrgIAMPolicy *OrgIAMPolicy
|
DefaultOrgIAMPolicy *OrgIAMPolicy
|
||||||
DefaultPasswordComplexityPolicy *PasswordComplexityPolicy
|
DefaultPasswordComplexityPolicy *PasswordComplexityPolicy
|
||||||
DefaultPasswordAgePolicy *PasswordAgePolicy
|
DefaultPasswordAgePolicy *PasswordAgePolicy
|
||||||
DefaultPasswordLockoutPolicy *PasswordLockoutPolicy
|
DefaultPasswordLockoutPolicy *LockoutPolicy
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ type Org struct {
|
|||||||
LabelPolicy *LabelPolicy
|
LabelPolicy *LabelPolicy
|
||||||
PasswordComplexityPolicy *PasswordComplexityPolicy
|
PasswordComplexityPolicy *PasswordComplexityPolicy
|
||||||
PasswordAgePolicy *PasswordAgePolicy
|
PasswordAgePolicy *PasswordAgePolicy
|
||||||
PasswordLockoutPolicy *PasswordLockoutPolicy
|
PasswordLockoutPolicy *LockoutPolicy
|
||||||
IDPs []*IDPConfig
|
IDPs []*IDPConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,9 +4,10 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PasswordLockoutPolicy struct {
|
type LockoutPolicy struct {
|
||||||
models.ObjectRoot
|
models.ObjectRoot
|
||||||
|
|
||||||
MaxAttempts uint64
|
Default bool
|
||||||
|
MaxPasswordAttempts uint64
|
||||||
ShowLockOutFailures bool
|
ShowLockOutFailures bool
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ const (
|
|||||||
Step15
|
Step15
|
||||||
Step16
|
Step16
|
||||||
Step17
|
Step17
|
||||||
|
Step18
|
||||||
//StepCount marks the the length of possible steps (StepCount-1 == last possible step)
|
//StepCount marks the the length of possible steps (StepCount-1 == last possible step)
|
||||||
StepCount
|
StepCount
|
||||||
)
|
)
|
||||||
|
@ -35,7 +35,7 @@ type IAM struct {
|
|||||||
DefaultOrgIAMPolicy *OrgIAMPolicy
|
DefaultOrgIAMPolicy *OrgIAMPolicy
|
||||||
DefaultPasswordComplexityPolicy *PasswordComplexityPolicy
|
DefaultPasswordComplexityPolicy *PasswordComplexityPolicy
|
||||||
DefaultPasswordAgePolicy *PasswordAgePolicy
|
DefaultPasswordAgePolicy *PasswordAgePolicy
|
||||||
DefaultPasswordLockoutPolicy *PasswordLockoutPolicy
|
DefaultLockoutPolicy *LockoutPolicy
|
||||||
DefaultMailTemplate *MailTemplate
|
DefaultMailTemplate *MailTemplate
|
||||||
DefaultMailTexts []*MailText
|
DefaultMailTexts []*MailText
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,10 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PasswordLockoutPolicy struct {
|
type LockoutPolicy struct {
|
||||||
models.ObjectRoot
|
models.ObjectRoot
|
||||||
|
|
||||||
State PolicyState
|
State PolicyState
|
||||||
MaxAttempts uint64
|
MaxPasswordAttempts uint64
|
||||||
ShowLockOutFailures bool
|
ShowLockOutFailures bool
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PasswordLockoutPolicyView struct {
|
type LockoutPolicyView struct {
|
||||||
AggregateID string
|
AggregateID string
|
||||||
MaxAttempts uint64
|
MaxPasswordAttempts uint64
|
||||||
ShowLockOutFailures bool
|
ShowLockOutFailures bool
|
||||||
Default bool
|
Default bool
|
||||||
|
|
||||||
@ -16,32 +16,32 @@ type PasswordLockoutPolicyView struct {
|
|||||||
Sequence uint64
|
Sequence uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
type PasswordLockoutPolicySearchRequest struct {
|
type LockoutPolicySearchRequest struct {
|
||||||
Offset uint64
|
Offset uint64
|
||||||
Limit uint64
|
Limit uint64
|
||||||
SortingColumn PasswordLockoutPolicySearchKey
|
SortingColumn LockoutPolicySearchKey
|
||||||
Asc bool
|
Asc bool
|
||||||
Queries []*PasswordLockoutPolicySearchQuery
|
Queries []*LockoutPolicySearchQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
type PasswordLockoutPolicySearchKey int32
|
type LockoutPolicySearchKey int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PasswordLockoutPolicySearchKeyUnspecified PasswordLockoutPolicySearchKey = iota
|
LockoutPolicySearchKeyUnspecified LockoutPolicySearchKey = iota
|
||||||
PasswordLockoutPolicySearchKeyAggregateID
|
LockoutPolicySearchKeyAggregateID
|
||||||
)
|
)
|
||||||
|
|
||||||
type PasswordLockoutPolicySearchQuery struct {
|
type LockoutPolicySearchQuery struct {
|
||||||
Key PasswordLockoutPolicySearchKey
|
Key LockoutPolicySearchKey
|
||||||
Method domain.SearchMethod
|
Method domain.SearchMethod
|
||||||
Value interface{}
|
Value interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type PasswordLockoutPolicySearchResponse struct {
|
type LockoutPolicySearchResponse struct {
|
||||||
Offset uint64
|
Offset uint64
|
||||||
Limit uint64
|
Limit uint64
|
||||||
TotalResult uint64
|
TotalResult uint64
|
||||||
Result []*PasswordLockoutPolicyView
|
Result []*LockoutPolicyView
|
||||||
Sequence uint64
|
Sequence uint64
|
||||||
Timestamp time.Time
|
Timestamp time.Time
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ type IAM struct {
|
|||||||
DefaultOrgIAMPolicy *OrgIAMPolicy `json:"-"`
|
DefaultOrgIAMPolicy *OrgIAMPolicy `json:"-"`
|
||||||
DefaultPasswordComplexityPolicy *PasswordComplexityPolicy `json:"-"`
|
DefaultPasswordComplexityPolicy *PasswordComplexityPolicy `json:"-"`
|
||||||
DefaultPasswordAgePolicy *PasswordAgePolicy `json:"-"`
|
DefaultPasswordAgePolicy *PasswordAgePolicy `json:"-"`
|
||||||
DefaultPasswordLockoutPolicy *PasswordLockoutPolicy `json:"-"`
|
DefaultLockoutPolicy *LockoutPolicy `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func IAMToModel(iam *IAM) *model.IAM {
|
func IAMToModel(iam *IAM) *model.IAM {
|
||||||
@ -66,8 +66,8 @@ func IAMToModel(iam *IAM) *model.IAM {
|
|||||||
if iam.DefaultPasswordAgePolicy != nil {
|
if iam.DefaultPasswordAgePolicy != nil {
|
||||||
converted.DefaultPasswordAgePolicy = PasswordAgePolicyToModel(iam.DefaultPasswordAgePolicy)
|
converted.DefaultPasswordAgePolicy = PasswordAgePolicyToModel(iam.DefaultPasswordAgePolicy)
|
||||||
}
|
}
|
||||||
if iam.DefaultPasswordLockoutPolicy != nil {
|
if iam.DefaultLockoutPolicy != nil {
|
||||||
converted.DefaultPasswordLockoutPolicy = PasswordLockoutPolicyToModel(iam.DefaultPasswordLockoutPolicy)
|
converted.DefaultLockoutPolicy = LockoutPolicyToModel(iam.DefaultLockoutPolicy)
|
||||||
}
|
}
|
||||||
if iam.DefaultOrgIAMPolicy != nil {
|
if iam.DefaultOrgIAMPolicy != nil {
|
||||||
converted.DefaultOrgIAMPolicy = OrgIAMPolicyToModel(iam.DefaultOrgIAMPolicy)
|
converted.DefaultOrgIAMPolicy = OrgIAMPolicyToModel(iam.DefaultOrgIAMPolicy)
|
||||||
@ -166,10 +166,10 @@ func (i *IAM) AppendEvent(event *es_models.Event) (err error) {
|
|||||||
return i.appendAddPasswordAgePolicyEvent(event)
|
return i.appendAddPasswordAgePolicyEvent(event)
|
||||||
case PasswordAgePolicyChanged:
|
case PasswordAgePolicyChanged:
|
||||||
return i.appendChangePasswordAgePolicyEvent(event)
|
return i.appendChangePasswordAgePolicyEvent(event)
|
||||||
case PasswordLockoutPolicyAdded:
|
case LockoutPolicyAdded:
|
||||||
return i.appendAddPasswordLockoutPolicyEvent(event)
|
return i.appendAddLockoutPolicyEvent(event)
|
||||||
case PasswordLockoutPolicyChanged:
|
case LockoutPolicyChanged:
|
||||||
return i.appendChangePasswordLockoutPolicyEvent(event)
|
return i.appendChangeLockoutPolicyEvent(event)
|
||||||
case OrgIAMPolicyAdded:
|
case OrgIAMPolicyAdded:
|
||||||
return i.appendAddOrgIAMPolicyEvent(event)
|
return i.appendAddOrgIAMPolicyEvent(event)
|
||||||
case OrgIAMPolicyChanged:
|
case OrgIAMPolicyChanged:
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/errors"
|
||||||
|
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||||
|
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LockoutPolicy struct {
|
||||||
|
es_models.ObjectRoot
|
||||||
|
|
||||||
|
State int32 `json:"-"`
|
||||||
|
MaxPasswordAttempts uint64 `json:"maxPasswordAttempts"`
|
||||||
|
ShowLockOutFailures bool `json:"showLockOutFailures"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func LockoutPolicyToModel(policy *LockoutPolicy) *iam_model.LockoutPolicy {
|
||||||
|
return &iam_model.LockoutPolicy{
|
||||||
|
ObjectRoot: policy.ObjectRoot,
|
||||||
|
State: iam_model.PolicyState(policy.State),
|
||||||
|
MaxPasswordAttempts: policy.MaxPasswordAttempts,
|
||||||
|
ShowLockOutFailures: policy.ShowLockOutFailures,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *LockoutPolicy) Changes(changed *LockoutPolicy) map[string]interface{} {
|
||||||
|
changes := make(map[string]interface{}, 2)
|
||||||
|
|
||||||
|
if p.MaxPasswordAttempts != changed.MaxPasswordAttempts {
|
||||||
|
changes["maxAttempts"] = changed.MaxPasswordAttempts
|
||||||
|
}
|
||||||
|
if p.ShowLockOutFailures != changed.ShowLockOutFailures {
|
||||||
|
changes["showLockOutFailures"] = changed.ShowLockOutFailures
|
||||||
|
}
|
||||||
|
return changes
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IAM) appendAddLockoutPolicyEvent(event *es_models.Event) error {
|
||||||
|
i.DefaultLockoutPolicy = new(LockoutPolicy)
|
||||||
|
err := i.DefaultLockoutPolicy.SetData(event)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
i.DefaultLockoutPolicy.ObjectRoot.CreationDate = event.CreationDate
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IAM) appendChangeLockoutPolicyEvent(event *es_models.Event) error {
|
||||||
|
return i.DefaultLockoutPolicy.SetData(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *LockoutPolicy) SetData(event *es_models.Event) error {
|
||||||
|
err := json.Unmarshal(event.Data, p)
|
||||||
|
if err != nil {
|
||||||
|
return errors.ThrowInternal(err, "EVENT-7JS9d", "unable to unmarshal data")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -8,8 +8,8 @@ import (
|
|||||||
|
|
||||||
func TestPasswordLockoutPolicyChanges(t *testing.T) {
|
func TestPasswordLockoutPolicyChanges(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
existing *PasswordLockoutPolicy
|
existing *LockoutPolicy
|
||||||
new *PasswordLockoutPolicy
|
new *LockoutPolicy
|
||||||
}
|
}
|
||||||
type res struct {
|
type res struct {
|
||||||
changesLen int
|
changesLen int
|
||||||
@ -22,8 +22,8 @@ func TestPasswordLockoutPolicyChanges(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "lockout policy all attributes change",
|
name: "lockout policy all attributes change",
|
||||||
args: args{
|
args: args{
|
||||||
existing: &PasswordLockoutPolicy{MaxAttempts: 365, ShowLockOutFailures: true},
|
existing: &LockoutPolicy{MaxPasswordAttempts: 365, ShowLockOutFailures: true},
|
||||||
new: &PasswordLockoutPolicy{MaxAttempts: 730, ShowLockOutFailures: false},
|
new: &LockoutPolicy{MaxPasswordAttempts: 730, ShowLockOutFailures: false},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
changesLen: 2,
|
changesLen: 2,
|
||||||
@ -32,8 +32,8 @@ func TestPasswordLockoutPolicyChanges(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "no changes",
|
name: "no changes",
|
||||||
args: args{
|
args: args{
|
||||||
existing: &PasswordLockoutPolicy{MaxAttempts: 10, ShowLockOutFailures: true},
|
existing: &LockoutPolicy{MaxPasswordAttempts: 10, ShowLockOutFailures: true},
|
||||||
new: &PasswordLockoutPolicy{MaxAttempts: 10, ShowLockOutFailures: true},
|
new: &LockoutPolicy{MaxPasswordAttempts: 10, ShowLockOutFailures: true},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
changesLen: 0,
|
changesLen: 0,
|
||||||
@ -53,7 +53,7 @@ func TestPasswordLockoutPolicyChanges(t *testing.T) {
|
|||||||
func TestAppendAddPasswordLockoutPolicyEvent(t *testing.T) {
|
func TestAppendAddPasswordLockoutPolicyEvent(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
iam *IAM
|
iam *IAM
|
||||||
policy *PasswordLockoutPolicy
|
policy *LockoutPolicy
|
||||||
event *es_models.Event
|
event *es_models.Event
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
@ -65,10 +65,10 @@ func TestAppendAddPasswordLockoutPolicyEvent(t *testing.T) {
|
|||||||
name: "append add password lockout policy event",
|
name: "append add password lockout policy event",
|
||||||
args: args{
|
args: args{
|
||||||
iam: new(IAM),
|
iam: new(IAM),
|
||||||
policy: &PasswordLockoutPolicy{MaxAttempts: 10, ShowLockOutFailures: true},
|
policy: &LockoutPolicy{MaxPasswordAttempts: 10, ShowLockOutFailures: true},
|
||||||
event: new(es_models.Event),
|
event: new(es_models.Event),
|
||||||
},
|
},
|
||||||
result: &IAM{DefaultPasswordLockoutPolicy: &PasswordLockoutPolicy{MaxAttempts: 10, ShowLockOutFailures: true}},
|
result: &IAM{DefaultLockoutPolicy: &LockoutPolicy{MaxPasswordAttempts: 10, ShowLockOutFailures: true}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@ -77,12 +77,12 @@ func TestAppendAddPasswordLockoutPolicyEvent(t *testing.T) {
|
|||||||
data, _ := json.Marshal(tt.args.policy)
|
data, _ := json.Marshal(tt.args.policy)
|
||||||
tt.args.event.Data = data
|
tt.args.event.Data = data
|
||||||
}
|
}
|
||||||
tt.args.iam.appendAddPasswordLockoutPolicyEvent(tt.args.event)
|
tt.args.iam.appendAddLockoutPolicyEvent(tt.args.event)
|
||||||
if tt.result.DefaultPasswordLockoutPolicy.MaxAttempts != tt.args.iam.DefaultPasswordLockoutPolicy.MaxAttempts {
|
if tt.result.DefaultLockoutPolicy.MaxPasswordAttempts != tt.args.iam.DefaultLockoutPolicy.MaxPasswordAttempts {
|
||||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultPasswordLockoutPolicy.MaxAttempts, tt.args.iam.DefaultPasswordLockoutPolicy.MaxAttempts)
|
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLockoutPolicy.MaxPasswordAttempts, tt.args.iam.DefaultLockoutPolicy.MaxPasswordAttempts)
|
||||||
}
|
}
|
||||||
if tt.result.DefaultPasswordLockoutPolicy.ShowLockOutFailures != tt.args.iam.DefaultPasswordLockoutPolicy.ShowLockOutFailures {
|
if tt.result.DefaultLockoutPolicy.ShowLockOutFailures != tt.args.iam.DefaultLockoutPolicy.ShowLockOutFailures {
|
||||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultPasswordLockoutPolicy.ShowLockOutFailures, tt.args.iam.DefaultPasswordLockoutPolicy.ShowLockOutFailures)
|
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLockoutPolicy.ShowLockOutFailures, tt.args.iam.DefaultLockoutPolicy.ShowLockOutFailures)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -91,7 +91,7 @@ func TestAppendAddPasswordLockoutPolicyEvent(t *testing.T) {
|
|||||||
func TestAppendChangePasswordLockoutPolicyEvent(t *testing.T) {
|
func TestAppendChangePasswordLockoutPolicyEvent(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
iam *IAM
|
iam *IAM
|
||||||
policy *PasswordLockoutPolicy
|
policy *LockoutPolicy
|
||||||
event *es_models.Event
|
event *es_models.Event
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
@ -102,14 +102,14 @@ func TestAppendChangePasswordLockoutPolicyEvent(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "append change password lockout policy event",
|
name: "append change password lockout policy event",
|
||||||
args: args{
|
args: args{
|
||||||
iam: &IAM{DefaultPasswordLockoutPolicy: &PasswordLockoutPolicy{
|
iam: &IAM{DefaultLockoutPolicy: &LockoutPolicy{
|
||||||
MaxAttempts: 10,
|
MaxPasswordAttempts: 10,
|
||||||
}},
|
}},
|
||||||
policy: &PasswordLockoutPolicy{MaxAttempts: 5},
|
policy: &LockoutPolicy{MaxPasswordAttempts: 5},
|
||||||
event: &es_models.Event{},
|
event: &es_models.Event{},
|
||||||
},
|
},
|
||||||
result: &IAM{DefaultPasswordLockoutPolicy: &PasswordLockoutPolicy{
|
result: &IAM{DefaultLockoutPolicy: &LockoutPolicy{
|
||||||
MaxAttempts: 5,
|
MaxPasswordAttempts: 5,
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -119,9 +119,9 @@ func TestAppendChangePasswordLockoutPolicyEvent(t *testing.T) {
|
|||||||
data, _ := json.Marshal(tt.args.policy)
|
data, _ := json.Marshal(tt.args.policy)
|
||||||
tt.args.event.Data = data
|
tt.args.event.Data = data
|
||||||
}
|
}
|
||||||
tt.args.iam.appendChangePasswordLockoutPolicyEvent(tt.args.event)
|
tt.args.iam.appendChangeLockoutPolicyEvent(tt.args.event)
|
||||||
if tt.result.DefaultPasswordLockoutPolicy.MaxAttempts != tt.args.iam.DefaultPasswordLockoutPolicy.MaxAttempts {
|
if tt.result.DefaultLockoutPolicy.MaxPasswordAttempts != tt.args.iam.DefaultLockoutPolicy.MaxPasswordAttempts {
|
||||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultPasswordLockoutPolicy.MaxAttempts, tt.args.iam.DefaultPasswordLockoutPolicy.MaxAttempts)
|
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLockoutPolicy.MaxPasswordAttempts, tt.args.iam.DefaultLockoutPolicy.MaxPasswordAttempts)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
@ -1,69 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/errors"
|
|
||||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PasswordLockoutPolicy struct {
|
|
||||||
es_models.ObjectRoot
|
|
||||||
|
|
||||||
State int32 `json:"-"`
|
|
||||||
MaxAttempts uint64 `json:"maxAttempts"`
|
|
||||||
ShowLockOutFailures bool `json:"showLockOutFailures"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func PasswordLockoutPolicyFromModel(policy *iam_model.PasswordLockoutPolicy) *PasswordLockoutPolicy {
|
|
||||||
return &PasswordLockoutPolicy{
|
|
||||||
ObjectRoot: policy.ObjectRoot,
|
|
||||||
State: int32(policy.State),
|
|
||||||
MaxAttempts: policy.MaxAttempts,
|
|
||||||
ShowLockOutFailures: policy.ShowLockOutFailures,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PasswordLockoutPolicyToModel(policy *PasswordLockoutPolicy) *iam_model.PasswordLockoutPolicy {
|
|
||||||
return &iam_model.PasswordLockoutPolicy{
|
|
||||||
ObjectRoot: policy.ObjectRoot,
|
|
||||||
State: iam_model.PolicyState(policy.State),
|
|
||||||
MaxAttempts: policy.MaxAttempts,
|
|
||||||
ShowLockOutFailures: policy.ShowLockOutFailures,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) Changes(changed *PasswordLockoutPolicy) map[string]interface{} {
|
|
||||||
changes := make(map[string]interface{}, 2)
|
|
||||||
|
|
||||||
if p.MaxAttempts != changed.MaxAttempts {
|
|
||||||
changes["maxAttempts"] = changed.MaxAttempts
|
|
||||||
}
|
|
||||||
if p.ShowLockOutFailures != changed.ShowLockOutFailures {
|
|
||||||
changes["showLockOutFailures"] = changed.ShowLockOutFailures
|
|
||||||
}
|
|
||||||
return changes
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *IAM) appendAddPasswordLockoutPolicyEvent(event *es_models.Event) error {
|
|
||||||
i.DefaultPasswordLockoutPolicy = new(PasswordLockoutPolicy)
|
|
||||||
err := i.DefaultPasswordLockoutPolicy.SetData(event)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
i.DefaultPasswordLockoutPolicy.ObjectRoot.CreationDate = event.CreationDate
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *IAM) appendChangePasswordLockoutPolicyEvent(event *es_models.Event) error {
|
|
||||||
return i.DefaultPasswordLockoutPolicy.SetData(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) SetData(event *es_models.Event) error {
|
|
||||||
err := json.Unmarshal(event.Data, p)
|
|
||||||
if err != nil {
|
|
||||||
return errors.ThrowInternal(err, "EVENT-7JS9d", "unable to unmarshal data")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -65,8 +65,8 @@ const (
|
|||||||
PasswordAgePolicyAdded models.EventType = "iam.policy.password.age.added"
|
PasswordAgePolicyAdded models.EventType = "iam.policy.password.age.added"
|
||||||
PasswordAgePolicyChanged models.EventType = "iam.policy.password.age.changed"
|
PasswordAgePolicyChanged models.EventType = "iam.policy.password.age.changed"
|
||||||
|
|
||||||
PasswordLockoutPolicyAdded models.EventType = "iam.policy.password.lockout.added"
|
LockoutPolicyAdded models.EventType = "iam.policy.lockout.added"
|
||||||
PasswordLockoutPolicyChanged models.EventType = "iam.policy.password.lockout.changed"
|
LockoutPolicyChanged models.EventType = "iam.policy.lockout.changed"
|
||||||
|
|
||||||
PrivacyPolicyAdded models.EventType = "iam.policy.privacy.added"
|
PrivacyPolicyAdded models.EventType = "iam.policy.privacy.added"
|
||||||
PrivacyPolicyChanged models.EventType = "iam.policy.privacy.changed"
|
PrivacyPolicyChanged models.EventType = "iam.policy.privacy.changed"
|
||||||
|
@ -2,6 +2,7 @@ package model
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/caos/zitadel/internal/domain"
|
||||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -14,65 +15,67 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PasswordLockoutKeyAggregateID = "aggregate_id"
|
LockoutKeyAggregateID = "aggregate_id"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PasswordLockoutPolicyView struct {
|
type LockoutPolicyView struct {
|
||||||
AggregateID string `json:"-" gorm:"column:aggregate_id;primary_key"`
|
AggregateID string `json:"-" gorm:"column:aggregate_id;primary_key"`
|
||||||
CreationDate time.Time `json:"-" gorm:"column:creation_date"`
|
CreationDate time.Time `json:"-" gorm:"column:creation_date"`
|
||||||
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
|
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
|
||||||
State int32 `json:"-" gorm:"column:lockout_policy_state"`
|
State int32 `json:"-" gorm:"column:lockout_policy_state"`
|
||||||
|
|
||||||
MaxAttempts uint64 `json:"maxAttempts" gorm:"column:max_attempts"`
|
MaxPasswordAttempts uint64 `json:"maxPasswordAttempts" gorm:"column:max_password_attempts"`
|
||||||
ShowLockOutFailures bool `json:"showLockOutFailures" gorm:"column:show_lockout_failures"`
|
ShowLockOutFailures bool `json:"showLockOutFailures" gorm:"column:show_lockout_failures"`
|
||||||
Default bool `json:"-" gorm:"-"`
|
Default bool `json:"-" gorm:"-"`
|
||||||
|
|
||||||
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func PasswordLockoutViewFromModel(policy *model.PasswordLockoutPolicyView) *PasswordLockoutPolicyView {
|
func LockoutViewToModel(policy *LockoutPolicyView) *model.LockoutPolicyView {
|
||||||
return &PasswordLockoutPolicyView{
|
return &model.LockoutPolicyView{
|
||||||
AggregateID: policy.AggregateID,
|
AggregateID: policy.AggregateID,
|
||||||
Sequence: policy.Sequence,
|
Sequence: policy.Sequence,
|
||||||
CreationDate: policy.CreationDate,
|
CreationDate: policy.CreationDate,
|
||||||
ChangeDate: policy.ChangeDate,
|
ChangeDate: policy.ChangeDate,
|
||||||
MaxAttempts: policy.MaxAttempts,
|
MaxPasswordAttempts: policy.MaxPasswordAttempts,
|
||||||
ShowLockOutFailures: policy.ShowLockOutFailures,
|
ShowLockOutFailures: policy.ShowLockOutFailures,
|
||||||
Default: policy.Default,
|
Default: policy.Default,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func PasswordLockoutViewToModel(policy *PasswordLockoutPolicyView) *model.PasswordLockoutPolicyView {
|
func (p *LockoutPolicyView) ToDomain() *domain.LockoutPolicy {
|
||||||
return &model.PasswordLockoutPolicyView{
|
return &domain.LockoutPolicy{
|
||||||
AggregateID: policy.AggregateID,
|
ObjectRoot: models.ObjectRoot{
|
||||||
Sequence: policy.Sequence,
|
AggregateID: p.AggregateID,
|
||||||
CreationDate: policy.CreationDate,
|
CreationDate: p.CreationDate,
|
||||||
ChangeDate: policy.ChangeDate,
|
ChangeDate: p.ChangeDate,
|
||||||
MaxAttempts: policy.MaxAttempts,
|
Sequence: p.Sequence,
|
||||||
ShowLockOutFailures: policy.ShowLockOutFailures,
|
},
|
||||||
Default: policy.Default,
|
MaxPasswordAttempts: p.MaxPasswordAttempts,
|
||||||
|
ShowLockOutFailures: p.ShowLockOutFailures,
|
||||||
|
Default: p.Default,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *PasswordLockoutPolicyView) AppendEvent(event *models.Event) (err error) {
|
func (i *LockoutPolicyView) AppendEvent(event *models.Event) (err error) {
|
||||||
i.Sequence = event.Sequence
|
i.Sequence = event.Sequence
|
||||||
i.ChangeDate = event.CreationDate
|
i.ChangeDate = event.CreationDate
|
||||||
switch event.Type {
|
switch event.Type {
|
||||||
case es_model.PasswordLockoutPolicyAdded, org_es_model.PasswordLockoutPolicyAdded:
|
case es_model.LockoutPolicyAdded, org_es_model.LockoutPolicyAdded:
|
||||||
i.setRootData(event)
|
i.setRootData(event)
|
||||||
i.CreationDate = event.CreationDate
|
i.CreationDate = event.CreationDate
|
||||||
err = i.SetData(event)
|
err = i.SetData(event)
|
||||||
case es_model.PasswordLockoutPolicyChanged, org_es_model.PasswordLockoutPolicyChanged:
|
case es_model.LockoutPolicyChanged, org_es_model.LockoutPolicyChanged:
|
||||||
err = i.SetData(event)
|
err = i.SetData(event)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *PasswordLockoutPolicyView) setRootData(event *models.Event) {
|
func (r *LockoutPolicyView) setRootData(event *models.Event) {
|
||||||
r.AggregateID = event.AggregateID
|
r.AggregateID = event.AggregateID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *PasswordLockoutPolicyView) SetData(event *models.Event) error {
|
func (r *LockoutPolicyView) SetData(event *models.Event) error {
|
||||||
if err := json.Unmarshal(event.Data, r); err != nil {
|
if err := json.Unmarshal(event.Data, r); err != nil {
|
||||||
logging.Log("EVEN-gHls0").WithError(err).Error("could not unmarshal event data")
|
logging.Log("EVEN-gHls0").WithError(err).Error("could not unmarshal event data")
|
||||||
return caos_errs.ThrowInternal(err, "MODEL-Hs8uf", "Could not unmarshal data")
|
return caos_errs.ThrowInternal(err, "MODEL-Hs8uf", "Could not unmarshal data")
|
||||||
|
@ -6,53 +6,53 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/view/repository"
|
"github.com/caos/zitadel/internal/view/repository"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PasswordLockoutPolicySearchRequest iam_model.PasswordLockoutPolicySearchRequest
|
type LockoutPolicySearchRequest iam_model.LockoutPolicySearchRequest
|
||||||
type PasswordLockoutPolicySearchQuery iam_model.PasswordLockoutPolicySearchQuery
|
type LockoutPolicySearchQuery iam_model.LockoutPolicySearchQuery
|
||||||
type PasswordLockoutPolicySearchKey iam_model.PasswordLockoutPolicySearchKey
|
type LockoutPolicySearchKey iam_model.LockoutPolicySearchKey
|
||||||
|
|
||||||
func (req PasswordLockoutPolicySearchRequest) GetLimit() uint64 {
|
func (req LockoutPolicySearchRequest) GetLimit() uint64 {
|
||||||
return req.Limit
|
return req.Limit
|
||||||
}
|
}
|
||||||
|
|
||||||
func (req PasswordLockoutPolicySearchRequest) GetOffset() uint64 {
|
func (req LockoutPolicySearchRequest) GetOffset() uint64 {
|
||||||
return req.Offset
|
return req.Offset
|
||||||
}
|
}
|
||||||
|
|
||||||
func (req PasswordLockoutPolicySearchRequest) GetSortingColumn() repository.ColumnKey {
|
func (req LockoutPolicySearchRequest) GetSortingColumn() repository.ColumnKey {
|
||||||
if req.SortingColumn == iam_model.PasswordLockoutPolicySearchKeyUnspecified {
|
if req.SortingColumn == iam_model.LockoutPolicySearchKeyUnspecified {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return PasswordLockoutPolicySearchKey(req.SortingColumn)
|
return LockoutPolicySearchKey(req.SortingColumn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (req PasswordLockoutPolicySearchRequest) GetAsc() bool {
|
func (req LockoutPolicySearchRequest) GetAsc() bool {
|
||||||
return req.Asc
|
return req.Asc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (req PasswordLockoutPolicySearchRequest) GetQueries() []repository.SearchQuery {
|
func (req LockoutPolicySearchRequest) GetQueries() []repository.SearchQuery {
|
||||||
result := make([]repository.SearchQuery, len(req.Queries))
|
result := make([]repository.SearchQuery, len(req.Queries))
|
||||||
for i, q := range req.Queries {
|
for i, q := range req.Queries {
|
||||||
result[i] = PasswordLockoutPolicySearchQuery{Key: q.Key, Value: q.Value, Method: q.Method}
|
result[i] = LockoutPolicySearchQuery{Key: q.Key, Value: q.Value, Method: q.Method}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (req PasswordLockoutPolicySearchQuery) GetKey() repository.ColumnKey {
|
func (req LockoutPolicySearchQuery) GetKey() repository.ColumnKey {
|
||||||
return PasswordLockoutPolicySearchKey(req.Key)
|
return LockoutPolicySearchKey(req.Key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (req PasswordLockoutPolicySearchQuery) GetMethod() domain.SearchMethod {
|
func (req LockoutPolicySearchQuery) GetMethod() domain.SearchMethod {
|
||||||
return req.Method
|
return req.Method
|
||||||
}
|
}
|
||||||
|
|
||||||
func (req PasswordLockoutPolicySearchQuery) GetValue() interface{} {
|
func (req LockoutPolicySearchQuery) GetValue() interface{} {
|
||||||
return req.Value
|
return req.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (key PasswordLockoutPolicySearchKey) ToColumnName() string {
|
func (key LockoutPolicySearchKey) ToColumnName() string {
|
||||||
switch iam_model.PasswordLockoutPolicySearchKey(key) {
|
switch iam_model.LockoutPolicySearchKey(key) {
|
||||||
case iam_model.PasswordLockoutPolicySearchKeyAggregateID:
|
case iam_model.LockoutPolicySearchKeyAggregateID:
|
||||||
return PasswordLockoutKeyAggregateID
|
return LockoutKeyAggregateID
|
||||||
default:
|
default:
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -9,24 +9,24 @@ import (
|
|||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetPasswordLockoutPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.PasswordLockoutPolicyView, error) {
|
func GetLockoutPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.LockoutPolicyView, error) {
|
||||||
policy := new(model.PasswordLockoutPolicyView)
|
policy := new(model.LockoutPolicyView)
|
||||||
aggregateIDQuery := &model.PasswordLockoutPolicySearchQuery{Key: iam_model.PasswordLockoutPolicySearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals}
|
aggregateIDQuery := &model.LockoutPolicySearchQuery{Key: iam_model.LockoutPolicySearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals}
|
||||||
query := repository.PrepareGetByQuery(table, aggregateIDQuery)
|
query := repository.PrepareGetByQuery(table, aggregateIDQuery)
|
||||||
err := query(db, policy)
|
err := query(db, policy)
|
||||||
if caos_errs.IsNotFound(err) {
|
if caos_errs.IsNotFound(err) {
|
||||||
return nil, caos_errs.ThrowNotFound(nil, "VIEW-M9fsf", "Errors.IAM.PasswordLockoutPolicy.NotExisting")
|
return nil, caos_errs.ThrowNotFound(nil, "VIEW-M9fsf", "Errors.IAM.LockoutPolicy.NotExisting")
|
||||||
}
|
}
|
||||||
return policy, err
|
return policy, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func PutPasswordLockoutPolicy(db *gorm.DB, table string, policy *model.PasswordLockoutPolicyView) error {
|
func PutLockoutPolicy(db *gorm.DB, table string, policy *model.LockoutPolicyView) error {
|
||||||
save := repository.PrepareSave(table)
|
save := repository.PrepareSave(table)
|
||||||
return save(db, policy)
|
return save(db, policy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeletePasswordLockoutPolicy(db *gorm.DB, table, aggregateID string) error {
|
func DeleteLockoutPolicy(db *gorm.DB, table, aggregateID string) error {
|
||||||
delete := repository.PrepareDeleteByKey(table, model.PasswordLockoutPolicySearchKey(iam_model.PasswordLockoutPolicySearchKeyAggregateID), aggregateID)
|
delete := repository.PrepareDeleteByKey(table, model.LockoutPolicySearchKey(iam_model.LockoutPolicySearchKeyAggregateID), aggregateID)
|
||||||
|
|
||||||
return delete(db)
|
return delete(db)
|
||||||
}
|
}
|
||||||
|
@ -501,55 +501,55 @@ func (repo *OrgRepository) GetDefaultPasswordAgePolicy(ctx context.Context) (*ia
|
|||||||
return iam_es_model.PasswordAgeViewToModel(policy), nil
|
return iam_es_model.PasswordAgeViewToModel(policy), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *OrgRepository) GetPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error) {
|
func (repo *OrgRepository) GetLockoutPolicy(ctx context.Context) (*iam_model.LockoutPolicyView, error) {
|
||||||
policy, viewErr := repo.View.PasswordLockoutPolicyByAggregateID(authz.GetCtxData(ctx).OrgID)
|
policy, viewErr := repo.View.LockoutPolicyByAggregateID(authz.GetCtxData(ctx).OrgID)
|
||||||
if viewErr != nil && !errors.IsNotFound(viewErr) {
|
if viewErr != nil && !errors.IsNotFound(viewErr) {
|
||||||
return nil, viewErr
|
return nil, viewErr
|
||||||
}
|
}
|
||||||
if errors.IsNotFound(viewErr) {
|
if errors.IsNotFound(viewErr) {
|
||||||
policy = new(iam_es_model.PasswordLockoutPolicyView)
|
policy = new(iam_es_model.LockoutPolicyView)
|
||||||
}
|
}
|
||||||
events, esErr := repo.getOrgEvents(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
events, esErr := repo.getOrgEvents(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
||||||
if errors.IsNotFound(viewErr) && len(events) == 0 {
|
if errors.IsNotFound(viewErr) && len(events) == 0 {
|
||||||
return repo.GetDefaultPasswordLockoutPolicy(ctx)
|
return repo.GetDefaultLockoutPolicy(ctx)
|
||||||
}
|
}
|
||||||
if esErr != nil {
|
if esErr != nil {
|
||||||
logging.Log("EVENT-mS9od").WithError(esErr).Debug("error retrieving new events")
|
logging.Log("EVENT-mS9od").WithError(esErr).Debug("error retrieving new events")
|
||||||
return iam_es_model.PasswordLockoutViewToModel(policy), nil
|
return iam_es_model.LockoutViewToModel(policy), nil
|
||||||
}
|
}
|
||||||
policyCopy := *policy
|
policyCopy := *policy
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
if err := policyCopy.AppendEvent(event); err != nil {
|
if err := policyCopy.AppendEvent(event); err != nil {
|
||||||
return iam_es_model.PasswordLockoutViewToModel(policy), nil
|
return iam_es_model.LockoutViewToModel(policy), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return iam_es_model.PasswordLockoutViewToModel(policy), nil
|
return iam_es_model.LockoutViewToModel(policy), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *OrgRepository) GetDefaultPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error) {
|
func (repo *OrgRepository) GetDefaultLockoutPolicy(ctx context.Context) (*iam_model.LockoutPolicyView, error) {
|
||||||
policy, viewErr := repo.View.PasswordLockoutPolicyByAggregateID(repo.SystemDefaults.IamID)
|
policy, viewErr := repo.View.LockoutPolicyByAggregateID(repo.SystemDefaults.IamID)
|
||||||
if viewErr != nil && !errors.IsNotFound(viewErr) {
|
if viewErr != nil && !errors.IsNotFound(viewErr) {
|
||||||
return nil, viewErr
|
return nil, viewErr
|
||||||
}
|
}
|
||||||
if errors.IsNotFound(viewErr) {
|
if errors.IsNotFound(viewErr) {
|
||||||
policy = new(iam_es_model.PasswordLockoutPolicyView)
|
policy = new(iam_es_model.LockoutPolicyView)
|
||||||
}
|
}
|
||||||
events, esErr := repo.getIAMEvents(ctx, policy.Sequence)
|
events, esErr := repo.getIAMEvents(ctx, policy.Sequence)
|
||||||
if errors.IsNotFound(viewErr) && len(events) == 0 {
|
if errors.IsNotFound(viewErr) && len(events) == 0 {
|
||||||
return nil, errors.ThrowNotFound(nil, "EVENT-cmO9s", "Errors.IAM.PasswordLockoutPolicy.NotFound")
|
return nil, errors.ThrowNotFound(nil, "EVENT-cmO9s", "Errors.IAM.LockoutPolicy.NotFound")
|
||||||
}
|
}
|
||||||
if esErr != nil {
|
if esErr != nil {
|
||||||
logging.Log("EVENT-2Ms9f").WithError(esErr).Debug("error retrieving new events")
|
logging.Log("EVENT-2Ms9f").WithError(esErr).Debug("error retrieving new events")
|
||||||
return iam_es_model.PasswordLockoutViewToModel(policy), nil
|
return iam_es_model.LockoutViewToModel(policy), nil
|
||||||
}
|
}
|
||||||
policyCopy := *policy
|
policyCopy := *policy
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
if err := policyCopy.AppendEvent(event); err != nil {
|
if err := policyCopy.AppendEvent(event); err != nil {
|
||||||
return iam_es_model.PasswordLockoutViewToModel(policy), nil
|
return iam_es_model.LockoutViewToModel(policy), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
policy.Default = true
|
policy.Default = true
|
||||||
return iam_es_model.PasswordLockoutViewToModel(policy), nil
|
return iam_es_model.LockoutViewToModel(policy), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *OrgRepository) GetPrivacyPolicy(ctx context.Context) (*iam_model.PrivacyPolicyView, error) {
|
func (repo *OrgRepository) GetPrivacyPolicy(ctx context.Context) (*iam_model.PrivacyPolicyView, error) {
|
||||||
|
@ -71,8 +71,8 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es
|
|||||||
handler{view, bulkLimit, configs.cycleDuration("PasswordComplexityPolicy"), errorCount, es}),
|
handler{view, bulkLimit, configs.cycleDuration("PasswordComplexityPolicy"), errorCount, es}),
|
||||||
newPasswordAgePolicy(
|
newPasswordAgePolicy(
|
||||||
handler{view, bulkLimit, configs.cycleDuration("PasswordAgePolicy"), errorCount, es}),
|
handler{view, bulkLimit, configs.cycleDuration("PasswordAgePolicy"), errorCount, es}),
|
||||||
newPasswordLockoutPolicy(
|
newLockoutPolicy(
|
||||||
handler{view, bulkLimit, configs.cycleDuration("PasswordLockoutPolicy"), errorCount, es}),
|
handler{view, bulkLimit, configs.cycleDuration("LockoutPolicy"), errorCount, es}),
|
||||||
newOrgIAMPolicy(
|
newOrgIAMPolicy(
|
||||||
handler{view, bulkLimit, configs.cycleDuration("OrgIAMPolicy"), errorCount, es}),
|
handler{view, bulkLimit, configs.cycleDuration("OrgIAMPolicy"), errorCount, es}),
|
||||||
newMailTemplate(
|
newMailTemplate(
|
||||||
|
@ -13,16 +13,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
passwordLockoutPolicyTable = "management.password_lockout_policies"
|
lockoutPolicyTable = "management.lockout_policies"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PasswordLockoutPolicy struct {
|
type LockoutPolicy struct {
|
||||||
handler
|
handler
|
||||||
subscription *v1.Subscription
|
subscription *v1.Subscription
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPasswordLockoutPolicy(handler handler) *PasswordLockoutPolicy {
|
func newLockoutPolicy(handler handler) *LockoutPolicy {
|
||||||
h := &PasswordLockoutPolicy{
|
h := &LockoutPolicy{
|
||||||
handler: handler,
|
handler: handler,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ func newPasswordLockoutPolicy(handler handler) *PasswordLockoutPolicy {
|
|||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *PasswordLockoutPolicy) subscribe() {
|
func (m *LockoutPolicy) subscribe() {
|
||||||
m.subscription = m.es.Subscribe(m.AggregateTypes()...)
|
m.subscription = m.es.Subscribe(m.AggregateTypes()...)
|
||||||
go func() {
|
go func() {
|
||||||
for event := range m.subscription.Events {
|
for event := range m.subscription.Events {
|
||||||
@ -40,28 +40,28 @@ func (m *PasswordLockoutPolicy) subscribe() {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) ViewModel() string {
|
func (p *LockoutPolicy) ViewModel() string {
|
||||||
return passwordLockoutPolicyTable
|
return lockoutPolicyTable
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) Subscription() *v1.Subscription {
|
func (p *LockoutPolicy) Subscription() *v1.Subscription {
|
||||||
return p.subscription
|
return p.subscription
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ *PasswordLockoutPolicy) AggregateTypes() []es_models.AggregateType {
|
func (_ *LockoutPolicy) AggregateTypes() []es_models.AggregateType {
|
||||||
return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate}
|
return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) CurrentSequence() (uint64, error) {
|
func (p *LockoutPolicy) CurrentSequence() (uint64, error) {
|
||||||
sequence, err := p.view.GetLatestPasswordLockoutPolicySequence()
|
sequence, err := p.view.GetLatestLockoutPolicySequence()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return sequence.CurrentSequence, nil
|
return sequence.CurrentSequence, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) EventQuery() (*es_models.SearchQuery, error) {
|
func (p *LockoutPolicy) EventQuery() (*es_models.SearchQuery, error) {
|
||||||
sequence, err := p.view.GetLatestPasswordLockoutPolicySequence()
|
sequence, err := p.view.GetLatestLockoutPolicySequence()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -70,7 +70,7 @@ func (p *PasswordLockoutPolicy) EventQuery() (*es_models.SearchQuery, error) {
|
|||||||
LatestSequenceFilter(sequence.CurrentSequence), nil
|
LatestSequenceFilter(sequence.CurrentSequence), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) Reduce(event *es_models.Event) (err error) {
|
func (p *LockoutPolicy) Reduce(event *es_models.Event) (err error) {
|
||||||
switch event.AggregateType {
|
switch event.AggregateType {
|
||||||
case model.OrgAggregate, iam_es_model.IAMAggregate:
|
case model.OrgAggregate, iam_es_model.IAMAggregate:
|
||||||
err = p.processPasswordLockoutPolicy(event)
|
err = p.processPasswordLockoutPolicy(event)
|
||||||
@ -78,33 +78,33 @@ func (p *PasswordLockoutPolicy) Reduce(event *es_models.Event) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) processPasswordLockoutPolicy(event *es_models.Event) (err error) {
|
func (p *LockoutPolicy) processPasswordLockoutPolicy(event *es_models.Event) (err error) {
|
||||||
policy := new(iam_model.PasswordLockoutPolicyView)
|
policy := new(iam_model.LockoutPolicyView)
|
||||||
switch event.Type {
|
switch event.Type {
|
||||||
case iam_es_model.PasswordLockoutPolicyAdded, model.PasswordLockoutPolicyAdded:
|
case iam_es_model.LockoutPolicyAdded, model.LockoutPolicyAdded:
|
||||||
err = policy.AppendEvent(event)
|
err = policy.AppendEvent(event)
|
||||||
case iam_es_model.PasswordLockoutPolicyChanged, model.PasswordLockoutPolicyChanged:
|
case iam_es_model.LockoutPolicyChanged, model.LockoutPolicyChanged:
|
||||||
policy, err = p.view.PasswordLockoutPolicyByAggregateID(event.AggregateID)
|
policy, err = p.view.LockoutPolicyByAggregateID(event.AggregateID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = policy.AppendEvent(event)
|
err = policy.AppendEvent(event)
|
||||||
case model.PasswordLockoutPolicyRemoved:
|
case model.LockoutPolicyRemoved:
|
||||||
return p.view.DeletePasswordLockoutPolicy(event.AggregateID, event)
|
return p.view.DeleteLockoutPolicy(event.AggregateID, event)
|
||||||
default:
|
default:
|
||||||
return p.view.ProcessedPasswordLockoutPolicySequence(event)
|
return p.view.ProcessedLockoutPolicySequence(event)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return p.view.PutPasswordLockoutPolicy(policy, event)
|
return p.view.PutLockoutPolicy(policy, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) OnError(event *es_models.Event, err error) error {
|
func (p *LockoutPolicy) OnError(event *es_models.Event, err error) error {
|
||||||
logging.LogWithFields("SPOOL-Bms8f", "id", event.AggregateID).WithError(err).Warn("something went wrong in passwordLockout policy handler")
|
logging.LogWithFields("SPOOL-Bms8f", "id", event.AggregateID).WithError(err).Warn("something went wrong in passwordLockout policy handler")
|
||||||
return spooler.HandleError(event, err, p.view.GetLatestPasswordLockoutPolicyFailedEvent, p.view.ProcessedPasswordLockoutPolicyFailedEvent, p.view.ProcessedPasswordLockoutPolicySequence, p.errorCountUntilSkip)
|
return spooler.HandleError(event, err, p.view.GetLatestLockoutPolicyFailedEvent, p.view.ProcessedLockoutPolicyFailedEvent, p.view.ProcessedLockoutPolicySequence, p.errorCountUntilSkip)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordLockoutPolicy) OnSuccess() error {
|
func (p *LockoutPolicy) OnSuccess() error {
|
||||||
return spooler.HandleSuccess(p.view.UpdatePasswordLockoutPolicySpoolerRunTimestamp)
|
return spooler.HandleSuccess(p.view.UpdateLockoutPolicySpoolerRunTimestamp)
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
package view
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/caos/zitadel/internal/errors"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||||
|
"github.com/caos/zitadel/internal/iam/repository/view"
|
||||||
|
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||||
|
global_view "github.com/caos/zitadel/internal/view/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
lockoutPolicyTable = "management.lockout_policies"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (v *View) LockoutPolicyByAggregateID(aggregateID string) (*model.LockoutPolicyView, error) {
|
||||||
|
return view.GetLockoutPolicyByAggregateID(v.Db, lockoutPolicyTable, aggregateID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) PutLockoutPolicy(policy *model.LockoutPolicyView, event *models.Event) error {
|
||||||
|
err := view.PutLockoutPolicy(v.Db, lockoutPolicyTable, policy)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return v.ProcessedLockoutPolicySequence(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) DeleteLockoutPolicy(aggregateID string, event *models.Event) error {
|
||||||
|
err := view.DeleteLockoutPolicy(v.Db, lockoutPolicyTable, aggregateID)
|
||||||
|
if err != nil && !errors.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return v.ProcessedLockoutPolicySequence(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) GetLatestLockoutPolicySequence() (*global_view.CurrentSequence, error) {
|
||||||
|
return v.latestSequence(lockoutPolicyTable)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) ProcessedLockoutPolicySequence(event *models.Event) error {
|
||||||
|
return v.saveCurrentSequence(lockoutPolicyTable, event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) UpdateLockoutPolicySpoolerRunTimestamp() error {
|
||||||
|
return v.updateSpoolerRunSequence(lockoutPolicyTable)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) GetLatestLockoutPolicyFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
|
||||||
|
return v.latestFailedEvent(lockoutPolicyTable, sequence)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *View) ProcessedLockoutPolicyFailedEvent(failedEvent *global_view.FailedEvent) error {
|
||||||
|
return v.saveFailedEvent(failedEvent)
|
||||||
|
}
|
@ -1,53 +0,0 @@
|
|||||||
package view
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/caos/zitadel/internal/errors"
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view"
|
|
||||||
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
|
||||||
global_view "github.com/caos/zitadel/internal/view/repository"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
passwordLockoutPolicyTable = "management.password_lockout_policies"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (v *View) PasswordLockoutPolicyByAggregateID(aggregateID string) (*model.PasswordLockoutPolicyView, error) {
|
|
||||||
return view.GetPasswordLockoutPolicyByAggregateID(v.Db, passwordLockoutPolicyTable, aggregateID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) PutPasswordLockoutPolicy(policy *model.PasswordLockoutPolicyView, event *models.Event) error {
|
|
||||||
err := view.PutPasswordLockoutPolicy(v.Db, passwordLockoutPolicyTable, policy)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedPasswordLockoutPolicySequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) DeletePasswordLockoutPolicy(aggregateID string, event *models.Event) error {
|
|
||||||
err := view.DeletePasswordLockoutPolicy(v.Db, passwordLockoutPolicyTable, aggregateID)
|
|
||||||
if err != nil && !errors.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return v.ProcessedPasswordLockoutPolicySequence(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestPasswordLockoutPolicySequence() (*global_view.CurrentSequence, error) {
|
|
||||||
return v.latestSequence(passwordLockoutPolicyTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedPasswordLockoutPolicySequence(event *models.Event) error {
|
|
||||||
return v.saveCurrentSequence(passwordLockoutPolicyTable, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) UpdatePasswordLockoutPolicySpoolerRunTimestamp() error {
|
|
||||||
return v.updateSpoolerRunSequence(passwordLockoutPolicyTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) GetLatestPasswordLockoutPolicyFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
|
|
||||||
return v.latestFailedEvent(passwordLockoutPolicyTable, sequence)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *View) ProcessedPasswordLockoutPolicyFailedEvent(failedEvent *global_view.FailedEvent) error {
|
|
||||||
return v.saveFailedEvent(failedEvent)
|
|
||||||
}
|
|
@ -42,8 +42,8 @@ type OrgRepository interface {
|
|||||||
GetPasswordAgePolicy(ctx context.Context) (*iam_model.PasswordAgePolicyView, error)
|
GetPasswordAgePolicy(ctx context.Context) (*iam_model.PasswordAgePolicyView, error)
|
||||||
GetDefaultPasswordAgePolicy(ctx context.Context) (*iam_model.PasswordAgePolicyView, error)
|
GetDefaultPasswordAgePolicy(ctx context.Context) (*iam_model.PasswordAgePolicyView, error)
|
||||||
|
|
||||||
GetPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error)
|
GetLockoutPolicy(ctx context.Context) (*iam_model.LockoutPolicyView, error)
|
||||||
GetDefaultPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error)
|
GetDefaultLockoutPolicy(ctx context.Context) (*iam_model.LockoutPolicyView, error)
|
||||||
|
|
||||||
GetPrivacyPolicy(ctx context.Context) (*iam_model.PrivacyPolicyView, error)
|
GetPrivacyPolicy(ctx context.Context) (*iam_model.PrivacyPolicyView, error)
|
||||||
GetDefaultPrivacyPolicy(ctx context.Context) (*iam_model.PrivacyPolicyView, error)
|
GetDefaultPrivacyPolicy(ctx context.Context) (*iam_model.PrivacyPolicyView, error)
|
||||||
|
@ -24,7 +24,7 @@ type Org struct {
|
|||||||
MailTexts []*iam_model.MailText
|
MailTexts []*iam_model.MailText
|
||||||
PasswordComplexityPolicy *iam_model.PasswordComplexityPolicy
|
PasswordComplexityPolicy *iam_model.PasswordComplexityPolicy
|
||||||
PasswordAgePolicy *iam_model.PasswordAgePolicy
|
PasswordAgePolicy *iam_model.PasswordAgePolicy
|
||||||
PasswordLockoutPolicy *iam_model.PasswordLockoutPolicy
|
LockoutPolicy *iam_model.LockoutPolicy
|
||||||
|
|
||||||
IDPs []*iam_model.IDPConfig
|
IDPs []*iam_model.IDPConfig
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ type Org struct {
|
|||||||
LoginPolicy *iam_es_model.LoginPolicy `json:"-"`
|
LoginPolicy *iam_es_model.LoginPolicy `json:"-"`
|
||||||
PasswordComplexityPolicy *iam_es_model.PasswordComplexityPolicy `json:"-"`
|
PasswordComplexityPolicy *iam_es_model.PasswordComplexityPolicy `json:"-"`
|
||||||
PasswordAgePolicy *iam_es_model.PasswordAgePolicy `json:"-"`
|
PasswordAgePolicy *iam_es_model.PasswordAgePolicy `json:"-"`
|
||||||
PasswordLockoutPolicy *iam_es_model.PasswordLockoutPolicy `json:"-"`
|
LockoutPolicy *iam_es_model.LockoutPolicy `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func OrgToModel(org *Org) *org_model.Org {
|
func OrgToModel(org *Org) *org_model.Org {
|
||||||
@ -60,8 +60,8 @@ func OrgToModel(org *Org) *org_model.Org {
|
|||||||
if org.PasswordAgePolicy != nil {
|
if org.PasswordAgePolicy != nil {
|
||||||
converted.PasswordAgePolicy = iam_es_model.PasswordAgePolicyToModel(org.PasswordAgePolicy)
|
converted.PasswordAgePolicy = iam_es_model.PasswordAgePolicyToModel(org.PasswordAgePolicy)
|
||||||
}
|
}
|
||||||
if org.PasswordLockoutPolicy != nil {
|
if org.LockoutPolicy != nil {
|
||||||
converted.PasswordLockoutPolicy = iam_es_model.PasswordLockoutPolicyToModel(org.PasswordLockoutPolicy)
|
converted.LockoutPolicy = iam_es_model.LockoutPolicyToModel(org.LockoutPolicy)
|
||||||
}
|
}
|
||||||
return converted
|
return converted
|
||||||
}
|
}
|
||||||
@ -196,12 +196,12 @@ func (o *Org) AppendEvent(event *es_models.Event) (err error) {
|
|||||||
err = o.appendChangePasswordAgePolicyEvent(event)
|
err = o.appendChangePasswordAgePolicyEvent(event)
|
||||||
case PasswordAgePolicyRemoved:
|
case PasswordAgePolicyRemoved:
|
||||||
o.appendRemovePasswordAgePolicyEvent(event)
|
o.appendRemovePasswordAgePolicyEvent(event)
|
||||||
case PasswordLockoutPolicyAdded:
|
case LockoutPolicyAdded:
|
||||||
err = o.appendAddPasswordLockoutPolicyEvent(event)
|
err = o.appendAddLockoutPolicyEvent(event)
|
||||||
case PasswordLockoutPolicyChanged:
|
case LockoutPolicyChanged:
|
||||||
err = o.appendChangePasswordLockoutPolicyEvent(event)
|
err = o.appendChangeLockoutPolicyEvent(event)
|
||||||
case PasswordLockoutPolicyRemoved:
|
case LockoutPolicyRemoved:
|
||||||
o.appendRemovePasswordLockoutPolicyEvent(event)
|
o.appendRemoveLockoutPolicyEvent(event)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -5,20 +5,20 @@ import (
|
|||||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (o *Org) appendAddPasswordLockoutPolicyEvent(event *es_models.Event) error {
|
func (o *Org) appendAddLockoutPolicyEvent(event *es_models.Event) error {
|
||||||
o.PasswordLockoutPolicy = new(iam_es_model.PasswordLockoutPolicy)
|
o.LockoutPolicy = new(iam_es_model.LockoutPolicy)
|
||||||
err := o.PasswordLockoutPolicy.SetData(event)
|
err := o.LockoutPolicy.SetData(event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
o.PasswordLockoutPolicy.ObjectRoot.CreationDate = event.CreationDate
|
o.LockoutPolicy.ObjectRoot.CreationDate = event.CreationDate
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Org) appendChangePasswordLockoutPolicyEvent(event *es_models.Event) error {
|
func (o *Org) appendChangeLockoutPolicyEvent(event *es_models.Event) error {
|
||||||
return o.PasswordLockoutPolicy.SetData(event)
|
return o.LockoutPolicy.SetData(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Org) appendRemovePasswordLockoutPolicyEvent(event *es_models.Event) {
|
func (o *Org) appendRemoveLockoutPolicyEvent(event *es_models.Event) {
|
||||||
o.PasswordLockoutPolicy = nil
|
o.LockoutPolicy = nil
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,10 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAppendAddPasswordLockoutPolicyEvent(t *testing.T) {
|
func TestAppendAddLockoutPolicyEvent(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
org *Org
|
org *Org
|
||||||
policy *iam_es_model.PasswordLockoutPolicy
|
policy *iam_es_model.LockoutPolicy
|
||||||
event *es_models.Event
|
event *es_models.Event
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
@ -19,13 +19,13 @@ func TestAppendAddPasswordLockoutPolicyEvent(t *testing.T) {
|
|||||||
result *Org
|
result *Org
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "append add password age policy event",
|
name: "append add lockout policy event",
|
||||||
args: args{
|
args: args{
|
||||||
org: &Org{},
|
org: &Org{},
|
||||||
policy: &iam_es_model.PasswordLockoutPolicy{MaxAttempts: 10},
|
policy: &iam_es_model.LockoutPolicy{MaxPasswordAttempts: 10},
|
||||||
event: &es_models.Event{},
|
event: &es_models.Event{},
|
||||||
},
|
},
|
||||||
result: &Org{PasswordLockoutPolicy: &iam_es_model.PasswordLockoutPolicy{MaxAttempts: 10}},
|
result: &Org{LockoutPolicy: &iam_es_model.LockoutPolicy{MaxPasswordAttempts: 10}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@ -34,18 +34,18 @@ func TestAppendAddPasswordLockoutPolicyEvent(t *testing.T) {
|
|||||||
data, _ := json.Marshal(tt.args.policy)
|
data, _ := json.Marshal(tt.args.policy)
|
||||||
tt.args.event.Data = data
|
tt.args.event.Data = data
|
||||||
}
|
}
|
||||||
tt.args.org.appendAddPasswordLockoutPolicyEvent(tt.args.event)
|
tt.args.org.appendAddLockoutPolicyEvent(tt.args.event)
|
||||||
if tt.result.PasswordLockoutPolicy.MaxAttempts != tt.args.org.PasswordLockoutPolicy.MaxAttempts {
|
if tt.result.LockoutPolicy.MaxPasswordAttempts != tt.args.org.LockoutPolicy.MaxPasswordAttempts {
|
||||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.PasswordLockoutPolicy.MaxAttempts, tt.args.org.PasswordLockoutPolicy.MaxAttempts)
|
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.LockoutPolicy.MaxPasswordAttempts, tt.args.org.LockoutPolicy.MaxPasswordAttempts)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAppendChangePasswordLockoutPolicyEvent(t *testing.T) {
|
func TestAppendChangeLockoutPolicyEvent(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
org *Org
|
org *Org
|
||||||
policy *iam_es_model.PasswordLockoutPolicy
|
policy *iam_es_model.LockoutPolicy
|
||||||
event *es_models.Event
|
event *es_models.Event
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
@ -54,16 +54,16 @@ func TestAppendChangePasswordLockoutPolicyEvent(t *testing.T) {
|
|||||||
result *Org
|
result *Org
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "append change password age policy event",
|
name: "append change lockout policy event",
|
||||||
args: args{
|
args: args{
|
||||||
org: &Org{PasswordLockoutPolicy: &iam_es_model.PasswordLockoutPolicy{
|
org: &Org{LockoutPolicy: &iam_es_model.LockoutPolicy{
|
||||||
MaxAttempts: 10,
|
MaxPasswordAttempts: 10,
|
||||||
}},
|
}},
|
||||||
policy: &iam_es_model.PasswordLockoutPolicy{MaxAttempts: 5, ShowLockOutFailures: true},
|
policy: &iam_es_model.LockoutPolicy{MaxPasswordAttempts: 5, ShowLockOutFailures: true},
|
||||||
event: &es_models.Event{},
|
event: &es_models.Event{},
|
||||||
},
|
},
|
||||||
result: &Org{PasswordLockoutPolicy: &iam_es_model.PasswordLockoutPolicy{
|
result: &Org{LockoutPolicy: &iam_es_model.LockoutPolicy{
|
||||||
MaxAttempts: 5,
|
MaxPasswordAttempts: 5,
|
||||||
ShowLockOutFailures: true,
|
ShowLockOutFailures: true,
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
@ -74,12 +74,12 @@ func TestAppendChangePasswordLockoutPolicyEvent(t *testing.T) {
|
|||||||
data, _ := json.Marshal(tt.args.policy)
|
data, _ := json.Marshal(tt.args.policy)
|
||||||
tt.args.event.Data = data
|
tt.args.event.Data = data
|
||||||
}
|
}
|
||||||
tt.args.org.appendChangePasswordLockoutPolicyEvent(tt.args.event)
|
tt.args.org.appendChangeLockoutPolicyEvent(tt.args.event)
|
||||||
if tt.result.PasswordLockoutPolicy.MaxAttempts != tt.args.org.PasswordLockoutPolicy.MaxAttempts {
|
if tt.result.LockoutPolicy.MaxPasswordAttempts != tt.args.org.LockoutPolicy.MaxPasswordAttempts {
|
||||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.PasswordLockoutPolicy.MaxAttempts, tt.args.org.PasswordLockoutPolicy.MaxAttempts)
|
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.LockoutPolicy.MaxPasswordAttempts, tt.args.org.LockoutPolicy.MaxPasswordAttempts)
|
||||||
}
|
}
|
||||||
if tt.result.PasswordLockoutPolicy.ShowLockOutFailures != tt.args.org.PasswordLockoutPolicy.ShowLockOutFailures {
|
if tt.result.LockoutPolicy.ShowLockOutFailures != tt.args.org.LockoutPolicy.ShowLockOutFailures {
|
||||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.PasswordLockoutPolicy.ShowLockOutFailures, tt.args.org.PasswordLockoutPolicy.ShowLockOutFailures)
|
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.LockoutPolicy.ShowLockOutFailures, tt.args.org.LockoutPolicy.ShowLockOutFailures)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -89,9 +89,9 @@ const (
|
|||||||
PasswordAgePolicyChanged models.EventType = "org.policy.password.age.changed"
|
PasswordAgePolicyChanged models.EventType = "org.policy.password.age.changed"
|
||||||
PasswordAgePolicyRemoved models.EventType = "org.policy.password.age.removed"
|
PasswordAgePolicyRemoved models.EventType = "org.policy.password.age.removed"
|
||||||
|
|
||||||
PasswordLockoutPolicyAdded models.EventType = "org.policy.password.lockout.added"
|
LockoutPolicyAdded models.EventType = "org.policy.lockout.added"
|
||||||
PasswordLockoutPolicyChanged models.EventType = "org.policy.password.lockout.changed"
|
LockoutPolicyChanged models.EventType = "org.policy.lockout.changed"
|
||||||
PasswordLockoutPolicyRemoved models.EventType = "org.policy.password.lockout.removed"
|
LockoutPolicyRemoved models.EventType = "org.policy.lockout.removed"
|
||||||
|
|
||||||
PrivacyPolicyAdded models.EventType = "org.policy.privacy.added"
|
PrivacyPolicyAdded models.EventType = "org.policy.privacy.added"
|
||||||
PrivacyPolicyChanged models.EventType = "org.policy.privacy.changed"
|
PrivacyPolicyChanged models.EventType = "org.policy.privacy.changed"
|
||||||
|
@ -20,7 +20,7 @@ func readModelToIAM(readModel *ReadModel) *model.IAM {
|
|||||||
DefaultOrgIAMPolicy: readModelToOrgIAMPolicy(&readModel.DefaultOrgIAMPolicy),
|
DefaultOrgIAMPolicy: readModelToOrgIAMPolicy(&readModel.DefaultOrgIAMPolicy),
|
||||||
DefaultPasswordAgePolicy: readModelToPasswordAgePolicy(&readModel.DefaultPasswordAgePolicy),
|
DefaultPasswordAgePolicy: readModelToPasswordAgePolicy(&readModel.DefaultPasswordAgePolicy),
|
||||||
DefaultPasswordComplexityPolicy: readModelToPasswordComplexityPolicy(&readModel.DefaultPasswordComplexityPolicy),
|
DefaultPasswordComplexityPolicy: readModelToPasswordComplexityPolicy(&readModel.DefaultPasswordComplexityPolicy),
|
||||||
DefaultPasswordLockoutPolicy: readModelToPasswordLockoutPolicy(&readModel.DefaultPasswordLockoutPolicy),
|
DefaultLockoutPolicy: readModelToPasswordLockoutPolicy(&readModel.DefaultPasswordLockoutPolicy),
|
||||||
IDPs: readModelToIDPConfigs(&readModel.IDPs),
|
IDPs: readModelToIDPConfigs(&readModel.IDPs),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,10 +121,10 @@ func readModelToPasswordComplexityPolicy(readModel *IAMPasswordComplexityPolicyR
|
|||||||
MinLength: readModel.MinLength,
|
MinLength: readModel.MinLength,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func readModelToPasswordLockoutPolicy(readModel *IAMPasswordLockoutPolicyReadModel) *model.PasswordLockoutPolicy {
|
func readModelToPasswordLockoutPolicy(readModel *IAMLockoutPolicyReadModel) *model.LockoutPolicy {
|
||||||
return &model.PasswordLockoutPolicy{
|
return &model.LockoutPolicy{
|
||||||
ObjectRoot: readModelToObjectRoot(readModel.PasswordLockoutPolicyReadModel.ReadModel),
|
ObjectRoot: readModelToObjectRoot(readModel.LockoutPolicyReadModel.ReadModel),
|
||||||
MaxAttempts: readModel.MaxAttempts,
|
MaxPasswordAttempts: readModel.MaxAttempts,
|
||||||
ShowLockOutFailures: readModel.ShowLockOutFailures,
|
ShowLockOutFailures: readModel.ShowLockOutFailures,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ type ReadModel struct {
|
|||||||
DefaultOrgIAMPolicy IAMOrgIAMPolicyReadModel
|
DefaultOrgIAMPolicy IAMOrgIAMPolicyReadModel
|
||||||
DefaultPasswordComplexityPolicy IAMPasswordComplexityPolicyReadModel
|
DefaultPasswordComplexityPolicy IAMPasswordComplexityPolicyReadModel
|
||||||
DefaultPasswordAgePolicy IAMPasswordAgePolicyReadModel
|
DefaultPasswordAgePolicy IAMPasswordAgePolicyReadModel
|
||||||
DefaultPasswordLockoutPolicy IAMPasswordLockoutPolicyReadModel
|
DefaultPasswordLockoutPolicy IAMLockoutPolicyReadModel
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewReadModel(id string) *ReadModel {
|
func NewReadModel(id string) *ReadModel {
|
||||||
@ -80,8 +80,8 @@ func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) {
|
|||||||
*policy.PasswordAgePolicyChangedEvent:
|
*policy.PasswordAgePolicyChangedEvent:
|
||||||
|
|
||||||
rm.DefaultPasswordAgePolicy.AppendEvents(event)
|
rm.DefaultPasswordAgePolicy.AppendEvents(event)
|
||||||
case *policy.PasswordLockoutPolicyAddedEvent,
|
case *policy.LockoutPolicyAddedEvent,
|
||||||
*policy.PasswordLockoutPolicyChangedEvent:
|
*policy.LockoutPolicyChangedEvent:
|
||||||
|
|
||||||
rm.DefaultPasswordLockoutPolicy.AppendEvents(event)
|
rm.DefaultPasswordLockoutPolicy.AppendEvents(event)
|
||||||
}
|
}
|
||||||
|
@ -6,19 +6,19 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/repository/policy"
|
"github.com/caos/zitadel/internal/repository/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
type IAMPasswordLockoutPolicyReadModel struct {
|
type IAMLockoutPolicyReadModel struct {
|
||||||
PasswordLockoutPolicyReadModel
|
LockoutPolicyReadModel
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rm *IAMPasswordLockoutPolicyReadModel) AppendEvents(events ...eventstore.EventReader) {
|
func (rm *IAMLockoutPolicyReadModel) AppendEvents(events ...eventstore.EventReader) {
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *iam.PasswordLockoutPolicyAddedEvent:
|
case *iam.LockoutPolicyAddedEvent:
|
||||||
rm.PasswordLockoutPolicyReadModel.AppendEvents(&e.PasswordLockoutPolicyAddedEvent)
|
rm.LockoutPolicyReadModel.AppendEvents(&e.LockoutPolicyAddedEvent)
|
||||||
case *iam.PasswordLockoutPolicyChangedEvent:
|
case *iam.LockoutPolicyChangedEvent:
|
||||||
rm.PasswordLockoutPolicyReadModel.AppendEvents(&e.PasswordLockoutPolicyChangedEvent)
|
rm.LockoutPolicyReadModel.AppendEvents(&e.LockoutPolicyChangedEvent)
|
||||||
case *policy.PasswordLockoutPolicyAddedEvent, *policy.PasswordLockoutPolicyChangedEvent:
|
case *policy.LockoutPolicyAddedEvent, *policy.LockoutPolicyChangedEvent:
|
||||||
rm.PasswordLockoutPolicyReadModel.AppendEvents(e)
|
rm.LockoutPolicyReadModel.AppendEvents(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,18 +7,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type OrgPasswordLockoutPolicyReadModel struct {
|
type OrgPasswordLockoutPolicyReadModel struct {
|
||||||
PasswordLockoutPolicyReadModel
|
LockoutPolicyReadModel
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rm *OrgPasswordLockoutPolicyReadModel) AppendEvents(events ...eventstore.EventReader) {
|
func (rm *OrgPasswordLockoutPolicyReadModel) AppendEvents(events ...eventstore.EventReader) {
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *org.PasswordLockoutPolicyAddedEvent:
|
case *org.LockoutPolicyAddedEvent:
|
||||||
rm.PasswordLockoutPolicyReadModel.AppendEvents(&e.PasswordLockoutPolicyAddedEvent)
|
rm.LockoutPolicyReadModel.AppendEvents(&e.LockoutPolicyAddedEvent)
|
||||||
case *org.PasswordLockoutPolicyChangedEvent:
|
case *org.LockoutPolicyChangedEvent:
|
||||||
rm.PasswordLockoutPolicyReadModel.AppendEvents(&e.PasswordLockoutPolicyChangedEvent)
|
rm.LockoutPolicyReadModel.AppendEvents(&e.LockoutPolicyChangedEvent)
|
||||||
case *policy.PasswordLockoutPolicyAddedEvent, *policy.PasswordLockoutPolicyChangedEvent:
|
case *policy.LockoutPolicyAddedEvent, *policy.LockoutPolicyChangedEvent:
|
||||||
rm.PasswordLockoutPolicyReadModel.AppendEvents(e)
|
rm.LockoutPolicyReadModel.AppendEvents(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,22 +5,22 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/repository/policy"
|
"github.com/caos/zitadel/internal/repository/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PasswordLockoutPolicyReadModel struct {
|
type LockoutPolicyReadModel struct {
|
||||||
eventstore.ReadModel
|
eventstore.ReadModel
|
||||||
|
|
||||||
MaxAttempts uint64
|
MaxAttempts uint64
|
||||||
ShowLockOutFailures bool
|
ShowLockOutFailures bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rm *PasswordLockoutPolicyReadModel) Reduce() error {
|
func (rm *LockoutPolicyReadModel) Reduce() error {
|
||||||
for _, event := range rm.Events {
|
for _, event := range rm.Events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *policy.PasswordLockoutPolicyAddedEvent:
|
case *policy.LockoutPolicyAddedEvent:
|
||||||
rm.MaxAttempts = e.MaxAttempts
|
rm.MaxAttempts = e.MaxPasswordAttempts
|
||||||
rm.ShowLockOutFailures = e.ShowLockOutFailures
|
rm.ShowLockOutFailures = e.ShowLockOutFailures
|
||||||
case *policy.PasswordLockoutPolicyChangedEvent:
|
case *policy.LockoutPolicyChangedEvent:
|
||||||
if e.MaxAttempts != nil {
|
if e.MaxPasswordAttempts != nil {
|
||||||
rm.MaxAttempts = *e.MaxAttempts
|
rm.MaxAttempts = *e.MaxPasswordAttempts
|
||||||
}
|
}
|
||||||
if e.ShowLockOutFailures != nil {
|
if e.ShowLockOutFailures != nil {
|
||||||
rm.ShowLockOutFailures = *e.ShowLockOutFailures
|
rm.ShowLockOutFailures = *e.ShowLockOutFailures
|
||||||
|
@ -32,8 +32,8 @@ func RegisterEventMappers(es *eventstore.Eventstore) {
|
|||||||
RegisterFilterEventMapper(PasswordAgePolicyChangedEventType, PasswordAgePolicyChangedEventMapper).
|
RegisterFilterEventMapper(PasswordAgePolicyChangedEventType, PasswordAgePolicyChangedEventMapper).
|
||||||
RegisterFilterEventMapper(PasswordComplexityPolicyAddedEventType, PasswordComplexityPolicyAddedEventMapper).
|
RegisterFilterEventMapper(PasswordComplexityPolicyAddedEventType, PasswordComplexityPolicyAddedEventMapper).
|
||||||
RegisterFilterEventMapper(PasswordComplexityPolicyChangedEventType, PasswordComplexityPolicyChangedEventMapper).
|
RegisterFilterEventMapper(PasswordComplexityPolicyChangedEventType, PasswordComplexityPolicyChangedEventMapper).
|
||||||
RegisterFilterEventMapper(PasswordLockoutPolicyAddedEventType, PasswordLockoutPolicyAddedEventMapper).
|
RegisterFilterEventMapper(LockoutPolicyAddedEventType, LockoutPolicyAddedEventMapper).
|
||||||
RegisterFilterEventMapper(PasswordLockoutPolicyChangedEventType, PasswordLockoutPolicyChangedEventMapper).
|
RegisterFilterEventMapper(LockoutPolicyChangedEventType, LockoutPolicyChangedEventMapper).
|
||||||
RegisterFilterEventMapper(PrivacyPolicyAddedEventType, PrivacyPolicyAddedEventMapper).
|
RegisterFilterEventMapper(PrivacyPolicyAddedEventType, PrivacyPolicyAddedEventMapper).
|
||||||
RegisterFilterEventMapper(PrivacyPolicyChangedEventType, PrivacyPolicyChangedEventMapper).
|
RegisterFilterEventMapper(PrivacyPolicyChangedEventType, PrivacyPolicyChangedEventMapper).
|
||||||
RegisterFilterEventMapper(MemberAddedEventType, MemberAddedEventMapper).
|
RegisterFilterEventMapper(MemberAddedEventType, MemberAddedEventMapper).
|
||||||
|
@ -9,67 +9,67 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
PasswordLockoutPolicyAddedEventType = iamEventTypePrefix + policy.PasswordLockoutPolicyAddedEventType
|
LockoutPolicyAddedEventType = iamEventTypePrefix + policy.LockoutPolicyAddedEventType
|
||||||
PasswordLockoutPolicyChangedEventType = iamEventTypePrefix + policy.PasswordLockoutPolicyChangedEventType
|
LockoutPolicyChangedEventType = iamEventTypePrefix + policy.LockoutPolicyChangedEventType
|
||||||
)
|
)
|
||||||
|
|
||||||
type PasswordLockoutPolicyAddedEvent struct {
|
type LockoutPolicyAddedEvent struct {
|
||||||
policy.PasswordLockoutPolicyAddedEvent
|
policy.LockoutPolicyAddedEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPasswordLockoutPolicyAddedEvent(
|
func NewLockoutPolicyAddedEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
aggregate *eventstore.Aggregate,
|
aggregate *eventstore.Aggregate,
|
||||||
maxAttempts uint64,
|
maxAttempts uint64,
|
||||||
showLockoutFailure bool,
|
showLockoutFailure bool,
|
||||||
) *PasswordLockoutPolicyAddedEvent {
|
) *LockoutPolicyAddedEvent {
|
||||||
return &PasswordLockoutPolicyAddedEvent{
|
return &LockoutPolicyAddedEvent{
|
||||||
PasswordLockoutPolicyAddedEvent: *policy.NewPasswordLockoutPolicyAddedEvent(
|
LockoutPolicyAddedEvent: *policy.NewLockoutPolicyAddedEvent(
|
||||||
eventstore.NewBaseEventForPush(
|
eventstore.NewBaseEventForPush(
|
||||||
ctx,
|
ctx,
|
||||||
aggregate,
|
aggregate,
|
||||||
PasswordLockoutPolicyAddedEventType),
|
LockoutPolicyAddedEventType),
|
||||||
maxAttempts,
|
maxAttempts,
|
||||||
showLockoutFailure),
|
showLockoutFailure),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func PasswordLockoutPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
func LockoutPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||||
e, err := policy.PasswordLockoutPolicyAddedEventMapper(event)
|
e, err := policy.LockoutPolicyAddedEventMapper(event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &PasswordLockoutPolicyAddedEvent{PasswordLockoutPolicyAddedEvent: *e.(*policy.PasswordLockoutPolicyAddedEvent)}, nil
|
return &LockoutPolicyAddedEvent{LockoutPolicyAddedEvent: *e.(*policy.LockoutPolicyAddedEvent)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type PasswordLockoutPolicyChangedEvent struct {
|
type LockoutPolicyChangedEvent struct {
|
||||||
policy.PasswordLockoutPolicyChangedEvent
|
policy.LockoutPolicyChangedEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPasswordLockoutPolicyChangedEvent(
|
func NewLockoutPolicyChangedEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
aggregate *eventstore.Aggregate,
|
aggregate *eventstore.Aggregate,
|
||||||
changes []policy.PasswordLockoutPolicyChanges,
|
changes []policy.LockoutPolicyChanges,
|
||||||
) (*PasswordLockoutPolicyChangedEvent, error) {
|
) (*LockoutPolicyChangedEvent, error) {
|
||||||
changedEvent, err := policy.NewPasswordLockoutPolicyChangedEvent(
|
changedEvent, err := policy.NewLockoutPolicyChangedEvent(
|
||||||
eventstore.NewBaseEventForPush(
|
eventstore.NewBaseEventForPush(
|
||||||
ctx,
|
ctx,
|
||||||
aggregate,
|
aggregate,
|
||||||
PasswordLockoutPolicyChangedEventType),
|
LockoutPolicyChangedEventType),
|
||||||
changes,
|
changes,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &PasswordLockoutPolicyChangedEvent{PasswordLockoutPolicyChangedEvent: *changedEvent}, nil
|
return &LockoutPolicyChangedEvent{LockoutPolicyChangedEvent: *changedEvent}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func PasswordLockoutPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
func LockoutPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||||
e, err := policy.PasswordLockoutPolicyChangedEventMapper(event)
|
e, err := policy.LockoutPolicyChangedEventMapper(event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &PasswordLockoutPolicyChangedEvent{PasswordLockoutPolicyChangedEvent: *e.(*policy.PasswordLockoutPolicyChangedEvent)}, nil
|
return &LockoutPolicyChangedEvent{LockoutPolicyChangedEvent: *e.(*policy.LockoutPolicyChangedEvent)}, nil
|
||||||
}
|
}
|
||||||
|
@ -53,9 +53,9 @@ func RegisterEventMappers(es *eventstore.Eventstore) {
|
|||||||
RegisterFilterEventMapper(PasswordComplexityPolicyAddedEventType, PasswordComplexityPolicyAddedEventMapper).
|
RegisterFilterEventMapper(PasswordComplexityPolicyAddedEventType, PasswordComplexityPolicyAddedEventMapper).
|
||||||
RegisterFilterEventMapper(PasswordComplexityPolicyChangedEventType, PasswordComplexityPolicyChangedEventMapper).
|
RegisterFilterEventMapper(PasswordComplexityPolicyChangedEventType, PasswordComplexityPolicyChangedEventMapper).
|
||||||
RegisterFilterEventMapper(PasswordComplexityPolicyRemovedEventType, PasswordComplexityPolicyRemovedEventMapper).
|
RegisterFilterEventMapper(PasswordComplexityPolicyRemovedEventType, PasswordComplexityPolicyRemovedEventMapper).
|
||||||
RegisterFilterEventMapper(PasswordLockoutPolicyAddedEventType, PasswordLockoutPolicyAddedEventMapper).
|
RegisterFilterEventMapper(LockoutPolicyAddedEventType, LockoutPolicyAddedEventMapper).
|
||||||
RegisterFilterEventMapper(PasswordLockoutPolicyChangedEventType, PasswordLockoutPolicyChangedEventMapper).
|
RegisterFilterEventMapper(LockoutPolicyChangedEventType, LockoutPolicyChangedEventMapper).
|
||||||
RegisterFilterEventMapper(PasswordLockoutPolicyRemovedEventType, PasswordLockoutPolicyRemovedEventMapper).
|
RegisterFilterEventMapper(LockoutPolicyRemovedEventType, LockoutPolicyRemovedEventMapper).
|
||||||
RegisterFilterEventMapper(PrivacyPolicyAddedEventType, PrivacyPolicyAddedEventMapper).
|
RegisterFilterEventMapper(PrivacyPolicyAddedEventType, PrivacyPolicyAddedEventMapper).
|
||||||
RegisterFilterEventMapper(PrivacyPolicyChangedEventType, PrivacyPolicyChangedEventMapper).
|
RegisterFilterEventMapper(PrivacyPolicyChangedEventType, PrivacyPolicyChangedEventMapper).
|
||||||
RegisterFilterEventMapper(PrivacyPolicyRemovedEventType, PrivacyPolicyRemovedEventMapper).
|
RegisterFilterEventMapper(PrivacyPolicyRemovedEventType, PrivacyPolicyRemovedEventMapper).
|
||||||
|
@ -9,95 +9,95 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
PasswordLockoutPolicyAddedEventType = orgEventTypePrefix + policy.PasswordLockoutPolicyAddedEventType
|
LockoutPolicyAddedEventType = orgEventTypePrefix + policy.LockoutPolicyAddedEventType
|
||||||
PasswordLockoutPolicyChangedEventType = orgEventTypePrefix + policy.PasswordLockoutPolicyChangedEventType
|
LockoutPolicyChangedEventType = orgEventTypePrefix + policy.LockoutPolicyChangedEventType
|
||||||
PasswordLockoutPolicyRemovedEventType = orgEventTypePrefix + policy.PasswordLockoutPolicyRemovedEventType
|
LockoutPolicyRemovedEventType = orgEventTypePrefix + policy.LockoutPolicyRemovedEventType
|
||||||
)
|
)
|
||||||
|
|
||||||
type PasswordLockoutPolicyAddedEvent struct {
|
type LockoutPolicyAddedEvent struct {
|
||||||
policy.PasswordLockoutPolicyAddedEvent
|
policy.LockoutPolicyAddedEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPasswordLockoutPolicyAddedEvent(
|
func NewLockoutPolicyAddedEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
aggregate *eventstore.Aggregate,
|
aggregate *eventstore.Aggregate,
|
||||||
maxAttempts uint64,
|
maxAttempts uint64,
|
||||||
showLockoutFailure bool,
|
showLockoutFailure bool,
|
||||||
) *PasswordLockoutPolicyAddedEvent {
|
) *LockoutPolicyAddedEvent {
|
||||||
return &PasswordLockoutPolicyAddedEvent{
|
return &LockoutPolicyAddedEvent{
|
||||||
PasswordLockoutPolicyAddedEvent: *policy.NewPasswordLockoutPolicyAddedEvent(
|
LockoutPolicyAddedEvent: *policy.NewLockoutPolicyAddedEvent(
|
||||||
eventstore.NewBaseEventForPush(
|
eventstore.NewBaseEventForPush(
|
||||||
ctx,
|
ctx,
|
||||||
aggregate,
|
aggregate,
|
||||||
PasswordLockoutPolicyAddedEventType),
|
LockoutPolicyAddedEventType),
|
||||||
maxAttempts,
|
maxAttempts,
|
||||||
showLockoutFailure),
|
showLockoutFailure),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func PasswordLockoutPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
func LockoutPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||||
e, err := policy.PasswordLockoutPolicyAddedEventMapper(event)
|
e, err := policy.LockoutPolicyAddedEventMapper(event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &PasswordLockoutPolicyAddedEvent{PasswordLockoutPolicyAddedEvent: *e.(*policy.PasswordLockoutPolicyAddedEvent)}, nil
|
return &LockoutPolicyAddedEvent{LockoutPolicyAddedEvent: *e.(*policy.LockoutPolicyAddedEvent)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type PasswordLockoutPolicyChangedEvent struct {
|
type LockoutPolicyChangedEvent struct {
|
||||||
policy.PasswordLockoutPolicyChangedEvent
|
policy.LockoutPolicyChangedEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPasswordLockoutPolicyChangedEvent(
|
func NewLockoutPolicyChangedEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
aggregate *eventstore.Aggregate,
|
aggregate *eventstore.Aggregate,
|
||||||
changes []policy.PasswordLockoutPolicyChanges,
|
changes []policy.LockoutPolicyChanges,
|
||||||
) (*PasswordLockoutPolicyChangedEvent, error) {
|
) (*LockoutPolicyChangedEvent, error) {
|
||||||
changedEvent, err := policy.NewPasswordLockoutPolicyChangedEvent(
|
changedEvent, err := policy.NewLockoutPolicyChangedEvent(
|
||||||
eventstore.NewBaseEventForPush(
|
eventstore.NewBaseEventForPush(
|
||||||
ctx,
|
ctx,
|
||||||
aggregate,
|
aggregate,
|
||||||
PasswordLockoutPolicyChangedEventType),
|
LockoutPolicyChangedEventType),
|
||||||
changes,
|
changes,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &PasswordLockoutPolicyChangedEvent{PasswordLockoutPolicyChangedEvent: *changedEvent}, nil
|
return &LockoutPolicyChangedEvent{LockoutPolicyChangedEvent: *changedEvent}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func PasswordLockoutPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
func LockoutPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||||
e, err := policy.PasswordLockoutPolicyChangedEventMapper(event)
|
e, err := policy.LockoutPolicyChangedEventMapper(event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &PasswordLockoutPolicyChangedEvent{PasswordLockoutPolicyChangedEvent: *e.(*policy.PasswordLockoutPolicyChangedEvent)}, nil
|
return &LockoutPolicyChangedEvent{LockoutPolicyChangedEvent: *e.(*policy.LockoutPolicyChangedEvent)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type PasswordLockoutPolicyRemovedEvent struct {
|
type LockoutPolicyRemovedEvent struct {
|
||||||
policy.PasswordLockoutPolicyRemovedEvent
|
policy.LockoutPolicyRemovedEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPasswordLockoutPolicyRemovedEvent(
|
func NewLockoutPolicyRemovedEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
aggregate *eventstore.Aggregate,
|
aggregate *eventstore.Aggregate,
|
||||||
) *PasswordLockoutPolicyRemovedEvent {
|
) *LockoutPolicyRemovedEvent {
|
||||||
return &PasswordLockoutPolicyRemovedEvent{
|
return &LockoutPolicyRemovedEvent{
|
||||||
PasswordLockoutPolicyRemovedEvent: *policy.NewPasswordLockoutPolicyRemovedEvent(
|
LockoutPolicyRemovedEvent: *policy.NewLockoutPolicyRemovedEvent(
|
||||||
eventstore.NewBaseEventForPush(
|
eventstore.NewBaseEventForPush(
|
||||||
ctx,
|
ctx,
|
||||||
aggregate,
|
aggregate,
|
||||||
PasswordLockoutPolicyRemovedEventType),
|
LockoutPolicyRemovedEventType),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func PasswordLockoutPolicyRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
func LockoutPolicyRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||||
e, err := policy.PasswordLockoutPolicyRemovedEventMapper(event)
|
e, err := policy.LockoutPolicyRemovedEventMapper(event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &PasswordLockoutPolicyRemovedEvent{PasswordLockoutPolicyRemovedEvent: *e.(*policy.PasswordLockoutPolicyRemovedEvent)}, nil
|
return &LockoutPolicyRemovedEvent{LockoutPolicyRemovedEvent: *e.(*policy.LockoutPolicyRemovedEvent)}, nil
|
||||||
}
|
}
|
||||||
|
@ -9,41 +9,41 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PasswordLockoutPolicyAddedEventType = "policy.password.lockout.added"
|
LockoutPolicyAddedEventType = "policy.lockout.added"
|
||||||
PasswordLockoutPolicyChangedEventType = "policy.password.lockout.changed"
|
LockoutPolicyChangedEventType = "policy.lockout.changed"
|
||||||
PasswordLockoutPolicyRemovedEventType = "policy.password.lockout.removed"
|
LockoutPolicyRemovedEventType = "policy.lockout.removed"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PasswordLockoutPolicyAddedEvent struct {
|
type LockoutPolicyAddedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
MaxAttempts uint64 `json:"maxAttempts,omitempty"`
|
MaxPasswordAttempts uint64 `json:"maxPasswordAttempts,omitempty"`
|
||||||
ShowLockOutFailures bool `json:"showLockOutFailures,omitempty"`
|
ShowLockOutFailures bool `json:"showLockOutFailures,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *PasswordLockoutPolicyAddedEvent) Data() interface{} {
|
func (e *LockoutPolicyAddedEvent) Data() interface{} {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *PasswordLockoutPolicyAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
func (e *LockoutPolicyAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPasswordLockoutPolicyAddedEvent(
|
func NewLockoutPolicyAddedEvent(
|
||||||
base *eventstore.BaseEvent,
|
base *eventstore.BaseEvent,
|
||||||
maxAttempts uint64,
|
maxAttempts uint64,
|
||||||
showLockOutFailures bool,
|
showLockOutFailures bool,
|
||||||
) *PasswordLockoutPolicyAddedEvent {
|
) *LockoutPolicyAddedEvent {
|
||||||
|
|
||||||
return &PasswordLockoutPolicyAddedEvent{
|
return &LockoutPolicyAddedEvent{
|
||||||
BaseEvent: *base,
|
BaseEvent: *base,
|
||||||
MaxAttempts: maxAttempts,
|
MaxPasswordAttempts: maxAttempts,
|
||||||
ShowLockOutFailures: showLockOutFailures,
|
ShowLockOutFailures: showLockOutFailures,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func PasswordLockoutPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
func LockoutPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||||
e := &PasswordLockoutPolicyAddedEvent{
|
e := &LockoutPolicyAddedEvent{
|
||||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,29 +55,29 @@ func PasswordLockoutPolicyAddedEventMapper(event *repository.Event) (eventstore.
|
|||||||
return e, nil
|
return e, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type PasswordLockoutPolicyChangedEvent struct {
|
type LockoutPolicyChangedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
MaxAttempts *uint64 `json:"maxAttempts,omitempty"`
|
MaxPasswordAttempts *uint64 `json:"maxPasswordAttempts,omitempty"`
|
||||||
ShowLockOutFailures *bool `json:"showLockOutFailures,omitempty"`
|
ShowLockOutFailures *bool `json:"showLockOutFailures,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *PasswordLockoutPolicyChangedEvent) Data() interface{} {
|
func (e *LockoutPolicyChangedEvent) Data() interface{} {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *PasswordLockoutPolicyChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
func (e *LockoutPolicyChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPasswordLockoutPolicyChangedEvent(
|
func NewLockoutPolicyChangedEvent(
|
||||||
base *eventstore.BaseEvent,
|
base *eventstore.BaseEvent,
|
||||||
changes []PasswordLockoutPolicyChanges,
|
changes []LockoutPolicyChanges,
|
||||||
) (*PasswordLockoutPolicyChangedEvent, error) {
|
) (*LockoutPolicyChangedEvent, error) {
|
||||||
if len(changes) == 0 {
|
if len(changes) == 0 {
|
||||||
return nil, errors.ThrowPreconditionFailed(nil, "POLICY-sdgh6", "Errors.NoChangesFound")
|
return nil, errors.ThrowPreconditionFailed(nil, "POLICY-sdgh6", "Errors.NoChangesFound")
|
||||||
}
|
}
|
||||||
changeEvent := &PasswordLockoutPolicyChangedEvent{
|
changeEvent := &LockoutPolicyChangedEvent{
|
||||||
BaseEvent: *base,
|
BaseEvent: *base,
|
||||||
}
|
}
|
||||||
for _, change := range changes {
|
for _, change := range changes {
|
||||||
@ -86,22 +86,22 @@ func NewPasswordLockoutPolicyChangedEvent(
|
|||||||
return changeEvent, nil
|
return changeEvent, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type PasswordLockoutPolicyChanges func(*PasswordLockoutPolicyChangedEvent)
|
type LockoutPolicyChanges func(*LockoutPolicyChangedEvent)
|
||||||
|
|
||||||
func ChangeMaxAttempts(maxAttempts uint64) func(*PasswordLockoutPolicyChangedEvent) {
|
func ChangeMaxAttempts(maxAttempts uint64) func(*LockoutPolicyChangedEvent) {
|
||||||
return func(e *PasswordLockoutPolicyChangedEvent) {
|
return func(e *LockoutPolicyChangedEvent) {
|
||||||
e.MaxAttempts = &maxAttempts
|
e.MaxPasswordAttempts = &maxAttempts
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ChangeShowLockOutFailures(showLockOutFailures bool) func(*PasswordLockoutPolicyChangedEvent) {
|
func ChangeShowLockOutFailures(showLockOutFailures bool) func(*LockoutPolicyChangedEvent) {
|
||||||
return func(e *PasswordLockoutPolicyChangedEvent) {
|
return func(e *LockoutPolicyChangedEvent) {
|
||||||
e.ShowLockOutFailures = &showLockOutFailures
|
e.ShowLockOutFailures = &showLockOutFailures
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func PasswordLockoutPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
func LockoutPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||||
e := &PasswordLockoutPolicyChangedEvent{
|
e := &LockoutPolicyChangedEvent{
|
||||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,26 +113,26 @@ func PasswordLockoutPolicyChangedEventMapper(event *repository.Event) (eventstor
|
|||||||
return e, nil
|
return e, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type PasswordLockoutPolicyRemovedEvent struct {
|
type LockoutPolicyRemovedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
eventstore.BaseEvent `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *PasswordLockoutPolicyRemovedEvent) Data() interface{} {
|
func (e *LockoutPolicyRemovedEvent) Data() interface{} {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *PasswordLockoutPolicyRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
func (e *LockoutPolicyRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPasswordLockoutPolicyRemovedEvent(base *eventstore.BaseEvent) *PasswordLockoutPolicyRemovedEvent {
|
func NewLockoutPolicyRemovedEvent(base *eventstore.BaseEvent) *LockoutPolicyRemovedEvent {
|
||||||
return &PasswordLockoutPolicyRemovedEvent{
|
return &LockoutPolicyRemovedEvent{
|
||||||
BaseEvent: *base,
|
BaseEvent: *base,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func PasswordLockoutPolicyRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
func LockoutPolicyRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||||
return &PasswordLockoutPolicyRemovedEvent{
|
return &LockoutPolicyRemovedEvent{
|
||||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ type IAMSetUp struct {
|
|||||||
Step15 *command.Step15
|
Step15 *command.Step15
|
||||||
Step16 *command.Step16
|
Step16 *command.Step16
|
||||||
Step17 *command.Step17
|
Step17 *command.Step17
|
||||||
|
Step18 *command.Step18
|
||||||
}
|
}
|
||||||
|
|
||||||
func (setup *IAMSetUp) Steps(currentDone domain.Step) ([]command.Step, error) {
|
func (setup *IAMSetUp) Steps(currentDone domain.Step) ([]command.Step, error) {
|
||||||
@ -46,6 +47,7 @@ func (setup *IAMSetUp) Steps(currentDone domain.Step) ([]command.Step, error) {
|
|||||||
setup.Step15,
|
setup.Step15,
|
||||||
setup.Step16,
|
setup.Step16,
|
||||||
setup.Step17,
|
setup.Step17,
|
||||||
|
setup.Step18,
|
||||||
} {
|
} {
|
||||||
if step.Step() <= currentDone {
|
if step.Step() <= currentDone {
|
||||||
continue
|
continue
|
||||||
|
@ -231,6 +231,10 @@ func (l *Login) renderNextStep(w http.ResponseWriter, r *http.Request, authReq *
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *Login) renderError(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, err error) {
|
func (l *Login) renderError(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, err error) {
|
||||||
|
if err != nil {
|
||||||
|
l.renderInternalError(w, r, authReq, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
if authReq == nil || len(authReq.PossibleSteps) == 0 {
|
if authReq == nil || len(authReq.PossibleSteps) == 0 {
|
||||||
l.renderInternalError(w, r, authReq, caos_errs.ThrowInternal(err, "APP-OVOiT", "no possible steps"))
|
l.renderInternalError(w, r, authReq, caos_errs.ThrowInternal(err, "APP-OVOiT", "no possible steps"))
|
||||||
return
|
return
|
||||||
@ -292,7 +296,7 @@ func (l *Login) chooseNextStep(w http.ResponseWriter, r *http.Request, authReq *
|
|||||||
func (l *Login) renderInternalError(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, err error) {
|
func (l *Login) renderInternalError(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, err error) {
|
||||||
var msg string
|
var msg string
|
||||||
if err != nil {
|
if err != nil {
|
||||||
msg = err.Error()
|
_, msg = l.getErrorMessage(r, err)
|
||||||
}
|
}
|
||||||
data := l.getBaseData(r, authReq, "Error", "Internal", msg)
|
data := l.getBaseData(r, authReq, "Error", "Internal", msg)
|
||||||
l.renderer.RenderTemplate(w, r, l.getTranslator(authReq), l.renderer.Templates[tmplError], data, nil)
|
l.renderer.RenderTemplate(w, r, l.getTranslator(authReq), l.renderer.Templates[tmplError], data, nil)
|
||||||
|
@ -288,6 +288,7 @@ Errors:
|
|||||||
ConfirmationWrong: Passwort Bestätigung stimmt nicht überein
|
ConfirmationWrong: Passwort Bestätigung stimmt nicht überein
|
||||||
Empty: Passwort ist leer
|
Empty: Passwort ist leer
|
||||||
Invalid: Passwort ungültig
|
Invalid: Passwort ungültig
|
||||||
|
InvalidAndLocked: Password ist undgültig und Benutzer wurde gesperrt, melden Sie sich bei ihrem Administrator.
|
||||||
PasswordComplexityPolicy:
|
PasswordComplexityPolicy:
|
||||||
NotFound: Passwort Policy konnte nicht gefunden werden
|
NotFound: Passwort Policy konnte nicht gefunden werden
|
||||||
MinLength: Passwort ist zu kurz
|
MinLength: Passwort ist zu kurz
|
||||||
@ -312,6 +313,7 @@ Errors:
|
|||||||
InvalidCode: Code ist ungültig
|
InvalidCode: Code ist ungültig
|
||||||
NotReady: Multifaktor OTP (OneTimePassword) ist nicht bereit
|
NotReady: Multifaktor OTP (OneTimePassword) ist nicht bereit
|
||||||
Locked: Benutzer ist gesperrt
|
Locked: Benutzer ist gesperrt
|
||||||
|
SomethingWentWrong: Irgendetwas ist schief gelaufen
|
||||||
NotActive: Benutzer ist nicht aktiv
|
NotActive: Benutzer ist nicht aktiv
|
||||||
ExternalIDP:
|
ExternalIDP:
|
||||||
IDPTypeNotImplemented: IDP Typ ist nicht implementiert
|
IDPTypeNotImplemented: IDP Typ ist nicht implementiert
|
||||||
@ -319,5 +321,8 @@ Errors:
|
|||||||
GrantRequired: Der Login an diese Applikation ist nicht möglich. Der Benutzer benötigt mindestens eine Berechtigung an der Applikation. Bitte melde dich bei deinem Administrator.
|
GrantRequired: Der Login an diese Applikation ist nicht möglich. Der Benutzer benötigt mindestens eine Berechtigung an der Applikation. Bitte melde dich bei deinem Administrator.
|
||||||
IdentityProvider:
|
IdentityProvider:
|
||||||
InvalidConfig: Identitäts Provider Konfiguration ist ungültig
|
InvalidConfig: Identitäts Provider Konfiguration ist ungültig
|
||||||
|
IAM:
|
||||||
|
LockoutPolicy:
|
||||||
|
NotExisting: Lockout Policy existiert nicht
|
||||||
|
|
||||||
optional: (optional)
|
optional: (optional)
|
||||||
|
@ -288,6 +288,7 @@ Errors:
|
|||||||
ConfirmationWrong: Passwordconfirmation is wrong
|
ConfirmationWrong: Passwordconfirmation is wrong
|
||||||
Empty: Password is empty
|
Empty: Password is empty
|
||||||
Invalid: Password is invalid
|
Invalid: Password is invalid
|
||||||
|
InvalidAndLocked: Password is invalid and user is locked, contact your administrator.
|
||||||
PasswordComplexityPolicy:
|
PasswordComplexityPolicy:
|
||||||
NotFound: Password policy not found
|
NotFound: Password policy not found
|
||||||
MinLength: Password is to short
|
MinLength: Password is to short
|
||||||
@ -312,6 +313,7 @@ Errors:
|
|||||||
InvalidCode: Invalid code
|
InvalidCode: Invalid code
|
||||||
NotReady: Multifactor OTP (OneTimePassword) isn't ready
|
NotReady: Multifactor OTP (OneTimePassword) isn't ready
|
||||||
Locked: User is locked
|
Locked: User is locked
|
||||||
|
SomethingWentWrong: Something went wrong
|
||||||
NotActive: User is not active
|
NotActive: User is not active
|
||||||
ExternalIDP:
|
ExternalIDP:
|
||||||
IDPTypeNotImplemented: IDP Type is not implemented
|
IDPTypeNotImplemented: IDP Type is not implemented
|
||||||
@ -319,5 +321,8 @@ Errors:
|
|||||||
GrantRequired: Login not possible. The user is required to have at least one grant on the application. Please contact your administrator.
|
GrantRequired: Login not possible. The user is required to have at least one grant on the application. Please contact your administrator.
|
||||||
IdentityProvider:
|
IdentityProvider:
|
||||||
InvalidConfig: Identity Provider configuration is invalid
|
InvalidConfig: Identity Provider configuration is invalid
|
||||||
|
IAM:
|
||||||
|
LockoutPolicy:
|
||||||
|
NotExisting: Lockout Policy not existing
|
||||||
|
|
||||||
optional: (optional)
|
optional: (optional)
|
||||||
|
45
migrations/cockroach/V1.59__user_lock.sql
Normal file
45
migrations/cockroach/V1.59__user_lock.sql
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
CREATE TABLE management.lockout_policies (
|
||||||
|
aggregate_id TEXT,
|
||||||
|
|
||||||
|
creation_date TIMESTAMPTZ,
|
||||||
|
change_date TIMESTAMPTZ,
|
||||||
|
lockout_policy_state SMALLINT,
|
||||||
|
sequence BIGINT,
|
||||||
|
|
||||||
|
max_password_attempts BIGINT,
|
||||||
|
show_lockout_failures BOOLEAN,
|
||||||
|
|
||||||
|
PRIMARY KEY (aggregate_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE adminapi.lockout_policies (
|
||||||
|
aggregate_id TEXT,
|
||||||
|
|
||||||
|
creation_date TIMESTAMPTZ,
|
||||||
|
change_date TIMESTAMPTZ,
|
||||||
|
lockout_policy_state SMALLINT,
|
||||||
|
sequence BIGINT,
|
||||||
|
|
||||||
|
max_password_attempts BIGINT,
|
||||||
|
show_lockout_failures BOOLEAN,
|
||||||
|
|
||||||
|
PRIMARY KEY (aggregate_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE auth.lockout_policies (
|
||||||
|
aggregate_id TEXT,
|
||||||
|
|
||||||
|
creation_date TIMESTAMPTZ,
|
||||||
|
change_date TIMESTAMPTZ,
|
||||||
|
lockout_policy_state SMALLINT,
|
||||||
|
sequence BIGINT,
|
||||||
|
|
||||||
|
max_password_attempts BIGINT,
|
||||||
|
show_lockout_failures BOOLEAN,
|
||||||
|
|
||||||
|
PRIMARY KEY (aggregate_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
DROP TABLE management.password_lockout_policies;
|
||||||
|
DROP TABLE adminapi.password_lockout_policies;
|
||||||
|
DROP TABLE auth.password_lockout_policies;
|
@ -1425,10 +1425,10 @@ service AdminService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//Returns the password lockout policy defined by the administrators of ZITADEL
|
//Returns the lockout policy defined by the administrators of ZITADEL
|
||||||
rpc GetPasswordLockoutPolicy(GetPasswordLockoutPolicyRequest) returns (GetPasswordLockoutPolicyResponse) {
|
rpc GetLockoutPolicy(GetLockoutPolicyRequest) returns (GetLockoutPolicyResponse) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
get: "/policies/password/lockout";
|
get: "/policies/lockout";
|
||||||
};
|
};
|
||||||
|
|
||||||
option (zitadel.v1.auth_option) = {
|
option (zitadel.v1.auth_option) = {
|
||||||
@ -1437,20 +1437,19 @@ service AdminService {
|
|||||||
|
|
||||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||||
tags: "policy";
|
tags: "policy";
|
||||||
tags: "password policy";
|
tags: "lockout policy";
|
||||||
tags: "password lockout policy";
|
|
||||||
responses: {
|
responses: {
|
||||||
key: "200";
|
key: "200";
|
||||||
value: {
|
value: {
|
||||||
description: "default password lockout policy";
|
description: "default lockout policy";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//Updates the default password lockout policy of ZITADEL
|
//Updates the default lockout policy of ZITADEL
|
||||||
// it impacts all organisations without a customised policy
|
// it impacts all organisations without a customised policy
|
||||||
rpc UpdatePasswordLockoutPolicy(UpdatePasswordLockoutPolicyRequest) returns (UpdatePasswordLockoutPolicyResponse) {
|
rpc UpdateLockoutPolicy(UpdateLockoutPolicyRequest) returns (UpdateLockoutPolicyResponse) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
put: "/policies/password/lockout";
|
put: "/policies/password/lockout";
|
||||||
body: "*";
|
body: "*";
|
||||||
@ -3086,25 +3085,23 @@ message UpdatePasswordAgePolicyResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//This is an empty request
|
//This is an empty request
|
||||||
message GetPasswordLockoutPolicyRequest {}
|
message GetLockoutPolicyRequest {}
|
||||||
|
|
||||||
message GetPasswordLockoutPolicyResponse {
|
message GetLockoutPolicyResponse {
|
||||||
zitadel.policy.v1.PasswordLockoutPolicy policy = 1;
|
zitadel.policy.v1.LockoutPolicy policy = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdatePasswordLockoutPolicyRequest {
|
message UpdateLockoutPolicyRequest {
|
||||||
// failed attempts until a user gets locked
|
// failed attempts until a user gets locked
|
||||||
uint32 max_attempts = 1 [
|
uint32 max_password_attempts = 1 [
|
||||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
description: "Maximum attempts before the account gets locked. Attempts are reset as soon as the password is entered correct or the password is reset."
|
description: "Maximum password check attempts before the account gets locked. Attempts are reset as soon as the password is entered correct or the password is reset."
|
||||||
example: "\"10\""
|
example: "\"10\""
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
// If an error should be displayed during a lockout or not
|
|
||||||
bool show_lockout_failure = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdatePasswordLockoutPolicyResponse {
|
message UpdateLockoutPolicyResponse {
|
||||||
zitadel.v1.ObjectDetails details = 1;
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1971,10 +1971,9 @@ service ManagementService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// The password lockout policy is not used at the moment
|
rpc GetLockoutPolicy(GetLockoutPolicyRequest) returns (GetLockoutPolicyResponse) {
|
||||||
rpc GetPasswordLockoutPolicy(GetPasswordLockoutPolicyRequest) returns (GetPasswordLockoutPolicyResponse) {
|
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
get: "/policies/password/lockout"
|
get: "/policies/lockout"
|
||||||
};
|
};
|
||||||
|
|
||||||
option (zitadel.v1.auth_option) = {
|
option (zitadel.v1.auth_option) = {
|
||||||
@ -1982,10 +1981,9 @@ service ManagementService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// The password lockout policy is not used at the moment
|
rpc GetDefaultLockoutPolicy(GetDefaultLockoutPolicyRequest) returns (GetDefaultLockoutPolicyResponse) {
|
||||||
rpc GetDefaultPasswordLockoutPolicy(GetDefaultPasswordLockoutPolicyRequest) returns (GetDefaultPasswordLockoutPolicyResponse) {
|
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
get: "/policies/default/password/lockout"
|
get: "/policies/default/lockout"
|
||||||
};
|
};
|
||||||
|
|
||||||
option (zitadel.v1.auth_option) = {
|
option (zitadel.v1.auth_option) = {
|
||||||
@ -1993,10 +1991,9 @@ service ManagementService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// The password lockout policy is not used at the moment
|
rpc AddCustomLockoutPolicy(AddCustomLockoutPolicyRequest) returns (AddCustomLockoutPolicyResponse) {
|
||||||
rpc AddCustomPasswordLockoutPolicy(AddCustomPasswordLockoutPolicyRequest) returns (AddCustomPasswordLockoutPolicyResponse) {
|
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
post: "/policies/password/lockout"
|
post: "/policies/lockout"
|
||||||
body: "*"
|
body: "*"
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2005,10 +2002,9 @@ service ManagementService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// The password lockout policy is not used at the moment
|
rpc UpdateCustomLockoutPolicy(UpdateCustomLockoutPolicyRequest) returns (UpdateCustomLockoutPolicyResponse) {
|
||||||
rpc UpdateCustomPasswordLockoutPolicy(UpdateCustomPasswordLockoutPolicyRequest) returns (UpdateCustomPasswordLockoutPolicyResponse) {
|
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
put: "/policies/password/lockout"
|
put: "/policies/lockout"
|
||||||
body: "*"
|
body: "*"
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2017,10 +2013,9 @@ service ManagementService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// The password lockout policy is not used at the moment
|
rpc ResetLockoutPolicyToDefault(ResetLockoutPolicyToDefaultRequest) returns (ResetLockoutPolicyToDefaultResponse) {
|
||||||
rpc ResetPasswordLockoutPolicyToDefault(ResetPasswordLockoutPolicyToDefaultRequest) returns (ResetPasswordLockoutPolicyToDefaultResponse) {
|
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
delete: "/policies/password/lockout"
|
delete: "/policies/lockout"
|
||||||
};
|
};
|
||||||
|
|
||||||
option (zitadel.v1.auth_option) = {
|
option (zitadel.v1.auth_option) = {
|
||||||
@ -4275,42 +4270,40 @@ message ResetPasswordAgePolicyToDefaultResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//This is an empty request
|
//This is an empty request
|
||||||
message GetPasswordLockoutPolicyRequest {}
|
message GetLockoutPolicyRequest {}
|
||||||
|
|
||||||
message GetPasswordLockoutPolicyResponse {
|
message GetLockoutPolicyResponse {
|
||||||
zitadel.policy.v1.PasswordLockoutPolicy policy = 1;
|
zitadel.policy.v1.LockoutPolicy policy = 1;
|
||||||
bool is_default = 2;
|
bool is_default = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
//This is an empty request
|
//This is an empty request
|
||||||
message GetDefaultPasswordLockoutPolicyRequest {}
|
message GetDefaultLockoutPolicyRequest {}
|
||||||
|
|
||||||
message GetDefaultPasswordLockoutPolicyResponse {
|
message GetDefaultLockoutPolicyResponse {
|
||||||
zitadel.policy.v1.PasswordLockoutPolicy policy = 1;
|
zitadel.policy.v1.LockoutPolicy policy = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AddCustomPasswordLockoutPolicyRequest {
|
message AddCustomLockoutPolicyRequest {
|
||||||
uint32 max_attempts = 1;
|
uint32 max_password_attempts = 1;
|
||||||
bool show_lockout_failure = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message AddCustomPasswordLockoutPolicyResponse {
|
message AddCustomLockoutPolicyResponse {
|
||||||
zitadel.v1.ObjectDetails details = 1;
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdateCustomPasswordLockoutPolicyRequest {
|
message UpdateCustomLockoutPolicyRequest {
|
||||||
uint32 max_attempts = 1;
|
uint32 max_password_attempts = 1;
|
||||||
bool show_lockout_failure = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdateCustomPasswordLockoutPolicyResponse {
|
message UpdateCustomLockoutPolicyResponse {
|
||||||
zitadel.v1.ObjectDetails details = 1;
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//This is an empty request
|
//This is an empty request
|
||||||
message ResetPasswordLockoutPolicyToDefaultRequest {}
|
message ResetLockoutPolicyToDefaultRequest {}
|
||||||
|
|
||||||
message ResetPasswordLockoutPolicyToDefaultResponse {
|
message ResetLockoutPolicyToDefaultResponse {
|
||||||
zitadel.v1.ObjectDetails details = 1;
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user