mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-28 21:07:22 +00:00
cherry pick changes from main (#3371)
* feat: remove exif data from uploaded images (#3221) * feat: remove exif tags from images * feat: remove exif data * feat: remove exif * fix: add preferredLoginName to user grant response (#3271) * chore: log webauthn parse error (#3272) * log error * log error * feat: Help link in privacy policy * fix: convert correct detail data on organization (#3279) * fix: handle empty editor users * fix: add some missing translations (#3291) * fix: org policy translations * fix: metadata event types translation * fix: translations * fix: filter resource owner correctly on project grant members (#3281) * fix: filter resource owner correctly on project grant members * fix: filter resource owner correctly on project grant members * fix: add orgIDs to zitadel permissions request Co-authored-by: fabi <fabienne.gerschwiler@gmail.com> * fix: get IAM memberships correctly in MyZitadelPermissions (#3309) * fix: correct login names on auth and notification users (#3349) * fix: correct login names on auth and notification users * fix: migration * fix: handle resource owner in action flows (#3361) * fix merge * fix: exchange exif library (#3366) * fix: exchange exif library * ignore tiffs * requested fixes * feat: Help link in privacy policy Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: fabi <fabienne.gerschwiler@gmail.com>
This commit is contained in:
parent
56b916a2b0
commit
504fe5b761
@ -1,31 +1,42 @@
|
||||
<div *ngIf="currentMap">
|
||||
<div *ngIf="currentMap">
|
||||
|
||||
|
||||
<form [formGroup]="form" >
|
||||
<form [formGroup]="form">
|
||||
<ng-container *ngFor="let key of (current$ | async) | keyvalue">
|
||||
<div class="block">
|
||||
<div class="flex" *ngIf="(default$ | async) as defaultmap">
|
||||
<cnsl-form-field class="formfield" >
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{key.key}}</cnsl-label>
|
||||
<textarea class="text" cnslInput [formControlName]="key.key" [placeholder]="defaultmap[key.key]" [name]="key.key" [ngClass]="{'defaulttext': form.get(key.key)?.value === ''}"></textarea>
|
||||
<textarea class="text" cnslInput [formControlName]="key.key" [placeholder]="defaultmap[key.key]"
|
||||
[name]="key.key" [ngClass]="{'defaulttext': form.get(key.key)?.value === ''}"></textarea>
|
||||
<div class="chips" *ngIf="warnText[key.key] === undefined">
|
||||
<ng-container *ngFor="let chip of chips" >
|
||||
<div class="chip" cnslCopyToClipboard [valueToCopy]="chip.value" (copiedValue)="copied = $event" (click)="addChip(key.key, chip.value)">
|
||||
<span class="key">{{chip.key | translate}}</span>
|
||||
<span class="value">{{chip.value}}</span>
|
||||
<i *ngIf="copied !== chip.value" class="las la-clipboard"></i>
|
||||
<i *ngIf="copied === chip.value" class="las la-clipboard-check"></i>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container *ngFor="let chip of chips">
|
||||
<div class="chip" cnslCopyToClipboard [valueToCopy]="chip.value" (copiedValue)="copied = $event"
|
||||
(click)="addChip(key.key, chip.value)">
|
||||
<span class="key">{{chip.key | translate}}</span>
|
||||
<span class="value">{{chip.value}}</span>
|
||||
<i *ngIf="copied !== chip.value" class="las la-clipboard"></i>
|
||||
<i *ngIf="copied === chip.value" class="las la-clipboard-check"></i>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</cnsl-form-field>
|
||||
<div class="actions">
|
||||
<button matTooltip="{{'ACTIONS.RESETDEFAULT'| translate }}" mat-icon-button [disabled]="form.get(key.key)?.value === defaultmap[key.key] || disabled" (click)="form.get(key.key)?.setValue(defaultmap[key.key])" (mouseenter) = "form.get(key.key)?.value !== defaultmap[key.key] && setWarnText(key.key, defaultmap[key.key])" (mouseleave) ="setWarnText(key.key, undefined)"><i class="las la-history"></i></button>
|
||||
<button matTooltip="{{'ACTIONS.RESETCURRENT'| translate }}" mat-icon-button [disabled]="form.get(key.key)?.value === currentMap[key.key] || disabled" (click)="form.get(key.key)?.setValue(currentMap[key.key])" (mouseenter) = "form.get(key.key)?.value !== currentMap[key.key] && setWarnText(key.key, currentMap[key.key])" (mouseleave) ="setWarnText(key.key, undefined)"><i class="las la-undo"></i></button>
|
||||
<button matTooltip="{{'ACTIONS.RESETDEFAULT'| translate }}" mat-icon-button
|
||||
[disabled]="form.get(key.key)?.value === defaultmap[key.key] || disabled"
|
||||
(click)="form.get(key.key)?.setValue(defaultmap[key.key])"
|
||||
(mouseenter)="form.get(key.key)?.value !== defaultmap[key.key] && setWarnText(key.key, defaultmap[key.key])"
|
||||
(mouseleave)="setWarnText(key.key, undefined)"><i class="las la-history"></i></button>
|
||||
<button matTooltip="{{'ACTIONS.RESETCURRENT'| translate }}" mat-icon-button
|
||||
[disabled]="form.get(key.key)?.value === currentMap[key.key] || disabled"
|
||||
(click)="form.get(key.key)?.setValue(currentMap[key.key])"
|
||||
(mouseenter)="form.get(key.key)?.value !== currentMap[key.key] && setWarnText(key.key, currentMap[key.key])"
|
||||
(mouseleave)="setWarnText(key.key, undefined)"><i class="las la-undo"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<cnsl-info-section *ngIf="warnText[key.key] !== undefined" class="info" [type]="InfoSectionType.WARN">{{'ACTIONS.RESETTO'| translate }} <cite>'{{warnText[key.key]}}'</cite></cnsl-info-section>
|
||||
<cnsl-info-section *ngIf="warnText[key.key] !== undefined" class="info" [type]="InfoSectionType.WARN">
|
||||
{{'ACTIONS.RESETTO'| translate }} <cite>'{{warnText[key.key]}}'</cite></cnsl-info-section>
|
||||
</ng-container>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -71,7 +71,6 @@ export function mapRequestValues(map: Partial<Map>, req: Req): Req {
|
||||
|
||||
const r3 = new FooterText();
|
||||
r3.setHelp(map.footerText?.help ?? '');
|
||||
r3.setHelpLink(map.footerText?.helpLink ?? '');
|
||||
r3.setPrivacyPolicy(map.footerText?.privacyPolicy ?? '');
|
||||
r3.setTos(map.footerText?.tos ?? '');
|
||||
req.setFooterText(r3);
|
||||
@ -102,7 +101,6 @@ export function mapRequestValues(map: Partial<Map>, req: Req): Req {
|
||||
r6.setU2fOption(map.initMfaPromptText?.otpOption ?? '');
|
||||
req.setInitMfaPromptText(r6);
|
||||
|
||||
|
||||
const r7 = new InitMFAU2FScreenText();
|
||||
r7.setDescription(map.initMfaU2fText?.description ?? '');
|
||||
r7.setErrorRetry(map.initMfaU2fText?.errorRetry ?? '');
|
||||
@ -112,7 +110,6 @@ export function mapRequestValues(map: Partial<Map>, req: Req): Req {
|
||||
r7.setTokenNameLabel(map.initMfaU2fText?.tokenNameLabel ?? '');
|
||||
req.setInitMfaU2fText(r7);
|
||||
|
||||
|
||||
const r8 = new InitPasswordDoneScreenText();
|
||||
r8.setCancelButtonText(map.initPasswordDoneText?.cancelButtonText ?? '');
|
||||
r8.setDescription(map.initPasswordDoneText?.description ?? '');
|
||||
@ -348,7 +345,6 @@ export function mapRequestValues(map: Partial<Map>, req: Req): Req {
|
||||
r32.setTokenNameLabel(map.passwordlessRegistrationText?.tokenNameLabel ?? '');
|
||||
req.setPasswordlessRegistrationText(r32);
|
||||
|
||||
|
||||
const r33 = new PasswordlessScreenText();
|
||||
r33.setDescription(map.passwordlessText?.description ?? '');
|
||||
r33.setErrorRetry(map.passwordlessText?.errorRetry ?? '');
|
||||
|
@ -1,35 +1,59 @@
|
||||
<cnsl-detail-layout [backRouterLink]="[ serviceType === PolicyComponentServiceType.ADMIN ? '/iam/policies' : '/org']"
|
||||
[title]="'POLICY.PRIVACY_POLICY.TITLE' | translate"
|
||||
[description]="'POLICY.PRIVACY_POLICY.DESCRIPTION' | translate">
|
||||
[title]="'POLICY.PRIVACY_POLICY.TITLE' | translate" [description]="'POLICY.PRIVACY_POLICY.DESCRIPTION' | translate">
|
||||
|
||||
<cnsl-info-section *ngIf="isDefault"> {{'POLICY.DEFAULTLABEL' | translate}}</cnsl-info-section>
|
||||
|
||||
<cnsl-info-section *ngIf="serviceType === PolicyComponentServiceType.MGMT && (['privacy_policy'] | hasFeature | async) === false" [featureLink]="['/org/features']" class="info" [type]="InfoSectionType.WARN">
|
||||
<cnsl-info-section
|
||||
*ngIf="serviceType === PolicyComponentServiceType.MGMT && (['privacy_policy'] | hasFeature | async) === false"
|
||||
[featureLink]="['/org/features']" class="info" [type]="InfoSectionType.WARN">
|
||||
<span [innerHTML]="'FEATURES.NOTAVAILABLE' | translate: ({value: 'privacy_policy'})"></span>
|
||||
</cnsl-info-section>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="content" >
|
||||
<div class="content">
|
||||
<form *ngIf="form" [formGroup]="form">
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.TOSLINK' | translate }}</cnsl-label>
|
||||
<input cnslInput name="tosLink" formControlName="tosLink" />
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.TOSLINK' | translate }}</cnsl-label>
|
||||
<input cnslInput name="tosLink" formControlName="tosLink" />
|
||||
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{key: 'tosLink'}"></template>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.POLICYLINK' | translate }}</cnsl-label>
|
||||
<input cnslInput name="privacyLink" formControlName="privacyLink" />
|
||||
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{key: 'privacyLink'}"></template>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.HELPLINK' | translate }}</cnsl-label>
|
||||
<input cnslInput name="helpLink" formControlName="helpLink" />
|
||||
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{key: 'helpLink'}"></template>
|
||||
</cnsl-form-field>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<button *ngIf="!privacyPolicy?.isDefault" class="reset-button" [disabled]="serviceType === PolicyComponentServiceType.MGMT && (['privacy_policy'] | hasFeature | async) === false" (click)="resetDefault()" color="warn" type="submit"
|
||||
mat-stroked-button><i class="las la-history"></i> {{ 'ACTIONS.RESETDEFAULT' | translate }}</button>
|
||||
<button class="save-button" [disabled]="serviceType === PolicyComponentServiceType.MGMT && (['privacy_policy'] | hasFeature | async) === false" (click)="saveCurrentMessage()" color="primary" type="submit"
|
||||
mat-raised-button>{{ 'ACTIONS.SAVE' | translate }}</button>
|
||||
<button *ngIf="privacyPolicy && privacyPolicy.isDefault === false" class="reset-button"
|
||||
[disabled]="serviceType === PolicyComponentServiceType.MGMT && (['privacy_policy'] | hasFeature | async) === false"
|
||||
(click)="resetDefault()" color="warn" type="submit" mat-stroked-button><i class="las la-history"></i> {{
|
||||
'ACTIONS.RESETDEFAULT' | translate }}</button>
|
||||
<button class="save-button"
|
||||
[disabled]="serviceType === PolicyComponentServiceType.MGMT && (['privacy_policy'] | hasFeature | async) === false"
|
||||
(click)="saveCurrentMessage()" color="primary" type="submit" mat-raised-button>{{ 'ACTIONS.SAVE' | translate
|
||||
}}</button>
|
||||
</div>
|
||||
|
||||
<cnsl-policy-grid [currentPolicy]="currentPolicy" [type]="serviceType" tagForFilter="text"></cnsl-policy-grid>
|
||||
<cnsl-policy-grid [currentPolicy]="currentPolicy" [type]="serviceType" tagForFilter="text"></cnsl-policy-grid>
|
||||
</cnsl-detail-layout>
|
||||
|
||||
<ng-template #templateRef let-key="key">
|
||||
<div class="chips">
|
||||
<div class="chip" cnslCopyToClipboard [valueToCopy]="LANGPLACEHOLDER" (copiedValue)="copied = $event"
|
||||
(click)="addChip(key, LANGPLACEHOLDER)">
|
||||
<span class="key">{{LANGPLACEHOLDER}}</span>
|
||||
<i *ngIf="copied !== LANGPLACEHOLDER" class="las la-clipboard"></i>
|
||||
<i *ngIf="copied === LANGPLACEHOLDER" class="las la-clipboard-check"></i>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
@ -1,26 +1,26 @@
|
||||
.spinner-wr {
|
||||
margin: .5rem 0;
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
|
||||
.top-actions {
|
||||
display: flex;
|
||||
margin: 0 -.5rem;
|
||||
margin: 0 -0.5rem;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.keys {
|
||||
flex: 1;
|
||||
margin: 0 .5rem;
|
||||
margin: 0 0.5rem;
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
.language {
|
||||
margin: 0 .5rem;
|
||||
margin: 0 0.5rem;
|
||||
min-width: 150px;
|
||||
|
||||
.lighter {
|
||||
font-size: 12px;
|
||||
color: var(--grey);
|
||||
padding: 0 .5rem;
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -34,40 +34,66 @@
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.chips {
|
||||
display: flex;
|
||||
margin: 0 -.25rem;
|
||||
|
||||
.chip {
|
||||
border-radius: 50vw;
|
||||
padding: 2px .5rem;
|
||||
font-size: 12px;
|
||||
background: #cbf4c9;
|
||||
color: #0e6245;
|
||||
margin: .25rem;
|
||||
.privacy-policy-formfield {
|
||||
.chips {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10;
|
||||
flex-wrap: wrap;
|
||||
opacity: 0;
|
||||
margin: 0 -0.25rem;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
.chip {
|
||||
border-radius: 50vw;
|
||||
padding: 4px 0.5rem;
|
||||
font-size: 12px;
|
||||
background: #5282c1;
|
||||
color: white;
|
||||
margin: 0.25rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10;
|
||||
|
||||
* {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
i {
|
||||
opacity: 0.5;
|
||||
font-size: 1.1rem;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.key {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.cnsl-focused {
|
||||
.chips {
|
||||
opacity: 1;
|
||||
cursor: copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.divider {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: rgba(#81868a, .5);
|
||||
background-color: rgba(#81868a, 0.5);
|
||||
margin: 1.5rem 0 0 0;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin: 0 -.25rem;
|
||||
margin: 0 -0.25rem;
|
||||
|
||||
.save-button,
|
||||
.reset-button {
|
||||
display: block;
|
||||
margin: 0 .25rem 3rem .25rem;
|
||||
margin: 0 0.25rem 3rem 0.25rem;
|
||||
}
|
||||
|
||||
.reset-button {
|
||||
|
@ -37,11 +37,14 @@ export class PrivacyPolicyComponent implements OnDestroy {
|
||||
public nextLinks: CnslLinks[] = [];
|
||||
private sub: Subscription = new Subscription();
|
||||
|
||||
public privacyPolicy!: PrivacyPolicy.AsObject;
|
||||
public privacyPolicy: PrivacyPolicy.AsObject | undefined = undefined;
|
||||
public form!: FormGroup;
|
||||
public currentPolicy: GridPolicy = PRIVACY_POLICY;
|
||||
public InfoSectionType: any = InfoSectionType;
|
||||
|
||||
public LANGPLACEHOLDER: string = '{{.Lang}}';
|
||||
public copied: string = '';
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private injector: Injector,
|
||||
@ -49,70 +52,108 @@ export class PrivacyPolicyComponent implements OnDestroy {
|
||||
private toast: ToastService,
|
||||
private fb: FormBuilder,
|
||||
) {
|
||||
|
||||
this.form = this.fb.group({
|
||||
tosLink: ['', []],
|
||||
privacyLink: ['', []],
|
||||
helpLink: ['', []],
|
||||
});
|
||||
|
||||
this.route.data.pipe(switchMap(data => {
|
||||
this.serviceType = data.serviceType;
|
||||
switch (this.serviceType) {
|
||||
case PolicyComponentServiceType.MGMT:
|
||||
this.service = this.injector.get(ManagementService as Type<ManagementService>);
|
||||
this.loadData();
|
||||
break;
|
||||
case PolicyComponentServiceType.ADMIN:
|
||||
this.service = this.injector.get(AdminService as Type<AdminService>);
|
||||
this.loadData();
|
||||
break;
|
||||
}
|
||||
this.route.data
|
||||
.pipe(
|
||||
switchMap((data) => {
|
||||
this.serviceType = data.serviceType;
|
||||
switch (this.serviceType) {
|
||||
case PolicyComponentServiceType.MGMT:
|
||||
this.service = this.injector.get(ManagementService as Type<ManagementService>);
|
||||
this.loadData();
|
||||
break;
|
||||
case PolicyComponentServiceType.ADMIN:
|
||||
this.service = this.injector.get(AdminService as Type<AdminService>);
|
||||
this.loadData();
|
||||
break;
|
||||
}
|
||||
|
||||
return this.route.params;
|
||||
})).subscribe();
|
||||
return this.route.params;
|
||||
}),
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
public addChip(formControlName: string, value: string): void {
|
||||
const c = this.form.get(formControlName)?.value;
|
||||
this.form.get(formControlName)?.setValue(`${c}${value}`);
|
||||
}
|
||||
|
||||
public async loadData(): Promise<any> {
|
||||
const getData = ():
|
||||
Promise<AdminGetPrivacyPolicyResponse.AsObject | GetPrivacyPolicyResponse.AsObject> => {
|
||||
return (this.service as AdminService).getPrivacyPolicy();
|
||||
const getData = (): Promise<AdminGetPrivacyPolicyResponse.AsObject | GetPrivacyPolicyResponse.AsObject> => {
|
||||
return this.service.getPrivacyPolicy();
|
||||
};
|
||||
|
||||
getData().then(resp => {
|
||||
if (resp.policy) {
|
||||
this.privacyPolicy = resp.policy;
|
||||
this.form.patchValue(this.privacyPolicy);
|
||||
}
|
||||
});
|
||||
getData()
|
||||
.then((resp) => {
|
||||
if (resp.policy) {
|
||||
this.privacyPolicy = resp.policy;
|
||||
this.form.patchValue(this.privacyPolicy);
|
||||
} else {
|
||||
this.privacyPolicy = undefined;
|
||||
this.form.patchValue({
|
||||
tosLink: '',
|
||||
privacyLink: '',
|
||||
helpLink: '',
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.privacyPolicy = undefined;
|
||||
this.form.patchValue({
|
||||
tosLink: '',
|
||||
privacyLink: '',
|
||||
helpLink: '',
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public saveCurrentMessage(): void {
|
||||
console.log(this.form.get('privacyLink')?.value, this.form.get('tosLink')?.value);
|
||||
if (this.serviceType === PolicyComponentServiceType.MGMT) {
|
||||
if ((this.privacyPolicy as PrivacyPolicy.AsObject).isDefault) {
|
||||
if (!this.privacyPolicy || (this.privacyPolicy as PrivacyPolicy.AsObject).isDefault) {
|
||||
const req = new AddCustomPrivacyPolicyRequest();
|
||||
req.setPrivacyLink(this.form.get('privacyLink')?.value);
|
||||
req.setTosLink(this.form.get('tosLink')?.value);
|
||||
(this.service as ManagementService).addCustomPrivacyPolicy(req).then(() => {
|
||||
this.toast.showInfo('POLICY.PRIVACY_POLICY.SAVED', true);
|
||||
}).catch(error => this.toast.showError(error));
|
||||
req.setHelpLink(this.form.get('helpLink')?.value);
|
||||
(this.service as ManagementService)
|
||||
.addCustomPrivacyPolicy(req)
|
||||
.then(() => {
|
||||
this.toast.showInfo('POLICY.PRIVACY_POLICY.SAVED', true);
|
||||
this.loadData();
|
||||
})
|
||||
.catch((error) => this.toast.showError(error));
|
||||
} else {
|
||||
const req = new UpdateCustomPrivacyPolicyRequest();
|
||||
req.setPrivacyLink(this.form.get('privacyLink')?.value);
|
||||
req.setTosLink(this.form.get('tosLink')?.value);
|
||||
(this.service as ManagementService).updateCustomPrivacyPolicy(req).then(() => {
|
||||
this.toast.showInfo('POLICY.PRIVACY_POLICY.SAVED', true);
|
||||
}).catch(error => this.toast.showError(error));
|
||||
}
|
||||
req.setHelpLink(this.form.get('helpLink')?.value);
|
||||
|
||||
(this.service as ManagementService)
|
||||
.updateCustomPrivacyPolicy(req)
|
||||
.then(() => {
|
||||
this.toast.showInfo('POLICY.PRIVACY_POLICY.SAVED', true);
|
||||
this.loadData();
|
||||
})
|
||||
.catch((error) => this.toast.showError(error));
|
||||
}
|
||||
} else if (this.serviceType === PolicyComponentServiceType.ADMIN) {
|
||||
const req = new UpdatePrivacyPolicyRequest();
|
||||
req.setPrivacyLink(this.form.get('privacyLink')?.value);
|
||||
req.setTosLink(this.form.get('tosLink')?.value);
|
||||
req.setHelpLink(this.form.get('helpLink')?.value);
|
||||
|
||||
(this.service as AdminService).updatePrivacyPolicy(req).then(() => {
|
||||
this.toast.showInfo('POLICY.PRIVACY_POLICY.SAVED', true);
|
||||
}).catch(error => this.toast.showError(error));
|
||||
(this.service as AdminService)
|
||||
.updatePrivacyPolicy(req)
|
||||
.then(() => {
|
||||
this.toast.showInfo('POLICY.PRIVACY_POLICY.SAVED', true);
|
||||
this.loadData();
|
||||
})
|
||||
.catch((error) => this.toast.showError(error));
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,16 +169,19 @@ export class PrivacyPolicyComponent implements OnDestroy {
|
||||
width: '400px',
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(resp => {
|
||||
dialogRef.afterClosed().subscribe((resp) => {
|
||||
if (resp) {
|
||||
if (this.serviceType === PolicyComponentServiceType.MGMT) {
|
||||
(this.service as ManagementService).resetPrivacyPolicyToDefault().then(() => {
|
||||
setTimeout(() => {
|
||||
this.loadData();
|
||||
}, 1000);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
(this.service as ManagementService)
|
||||
.resetPrivacyPolicyToDefault()
|
||||
.then(() => {
|
||||
setTimeout(() => {
|
||||
this.loadData();
|
||||
}, 1000);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -9,6 +9,7 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { CopyToClipboardModule } from 'src/app/directives/copy-to-clipboard/copy-to-clipboard.module';
|
||||
|
||||
import { HasRoleModule } from '../../../directives/has-role/has-role.module';
|
||||
import { DetailLayoutModule } from '../../../modules/detail-layout/detail-layout.module';
|
||||
@ -32,6 +33,7 @@ import { PrivacyPolicyComponent } from './privacy-policy.component';
|
||||
FormsModule,
|
||||
InputModule,
|
||||
FormFieldModule,
|
||||
CopyToClipboardModule,
|
||||
MatButtonModule,
|
||||
HasFeaturePipeModule,
|
||||
MatIconModule,
|
||||
@ -49,4 +51,4 @@ import { PrivacyPolicyComponent } from './privacy-policy.component';
|
||||
InfoSectionModule,
|
||||
],
|
||||
})
|
||||
export class PrivacyPolicyModule { }
|
||||
export class PrivacyPolicyModule {}
|
||||
|
@ -873,6 +873,7 @@
|
||||
"DESCRIPTION": "Legen Sie Ihre Datenschutzrichtlinien und Nutzungsbedingungen fest",
|
||||
"TOSLINK": "Link zu den Allgemeinen Geschäftsbedingungen",
|
||||
"POLICYLINK": "Link zur den Datenschutzrichtlinien",
|
||||
"HELPLINK": "Link zur Hilfestellung",
|
||||
"SAVED": "Saved successfully!",
|
||||
"RESET_TITLE": "Standardwerte wiederherstellen",
|
||||
"RESET_DESCRIPTION": "Sie sind im Begriff die Standardlinks für die AGBs und Datenschutzrichtlinie wiederherzustellen. Wollen Sie fortfahren?"
|
||||
|
@ -873,6 +873,7 @@
|
||||
"DESCRIPTION": "Set your Privacy Policy and Terms of Service Links",
|
||||
"TOSLINK": "Link to Terms of Service",
|
||||
"POLICYLINK": "Link to Privacy Policy",
|
||||
"HELPLINK": "Link to Help",
|
||||
"SAVED": "Saved successfully!",
|
||||
"RESET_TITLE": "Restore Default Values",
|
||||
"RESET_DESCRIPTION": "You are about to restore the default Links for TOS and Privacy Policy. Do you really want to continue?"
|
||||
|
@ -873,6 +873,7 @@
|
||||
"DESCRIPTION": "Imposta i tuoi link all'informativa sulla privacy e ai termini di servizio",
|
||||
"TOSLINK": "Link ai termini di servizio",
|
||||
"POLICYLINK": "Link all'informativa sulla privacy",
|
||||
"HELPLINK": "link per l'aiuto",
|
||||
"SAVED": "Salvato con successo!",
|
||||
"RESET_TITLE": "Ripristina i valori predefiniti",
|
||||
"RESET_DESCRIPTION": "Stai per ripristinare i link predefiniti per i TOS e l'informativa sulla privacy. Vuoi davvero continuare?"
|
||||
|
@ -888,6 +888,7 @@ Returns the privacy policy defined by the administrators of ZITADEL
|
||||
|
||||
Updates the default privacy policy of ZITADEL
|
||||
it impacts all organisations without a customised policy
|
||||
Variable {{.Lang}} can be set to have different links based on the language
|
||||
|
||||
|
||||
|
||||
@ -3816,6 +3817,7 @@ This is an empty request
|
||||
| ----- | ---- | ----------- | ----------- |
|
||||
| tos_link | string | - | |
|
||||
| privacy_link | string | - | |
|
||||
| help_link | string | - | |
|
||||
|
||||
|
||||
|
||||
|
@ -2095,6 +2095,7 @@ With this policy the privacy relevant things can be configured (e.g tos link)
|
||||
|
||||
Add a custom privacy policy for the organisation
|
||||
With this policy privacy relevant things can be configured (e.g. tos link)
|
||||
Variable {{.Lang}} can be set to have different links based on the language
|
||||
|
||||
|
||||
|
||||
@ -2108,6 +2109,7 @@ With this policy privacy relevant things can be configured (e.g. tos link)
|
||||
|
||||
Update the privacy complexity policy for the organisation
|
||||
With this policy privacy relevant things can be configured (e.g. tos link)
|
||||
Variable {{.Lang}} can be set to have different links based on the language
|
||||
|
||||
|
||||
|
||||
@ -3113,6 +3115,7 @@ This is an empty request
|
||||
| ----- | ---- | ----------- | ----------- |
|
||||
| tos_link | string | - | |
|
||||
| privacy_link | string | - | |
|
||||
| help_link | string | - | |
|
||||
|
||||
|
||||
|
||||
@ -7833,6 +7836,7 @@ This is an empty request
|
||||
| ----- | ---- | ----------- | ----------- |
|
||||
| tos_link | string | - | |
|
||||
| privacy_link | string | - | |
|
||||
| help_link | string | - | |
|
||||
|
||||
|
||||
|
||||
|
@ -126,6 +126,7 @@ title: zitadel/policy.proto
|
||||
| tos_link | string | - | |
|
||||
| privacy_link | string | - | |
|
||||
| is_default | bool | - | |
|
||||
| help_link | string | - | |
|
||||
|
||||
|
||||
|
||||
|
@ -93,7 +93,6 @@ title: zitadel/text.proto
|
||||
| tos | string | - | string.max_len: 200<br /> |
|
||||
| privacy_policy | string | - | string.max_len: 200<br /> |
|
||||
| help | string | - | string.max_len: 200<br /> |
|
||||
| help_link | string | - | string.max_len: 500<br /> |
|
||||
|
||||
|
||||
|
||||
|
@ -374,6 +374,7 @@ UserTypeQuery is always equals
|
||||
| project_name | string | - | |
|
||||
| project_grant_id | string | - | |
|
||||
| avatar_url | string | - | |
|
||||
| preferred_login_name | string | - | |
|
||||
|
||||
|
||||
|
||||
|
15
go.mod
15
go.mod
@ -44,10 +44,12 @@ require (
|
||||
github.com/pquerna/otp v1.3.0
|
||||
github.com/rakyll/statik v0.1.7
|
||||
github.com/rs/cors v1.8.0
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/sony/sonyflake v1.0.0
|
||||
github.com/spf13/cobra v1.3.0
|
||||
github.com/spf13/viper v1.10.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203
|
||||
github.com/ttacon/libphonenumber v1.2.1
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.27.0
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.27.0
|
||||
@ -88,17 +90,28 @@ require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
|
||||
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 // indirect
|
||||
github.com/dsoprea/go-exif v0.0.0-20210131231135-d154f10435cc // indirect
|
||||
github.com/dsoprea/go-exif/v2 v2.0.0-20200604193436-ca8584a0e1c4 // indirect
|
||||
github.com/dsoprea/go-iptc v0.0.0-20200609062250-162ae6b44feb // indirect
|
||||
github.com/dsoprea/go-jpeg-image-structure v0.0.0-20210128210355-86b1014917f2 // indirect
|
||||
github.com/dsoprea/go-logging v0.0.0-20200517223158-a10564966e9d // indirect
|
||||
github.com/dsoprea/go-photoshop-info-format v0.0.0-20200609050348-3db9b63b202c // indirect
|
||||
github.com/dsoprea/go-png-image-structure v0.0.0-20200807080309-a98d4e94ac82 // indirect
|
||||
github.com/dsoprea/go-utility v0.0.0-20200512094054-1abbbc781176 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||
github.com/envoyproxy/go-control-plane v0.10.1 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.2 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.1 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.2.0 // indirect
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
github.com/go-errors/errors v1.0.2 // indirect
|
||||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
|
||||
github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect
|
||||
github.com/gofrs/flock v0.8.1 // indirect
|
||||
github.com/gofrs/uuid v4.0.0+incompatible // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.1.0 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/golang/geo v0.0.0-20200319012246-673a6f80352d // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/certificate-transparency-go v1.0.21 // indirect
|
||||
@ -107,6 +120,7 @@ require (
|
||||
github.com/googleapis/gax-go/v2 v2.1.1 // indirect
|
||||
github.com/gorilla/handlers v1.5.1 // indirect
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
github.com/h2non/filetype v1.1.1 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/huandu/xstrings v1.3.2 // indirect
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
@ -139,7 +153,6 @@ require (
|
||||
github.com/prometheus/procfs v0.6.0 // indirect
|
||||
github.com/rs/xid v1.2.1 // indirect
|
||||
github.com/satori/go.uuid v1.2.0 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
github.com/spf13/afero v1.8.1 // indirect
|
||||
github.com/spf13/cast v1.4.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
|
32
go.sum
32
go.sum
@ -203,6 +203,24 @@ github.com/dop251/goja v0.0.0-20211129110639-4739a1d10a51/go.mod h1:R9ET47fwRVRP
|
||||
github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
|
||||
github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d h1:W1n4DvpzZGOISgp7wWNtraLcHtnmnTwBlJidqtMIuwQ=
|
||||
github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM=
|
||||
github.com/dsoprea/go-exif v0.0.0-20210131231135-d154f10435cc h1:AuzYp98IFVOi0NU/WcZyGDQ6vAh/zkCjxGD3kt8aLzA=
|
||||
github.com/dsoprea/go-exif v0.0.0-20210131231135-d154f10435cc/go.mod h1:lOaOt7+UEppOgyvRy749v3do836U/hw0YVJNjoyPaEs=
|
||||
github.com/dsoprea/go-exif/v2 v2.0.0-20200321225314-640175a69fe4/go.mod h1:Lm2lMM2zx8p4a34ZemkaUV95AnMl4ZvLbCUbwOvLC2E=
|
||||
github.com/dsoprea/go-exif/v2 v2.0.0-20200604193436-ca8584a0e1c4 h1:Mg7pY7kxDQD2Bkvr1N+XW4BESSIQ7tTTR7Vv+Gi2CsM=
|
||||
github.com/dsoprea/go-exif/v2 v2.0.0-20200604193436-ca8584a0e1c4/go.mod h1:9EXlPeHfblFFnwu5UOqmP2eoZfJyAZ2Ri/Vki33ajO0=
|
||||
github.com/dsoprea/go-iptc v0.0.0-20200609062250-162ae6b44feb h1:gwjJjUr6FY7zAWVEueFPrcRHhd9+IK81TcItbqw2du4=
|
||||
github.com/dsoprea/go-iptc v0.0.0-20200609062250-162ae6b44feb/go.mod h1:kYIdx9N9NaOyD7U6D+YtExN7QhRm+5kq7//yOsRXQtM=
|
||||
github.com/dsoprea/go-jpeg-image-structure v0.0.0-20210128210355-86b1014917f2 h1:ULCSN6v0WISNbALxomGPXh4dSjRKPW+7+seYoMz8UTc=
|
||||
github.com/dsoprea/go-jpeg-image-structure v0.0.0-20210128210355-86b1014917f2/go.mod h1:ZoOP3yUG0HD1T4IUjIFsz/2OAB2yB4YX6NSm4K+uJRg=
|
||||
github.com/dsoprea/go-logging v0.0.0-20190624164917-c4f10aab7696/go.mod h1:Nm/x2ZUNRW6Fe5C3LxdY1PyZY5wmDv/s5dkPJ/VB3iA=
|
||||
github.com/dsoprea/go-logging v0.0.0-20200517223158-a10564966e9d h1:F/7L5wr/fP/SKeO5HuMlNEX9Ipyx2MbH2rV9G4zJRpk=
|
||||
github.com/dsoprea/go-logging v0.0.0-20200517223158-a10564966e9d/go.mod h1:7I+3Pe2o/YSU88W0hWlm9S22W7XI1JFNJ86U0zPKMf8=
|
||||
github.com/dsoprea/go-photoshop-info-format v0.0.0-20200609050348-3db9b63b202c h1:7j5aWACOzROpr+dvMtu8GnI97g9ShLWD72XIELMgn+c=
|
||||
github.com/dsoprea/go-photoshop-info-format v0.0.0-20200609050348-3db9b63b202c/go.mod h1:pqKB+ijp27cEcrHxhXVgUUMlSDRuGJJp1E+20Lj5H0E=
|
||||
github.com/dsoprea/go-png-image-structure v0.0.0-20200807080309-a98d4e94ac82 h1:RdwKOEEe2ND/JmoKh6I/EQlR9idKJTDOMffPFK6vN2M=
|
||||
github.com/dsoprea/go-png-image-structure v0.0.0-20200807080309-a98d4e94ac82/go.mod h1:aDYQkL/5gfRNZkoxiLTSWU4Y8/gV/4MVsy/MU9uwTak=
|
||||
github.com/dsoprea/go-utility v0.0.0-20200512094054-1abbbc781176 h1:CfXezFYb2STGOd1+n1HshvE191zVx+QX3A1nML5xxME=
|
||||
github.com/dsoprea/go-utility v0.0.0-20200512094054-1abbbc781176/go.mod h1:95+K3z2L0mqsVYd6yveIv1lmtT3tcQQ3dVakPySffW8=
|
||||
github.com/duo-labs/webauthn v0.0.0-20211216225436-9a12cd078b8a h1:mKoV2b/J8sVVvc6jCl7SxdOrED5cHKdQaHUxjoO5W74=
|
||||
github.com/duo-labs/webauthn v0.0.0-20211216225436-9a12cd078b8a/go.mod h1:EYSpSkwoEcryMmQGfhol2IiB3IMN9IIIaNd/wcAQMGQ=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
@ -256,8 +274,9 @@ github.com/gin-gonic/gin v1.7.4 h1:QmUZXrvJ9qZ3GfWvQ+2wnW/1ePrTEJqPKMYEU3lD/DM=
|
||||
github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||
github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
|
||||
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
github.com/go-errors/errors v1.0.2 h1:xMxH9j2fNg/L4hLn/4y3M0IUsn0M6Wbu/Uh9QlOfBh4=
|
||||
github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
@ -286,6 +305,8 @@ github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo=
|
||||
github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
|
||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
|
||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
|
||||
github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
|
||||
@ -309,6 +330,9 @@ github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZ
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
||||
github.com/golang/geo v0.0.0-20200319012246-673a6f80352d h1:C/hKUcHT483btRbeGkrRjJz+Zbcj8audldIi9tRJDCc=
|
||||
github.com/golang/geo v0.0.0-20200319012246-673a6f80352d/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
|
||||
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
|
||||
@ -434,6 +458,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.1 h1:p5m7GOEGXyoq6QWl4/RRMsQ6tWbTpbQmAnkxXgWSprY=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.1/go.mod h1:8ZeZajTed/blCOHBbj8Fss8bPHiFKcmJJzuIbUtFCAo=
|
||||
github.com/h2non/filetype v1.1.1 h1:xvOwnXKAckvtLWsN398qS9QhlxlnVXBjXBydK2/UFB4=
|
||||
github.com/h2non/filetype v1.1.1/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY=
|
||||
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||
github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
|
||||
github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0=
|
||||
@ -535,6 +561,7 @@ github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0f
|
||||
github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o=
|
||||
github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
@ -870,6 +897,8 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203 h1:1SWXcTphBQjYGWRRxLFIAR1LVtQEj4eR7xPtyeOVM/c=
|
||||
github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203/go.mod h1:0Xw5cYMOYpgaWs+OOSx41ugycl2qvKTi9tlMMcZhFyY=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 h1:5u+EJUQiosu3JFX0XS0qTf5FznsMOzTjGqavBGuCbo0=
|
||||
github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2/go.mod h1:4kyMkleCiLkgY6z8gK5BkI01ChBtxR0ro3I1ZDcGM3w=
|
||||
@ -1073,6 +1102,7 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200320220750-118fecf932d8/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
|
@ -1,8 +1,10 @@
|
||||
package assets
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@ -11,6 +13,7 @@ import (
|
||||
"github.com/caos/logging"
|
||||
sentryhttp "github.com/getsentry/sentry-go/http"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/superseriousbusiness/exifremove/pkg/exifremove"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
http_mw "github.com/caos/zitadel/internal/api/http/middleware"
|
||||
@ -136,7 +139,13 @@ func UploadHandleFunc(s AssetsService, uploader Uploader) func(http.ResponseWrit
|
||||
s.ErrorHandler()(w, r, fmt.Errorf("upload failed: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
info, err := s.Commands().UploadAsset(ctx, bucketName, objectName, contentType, file, size)
|
||||
cleanedFile, cleanedSize, err := removeExif(file, size, contentType)
|
||||
if err != nil {
|
||||
s.ErrorHandler()(w, r, fmt.Errorf("remove exif error: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
info, err := s.Commands().UploadAsset(ctx, bucketName, objectName, contentType, cleanedFile, cleanedSize)
|
||||
if err != nil {
|
||||
s.ErrorHandler()(w, r, fmt.Errorf("upload failed: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
@ -191,3 +200,25 @@ func DownloadHandleFunc(s AssetsService, downloader Downloader) func(http.Respon
|
||||
w.Write(data)
|
||||
}
|
||||
}
|
||||
|
||||
func removeExif(file io.Reader, size int64, contentType string) (io.Reader, int64, error) {
|
||||
if !isAllowedContentType(contentType) {
|
||||
return file, size, nil
|
||||
}
|
||||
buf := new(bytes.Buffer)
|
||||
_, err := buf.ReadFrom(file)
|
||||
if err != nil {
|
||||
return file, 0, err
|
||||
}
|
||||
data, err := exifremove.Remove(buf.Bytes())
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return bytes.NewReader(data), int64(len(data)), nil
|
||||
}
|
||||
|
||||
func isAllowedContentType(contentType string) bool {
|
||||
return strings.HasSuffix(contentType, "png") ||
|
||||
strings.HasSuffix(contentType, "jpg") ||
|
||||
strings.HasSuffix(contentType, "jpeg")
|
||||
}
|
||||
|
@ -9,5 +9,6 @@ func UpdatePrivacyPolicyToDomain(req *admin_pb.UpdatePrivacyPolicyRequest) *doma
|
||||
return &domain.PrivacyPolicy{
|
||||
TOSLink: req.TosLink,
|
||||
PrivacyLink: req.PrivacyLink,
|
||||
HelpLink: req.HelpLink,
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
func (s *Server) ListMyZitadelPermissions(ctx context.Context, _ *auth_pb.ListMyZitadelPermissionsRequest) (*auth_pb.ListMyZitadelPermissionsResponse, error) {
|
||||
perms, err := s.query.MyZitadelPermissions(ctx, authz.GetCtxData(ctx).UserID)
|
||||
perms, err := s.query.MyZitadelPermissions(ctx, authz.GetCtxData(ctx).OrgID, authz.GetCtxData(ctx).UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -168,6 +168,7 @@ func (s *Server) ListMyProjectOrgs(ctx context.Context, req *auth_pb.ListMyProje
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
grants, err := s.query.UserGrants(ctx, &query.UserGrantsQueries{Queries: []query.SearchQuery{userGrantProjectID, userGrantUserID}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -9,6 +9,7 @@ func AddPrivacyPolicyToDomain(req *mgmt_pb.AddCustomPrivacyPolicyRequest) *domai
|
||||
return &domain.PrivacyPolicy{
|
||||
TOSLink: req.TosLink,
|
||||
PrivacyLink: req.PrivacyLink,
|
||||
HelpLink: req.HelpLink,
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,5 +17,6 @@ func UpdatePrivacyPolicyToDomain(req *mgmt_pb.UpdateCustomPrivacyPolicyRequest)
|
||||
return &domain.PrivacyPolicy{
|
||||
TOSLink: req.TosLink,
|
||||
PrivacyLink: req.PrivacyLink,
|
||||
HelpLink: req.HelpLink,
|
||||
}
|
||||
}
|
||||
|
@ -126,11 +126,6 @@ func ListProjectGrantMembersRequestToModel(ctx context.Context, req *mgmt_pb.Lis
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ownerQuery, err := query.NewMemberResourceOwnerSearchQuery(authz.GetCtxData(ctx).OrgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
queries = append(queries, ownerQuery)
|
||||
return &query.ProjectGrantMembersQuery{
|
||||
MembersQuery: query.MembersQuery{
|
||||
SearchRequest: query.SearchRequest{
|
||||
@ -143,6 +138,7 @@ func ListProjectGrantMembersRequestToModel(ctx context.Context, req *mgmt_pb.Lis
|
||||
},
|
||||
ProjectID: req.ProjectId,
|
||||
GrantID: req.GrantId,
|
||||
OrgID: authz.GetCtxData(ctx).OrgID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ func OrgToPb(org *query.Org) *org_pb.Org {
|
||||
Id: org.ID,
|
||||
Name: org.Name,
|
||||
PrimaryDomain: org.Domain,
|
||||
Details: object.AddToDetailsPb(org.Sequence, org.CreationDate, org.ResourceOwner),
|
||||
Details: object.ToViewDetailsPb(org.Sequence, org.CreationDate, org.ChangeDate, org.ResourceOwner),
|
||||
State: OrgStateToPb(org.State),
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ func ModelPrivacyPolicyToPb(policy *query.PrivacyPolicy) *policy_pb.PrivacyPolic
|
||||
IsDefault: policy.IsDefault,
|
||||
TosLink: policy.TOSLink,
|
||||
PrivacyLink: policy.PrivacyLink,
|
||||
HelpLink: policy.HelpLink,
|
||||
Details: object.ToViewDetailsPb(
|
||||
policy.Sequence,
|
||||
policy.CreationDate,
|
||||
|
@ -457,7 +457,6 @@ func FooterTextToPb(text domain.FooterText) *text_pb.FooterText {
|
||||
Tos: text.TOS,
|
||||
PrivacyPolicy: text.PrivacyPolicy,
|
||||
Help: text.Help,
|
||||
HelpLink: text.HelpLink,
|
||||
}
|
||||
}
|
||||
|
||||
@ -947,6 +946,5 @@ func FooterTextPbToDomain(text *text_pb.FooterText) domain.FooterText {
|
||||
TOS: text.Tos,
|
||||
PrivacyPolicy: text.PrivacyPolicy,
|
||||
Help: text.Help,
|
||||
HelpLink: text.HelpLink,
|
||||
}
|
||||
}
|
||||
|
@ -21,22 +21,23 @@ func UserGrantsToPb(assetPrefix string, grants []*query.UserGrant) []*user_pb.Us
|
||||
|
||||
func UserGrantToPb(assetPrefix string, grant *query.UserGrant) *user_pb.UserGrant {
|
||||
return &user_pb.UserGrant{
|
||||
Id: grant.ID,
|
||||
UserId: grant.UserID,
|
||||
State: user_pb.UserGrantState_USER_GRANT_STATE_ACTIVE,
|
||||
RoleKeys: grant.Roles,
|
||||
ProjectId: grant.ProjectID,
|
||||
OrgId: grant.ResourceOwner,
|
||||
ProjectGrantId: grant.GrantID,
|
||||
UserName: grant.Username,
|
||||
FirstName: grant.FirstName,
|
||||
LastName: grant.LastName,
|
||||
Email: grant.Email,
|
||||
DisplayName: grant.DisplayName,
|
||||
OrgDomain: grant.OrgPrimaryDomain,
|
||||
OrgName: grant.OrgName,
|
||||
ProjectName: grant.ProjectName,
|
||||
AvatarUrl: domain.AvatarURL(assetPrefix, grant.UserResourceOwner, grant.AvatarURL),
|
||||
Id: grant.ID,
|
||||
UserId: grant.UserID,
|
||||
State: user_pb.UserGrantState_USER_GRANT_STATE_ACTIVE,
|
||||
RoleKeys: grant.Roles,
|
||||
ProjectId: grant.ProjectID,
|
||||
OrgId: grant.ResourceOwner,
|
||||
ProjectGrantId: grant.GrantID,
|
||||
UserName: grant.Username,
|
||||
FirstName: grant.FirstName,
|
||||
LastName: grant.LastName,
|
||||
Email: grant.Email,
|
||||
DisplayName: grant.DisplayName,
|
||||
OrgDomain: grant.OrgPrimaryDomain,
|
||||
OrgName: grant.OrgName,
|
||||
ProjectName: grant.ProjectName,
|
||||
AvatarUrl: domain.AvatarURL(assetPrefix, grant.UserResourceOwner, grant.AvatarURL),
|
||||
PreferredLoginName: grant.PreferredLoginName,
|
||||
Details: object.ToViewDetailsPb(
|
||||
grant.Sequence,
|
||||
grant.CreationDate,
|
||||
|
@ -95,7 +95,7 @@ func (o *OPStorage) CreateAccessToken(ctx context.Context, req op.TokenRequest)
|
||||
applicationID = authReq.ApplicationID
|
||||
userOrgID = authReq.UserOrgID
|
||||
}
|
||||
resp, err := o.command.AddUserToken(ctx, userOrgID, userAgentID, applicationID, req.GetSubject(), req.GetAudience(), req.GetScopes(), o.defaultAccessTokenLifetime) //PLANNED: lifetime from client
|
||||
resp, err := o.command.AddUserToken(setContextUserSystem(ctx), userOrgID, userAgentID, applicationID, req.GetSubject(), req.GetAudience(), req.GetScopes(), o.defaultAccessTokenLifetime) //PLANNED: lifetime from client
|
||||
if err != nil {
|
||||
return "", time.Time{}, err
|
||||
}
|
||||
@ -123,7 +123,7 @@ func (o *OPStorage) CreateAccessAndRefreshTokens(ctx context.Context, req op.Tok
|
||||
if request, ok := req.(op.RefreshTokenRequest); ok {
|
||||
request.SetCurrentScopes(scopes)
|
||||
}
|
||||
resp, token, err := o.command.AddAccessAndRefreshToken(ctx, userOrgID, userAgentID, applicationID, req.GetSubject(),
|
||||
resp, token, err := o.command.AddAccessAndRefreshToken(setContextUserSystem(ctx), userOrgID, userAgentID, applicationID, req.GetSubject(),
|
||||
refreshToken, req.GetAudience(), scopes, authMethodsReferences, o.defaultAccessTokenLifetime,
|
||||
o.defaultRefreshTokenIdleExpiration, o.defaultRefreshTokenExpiration, authTime) //PLANNED: lifetime from client
|
||||
if err != nil {
|
||||
@ -171,7 +171,10 @@ func (o *OPStorage) TerminateSession(ctx context.Context, userID, clientID strin
|
||||
if len(userIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
err = o.command.HumansSignOut(ctx, userAgentID, userIDs)
|
||||
data := authz.CtxData{
|
||||
UserID: userID,
|
||||
}
|
||||
err = o.command.HumansSignOut(authz.SetCtxData(ctx, data), userAgentID, userIDs)
|
||||
logging.Log("OIDC-Dggt2").OnError(err).Error("error signing out")
|
||||
return err
|
||||
}
|
||||
@ -255,3 +258,10 @@ func (o *OPStorage) assertClientScopesForPAT(ctx context.Context, token *model.T
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func setContextUserSystem(ctx context.Context) context.Context {
|
||||
data := authz.CtxData{
|
||||
UserID: "SYSTEM",
|
||||
}
|
||||
return authz.SetCtxData(ctx, data)
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ func (l *Login) handleExternalUserAuthenticated(w http.ResponseWriter, r *http.R
|
||||
}
|
||||
|
||||
instanceID := authz.GetInstance(r.Context()).ID
|
||||
err = l.authRepo.CheckExternalUserLogin(r.Context(), authReq.ID, userAgentID, instanceID, externalUser, domain.BrowserInfoFromRequest(r))
|
||||
err = l.authRepo.CheckExternalUserLogin(setContext(r.Context(), ""), authReq.ID, userAgentID, instanceID, externalUser, domain.BrowserInfoFromRequest(r))
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
err = nil
|
||||
|
@ -84,7 +84,7 @@ func (l *Login) handleJWTExtraction(w http.ResponseWriter, r *http.Request, auth
|
||||
return
|
||||
}
|
||||
metadata := externalUser.Metadatas
|
||||
err = l.authRepo.CheckExternalUserLogin(r.Context(), authReq.ID, authReq.AgentID, authReq.InstanceID, externalUser, domain.BrowserInfoFromRequest(r))
|
||||
err = l.authRepo.CheckExternalUserLogin(setContext(r.Context(), ""), authReq.ID, authReq.AgentID, authReq.InstanceID, externalUser, domain.BrowserInfoFromRequest(r))
|
||||
if err != nil {
|
||||
l.jwtExtractionUserNotFound(w, r, authReq, idpConfig, tokens, err)
|
||||
return
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/i18n"
|
||||
"github.com/caos/zitadel/internal/notification/templates"
|
||||
"github.com/caos/zitadel/internal/renderer"
|
||||
"github.com/caos/zitadel/internal/static"
|
||||
)
|
||||
@ -30,6 +31,10 @@ type Renderer struct {
|
||||
staticStorage static.Storage
|
||||
}
|
||||
|
||||
type LanguageData struct {
|
||||
Lang string
|
||||
}
|
||||
|
||||
func CreateRenderer(pathPrefix string, staticDir http.FileSystem, staticStorage static.Storage, cookieName string, defaultLanguage language.Tag) *Renderer {
|
||||
r := &Renderer{
|
||||
pathPrefix: pathPrefix,
|
||||
@ -345,24 +350,23 @@ func (l *Login) getBaseData(r *http.Request, authReq *domain.AuthRequest, title
|
||||
CSRF: csrf.TemplateField(r),
|
||||
Nonce: http_mw.GetNonce(r),
|
||||
}
|
||||
var privacyPolicy *domain.PrivacyPolicy
|
||||
if authReq != nil {
|
||||
baseData.LoginPolicy = authReq.LoginPolicy
|
||||
baseData.LabelPolicy = authReq.LabelPolicy
|
||||
baseData.IDPProviders = authReq.AllowedExternalIDPs
|
||||
if authReq.PrivacyPolicy != nil {
|
||||
baseData.TOSLink = authReq.PrivacyPolicy.TOSLink
|
||||
baseData.PrivacyLink = authReq.PrivacyPolicy.PrivacyLink
|
||||
if authReq.PrivacyPolicy == nil {
|
||||
return baseData
|
||||
}
|
||||
privacyPolicy = authReq.PrivacyPolicy
|
||||
} else {
|
||||
privacyPolicy, err := l.query.DefaultPrivacyPolicy(r.Context())
|
||||
policy, err := l.query.DefaultPrivacyPolicy(r.Context())
|
||||
if err != nil {
|
||||
return baseData
|
||||
}
|
||||
if privacyPolicy != nil {
|
||||
baseData.TOSLink = privacyPolicy.TOSLink
|
||||
baseData.PrivacyLink = privacyPolicy.PrivacyLink
|
||||
}
|
||||
privacyPolicy = policy.ToDomain()
|
||||
}
|
||||
baseData = l.setLinksOnBaseData(baseData, privacyPolicy)
|
||||
return baseData
|
||||
}
|
||||
|
||||
@ -392,6 +396,26 @@ func (l *Login) getProfileData(authReq *domain.AuthRequest) profileData {
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Login) setLinksOnBaseData(baseData baseData, privacyPolicy *domain.PrivacyPolicy) baseData {
|
||||
lang := LanguageData{
|
||||
Lang: baseData.Lang,
|
||||
}
|
||||
baseData.TOSLink = privacyPolicy.TOSLink
|
||||
baseData.PrivacyLink = privacyPolicy.PrivacyLink
|
||||
baseData.HelpLink = privacyPolicy.HelpLink
|
||||
|
||||
if link, err := templates.ParseTemplateText(privacyPolicy.TOSLink, lang); err == nil {
|
||||
baseData.TOSLink = link
|
||||
}
|
||||
if link, err := templates.ParseTemplateText(privacyPolicy.PrivacyLink, lang); err == nil {
|
||||
baseData.PrivacyLink = link
|
||||
}
|
||||
if link, err := templates.ParseTemplateText(privacyPolicy.HelpLink, lang); err == nil {
|
||||
baseData.HelpLink = link
|
||||
}
|
||||
return baseData
|
||||
}
|
||||
|
||||
func (l *Login) getErrorMessage(r *http.Request, err error) (errID, errMsg string) {
|
||||
caosErr := new(caos_errs.CaosError)
|
||||
if errors.As(err, &caosErr) {
|
||||
@ -519,6 +543,7 @@ type baseData struct {
|
||||
DisplayLoginNameSuffix bool
|
||||
TOSLink string
|
||||
PrivacyLink string
|
||||
HelpLink string
|
||||
AuthReqID string
|
||||
CSRF template.HTML
|
||||
Nonce string
|
||||
|
@ -297,7 +297,6 @@ Footer:
|
||||
Tos: AGB
|
||||
PrivacyPolicy: Datenschutzerklärung
|
||||
Help: Hilfe
|
||||
HelpLink: https://docs.zitadel.ch/docs/manuals/user-login
|
||||
|
||||
Errors:
|
||||
Internal: Es ist ein interner Fehler aufgetreten
|
||||
|
@ -298,7 +298,6 @@ Footer:
|
||||
Tos: TOS
|
||||
PrivacyPolicy: Privacy policy
|
||||
Help: Help
|
||||
HelpLink: https://docs.zitadel.ch/docs/manuals/user-login
|
||||
|
||||
Errors:
|
||||
Internal: An internal error occured
|
||||
|
@ -298,7 +298,6 @@ Footer:
|
||||
Tos: Termini di servizio
|
||||
PrivacyPolicy: l'informativa sulla privacy
|
||||
Help: Aiuto
|
||||
HelpLink: 'https://docs.zitadel.ch/docs/manuals/user-login'
|
||||
|
||||
Errors:
|
||||
Internal: Si è verificato un errore interno
|
||||
|
@ -13,6 +13,8 @@
|
||||
{{ if .PrivacyLink }}
|
||||
<a href="{{.PrivacyLink}}" rel="noopener noreferrer" target="_blank" alt="Privacy Policy">{{t "Footer.PrivacyPolicy"}}</a>
|
||||
{{end}}
|
||||
<a href="{{t "Footer.HelpLink"}}" target="_black" alt="Help">{{t "Footer.Help"}}</a>
|
||||
{{ if .HelpLink }}
|
||||
<a href="{{.HelpLink}}" rel="noopener noreferrer" target="_blank" alt="Help">{{t "Footer.Help"}}</a>
|
||||
{{end}}
|
||||
</footer>
|
||||
{{end}}
|
||||
|
@ -560,7 +560,7 @@ func (repo *AuthRequestRepo) fillPolicies(ctx context.Context, request *domain.A
|
||||
return err
|
||||
}
|
||||
request.LockoutPolicy = lockoutPolicyToDomain(lockoutPolicy)
|
||||
privacyPolicy, err := repo.getPrivacyPolicy(ctx, orgID)
|
||||
privacyPolicy, err := repo.GetPrivacyPolicy(ctx, orgID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -936,8 +936,11 @@ func (repo *AuthRequestRepo) mfaSkippedOrSetUp(user *user_model.UserView, reques
|
||||
return checkVerificationTime(user.MFAInitSkipped, request.LoginPolicy.MFAInitSkipLifetime)
|
||||
}
|
||||
|
||||
func (repo *AuthRequestRepo) getPrivacyPolicy(ctx context.Context, orgID string) (*domain.PrivacyPolicy, error) {
|
||||
func (repo *AuthRequestRepo) GetPrivacyPolicy(ctx context.Context, orgID string) (*domain.PrivacyPolicy, error) {
|
||||
policy, err := repo.PrivacyPolicyProvider.PrivacyPolicyByOrg(ctx, orgID)
|
||||
if errors.IsNotFound(err) {
|
||||
return new(domain.PrivacyPolicy), nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -957,6 +960,7 @@ func privacyPolicyToDomain(p *query.PrivacyPolicy) *domain.PrivacyPolicy {
|
||||
Default: p.IsDefault,
|
||||
TOSLink: p.TOSLink,
|
||||
PrivacyLink: p.PrivacyLink,
|
||||
HelpLink: p.HelpLink,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,9 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||
v1 "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"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk"
|
||||
@ -172,19 +173,12 @@ func (u *User) ProcessUser(event *es_models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (u *User) fillLoginNames(user *view_model.UserView) (err error) {
|
||||
org, err := u.getOrgByID(context.Background(), user.ResourceOwner)
|
||||
userLoginMustBeDomain, primaryDomain, domains, err := u.loginNameInformation(context.Background(), user.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := new(query2.OrgIAMPolicy)
|
||||
if policy == nil {
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
user.SetLoginNames(policy, org.Domains)
|
||||
user.PreferredLoginName = user.GenerateLoginName(org.GetPrimaryDomain().Domain, policy.UserLoginMustBeDomain)
|
||||
user.SetLoginNames(userLoginMustBeDomain, domains)
|
||||
user.PreferredLoginName = user.GenerateLoginName(primaryDomain, userLoginMustBeDomain)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -204,40 +198,26 @@ func (u *User) ProcessOrg(event *es_models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (u *User) fillLoginNamesOnOrgUsers(event *es_models.Event) error {
|
||||
org, err := u.getOrgByID(context.Background(), event.ResourceOwner)
|
||||
userLoginMustBeDomain, _, domains, err := u.loginNameInformation(context.Background(), event.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := new(query2.OrgIAMPolicy)
|
||||
if policy == nil {
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
users, err := u.view.UsersByOrgID(event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, user := range users {
|
||||
user.SetLoginNames(policy, org.Domains)
|
||||
user.SetLoginNames(userLoginMustBeDomain, domains)
|
||||
}
|
||||
return u.view.PutUsers(users, event)
|
||||
}
|
||||
|
||||
func (u *User) fillPreferredLoginNamesOnOrgUsers(event *es_models.Event) error {
|
||||
org, err := u.getOrgByID(context.Background(), event.ResourceOwner)
|
||||
userLoginMustBeDomain, primaryDomain, _, err := u.loginNameInformation(context.Background(), event.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := new(query2.OrgIAMPolicy)
|
||||
if policy == nil {
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !policy.UserLoginMustBeDomain {
|
||||
if !userLoginMustBeDomain {
|
||||
return nil
|
||||
}
|
||||
users, err := u.view.UsersByOrgID(event.AggregateID)
|
||||
@ -245,7 +225,7 @@ func (u *User) fillPreferredLoginNamesOnOrgUsers(event *es_models.Event) error {
|
||||
return err
|
||||
}
|
||||
for _, user := range users {
|
||||
user.PreferredLoginName = user.GenerateLoginName(org.GetPrimaryDomain().Domain, policy.UserLoginMustBeDomain)
|
||||
user.PreferredLoginName = user.GenerateLoginName(primaryDomain, userLoginMustBeDomain)
|
||||
}
|
||||
return u.view.PutUsers(users, event)
|
||||
}
|
||||
@ -281,6 +261,17 @@ func (u *User) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, er
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *User) getDefaultOrgIAMPolicy(ctx context.Context) (*query2.OrgIAMPolicy, error) {
|
||||
return u.queries.DefaultOrgIAMPolicy(ctx)
|
||||
func (u *User) loginNameInformation(ctx context.Context, orgID string) (userLoginMustBeDomain bool, primaryDomain string, domains []*org_model.OrgDomain, err error) {
|
||||
org, err := u.getOrgByID(ctx, orgID)
|
||||
if err != nil {
|
||||
return false, "", nil, err
|
||||
}
|
||||
if org.OrgIamPolicy == nil {
|
||||
policy, err := u.queries.DefaultOrgIAMPolicy(ctx)
|
||||
if err != nil {
|
||||
return false, "", nil, err
|
||||
}
|
||||
userLoginMustBeDomain = policy.UserLoginMustBeDomain
|
||||
}
|
||||
return userLoginMustBeDomain, org.GetPrimaryDomain().Domain, org.Domains, nil
|
||||
}
|
||||
|
@ -1089,10 +1089,6 @@ func (c *Commands) createFooterTextEvents(ctx context.Context, agg *eventstore.A
|
||||
if event != nil {
|
||||
events = append(events, event)
|
||||
}
|
||||
event = c.createCustomLoginTextEvent(ctx, agg, domain.LoginKeyFooterHelpLink, existingText.FooterHelpLink, text.Footer.HelpLink, text.Language, defaultText)
|
||||
if event != nil {
|
||||
events = append(events, event)
|
||||
}
|
||||
return events
|
||||
}
|
||||
|
||||
|
@ -2508,10 +2508,6 @@ func (wm *CustomLoginTextReadModel) handleFooterTextSetEvent(e *policy.CustomTex
|
||||
wm.FooterHelp = e.Text
|
||||
return
|
||||
}
|
||||
if e.Key == domain.LoginKeyFooterHelpLink {
|
||||
wm.FooterHelpLink = e.Text
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *CustomLoginTextReadModel) handleFooterTextRemoveEvent(e *policy.CustomTextRemovedEvent) {
|
||||
@ -2527,8 +2523,4 @@ func (wm *CustomLoginTextReadModel) handleFooterTextRemoveEvent(e *policy.Custom
|
||||
wm.FooterHelp = ""
|
||||
return
|
||||
}
|
||||
if e.Key == domain.LoginKeyFooterHelpLink {
|
||||
wm.FooterHelpLink = ""
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -130,6 +130,7 @@ func writeModelToPrivacyPolicy(wm *PrivacyPolicyWriteModel) *domain.PrivacyPolic
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
||||
TOSLink: wm.TOSLink,
|
||||
PrivacyLink: wm.PrivacyLink,
|
||||
HelpLink: wm.HelpLink,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1143,11 +1143,6 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
||||
&iam.NewAggregate().Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
iam.NewCustomTextSetEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelpLink, "HelpLink", language.English,
|
||||
),
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
@ -1441,7 +1436,6 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
||||
TOS: "TOS",
|
||||
PrivacyPolicy: "PrivacyPolicy",
|
||||
Help: "Help",
|
||||
HelpLink: "HelpLink",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2547,11 +2541,6 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
||||
&iam.NewAggregate().Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
iam.NewCustomTextSetEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelpLink, "HelpLink", language.English,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
@ -3645,11 +3634,6 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
||||
&iam.NewAggregate().Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, language.English,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
iam.NewCustomTextRemovedEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelpLink, language.English,
|
||||
),
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
@ -4797,11 +4781,6 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
||||
&iam.NewAggregate().Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
iam.NewCustomTextSetEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelpLink, "HelpLink", language.English,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
iam.NewCustomTextRemovedEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate, domain.LoginCustomText, domain.LoginKeySelectAccountTitle, language.English,
|
||||
@ -5892,11 +5871,6 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
||||
&iam.NewAggregate().Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, language.English,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
iam.NewCustomTextRemovedEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelpLink, language.English,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
@ -6990,11 +6964,6 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
||||
&iam.NewAggregate().Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
iam.NewCustomTextSetEvent(context.Background(),
|
||||
&iam.NewAggregate().Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelpLink, "HelpLink", language.English,
|
||||
),
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
@ -7288,7 +7257,6 @@ func TestCommandSide_SetCustomIAMLoginText(t *testing.T) {
|
||||
TOS: "TOS",
|
||||
PrivacyPolicy: "PrivacyPolicy",
|
||||
Help: "Help",
|
||||
HelpLink: "HelpLink",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -52,7 +52,7 @@ func (c *Commands) addDefaultPrivacyPolicy(ctx context.Context, iamAgg *eventsto
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-M00rJ", "Errors.IAM.PrivacyPolicy.AlreadyExists")
|
||||
}
|
||||
|
||||
return iam_repo.NewPrivacyPolicyAddedEvent(ctx, iamAgg, policy.TOSLink, policy.PrivacyLink), nil
|
||||
return iam_repo.NewPrivacyPolicyAddedEvent(ctx, iamAgg, policy.TOSLink, policy.PrivacyLink, policy.HelpLink), nil
|
||||
}
|
||||
|
||||
func (c *Commands) ChangeDefaultPrivacyPolicy(ctx context.Context, policy *domain.PrivacyPolicy) (*domain.PrivacyPolicy, error) {
|
||||
@ -65,7 +65,7 @@ func (c *Commands) ChangeDefaultPrivacyPolicy(ctx context.Context, policy *domai
|
||||
}
|
||||
|
||||
iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PrivacyPolicyWriteModel.WriteModel)
|
||||
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, iamAgg, policy.TOSLink, policy.PrivacyLink)
|
||||
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, iamAgg, policy.TOSLink, policy.PrivacyLink, policy.HelpLink)
|
||||
if !hasChanged {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged")
|
||||
}
|
||||
|
@ -56,7 +56,8 @@ func (wm *IAMPrivacyPolicyWriteModel) NewChangedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
tosLink,
|
||||
privacyLink string,
|
||||
privacyLink,
|
||||
helpLink string,
|
||||
) (*iam.PrivacyPolicyChangedEvent, bool) {
|
||||
|
||||
changes := make([]policy.PrivacyPolicyChanges, 0)
|
||||
@ -66,6 +67,9 @@ func (wm *IAMPrivacyPolicyWriteModel) NewChangedEvent(
|
||||
if wm.PrivacyLink != privacyLink {
|
||||
changes = append(changes, policy.ChangePrivacyLink(privacyLink))
|
||||
}
|
||||
if wm.HelpLink != helpLink {
|
||||
changes = append(changes, policy.ChangeHelpLink(helpLink))
|
||||
}
|
||||
if len(changes) == 0 {
|
||||
return nil, false
|
||||
}
|
||||
|
@ -2,6 +2,10 @@ package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
@ -9,8 +13,6 @@ import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/repository/iam"
|
||||
"github.com/caos/zitadel/internal/repository/policy"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
||||
@ -42,6 +44,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
||||
&iam.NewAggregate().Aggregate,
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -52,6 +55,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -71,6 +75,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
||||
&iam.NewAggregate().Aggregate,
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
),
|
||||
),
|
||||
},
|
||||
@ -82,6 +87,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -92,6 +98,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
||||
},
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -108,6 +115,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
||||
&iam.NewAggregate().Aggregate,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
),
|
||||
),
|
||||
},
|
||||
@ -119,6 +127,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "",
|
||||
PrivacyLink: "",
|
||||
HelpLink: "",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -129,6 +138,7 @@ func TestCommandSide_AddDefaultPrivacyPolicy(t *testing.T) {
|
||||
},
|
||||
TOSLink: "",
|
||||
PrivacyLink: "",
|
||||
HelpLink: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -183,6 +193,7 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -200,6 +211,7 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
||||
&iam.NewAggregate().Aggregate,
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -210,6 +222,7 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -227,6 +240,7 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
||||
&iam.NewAggregate().Aggregate,
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -236,6 +250,7 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
||||
newDefaultPrivacyPolicyChangedEvent(context.Background(),
|
||||
"TOSLinkChanged",
|
||||
"PrivacyLinkChanged",
|
||||
"HelpLinkChanged",
|
||||
),
|
||||
),
|
||||
},
|
||||
@ -247,6 +262,7 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLinkChanged",
|
||||
PrivacyLink: "PrivacyLinkChanged",
|
||||
HelpLink: "HelpLinkChanged",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -257,6 +273,7 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
||||
},
|
||||
TOSLink: "TOSLinkChanged",
|
||||
PrivacyLink: "PrivacyLinkChanged",
|
||||
HelpLink: "HelpLinkChanged",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -280,12 +297,13 @@ func TestCommandSide_ChangeDefaultPrivacyPolicy(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func newDefaultPrivacyPolicyChangedEvent(ctx context.Context, tosLink, privacyLink string) *iam.PrivacyPolicyChangedEvent {
|
||||
func newDefaultPrivacyPolicyChangedEvent(ctx context.Context, tosLink, privacyLink, helpLink string) *iam.PrivacyPolicyChangedEvent {
|
||||
event, _ := iam.NewPrivacyPolicyChangedEvent(ctx,
|
||||
&iam.NewAggregate().Aggregate,
|
||||
[]policy.PrivacyPolicyChanges{
|
||||
policy.ChangeTOSLink(tosLink),
|
||||
policy.ChangePrivacyLink(privacyLink),
|
||||
policy.ChangeHelpLink(helpLink),
|
||||
},
|
||||
)
|
||||
return event
|
||||
|
@ -1161,11 +1161,6 @@ func TestCommandSide_SetCustomOrgLoginText(t *testing.T) {
|
||||
&org.NewAggregate("org1", "org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewCustomTextSetEvent(context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelpLink, "HelpLink", language.English,
|
||||
),
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
@ -1460,7 +1455,6 @@ func TestCommandSide_SetCustomOrgLoginText(t *testing.T) {
|
||||
TOS: "TOS",
|
||||
PrivacyPolicy: "PrivacyPolicy",
|
||||
Help: "Help",
|
||||
HelpLink: "HelpLink",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2566,11 +2560,6 @@ func TestCommandSide_SetCustomOrgLoginText(t *testing.T) {
|
||||
&org.NewAggregate("org1", "org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewCustomTextSetEvent(context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelpLink, "HelpLink", language.English,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
@ -3664,11 +3653,6 @@ func TestCommandSide_SetCustomOrgLoginText(t *testing.T) {
|
||||
&org.NewAggregate("org1", "org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, language.English,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewCustomTextRemovedEvent(context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelpLink, language.English,
|
||||
),
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
@ -4816,11 +4800,6 @@ func TestCommandSide_SetCustomOrgLoginText(t *testing.T) {
|
||||
&org.NewAggregate("org1", "org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewCustomTextSetEvent(context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelpLink, "HelpLink", language.English,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewCustomTextRemovedEvent(context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate, domain.LoginCustomText, domain.LoginKeySelectAccountTitle, language.English,
|
||||
@ -5911,11 +5890,6 @@ func TestCommandSide_SetCustomOrgLoginText(t *testing.T) {
|
||||
&org.NewAggregate("org1", "org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, language.English,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewCustomTextRemovedEvent(context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelpLink, language.English,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
@ -7009,11 +6983,6 @@ func TestCommandSide_SetCustomOrgLoginText(t *testing.T) {
|
||||
&org.NewAggregate("org1", "org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelp, "Help", language.English,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
org.NewCustomTextSetEvent(context.Background(),
|
||||
&org.NewAggregate("org1", "org1").Aggregate, domain.LoginCustomText, domain.LoginKeyFooterHelpLink, "HelpLink", language.English,
|
||||
),
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
@ -7308,7 +7277,6 @@ func TestCommandSide_SetCustomOrgLoginText(t *testing.T) {
|
||||
TOS: "TOS",
|
||||
PrivacyPolicy: "PrivacyPolicy",
|
||||
Help: "Help",
|
||||
HelpLink: "HelpLink",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -5,12 +5,13 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/caos/zitadel/internal/repository/user"
|
||||
"github.com/caos/zitadel/internal/static/mock"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/caos/zitadel/internal/repository/user"
|
||||
"github.com/caos/zitadel/internal/static/mock"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
@ -266,6 +267,7 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
||||
&iam.NewAggregate().Aggregate,
|
||||
"toslink",
|
||||
"privacylink",
|
||||
"helpLink",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -470,6 +472,7 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
||||
&iam.NewAggregate().Aggregate,
|
||||
"toslink",
|
||||
"privacylink",
|
||||
"helplink",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -686,6 +689,7 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
||||
&iam.NewAggregate().Aggregate,
|
||||
"toslink",
|
||||
"privacylink",
|
||||
"helplink",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -912,6 +916,7 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
||||
&iam.NewAggregate().Aggregate,
|
||||
"toslink",
|
||||
"privacylink",
|
||||
"helplink",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -1203,6 +1208,7 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
||||
&iam.NewAggregate().Aggregate,
|
||||
"toslink",
|
||||
"privacylink",
|
||||
"helplink",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -1420,6 +1426,7 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
|
||||
&iam.NewAggregate().Aggregate,
|
||||
"toslink",
|
||||
"privacylink",
|
||||
"helplink",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -1684,6 +1691,7 @@ func TestCommandSide_RemoveOrgFeatures(t *testing.T) {
|
||||
&iam.NewAggregate().Aggregate,
|
||||
"toslink",
|
||||
"privacylink",
|
||||
"helplink",
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -80,7 +80,7 @@ func (c *Commands) RemoveOrgIAMPolicy(ctx context.Context, orgID string) error {
|
||||
return err
|
||||
}
|
||||
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
|
||||
return caos_errs.ThrowNotFound(nil, "ORG-Dvsh3", "Errors.Org.OrgIAM.NotFound")
|
||||
return caos_errs.ThrowNotFound(nil, "ORG-Dvsh3", "Errors.Org.OrgIAMPolicy.NotFound")
|
||||
}
|
||||
|
||||
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PolicyOrgIAMWriteModel.WriteModel)
|
||||
|
@ -48,7 +48,8 @@ func (c *Commands) AddPrivacyPolicy(ctx context.Context, resourceOwner string, p
|
||||
ctx,
|
||||
orgAgg,
|
||||
policy.TOSLink,
|
||||
policy.PrivacyLink))
|
||||
policy.PrivacyLink,
|
||||
policy.HelpLink))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -74,7 +75,7 @@ func (c *Commands) ChangePrivacyPolicy(ctx context.Context, resourceOwner string
|
||||
}
|
||||
|
||||
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PrivacyPolicyWriteModel.WriteModel)
|
||||
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.TOSLink, policy.PrivacyLink)
|
||||
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.TOSLink, policy.PrivacyLink, policy.HelpLink)
|
||||
if !hasChanged {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-4N9fs", "Errors.Org.PrivacyPolicy.NotChanged")
|
||||
}
|
||||
|
@ -57,7 +57,8 @@ func (wm *OrgPrivacyPolicyWriteModel) NewChangedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
tosLink,
|
||||
privacyLink string,
|
||||
privacyLink,
|
||||
helpLink string,
|
||||
) (*org.PrivacyPolicyChangedEvent, bool) {
|
||||
|
||||
changes := make([]policy.PrivacyPolicyChanges, 0)
|
||||
@ -67,6 +68,9 @@ func (wm *OrgPrivacyPolicyWriteModel) NewChangedEvent(
|
||||
if wm.PrivacyLink != privacyLink {
|
||||
changes = append(changes, policy.ChangePrivacyLink(privacyLink))
|
||||
}
|
||||
if wm.HelpLink != helpLink {
|
||||
changes = append(changes, policy.ChangeHelpLink(helpLink))
|
||||
}
|
||||
if len(changes) == 0 {
|
||||
return nil, false
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -63,6 +64,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -74,6 +76,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -93,6 +96,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
),
|
||||
),
|
||||
},
|
||||
@ -105,6 +109,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -115,6 +120,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
||||
},
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -131,6 +137,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
),
|
||||
),
|
||||
},
|
||||
@ -143,6 +150,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "",
|
||||
PrivacyLink: "",
|
||||
HelpLink: "",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -153,6 +161,7 @@ func TestCommandSide_AddPrivacyPolicy(t *testing.T) {
|
||||
},
|
||||
TOSLink: "",
|
||||
PrivacyLink: "",
|
||||
HelpLink: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -207,6 +216,7 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -227,6 +237,7 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -244,6 +255,7 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -255,6 +267,7 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLink",
|
||||
PrivacyLink: "PrivacyLink",
|
||||
HelpLink: "HelpLink",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -272,13 +285,14 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
newPrivacyPolicyChangedEvent(context.Background(), "org1", "TOSLinkChange", "PrivacyLinkChange"),
|
||||
newPrivacyPolicyChangedEvent(context.Background(), "org1", "TOSLinkChange", "PrivacyLinkChange", "HelpLinkChange"),
|
||||
),
|
||||
},
|
||||
),
|
||||
@ -290,6 +304,7 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "TOSLinkChange",
|
||||
PrivacyLink: "PrivacyLinkChange",
|
||||
HelpLink: "HelpLinkChange",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -300,6 +315,7 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
},
|
||||
TOSLink: "TOSLinkChange",
|
||||
PrivacyLink: "PrivacyLinkChange",
|
||||
HelpLink: "HelpLinkChange",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -314,13 +330,14 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
newPrivacyPolicyChangedEvent(context.Background(), "org1", "", ""),
|
||||
newPrivacyPolicyChangedEvent(context.Background(), "org1", "", "", ""),
|
||||
),
|
||||
},
|
||||
),
|
||||
@ -332,6 +349,7 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
policy: &domain.PrivacyPolicy{
|
||||
TOSLink: "",
|
||||
PrivacyLink: "",
|
||||
HelpLink: "",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
@ -342,6 +360,7 @@ func TestCommandSide_ChangePrivacyPolicy(t *testing.T) {
|
||||
},
|
||||
TOSLink: "",
|
||||
PrivacyLink: "",
|
||||
HelpLink: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -424,6 +443,7 @@ func TestCommandSide_RemovePrivacyPolicy(t *testing.T) {
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"TOSLink",
|
||||
"PrivacyLink",
|
||||
"HelpLink",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -467,12 +487,13 @@ func TestCommandSide_RemovePrivacyPolicy(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func newPrivacyPolicyChangedEvent(ctx context.Context, orgID string, tosLink, privacyLink string) *org.PrivacyPolicyChangedEvent {
|
||||
func newPrivacyPolicyChangedEvent(ctx context.Context, orgID string, tosLink, privacyLink, helpLink string) *org.PrivacyPolicyChangedEvent {
|
||||
event, _ := org.NewPrivacyPolicyChangedEvent(ctx,
|
||||
&org.NewAggregate(orgID, orgID).Aggregate,
|
||||
[]policy.PrivacyPolicyChanges{
|
||||
policy.ChangeTOSLink(tosLink),
|
||||
policy.ChangePrivacyLink(privacyLink),
|
||||
policy.ChangeHelpLink(helpLink),
|
||||
},
|
||||
)
|
||||
return event
|
||||
|
@ -11,6 +11,7 @@ type PrivacyPolicyWriteModel struct {
|
||||
|
||||
TOSLink string
|
||||
PrivacyLink string
|
||||
HelpLink string
|
||||
State domain.PolicyState
|
||||
}
|
||||
|
||||
@ -20,6 +21,7 @@ func (wm *PrivacyPolicyWriteModel) Reduce() error {
|
||||
case *policy.PrivacyPolicyAddedEvent:
|
||||
wm.TOSLink = e.TOSLink
|
||||
wm.PrivacyLink = e.PrivacyLink
|
||||
wm.HelpLink = e.HelpLink
|
||||
wm.State = domain.PolicyStateActive
|
||||
case *policy.PrivacyPolicyChangedEvent:
|
||||
if e.PrivacyLink != nil {
|
||||
@ -28,6 +30,9 @@ func (wm *PrivacyPolicyWriteModel) Reduce() error {
|
||||
if e.TOSLink != nil {
|
||||
wm.TOSLink = *e.TOSLink
|
||||
}
|
||||
if e.HelpLink != nil {
|
||||
wm.HelpLink = *e.HelpLink
|
||||
}
|
||||
case *policy.PrivacyPolicyRemovedEvent:
|
||||
wm.State = domain.PolicyStateRemoved
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ func (c *Commands) ChangeUsername(ctx context.Context, orgID, userID, userName s
|
||||
|
||||
orgIAMPolicy, err := c.getOrgIAMPolicy(ctx, orgID)
|
||||
if err != nil {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-38fnu", "Errors.Org.OrgIAM.NotExisting")
|
||||
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-38fnu", "Errors.Org.OrgIAMPolicy.NotExisting")
|
||||
}
|
||||
|
||||
if err := CheckOrgIAMPolicyForUserName(userName, orgIAMPolicy); err != nil {
|
||||
@ -188,7 +188,7 @@ func (c *Commands) RemoveUser(ctx context.Context, userID, resourceOwner string,
|
||||
|
||||
orgIAMPolicy, err := c.getOrgIAMPolicy(ctx, existingUser.ResourceOwner)
|
||||
if err != nil {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-3M9fs", "Errors.Org.OrgIAM.NotExisting")
|
||||
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-3M9fs", "Errors.Org.OrgIAMPolicy.NotExisting")
|
||||
}
|
||||
var events []eventstore.Command
|
||||
userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel)
|
||||
|
@ -34,7 +34,7 @@ func (c *Commands) AddHuman(ctx context.Context, orgID string, human *domain.Hum
|
||||
}
|
||||
pwPolicy, err := c.getOrgPasswordComplexityPolicy(ctx, orgID)
|
||||
if err != nil {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-M5Fsd", "Errors.Org.PasswordComplexity.NotFound")
|
||||
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-M5Fsd", "Errors.Org.PasswordComplexityPolicy.NotFound")
|
||||
}
|
||||
events, addedHuman, err := c.addHuman(ctx, orgID, human, orgIAMPolicy, pwPolicy, initCodeGenerator, phoneCodeGenerator)
|
||||
if err != nil {
|
||||
@ -63,7 +63,7 @@ func (c *Commands) ImportHuman(ctx context.Context, orgID string, human *domain.
|
||||
}
|
||||
pwPolicy, err := c.getOrgPasswordComplexityPolicy(ctx, orgID)
|
||||
if err != nil {
|
||||
return nil, nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-4N8gs", "Errors.Org.PasswordComplexity.NotFound")
|
||||
return nil, nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-4N8gs", "Errors.Org.PasswordComplexityPolicy.NotFound")
|
||||
}
|
||||
events, addedHuman, addedCode, code, err := c.importHuman(ctx, orgID, human, passwordless, orgIAMPolicy, pwPolicy, initCodeGenerator, phoneCodeGenerator, passwordlessCodeGenerator)
|
||||
if err != nil {
|
||||
@ -128,7 +128,7 @@ func (c *Commands) RegisterHuman(ctx context.Context, orgID string, human *domai
|
||||
}
|
||||
pwPolicy, err := c.getOrgPasswordComplexityPolicy(ctx, orgID)
|
||||
if err != nil {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-M5Fsd", "Errors.Org.PasswordComplexity.NotFound")
|
||||
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-M5Fsd", "Errors.Org.PasswordComplexityPolicy.NotFound")
|
||||
}
|
||||
loginPolicy, err := c.getOrgLoginPolicy(ctx, orgID)
|
||||
if err != nil {
|
||||
|
@ -28,7 +28,7 @@ func (c *Commands) AddHumanOTP(ctx context.Context, userID, resourceowner string
|
||||
orgPolicy, err := c.getOrgIAMPolicy(ctx, org.AggregateID)
|
||||
if err != nil {
|
||||
logging.Log("COMMAND-y5zv9").WithError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Debug("unable to get org policy for loginname")
|
||||
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-8ugTs", "Errors.Org.OrgIAM.NotFound")
|
||||
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-8ugTs", "Errors.Org.OrgIAMPolicy.NotFound")
|
||||
}
|
||||
otpWriteModel, err := c.otpWriteModelByID(ctx, userID, resourceowner)
|
||||
if err != nil {
|
||||
|
@ -294,7 +294,6 @@ const (
|
||||
LoginKeyFooterTOS = LoginKeyFooter + "Tos"
|
||||
LoginKeyFooterPrivacyPolicy = LoginKeyFooter + "PrivacyPolicy"
|
||||
LoginKeyFooterHelp = LoginKeyFooter + "Help"
|
||||
LoginKeyFooterHelpLink = LoginKeyFooter + "HelpLink"
|
||||
)
|
||||
|
||||
type CustomLoginText struct {
|
||||
@ -637,7 +636,6 @@ type FooterText struct {
|
||||
TOS string
|
||||
PrivacyPolicy string
|
||||
Help string
|
||||
HelpLink string
|
||||
}
|
||||
|
||||
type PasswordlessPromptScreenText struct {
|
||||
|
@ -12,4 +12,5 @@ type PrivacyPolicy struct {
|
||||
|
||||
TOSLink string
|
||||
PrivacyLink string
|
||||
HelpLink string
|
||||
}
|
||||
|
@ -894,7 +894,4 @@ func footerKeyToDomain(text *CustomTextView, result *domain.CustomLoginText) {
|
||||
if text.Key == domain.LoginKeyFooterHelp {
|
||||
result.Footer.Help = text.Text
|
||||
}
|
||||
if text.Key == domain.LoginKeyFooterHelpLink {
|
||||
result.Footer.HelpLink = text.Text
|
||||
}
|
||||
}
|
||||
|
@ -3,14 +3,14 @@ package handler
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||
v1 "github.com/caos/zitadel/internal/eventstore/v1"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk"
|
||||
org_view "github.com/caos/zitadel/internal/org/repository/view"
|
||||
query2 "github.com/caos/zitadel/internal/query"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
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"
|
||||
@ -163,23 +163,16 @@ func (u *NotifyUser) ProcessOrg(event *es_models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (u *NotifyUser) fillLoginNamesOnOrgUsers(event *es_models.Event) error {
|
||||
org, err := u.getOrgByID(context.Background(), event.ResourceOwner)
|
||||
userLoginMustBeDomain, _, domains, err := u.loginNameInformation(context.Background(), event.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := new(query2.OrgIAMPolicy)
|
||||
if policy == nil {
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
users, err := u.view.NotifyUsersByOrgID(event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, user := range users {
|
||||
user.SetLoginNames(policy, org.Domains)
|
||||
user.SetLoginNames(userLoginMustBeDomain, domains)
|
||||
err := u.view.PutNotifyUser(user, event)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -189,16 +182,11 @@ func (u *NotifyUser) fillLoginNamesOnOrgUsers(event *es_models.Event) error {
|
||||
}
|
||||
|
||||
func (u *NotifyUser) fillPreferredLoginNamesOnOrgUsers(event *es_models.Event) error {
|
||||
org, err := u.getOrgByID(context.Background(), event.ResourceOwner)
|
||||
userLoginMustBeDomain, primaryDomain, _, err := u.loginNameInformation(context.Background(), event.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
policy, err := u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !policy.UserLoginMustBeDomain {
|
||||
if !userLoginMustBeDomain {
|
||||
return nil
|
||||
}
|
||||
users, err := u.view.NotifyUsersByOrgID(event.AggregateID)
|
||||
@ -206,7 +194,7 @@ func (u *NotifyUser) fillPreferredLoginNamesOnOrgUsers(event *es_models.Event) e
|
||||
return err
|
||||
}
|
||||
for _, user := range users {
|
||||
user.PreferredLoginName = user.GenerateLoginName(org.GetPrimaryDomain().Domain, policy.UserLoginMustBeDomain)
|
||||
user.PreferredLoginName = user.GenerateLoginName(primaryDomain, userLoginMustBeDomain)
|
||||
err := u.view.PutNotifyUser(user, event)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -216,17 +204,12 @@ func (u *NotifyUser) fillPreferredLoginNamesOnOrgUsers(event *es_models.Event) e
|
||||
}
|
||||
|
||||
func (u *NotifyUser) fillLoginNames(user *view_model.NotifyUser) (err error) {
|
||||
org, err := u.getOrgByID(context.Background(), user.ResourceOwner)
|
||||
userLoginMustBeDomain, primaryDomain, domains, err := u.loginNameInformation(context.Background(), user.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
policy, err := u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
user.SetLoginNames(policy, org.Domains)
|
||||
user.PreferredLoginName = user.GenerateLoginName(org.GetPrimaryDomain().Domain, policy.UserLoginMustBeDomain)
|
||||
user.SetLoginNames(userLoginMustBeDomain, domains)
|
||||
user.PreferredLoginName = user.GenerateLoginName(primaryDomain, userLoginMustBeDomain)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -261,6 +244,17 @@ func (u *NotifyUser) getOrgByID(ctx context.Context, orgID string) (*org_model.O
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *NotifyUser) getDefaultOrgIAMPolicy(ctx context.Context) (*query2.OrgIAMPolicy, error) {
|
||||
return u.queries.DefaultOrgIAMPolicy(ctx)
|
||||
func (u *NotifyUser) loginNameInformation(ctx context.Context, orgID string) (userLoginMustBeDomain bool, primaryDomain string, domains []*org_model.OrgDomain, err error) {
|
||||
org, err := u.getOrgByID(ctx, orgID)
|
||||
if err != nil {
|
||||
return false, "", nil, err
|
||||
}
|
||||
if org.OrgIamPolicy == nil {
|
||||
policy, err := u.queries.DefaultOrgIAMPolicy(ctx)
|
||||
if err != nil {
|
||||
return false, "", nil, err
|
||||
}
|
||||
userLoginMustBeDomain = policy.UserLoginMustBeDomain
|
||||
}
|
||||
return userLoginMustBeDomain, org.GetPrimaryDomain().Domain, org.Domains, nil
|
||||
}
|
||||
|
@ -1101,7 +1101,4 @@ func footerKeyToDomain(text *CustomText, result *domain.CustomLoginText) {
|
||||
if text.Key == domain.LoginKeyFooterHelp {
|
||||
result.Footer.Help = text.Text
|
||||
}
|
||||
if text.Key == domain.LoginKeyFooterHelpLink {
|
||||
result.Footer.HelpLink = text.Text
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ type PrivacyPolicy struct {
|
||||
|
||||
TOSLink string
|
||||
PrivacyLink string
|
||||
HelpLink string
|
||||
|
||||
IsDefault bool
|
||||
}
|
||||
@ -64,6 +65,10 @@ var (
|
||||
name: projection.PrivacyPolicyTOSLinkCol,
|
||||
table: privacyTable,
|
||||
}
|
||||
PrivacyColHelpLink = Column{
|
||||
name: projection.PrivacyPolicyHelpLinkCol,
|
||||
table: privacyTable,
|
||||
}
|
||||
PrivacyColIsDefault = Column{
|
||||
name: projection.PrivacyPolicyIsDefaultCol,
|
||||
table: privacyTable,
|
||||
@ -125,6 +130,7 @@ func preparePrivacyPolicyQuery() (sq.SelectBuilder, func(*sql.Row) (*PrivacyPoli
|
||||
PrivacyColResourceOwner.identifier(),
|
||||
PrivacyColPrivacyLink.identifier(),
|
||||
PrivacyColTOSLink.identifier(),
|
||||
PrivacyColHelpLink.identifier(),
|
||||
PrivacyColIsDefault.identifier(),
|
||||
PrivacyColState.identifier(),
|
||||
).
|
||||
@ -139,6 +145,7 @@ func preparePrivacyPolicyQuery() (sq.SelectBuilder, func(*sql.Row) (*PrivacyPoli
|
||||
&policy.ResourceOwner,
|
||||
&policy.PrivacyLink,
|
||||
&policy.TOSLink,
|
||||
&policy.HelpLink,
|
||||
&policy.IsDefault,
|
||||
&policy.State,
|
||||
)
|
||||
@ -151,3 +158,12 @@ func preparePrivacyPolicyQuery() (sq.SelectBuilder, func(*sql.Row) (*PrivacyPoli
|
||||
return policy, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PrivacyPolicy) ToDomain() *domain.PrivacyPolicy {
|
||||
return &domain.PrivacyPolicy{
|
||||
TOSLink: p.TOSLink,
|
||||
PrivacyLink: p.PrivacyLink,
|
||||
HelpLink: p.HelpLink,
|
||||
Default: p.IsDefault,
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ func Test_PrivacyPolicyPrepares(t *testing.T) {
|
||||
` projections.privacy_policies.resource_owner,`+
|
||||
` projections.privacy_policies.privacy_link,`+
|
||||
` projections.privacy_policies.tos_link,`+
|
||||
` projections.privacy_policies.help_link,`+
|
||||
` projections.privacy_policies.is_default,`+
|
||||
` projections.privacy_policies.state`+
|
||||
` FROM projections.privacy_policies`),
|
||||
@ -43,7 +44,7 @@ func Test_PrivacyPolicyPrepares(t *testing.T) {
|
||||
),
|
||||
err: func(err error) (error, bool) {
|
||||
if !errs.IsNotFound(err) {
|
||||
return fmt.Errorf("err should be zitadel.NotFoundError got: %w", err), false
|
||||
return fmt.Errorf("err should be NotFoundError got: %w", err), false
|
||||
}
|
||||
return nil, true
|
||||
},
|
||||
@ -62,6 +63,7 @@ func Test_PrivacyPolicyPrepares(t *testing.T) {
|
||||
` projections.privacy_policies.resource_owner,`+
|
||||
` projections.privacy_policies.privacy_link,`+
|
||||
` projections.privacy_policies.tos_link,`+
|
||||
` projections.privacy_policies.help_link,`+
|
||||
` projections.privacy_policies.is_default,`+
|
||||
` projections.privacy_policies.state`+
|
||||
` FROM projections.privacy_policies`),
|
||||
@ -73,6 +75,7 @@ func Test_PrivacyPolicyPrepares(t *testing.T) {
|
||||
"resource_owner",
|
||||
"privacy_link",
|
||||
"tos_link",
|
||||
"help_link",
|
||||
"is_default",
|
||||
"state",
|
||||
},
|
||||
@ -84,6 +87,7 @@ func Test_PrivacyPolicyPrepares(t *testing.T) {
|
||||
"ro",
|
||||
"privacy.ch",
|
||||
"tos.ch",
|
||||
"help.ch",
|
||||
true,
|
||||
domain.PolicyStateActive,
|
||||
},
|
||||
@ -98,6 +102,7 @@ func Test_PrivacyPolicyPrepares(t *testing.T) {
|
||||
State: domain.PolicyStateActive,
|
||||
PrivacyLink: "privacy.ch",
|
||||
TOSLink: "tos.ch",
|
||||
HelpLink: "help.ch",
|
||||
IsDefault: true,
|
||||
},
|
||||
},
|
||||
@ -113,6 +118,7 @@ func Test_PrivacyPolicyPrepares(t *testing.T) {
|
||||
` projections.privacy_policies.resource_owner,`+
|
||||
` projections.privacy_policies.privacy_link,`+
|
||||
` projections.privacy_policies.tos_link,`+
|
||||
` projections.privacy_policies.help_link,`+
|
||||
` projections.privacy_policies.is_default,`+
|
||||
` projections.privacy_policies.state`+
|
||||
` FROM projections.privacy_policies`),
|
||||
|
@ -58,15 +58,21 @@ var (
|
||||
|
||||
type ProjectGrantMembersQuery struct {
|
||||
MembersQuery
|
||||
ProjectID, GrantID string
|
||||
ProjectID, GrantID, OrgID string
|
||||
}
|
||||
|
||||
func (q *ProjectGrantMembersQuery) toQuery(query sq.SelectBuilder) sq.SelectBuilder {
|
||||
return q.MembersQuery.
|
||||
toQuery(query).
|
||||
Where(sq.Eq{
|
||||
ProjectGrantMemberProjectID.identifier(): q.ProjectID,
|
||||
ProjectGrantMemberGrantID.identifier(): q.GrantID,
|
||||
Where(sq.And{
|
||||
sq.Eq{
|
||||
ProjectGrantMemberProjectID.identifier(): q.ProjectID,
|
||||
ProjectGrantMemberGrantID.identifier(): q.GrantID,
|
||||
},
|
||||
sq.Or{
|
||||
sq.Eq{ProjectGrantColumnResourceOwner.identifier(): q.OrgID},
|
||||
sq.Eq{ProjectGrantColumnGrantedOrgID.identifier(): q.OrgID},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@ -117,6 +123,7 @@ func prepareProjectGrantMembersQuery() (sq.SelectBuilder, func(*sql.Rows) (*Memb
|
||||
LeftJoin(join(HumanUserIDCol, ProjectGrantMemberUserID)).
|
||||
LeftJoin(join(MachineUserIDCol, ProjectGrantMemberUserID)).
|
||||
LeftJoin(join(LoginNameUserIDCol, ProjectGrantMemberUserID)).
|
||||
LeftJoin(join(ProjectGrantColumnGrantID, ProjectGrantMemberGrantID)).
|
||||
Where(
|
||||
sq.Eq{LoginNameIsPrimaryCol.identifier(): true},
|
||||
).PlaceholderFormat(sq.Dollar),
|
||||
|
@ -34,6 +34,8 @@ var (
|
||||
"ON members.user_id = projections.users_machines.user_id " +
|
||||
"LEFT JOIN projections.login_names " +
|
||||
"ON members.user_id = projections.login_names.user_id " +
|
||||
"LEFT JOIN projections.project_grants " +
|
||||
"ON members.grant_id = projections.project_grants.grant_id " +
|
||||
"WHERE projections.login_names.is_primary = $1")
|
||||
projectGrantMembersColumns = []string{
|
||||
"creation_date",
|
||||
|
@ -76,6 +76,7 @@ func (p *FlowProjection) reduceTriggerActionsSetEventType(event eventstore.Event
|
||||
[]handler.Condition{
|
||||
handler.NewCond(FlowTypeCol, e.FlowType),
|
||||
handler.NewCond(FlowTriggerTypeCol, e.TriggerType),
|
||||
handler.NewCond(FlowResourceOwnerCol, e.Aggregate().ResourceOwner),
|
||||
},
|
||||
)
|
||||
for i, id := range e.ActionIDs {
|
||||
@ -104,6 +105,7 @@ func (p *FlowProjection) reduceFlowClearedEventType(event eventstore.Event) (*ha
|
||||
e,
|
||||
[]handler.Condition{
|
||||
handler.NewCond(FlowTypeCol, e.FlowType),
|
||||
handler.NewCond(FlowResourceOwnerCol, e.Aggregate().ResourceOwner),
|
||||
},
|
||||
), nil
|
||||
}
|
||||
|
@ -39,10 +39,11 @@ func TestFlowProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "DELETE FROM projections.flows_triggers WHERE (flow_type = $1) AND (trigger_type = $2)",
|
||||
expectedStmt: "DELETE FROM projections.flows_triggers WHERE (flow_type = $1) AND (trigger_type = $2) AND (resource_owner = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
domain.FlowTypeExternalAuthentication,
|
||||
domain.TriggerTypePostAuthentication,
|
||||
"ro-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -93,9 +94,10 @@ func TestFlowProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "DELETE FROM projections.flows_triggers WHERE (flow_type = $1)",
|
||||
expectedStmt: "DELETE FROM projections.flows_triggers WHERE (flow_type = $1) AND (resource_owner = $2)",
|
||||
expectedArgs: []interface{}{
|
||||
domain.FlowTypeExternalAuthentication,
|
||||
"ro-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -26,6 +26,7 @@ const (
|
||||
PrivacyPolicyInstanceIDCol = "instance_id"
|
||||
PrivacyPolicyPrivacyLinkCol = "privacy_link"
|
||||
PrivacyPolicyTOSLinkCol = "tos_link"
|
||||
PrivacyPolicyHelpLinkCol = "help_link"
|
||||
)
|
||||
|
||||
type PrivacyPolicyProjection struct {
|
||||
@ -48,6 +49,7 @@ func NewPrivacyPolicyProjection(ctx context.Context, config crdb.StatementHandle
|
||||
crdb.NewColumn(PrivacyPolicyInstanceIDCol, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(PrivacyPolicyPrivacyLinkCol, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(PrivacyPolicyTOSLinkCol, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(PrivacyPolicyHelpLinkCol, crdb.ColumnTypeText),
|
||||
},
|
||||
crdb.NewPrimaryKey(PrivacyPolicyInstanceIDCol, PrivacyPolicyIDCol),
|
||||
),
|
||||
@ -114,6 +116,7 @@ func (p *PrivacyPolicyProjection) reduceAdded(event eventstore.Event) (*handler.
|
||||
handler.NewCol(PrivacyPolicyStateCol, domain.PolicyStateActive),
|
||||
handler.NewCol(PrivacyPolicyPrivacyLinkCol, policyEvent.PrivacyLink),
|
||||
handler.NewCol(PrivacyPolicyTOSLinkCol, policyEvent.TOSLink),
|
||||
handler.NewCol(PrivacyPolicyHelpLinkCol, policyEvent.HelpLink),
|
||||
handler.NewCol(PrivacyPolicyIsDefaultCol, isDefault),
|
||||
handler.NewCol(PrivacyPolicyResourceOwnerCol, policyEvent.Aggregate().ResourceOwner),
|
||||
handler.NewCol(PrivacyPolicyInstanceIDCol, policyEvent.Aggregate().InstanceID),
|
||||
@ -140,6 +143,9 @@ func (p *PrivacyPolicyProjection) reduceChanged(event eventstore.Event) (*handle
|
||||
if policyEvent.TOSLink != nil {
|
||||
cols = append(cols, handler.NewCol(PrivacyPolicyTOSLinkCol, *policyEvent.TOSLink))
|
||||
}
|
||||
if policyEvent.HelpLink != nil {
|
||||
cols = append(cols, handler.NewCol(PrivacyPolicyHelpLinkCol, *policyEvent.HelpLink))
|
||||
}
|
||||
return crdb.NewUpdateStatement(
|
||||
&policyEvent,
|
||||
cols,
|
||||
|
@ -30,7 +30,8 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
org.AggregateType,
|
||||
[]byte(`{
|
||||
"tosLink": "http://tos.link",
|
||||
"privacyLink": "http://privacy.link"
|
||||
"privacyLink": "http://privacy.link",
|
||||
"helpLink": "http://help.link"
|
||||
}`),
|
||||
), org.PrivacyPolicyAddedEventMapper),
|
||||
},
|
||||
@ -43,7 +44,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.privacy_policies (creation_date, change_date, sequence, id, state, privacy_link, tos_link, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||
expectedStmt: "INSERT INTO projections.privacy_policies (creation_date, change_date, sequence, id, state, privacy_link, tos_link, help_link, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
anyArg{},
|
||||
@ -52,6 +53,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
domain.PolicyStateActive,
|
||||
"http://privacy.link",
|
||||
"http://tos.link",
|
||||
"http://help.link",
|
||||
false,
|
||||
"ro-id",
|
||||
"instance-id",
|
||||
@ -70,7 +72,8 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
org.AggregateType,
|
||||
[]byte(`{
|
||||
"tosLink": "http://tos.link",
|
||||
"privacyLink": "http://privacy.link"
|
||||
"privacyLink": "http://privacy.link",
|
||||
"helpLink": "http://help.link"
|
||||
}`),
|
||||
), org.PrivacyPolicyChangedEventMapper),
|
||||
},
|
||||
@ -82,12 +85,13 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.privacy_policies SET (change_date, sequence, privacy_link, tos_link) = ($1, $2, $3, $4) WHERE (id = $5)",
|
||||
expectedStmt: "UPDATE projections.privacy_policies SET (change_date, sequence, privacy_link, tos_link, help_link) = ($1, $2, $3, $4, $5) WHERE (id = $6)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"http://privacy.link",
|
||||
"http://tos.link",
|
||||
"http://help.link",
|
||||
"agg-id",
|
||||
},
|
||||
},
|
||||
@ -131,7 +135,8 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
iam.AggregateType,
|
||||
[]byte(`{
|
||||
"tosLink": "http://tos.link",
|
||||
"privacyLink": "http://privacy.link"
|
||||
"privacyLink": "http://privacy.link",
|
||||
"helpLink": "http://help.link"
|
||||
}`),
|
||||
), iam.PrivacyPolicyAddedEventMapper),
|
||||
},
|
||||
@ -143,7 +148,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.privacy_policies (creation_date, change_date, sequence, id, state, privacy_link, tos_link, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||
expectedStmt: "INSERT INTO projections.privacy_policies (creation_date, change_date, sequence, id, state, privacy_link, tos_link, help_link, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
anyArg{},
|
||||
@ -152,6 +157,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
domain.PolicyStateActive,
|
||||
"http://privacy.link",
|
||||
"http://tos.link",
|
||||
"http://help.link",
|
||||
true,
|
||||
"ro-id",
|
||||
"instance-id",
|
||||
@ -170,7 +176,8 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
iam.AggregateType,
|
||||
[]byte(`{
|
||||
"tosLink": "http://tos.link",
|
||||
"privacyLink": "http://privacy.link"
|
||||
"privacyLink": "http://privacy.link",
|
||||
"helpLink": "http://help.link"
|
||||
}`),
|
||||
), iam.PrivacyPolicyChangedEventMapper),
|
||||
},
|
||||
@ -182,12 +189,13 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.privacy_policies SET (change_date, sequence, privacy_link, tos_link) = ($1, $2, $3, $4) WHERE (id = $5)",
|
||||
expectedStmt: "UPDATE projections.privacy_policies SET (change_date, sequence, privacy_link, tos_link, help_link) = ($1, $2, $3, $4, $5) WHERE (id = $6)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"http://privacy.link",
|
||||
"http://tos.link",
|
||||
"http://help.link",
|
||||
"agg-id",
|
||||
},
|
||||
},
|
||||
|
@ -25,15 +25,16 @@ type UserGrant struct {
|
||||
GrantID string
|
||||
State domain.UserGrantState
|
||||
|
||||
UserID string
|
||||
Username string
|
||||
UserType domain.UserType
|
||||
UserResourceOwner string
|
||||
FirstName string
|
||||
LastName string
|
||||
Email string
|
||||
DisplayName string
|
||||
AvatarURL string
|
||||
UserID string
|
||||
Username string
|
||||
UserType domain.UserType
|
||||
UserResourceOwner string
|
||||
FirstName string
|
||||
LastName string
|
||||
Email string
|
||||
DisplayName string
|
||||
AvatarURL string
|
||||
PreferredLoginName string
|
||||
|
||||
ResourceOwner string
|
||||
OrgName string
|
||||
@ -255,6 +256,7 @@ func prepareUserGrantQuery() (sq.SelectBuilder, func(*sql.Row) (*UserGrant, erro
|
||||
HumanEmailCol.identifier(),
|
||||
HumanDisplayNameCol.identifier(),
|
||||
HumanAvatarURLCol.identifier(),
|
||||
LoginNameNameCol.identifier(),
|
||||
|
||||
UserGrantResourceOwner.identifier(),
|
||||
OrgColumnName.identifier(),
|
||||
@ -268,20 +270,24 @@ func prepareUserGrantQuery() (sq.SelectBuilder, func(*sql.Row) (*UserGrant, erro
|
||||
LeftJoin(join(HumanUserIDCol, UserGrantUserID)).
|
||||
LeftJoin(join(OrgColumnID, UserGrantResourceOwner)).
|
||||
LeftJoin(join(ProjectColumnID, UserGrantProjectID)).
|
||||
PlaceholderFormat(sq.Dollar),
|
||||
LeftJoin(join(LoginNameUserIDCol, UserGrantUserID)).
|
||||
Where(
|
||||
sq.Eq{LoginNameIsPrimaryCol.identifier(): true},
|
||||
).PlaceholderFormat(sq.Dollar),
|
||||
func(row *sql.Row) (*UserGrant, error) {
|
||||
g := new(UserGrant)
|
||||
|
||||
var (
|
||||
roles = pq.StringArray{}
|
||||
username sql.NullString
|
||||
firstName sql.NullString
|
||||
userType sql.NullInt32
|
||||
userOwner sql.NullString
|
||||
lastName sql.NullString
|
||||
email sql.NullString
|
||||
displayName sql.NullString
|
||||
avatarURL sql.NullString
|
||||
roles = pq.StringArray{}
|
||||
username sql.NullString
|
||||
firstName sql.NullString
|
||||
userType sql.NullInt32
|
||||
userOwner sql.NullString
|
||||
lastName sql.NullString
|
||||
email sql.NullString
|
||||
displayName sql.NullString
|
||||
avatarURL sql.NullString
|
||||
preferredLoginName sql.NullString
|
||||
|
||||
orgName sql.NullString
|
||||
orgDomain sql.NullString
|
||||
@ -307,6 +313,7 @@ func prepareUserGrantQuery() (sq.SelectBuilder, func(*sql.Row) (*UserGrant, erro
|
||||
&email,
|
||||
&displayName,
|
||||
&avatarURL,
|
||||
&preferredLoginName,
|
||||
|
||||
&g.ResourceOwner,
|
||||
&orgName,
|
||||
@ -331,6 +338,7 @@ func prepareUserGrantQuery() (sq.SelectBuilder, func(*sql.Row) (*UserGrant, erro
|
||||
g.Email = email.String
|
||||
g.DisplayName = displayName.String
|
||||
g.AvatarURL = avatarURL.String
|
||||
g.PreferredLoginName = preferredLoginName.String
|
||||
g.OrgName = orgName.String
|
||||
g.OrgPrimaryDomain = orgDomain.String
|
||||
g.ProjectName = projectName.String
|
||||
@ -358,6 +366,7 @@ func prepareUserGrantsQuery() (sq.SelectBuilder, func(*sql.Rows) (*UserGrants, e
|
||||
HumanEmailCol.identifier(),
|
||||
HumanDisplayNameCol.identifier(),
|
||||
HumanAvatarURLCol.identifier(),
|
||||
LoginNameNameCol.identifier(),
|
||||
|
||||
UserGrantResourceOwner.identifier(),
|
||||
OrgColumnName.identifier(),
|
||||
@ -373,7 +382,10 @@ func prepareUserGrantsQuery() (sq.SelectBuilder, func(*sql.Rows) (*UserGrants, e
|
||||
LeftJoin(join(HumanUserIDCol, UserGrantUserID)).
|
||||
LeftJoin(join(OrgColumnID, UserGrantResourceOwner)).
|
||||
LeftJoin(join(ProjectColumnID, UserGrantProjectID)).
|
||||
PlaceholderFormat(sq.Dollar),
|
||||
LeftJoin(join(LoginNameUserIDCol, UserGrantUserID)).
|
||||
Where(
|
||||
sq.Eq{LoginNameIsPrimaryCol.identifier(): true},
|
||||
).PlaceholderFormat(sq.Dollar),
|
||||
func(rows *sql.Rows) (*UserGrants, error) {
|
||||
userGrants := make([]*UserGrant, 0)
|
||||
var count uint64
|
||||
@ -381,15 +393,16 @@ func prepareUserGrantsQuery() (sq.SelectBuilder, func(*sql.Rows) (*UserGrants, e
|
||||
g := new(UserGrant)
|
||||
|
||||
var (
|
||||
roles = pq.StringArray{}
|
||||
username sql.NullString
|
||||
userType sql.NullInt32
|
||||
userOwner sql.NullString
|
||||
firstName sql.NullString
|
||||
lastName sql.NullString
|
||||
email sql.NullString
|
||||
displayName sql.NullString
|
||||
avatarURL sql.NullString
|
||||
roles = pq.StringArray{}
|
||||
username sql.NullString
|
||||
userType sql.NullInt32
|
||||
userOwner sql.NullString
|
||||
firstName sql.NullString
|
||||
lastName sql.NullString
|
||||
email sql.NullString
|
||||
displayName sql.NullString
|
||||
avatarURL sql.NullString
|
||||
preferredLoginName sql.NullString
|
||||
|
||||
orgName sql.NullString
|
||||
orgDomain sql.NullString
|
||||
@ -415,6 +428,7 @@ func prepareUserGrantsQuery() (sq.SelectBuilder, func(*sql.Rows) (*UserGrants, e
|
||||
&email,
|
||||
&displayName,
|
||||
&avatarURL,
|
||||
&preferredLoginName,
|
||||
|
||||
&g.ResourceOwner,
|
||||
&orgName,
|
||||
@ -438,6 +452,7 @@ func prepareUserGrantsQuery() (sq.SelectBuilder, func(*sql.Rows) (*UserGrants, e
|
||||
g.Email = email.String
|
||||
g.DisplayName = displayName.String
|
||||
g.AvatarURL = avatarURL.String
|
||||
g.PreferredLoginName = preferredLoginName.String
|
||||
g.OrgName = orgName.String
|
||||
g.OrgPrimaryDomain = orgDomain.String
|
||||
g.ProjectName = projectName.String
|
||||
|
@ -32,6 +32,7 @@ var (
|
||||
", projections.users_humans.email" +
|
||||
", projections.users_humans.display_name" +
|
||||
", projections.users_humans.avatar_key" +
|
||||
", projections.login_names.login_name" +
|
||||
", projections.user_grants.resource_owner" +
|
||||
", projections.orgs.name" +
|
||||
", projections.orgs.primary_domain" +
|
||||
@ -41,7 +42,9 @@ var (
|
||||
" LEFT JOIN projections.users ON projections.user_grants.user_id = projections.users.id" +
|
||||
" LEFT JOIN projections.users_humans ON projections.user_grants.user_id = projections.users_humans.user_id" +
|
||||
" LEFT JOIN projections.orgs ON projections.user_grants.resource_owner = projections.orgs.id" +
|
||||
" LEFT JOIN projections.projects ON projections.user_grants.project_id = projections.projects.id")
|
||||
" LEFT JOIN projections.projects ON projections.user_grants.project_id = projections.projects.id" +
|
||||
" LEFT JOIN projections.login_names ON projections.user_grants.user_id = projections.login_names.user_id" +
|
||||
" WHERE projections.login_names.is_primary = $1")
|
||||
userGrantCols = []string{
|
||||
"id",
|
||||
"creation_date",
|
||||
@ -59,6 +62,7 @@ var (
|
||||
"email",
|
||||
"display_name",
|
||||
"avatar_key",
|
||||
"login_name",
|
||||
"resource_owner", //user_grant resource owner
|
||||
"name", //org name
|
||||
"primary_domain",
|
||||
@ -82,6 +86,7 @@ var (
|
||||
", projections.users_humans.email" +
|
||||
", projections.users_humans.display_name" +
|
||||
", projections.users_humans.avatar_key" +
|
||||
", projections.login_names.login_name" +
|
||||
", projections.user_grants.resource_owner" +
|
||||
", projections.orgs.name" +
|
||||
", projections.orgs.primary_domain" +
|
||||
@ -92,7 +97,9 @@ var (
|
||||
" LEFT JOIN projections.users ON projections.user_grants.user_id = projections.users.id" +
|
||||
" LEFT JOIN projections.users_humans ON projections.user_grants.user_id = projections.users_humans.user_id" +
|
||||
" LEFT JOIN projections.orgs ON projections.user_grants.resource_owner = projections.orgs.id" +
|
||||
" LEFT JOIN projections.projects ON projections.user_grants.project_id = projections.projects.id")
|
||||
" LEFT JOIN projections.projects ON projections.user_grants.project_id = projections.projects.id" +
|
||||
" LEFT JOIN projections.login_names ON projections.user_grants.user_id = projections.login_names.user_id" +
|
||||
" WHERE projections.login_names.is_primary = $1")
|
||||
userGrantsCols = append(
|
||||
userGrantCols,
|
||||
"count",
|
||||
@ -152,6 +159,7 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
"email",
|
||||
"display-name",
|
||||
"avatar-key",
|
||||
"login-name",
|
||||
"ro",
|
||||
"org-name",
|
||||
"primary-domain",
|
||||
@ -161,27 +169,28 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
),
|
||||
},
|
||||
object: &UserGrant{
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeHuman,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "first-name",
|
||||
LastName: "last-name",
|
||||
Email: "email",
|
||||
DisplayName: "display-name",
|
||||
AvatarURL: "avatar-key",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "org-name",
|
||||
OrgPrimaryDomain: "primary-domain",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "project-name",
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeHuman,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "first-name",
|
||||
LastName: "last-name",
|
||||
Email: "email",
|
||||
DisplayName: "display-name",
|
||||
AvatarURL: "avatar-key",
|
||||
PreferredLoginName: "login-name",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "org-name",
|
||||
OrgPrimaryDomain: "primary-domain",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "project-name",
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -208,6 +217,7 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
"login-name",
|
||||
"ro",
|
||||
"org-name",
|
||||
"primary-domain",
|
||||
@ -217,27 +227,28 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
),
|
||||
},
|
||||
object: &UserGrant{
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeMachine,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "",
|
||||
LastName: "",
|
||||
Email: "",
|
||||
DisplayName: "",
|
||||
AvatarURL: "",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "org-name",
|
||||
OrgPrimaryDomain: "primary-domain",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "project-name",
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeMachine,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "",
|
||||
LastName: "",
|
||||
Email: "",
|
||||
DisplayName: "",
|
||||
AvatarURL: "",
|
||||
PreferredLoginName: "login-name",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "org-name",
|
||||
OrgPrimaryDomain: "primary-domain",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "project-name",
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -264,6 +275,7 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
"email",
|
||||
"display-name",
|
||||
"avatar-key",
|
||||
"login-name",
|
||||
"ro",
|
||||
nil,
|
||||
nil,
|
||||
@ -273,27 +285,28 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
),
|
||||
},
|
||||
object: &UserGrant{
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeHuman,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "first-name",
|
||||
LastName: "last-name",
|
||||
Email: "email",
|
||||
DisplayName: "display-name",
|
||||
AvatarURL: "avatar-key",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "",
|
||||
OrgPrimaryDomain: "",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "project-name",
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeHuman,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "first-name",
|
||||
LastName: "last-name",
|
||||
Email: "email",
|
||||
DisplayName: "display-name",
|
||||
AvatarURL: "avatar-key",
|
||||
PreferredLoginName: "login-name",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "",
|
||||
OrgPrimaryDomain: "",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "project-name",
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -320,6 +333,7 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
"email",
|
||||
"display-name",
|
||||
"avatar-key",
|
||||
"login-name",
|
||||
"ro",
|
||||
"org-name",
|
||||
"primary-domain",
|
||||
@ -329,27 +343,86 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
),
|
||||
},
|
||||
object: &UserGrant{
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeHuman,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "first-name",
|
||||
LastName: "last-name",
|
||||
Email: "email",
|
||||
DisplayName: "display-name",
|
||||
AvatarURL: "avatar-key",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "org-name",
|
||||
OrgPrimaryDomain: "primary-domain",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "",
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeHuman,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "first-name",
|
||||
LastName: "last-name",
|
||||
Email: "email",
|
||||
DisplayName: "display-name",
|
||||
AvatarURL: "avatar-key",
|
||||
PreferredLoginName: "login-name",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "org-name",
|
||||
OrgPrimaryDomain: "primary-domain",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "prepareUserGrantQuery (no loginname) found",
|
||||
prepare: prepareUserGrantQuery,
|
||||
want: want{
|
||||
sqlExpectations: mockQuery(
|
||||
userGrantStmt,
|
||||
userGrantCols,
|
||||
[]driver.Value{
|
||||
"id",
|
||||
testNow,
|
||||
testNow,
|
||||
20211111,
|
||||
"grant-id",
|
||||
pq.StringArray{"role-key"},
|
||||
domain.UserGrantStateActive,
|
||||
"user-id",
|
||||
"username",
|
||||
domain.UserTypeHuman,
|
||||
"resource-owner",
|
||||
"first-name",
|
||||
"last-name",
|
||||
"email",
|
||||
"display-name",
|
||||
"avatar-key",
|
||||
nil,
|
||||
"ro",
|
||||
"org-name",
|
||||
"primary-domain",
|
||||
"project-id",
|
||||
"project-name",
|
||||
},
|
||||
),
|
||||
},
|
||||
object: &UserGrant{
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeHuman,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "first-name",
|
||||
LastName: "last-name",
|
||||
Email: "email",
|
||||
DisplayName: "display-name",
|
||||
AvatarURL: "avatar-key",
|
||||
PreferredLoginName: "",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "org-name",
|
||||
OrgPrimaryDomain: "primary-domain",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "project-name",
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -406,6 +479,7 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
"email",
|
||||
"display-name",
|
||||
"avatar-key",
|
||||
"login-name",
|
||||
"ro",
|
||||
"org-name",
|
||||
"primary-domain",
|
||||
@ -421,27 +495,28 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
},
|
||||
UserGrants: []*UserGrant{
|
||||
{
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeHuman,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "first-name",
|
||||
LastName: "last-name",
|
||||
Email: "email",
|
||||
DisplayName: "display-name",
|
||||
AvatarURL: "avatar-key",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "org-name",
|
||||
OrgPrimaryDomain: "primary-domain",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "project-name",
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeHuman,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "first-name",
|
||||
LastName: "last-name",
|
||||
Email: "email",
|
||||
DisplayName: "display-name",
|
||||
AvatarURL: "avatar-key",
|
||||
PreferredLoginName: "login-name",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "org-name",
|
||||
OrgPrimaryDomain: "primary-domain",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "project-name",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -471,6 +546,7 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
"login-name",
|
||||
"ro",
|
||||
"org-name",
|
||||
"primary-domain",
|
||||
@ -486,27 +562,28 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
},
|
||||
UserGrants: []*UserGrant{
|
||||
{
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeMachine,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "",
|
||||
LastName: "",
|
||||
Email: "",
|
||||
DisplayName: "",
|
||||
AvatarURL: "",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "org-name",
|
||||
OrgPrimaryDomain: "primary-domain",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "project-name",
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeMachine,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "",
|
||||
LastName: "",
|
||||
Email: "",
|
||||
DisplayName: "",
|
||||
AvatarURL: "",
|
||||
PreferredLoginName: "login-name",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "org-name",
|
||||
OrgPrimaryDomain: "primary-domain",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "project-name",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -536,6 +613,7 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
"email",
|
||||
"display-name",
|
||||
"avatar-key",
|
||||
"login-name",
|
||||
"ro",
|
||||
nil,
|
||||
nil,
|
||||
@ -551,27 +629,28 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
},
|
||||
UserGrants: []*UserGrant{
|
||||
{
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeMachine,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "first-name",
|
||||
LastName: "last-name",
|
||||
Email: "email",
|
||||
DisplayName: "display-name",
|
||||
AvatarURL: "avatar-key",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "",
|
||||
OrgPrimaryDomain: "",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "project-name",
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeMachine,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "first-name",
|
||||
LastName: "last-name",
|
||||
Email: "email",
|
||||
DisplayName: "display-name",
|
||||
AvatarURL: "avatar-key",
|
||||
PreferredLoginName: "login-name",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "",
|
||||
OrgPrimaryDomain: "",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "project-name",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -601,6 +680,7 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
"email",
|
||||
"display-name",
|
||||
"avatar-key",
|
||||
"login-name",
|
||||
"ro",
|
||||
"org-name",
|
||||
"primary-domain",
|
||||
@ -616,27 +696,95 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
},
|
||||
UserGrants: []*UserGrant{
|
||||
{
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeHuman,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "first-name",
|
||||
LastName: "last-name",
|
||||
Email: "email",
|
||||
DisplayName: "display-name",
|
||||
AvatarURL: "avatar-key",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "org-name",
|
||||
OrgPrimaryDomain: "primary-domain",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "",
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeHuman,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "first-name",
|
||||
LastName: "last-name",
|
||||
Email: "email",
|
||||
DisplayName: "display-name",
|
||||
AvatarURL: "avatar-key",
|
||||
PreferredLoginName: "login-name",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "org-name",
|
||||
OrgPrimaryDomain: "primary-domain",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "prepareUserGrantsQuery one grant (no loginname)",
|
||||
prepare: prepareUserGrantsQuery,
|
||||
want: want{
|
||||
sqlExpectations: mockQueries(
|
||||
userGrantsStmt,
|
||||
userGrantsCols,
|
||||
[][]driver.Value{
|
||||
{
|
||||
"id",
|
||||
testNow,
|
||||
testNow,
|
||||
20211111,
|
||||
"grant-id",
|
||||
pq.StringArray{"role-key"},
|
||||
domain.UserGrantStateActive,
|
||||
"user-id",
|
||||
"username",
|
||||
domain.UserTypeHuman,
|
||||
"resource-owner",
|
||||
"first-name",
|
||||
"last-name",
|
||||
"email",
|
||||
"display-name",
|
||||
"avatar-key",
|
||||
nil,
|
||||
"ro",
|
||||
"org-name",
|
||||
"primary-domain",
|
||||
"project-id",
|
||||
"project-name",
|
||||
},
|
||||
},
|
||||
),
|
||||
},
|
||||
object: &UserGrants{
|
||||
SearchResponse: SearchResponse{
|
||||
Count: 1,
|
||||
},
|
||||
UserGrants: []*UserGrant{
|
||||
{
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeHuman,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "first-name",
|
||||
LastName: "last-name",
|
||||
Email: "email",
|
||||
DisplayName: "display-name",
|
||||
AvatarURL: "avatar-key",
|
||||
PreferredLoginName: "",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "org-name",
|
||||
OrgPrimaryDomain: "primary-domain",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "project-name",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -666,6 +814,7 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
"email",
|
||||
"display-name",
|
||||
"avatar-key",
|
||||
"login-name",
|
||||
"ro",
|
||||
"org-name",
|
||||
"primary-domain",
|
||||
@ -689,6 +838,7 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
"email",
|
||||
"display-name",
|
||||
"avatar-key",
|
||||
"login-name",
|
||||
"ro",
|
||||
"org-name",
|
||||
"primary-domain",
|
||||
@ -704,50 +854,52 @@ func Test_UserGrantPrepares(t *testing.T) {
|
||||
},
|
||||
UserGrants: []*UserGrant{
|
||||
{
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeHuman,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "first-name",
|
||||
LastName: "last-name",
|
||||
Email: "email",
|
||||
DisplayName: "display-name",
|
||||
AvatarURL: "avatar-key",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "org-name",
|
||||
OrgPrimaryDomain: "primary-domain",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "project-name",
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeHuman,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "first-name",
|
||||
LastName: "last-name",
|
||||
Email: "email",
|
||||
DisplayName: "display-name",
|
||||
AvatarURL: "avatar-key",
|
||||
PreferredLoginName: "login-name",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "org-name",
|
||||
OrgPrimaryDomain: "primary-domain",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "project-name",
|
||||
},
|
||||
{
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeHuman,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "first-name",
|
||||
LastName: "last-name",
|
||||
Email: "email",
|
||||
DisplayName: "display-name",
|
||||
AvatarURL: "avatar-key",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "org-name",
|
||||
OrgPrimaryDomain: "primary-domain",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "project-name",
|
||||
ID: "id",
|
||||
CreationDate: testNow,
|
||||
ChangeDate: testNow,
|
||||
Sequence: 20211111,
|
||||
Roles: []string{"role-key"},
|
||||
GrantID: "grant-id",
|
||||
State: domain.UserGrantStateActive,
|
||||
UserID: "user-id",
|
||||
Username: "username",
|
||||
UserType: domain.UserTypeHuman,
|
||||
UserResourceOwner: "resource-owner",
|
||||
FirstName: "first-name",
|
||||
LastName: "last-name",
|
||||
Email: "email",
|
||||
DisplayName: "display-name",
|
||||
AvatarURL: "avatar-key",
|
||||
PreferredLoginName: "login-name",
|
||||
ResourceOwner: "ro",
|
||||
OrgName: "org-name",
|
||||
OrgPrimaryDomain: "primary-domain",
|
||||
ProjectID: "project-id",
|
||||
ProjectName: "project-name",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -70,6 +70,14 @@ func NewMembershipOrgIDQuery(value string) (SearchQuery, error) {
|
||||
return NewTextQuery(membershipOrgID, value, TextEquals)
|
||||
}
|
||||
|
||||
func NewMembershipResourceOwnersSearchQuery(ids ...string) (SearchQuery, error) {
|
||||
list := make([]interface{}, len(ids))
|
||||
for i, value := range ids {
|
||||
list[i] = value
|
||||
}
|
||||
return NewListQuery(membershipResourceOwner, list, ListIn)
|
||||
}
|
||||
|
||||
func NewMembershipProjectIDQuery(value string) (SearchQuery, error) {
|
||||
return NewTextQuery(membershipProjectID, value, TextEquals)
|
||||
}
|
||||
|
@ -6,13 +6,17 @@ import (
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
)
|
||||
|
||||
func (q *Queries) MyZitadelPermissions(ctx context.Context, userID string) (*domain.Permissions, error) {
|
||||
func (q *Queries) MyZitadelPermissions(ctx context.Context, orgID, userID string) (*domain.Permissions, error) {
|
||||
userIDQuery, err := NewMembershipUserIDQuery(userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orgIDsQuery, err := NewMembershipResourceOwnersSearchQuery(orgID, domain.IAMID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
memberships, err := q.Memberships(ctx, &MembershipSearchQuery{
|
||||
Queries: []SearchQuery{userIDQuery},
|
||||
Queries: []SearchQuery{userIDQuery, orgIDsQuery},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -22,7 +22,8 @@ func NewPrivacyPolicyAddedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
tosLink,
|
||||
privacyLink string,
|
||||
privacyLink,
|
||||
helpLink string,
|
||||
) *PrivacyPolicyAddedEvent {
|
||||
return &PrivacyPolicyAddedEvent{
|
||||
PrivacyPolicyAddedEvent: *policy.NewPrivacyPolicyAddedEvent(
|
||||
@ -31,7 +32,8 @@ func NewPrivacyPolicyAddedEvent(
|
||||
aggregate,
|
||||
PrivacyPolicyAddedEventType),
|
||||
tosLink,
|
||||
privacyLink),
|
||||
privacyLink,
|
||||
helpLink),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,8 @@ func NewPrivacyPolicyAddedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
tosLink,
|
||||
privacyLink string,
|
||||
privacyLink,
|
||||
helpLink string,
|
||||
) *PrivacyPolicyAddedEvent {
|
||||
return &PrivacyPolicyAddedEvent{
|
||||
PrivacyPolicyAddedEvent: *policy.NewPrivacyPolicyAddedEvent(
|
||||
@ -32,7 +33,8 @@ func NewPrivacyPolicyAddedEvent(
|
||||
aggregate,
|
||||
PrivacyPolicyAddedEventType),
|
||||
tosLink,
|
||||
privacyLink),
|
||||
privacyLink,
|
||||
helpLink),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ type PrivacyPolicyAddedEvent struct {
|
||||
|
||||
TOSLink string `json:"tosLink,omitempty"`
|
||||
PrivacyLink string `json:"privacyLink,omitempty"`
|
||||
HelpLink string `json:"helpLink,omitempty"`
|
||||
}
|
||||
|
||||
func (e *PrivacyPolicyAddedEvent) Data() interface{} {
|
||||
@ -33,12 +34,14 @@ func (e *PrivacyPolicyAddedEvent) UniqueConstraints() []*eventstore.EventUniqueC
|
||||
func NewPrivacyPolicyAddedEvent(
|
||||
base *eventstore.BaseEvent,
|
||||
tosLink,
|
||||
privacyLink string,
|
||||
privacyLink,
|
||||
helpLink string,
|
||||
) *PrivacyPolicyAddedEvent {
|
||||
return &PrivacyPolicyAddedEvent{
|
||||
BaseEvent: *base,
|
||||
TOSLink: tosLink,
|
||||
PrivacyLink: privacyLink,
|
||||
HelpLink: helpLink,
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,6 +62,7 @@ type PrivacyPolicyChangedEvent struct {
|
||||
|
||||
TOSLink *string `json:"tosLink,omitempty"`
|
||||
PrivacyLink *string `json:"privacyLink,omitempty"`
|
||||
HelpLink *string `json:"helpLink,omitempty"`
|
||||
}
|
||||
|
||||
func (e *PrivacyPolicyChangedEvent) Data() interface{} {
|
||||
@ -99,6 +103,12 @@ func ChangePrivacyLink(privacyLink string) func(*PrivacyPolicyChangedEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
func ChangeHelpLink(helpLink string) func(*PrivacyPolicyChangedEvent) {
|
||||
return func(e *PrivacyPolicyChangedEvent) {
|
||||
e.HelpLink = &helpLink
|
||||
}
|
||||
}
|
||||
|
||||
func PrivacyPolicyChangedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||
e := &PrivacyPolicyChangedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
|
@ -193,22 +193,22 @@ Errors:
|
||||
NotChanged: Default Message Text wurde nicht verändert
|
||||
AlreadyExists: Default Message Text existiert bereits
|
||||
Invalid: Default Message Text ist ungültig
|
||||
PasswordComplexity:
|
||||
PasswordComplexityPolicy:
|
||||
NotFound: Password Komplexitäts Policy konnte nicht gefunden werden
|
||||
Empty: Passwort Komplexitäts Policy ist leer
|
||||
NotExisting: Passwort Komplexitäts Policy existiert nicht
|
||||
AlreadyExists: Passwort Komplexitäts Policy existiert bereits
|
||||
PasswordLockout:
|
||||
PasswordLockoutPolicy:
|
||||
NotFound: Password Lockout Policy konnte nicht gefunden werden
|
||||
Empty: Passwort Lockout Policy ist leer
|
||||
NotExisting: Passwort Lockout Policy existiert nicht
|
||||
AlreadyExists: Passwort Lockout Policy existiert bereits
|
||||
PasswordAge:
|
||||
PasswordAgePolicy:
|
||||
NotFound: Password Age Policy konnte nicht gefunden werden
|
||||
Empty: Passwort Age Policy ist leer
|
||||
NotExisting: Passwort Age Policy existiert nicht
|
||||
AlreadyExists: Passwort Age Policy existiert bereits
|
||||
OrgIAM:
|
||||
OrgIAMPolicy:
|
||||
Empty: Org IAM Policy ist leer
|
||||
NotExisting: Org IAM Policy existiert nicht
|
||||
AlreadyExists: Org IAM Policy existiert bereits
|
||||
@ -589,6 +589,10 @@ EventTypes:
|
||||
cascade:
|
||||
removed: Berechtigung entfernt
|
||||
changed: Berechtigung geändert
|
||||
metadata:
|
||||
set: Benutzer Metadaten gesetzt
|
||||
removed: Benutzer Metadaten gelöscht
|
||||
removed.all: Alle Benutzer Metadaten gelöscht
|
||||
org:
|
||||
added: Organisation hinzugefügt
|
||||
changed: Organisation geändert
|
||||
|
@ -193,22 +193,22 @@ Errors:
|
||||
NotChanged: Default Message Text has not been changed
|
||||
AlreadyExists: Default Message Text already exists
|
||||
Invalid: Default Message Text is invalid
|
||||
PasswordComplexity:
|
||||
PasswordComplexityPolicy:
|
||||
NotFound: Password Complexity Policy not found
|
||||
Empty: Password Complexity Policy is empty
|
||||
NotExisting: Password Complexity Policy doesn't exist
|
||||
AlreadyExists: Password Complexity Policy already exists
|
||||
PasswordLockout:
|
||||
PasswordLockoutPolicy:
|
||||
NotFound: Password Lockout Policy not found
|
||||
Empty: Password Lockout Policy is empty
|
||||
NotExisting: Password Lockout Policy doesn't exist
|
||||
AlreadyExists: Password Lockout Policy already exists
|
||||
PasswordAge:
|
||||
PasswordAgePolicy:
|
||||
NotFound: Password Age Policy not found
|
||||
Empty: Password Age Policy is empty
|
||||
NotExisting: Password Age Policy doesn't exist
|
||||
AlreadyExists: Password Age Policy already exists
|
||||
OrgIAM:
|
||||
OrgIAMPolicy:
|
||||
Empty: Org IAM Policy is empty
|
||||
NotExisting: Org IAM Policy doesn't exist
|
||||
AlreadyExists: Org IAM Policy already exists
|
||||
@ -589,6 +589,10 @@ EventTypes:
|
||||
cascade:
|
||||
removed: Authorization removed
|
||||
changed: Authorization changed
|
||||
metadata:
|
||||
set: User metadata set
|
||||
removed: User metadata removed
|
||||
removed.all: All user metadata removed
|
||||
org:
|
||||
added: Organization added
|
||||
changed: Organization changed
|
||||
|
@ -191,22 +191,22 @@ Errors:
|
||||
NotChanged: Il testo predefinito non è stato cambiato
|
||||
AlreadyExists: Il testo predefinito già eistente
|
||||
Invalid: Il testo predefinito non è valido
|
||||
PasswordComplexity:
|
||||
PasswordComplexityPolicy:
|
||||
NotFound: Impostazioni di complessità della password non trovati
|
||||
Empty: Mancano le impostazioni di complessità della password
|
||||
NotExisting: Impostazioni di complessità della password non esistenti
|
||||
AlreadyExists: Impostazioni di complessità della password sono già esistenti
|
||||
PasswordLockout:
|
||||
PasswordLockoutPolicy:
|
||||
NotFound: Impostazioni di blocco della password non trovati
|
||||
Empty: Mancano le impostazioni di blocco della password
|
||||
NotExisting: Le impostazioni di blocco della password non esistenti
|
||||
AlreadyExists: Le impostazioni di blocco della password sono già esistenti
|
||||
PasswordAge:
|
||||
PasswordAgePolicy:
|
||||
NotFound: Impostazioni di validità della password
|
||||
Empty: Impostazioni di validità della password mancanti
|
||||
NotExisting: Impostazioni di validità della password non esistenti
|
||||
AlreadyExists: Impostazioni di validità della password sono già esistenti
|
||||
OrgIAM:
|
||||
OrgIAMPolicy:
|
||||
Empty: Mancano le impostazioni Org IAM
|
||||
NotExisting: Impostazioni Org IAM non esistenti
|
||||
AlreadyExists: Impostazioni Org IAM già esistenti
|
||||
@ -587,6 +587,10 @@ EventTypes:
|
||||
cascade:
|
||||
removed: Autorizzazione rimossa
|
||||
changed: Autorizzazione cambiata
|
||||
metadata:
|
||||
set: Set di metadati utente
|
||||
removed: Metadati utente rimossi
|
||||
removed.all: Tutti i metadati utente rimossi
|
||||
org:
|
||||
added: Organizzazione aggiunta
|
||||
changed: Organizzazione cambiata
|
||||
|
@ -4,8 +4,6 @@ import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/lib/pq"
|
||||
|
||||
@ -100,14 +98,14 @@ func (u *NotifyUser) GenerateLoginName(domain string, appendDomain bool) string
|
||||
return u.UserName + "@" + domain
|
||||
}
|
||||
|
||||
func (u *NotifyUser) SetLoginNames(policy *query.OrgIAMPolicy, domains []*org_model.OrgDomain) {
|
||||
func (u *NotifyUser) SetLoginNames(userLoginMustBeDomain bool, domains []*org_model.OrgDomain) {
|
||||
loginNames := make([]string, 0)
|
||||
for _, d := range domains {
|
||||
if d.Verified {
|
||||
loginNames = append(loginNames, u.GenerateLoginName(d.Domain, true))
|
||||
}
|
||||
}
|
||||
if !policy.UserLoginMustBeDomain {
|
||||
if !userLoginMustBeDomain {
|
||||
loginNames = append(loginNames, u.UserName)
|
||||
}
|
||||
u.LoginNames = loginNames
|
||||
|
@ -8,8 +8,6 @@ import (
|
||||
"github.com/caos/logging"
|
||||
"github.com/lib/pq"
|
||||
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
|
||||
req_model "github.com/caos/zitadel/internal/auth_request/model"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
@ -230,14 +228,14 @@ func (u *UserView) GenerateLoginName(domain string, appendDomain bool) string {
|
||||
return u.UserName + "@" + domain
|
||||
}
|
||||
|
||||
func (u *UserView) SetLoginNames(policy *query.OrgIAMPolicy, domains []*org_model.OrgDomain) {
|
||||
func (u *UserView) SetLoginNames(userLoginMustBeDomain bool, domains []*org_model.OrgDomain) {
|
||||
loginNames := make([]string, 0)
|
||||
for _, d := range domains {
|
||||
if d.Verified {
|
||||
loginNames = append(loginNames, u.GenerateLoginName(d.Domain, true))
|
||||
}
|
||||
}
|
||||
if !policy.UserLoginMustBeDomain {
|
||||
if !userLoginMustBeDomain {
|
||||
loginNames = append(loginNames, u.UserName)
|
||||
}
|
||||
u.LoginNames = loginNames
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/duo-labs/webauthn/protocol"
|
||||
"github.com/duo-labs/webauthn/webauthn"
|
||||
|
||||
@ -107,6 +108,8 @@ func (w *WebAuthN) FinishRegistration(user *domain.Human, webAuthN *domain.WebAu
|
||||
}
|
||||
credentialData, err := protocol.ParseCredentialCreationResponseBody(bytes.NewReader(credData))
|
||||
if err != nil {
|
||||
e := *err.(*protocol.Error)
|
||||
logging.WithFields("error", e).Error("webauthn credential could not be parsed")
|
||||
return nil, caos_errs.ThrowInternal(err, "WEBAU-sEr8c", "Errors.User.WebAuthN.ErrorOnParseCredential")
|
||||
}
|
||||
sessionData := WebAuthNToSessionData(webAuthN)
|
||||
|
@ -1771,6 +1771,7 @@ service AdminService {
|
||||
|
||||
//Updates the default privacy policy of ZITADEL
|
||||
// it impacts all organisations without a customised policy
|
||||
// Variable {{.Lang}} can be set to have different links based on the language
|
||||
rpc UpdatePrivacyPolicy(UpdatePrivacyPolicyRequest) returns (UpdatePrivacyPolicyResponse) {
|
||||
option (google.api.http) = {
|
||||
put: "/policies/privacy";
|
||||
@ -3765,6 +3766,7 @@ message GetPrivacyPolicyResponse {
|
||||
message UpdatePrivacyPolicyRequest {
|
||||
string tos_link = 1;
|
||||
string privacy_link = 2;
|
||||
string help_link = 3;
|
||||
}
|
||||
|
||||
message UpdatePrivacyPolicyResponse {
|
||||
|
@ -2133,6 +2133,7 @@ service ManagementService {
|
||||
|
||||
// Add a custom privacy policy for the organisation
|
||||
// With this policy privacy relevant things can be configured (e.g. tos link)
|
||||
// Variable {{.Lang}} can be set to have different links based on the language
|
||||
rpc AddCustomPrivacyPolicy(AddCustomPrivacyPolicyRequest) returns (AddCustomPrivacyPolicyResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/policies/privacy"
|
||||
@ -2147,6 +2148,7 @@ service ManagementService {
|
||||
|
||||
// Update the privacy complexity policy for the organisation
|
||||
// With this policy privacy relevant things can be configured (e.g. tos link)
|
||||
// Variable {{.Lang}} can be set to have different links based on the language
|
||||
rpc UpdateCustomPrivacyPolicy(UpdateCustomPrivacyPolicyRequest) returns (UpdateCustomPrivacyPolicyResponse) {
|
||||
option (google.api.http) = {
|
||||
put: "/policies/privacy"
|
||||
@ -4646,6 +4648,7 @@ message GetDefaultPrivacyPolicyResponse {
|
||||
message AddCustomPrivacyPolicyRequest {
|
||||
string tos_link = 1;
|
||||
string privacy_link = 2;
|
||||
string help_link = 3;
|
||||
}
|
||||
|
||||
message AddCustomPrivacyPolicyResponse {
|
||||
@ -4655,6 +4658,7 @@ message AddCustomPrivacyPolicyResponse {
|
||||
message UpdateCustomPrivacyPolicyRequest {
|
||||
string tos_link = 1;
|
||||
string privacy_link = 2;
|
||||
string help_link = 3;
|
||||
}
|
||||
|
||||
message UpdateCustomPrivacyPolicyResponse {
|
||||
|
@ -229,4 +229,5 @@ message PrivacyPolicy {
|
||||
string tos_link = 2;
|
||||
string privacy_link = 3;
|
||||
bool is_default = 4;
|
||||
}
|
||||
string help_link = 5;
|
||||
}
|
||||
|
@ -382,12 +382,11 @@ message LogoutDoneScreenText {
|
||||
}
|
||||
|
||||
message FooterText {
|
||||
reserved 2, 4;
|
||||
reserved "tos_link", "privacy_policy_link";
|
||||
reserved 2, 4, 6;
|
||||
reserved "tos_link", "privacy_policy_link", "help_link";
|
||||
string tos = 1 [(validate.rules).string = {max_len: 200}];
|
||||
string privacy_policy = 3 [(validate.rules).string = {max_len: 200}];
|
||||
string help = 5 [(validate.rules).string = {max_len: 200}];
|
||||
string help_link = 6 [(validate.rules).string = {max_len: 500}];
|
||||
}
|
||||
|
||||
message PasswordlessPromptScreenText {
|
||||
|
@ -681,6 +681,11 @@ message UserGrant {
|
||||
example: "\"https://api.zitadel.ch/assets/v1/avatar-32432jkh4kj32\"";
|
||||
}
|
||||
];
|
||||
string preferred_login_name = 18 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"gigi@caos.ch\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
enum UserGrantState {
|
||||
|
Loading…
x
Reference in New Issue
Block a user