fix: console eventstore (#1476)

* fix org switch

* user grants

* fix project grants, user grant update

* fix idp removal, prettier buttons, attribute names
This commit is contained in:
Max Peintner 2021-03-25 15:47:56 +01:00 committed by GitHub
parent 4d10f3e715
commit ae66e40ace
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 59 additions and 64 deletions

View File

@ -55,7 +55,7 @@
<cnsl-label>{{ 'IDP.IDPDISPLAYNAMMAPPING' | translate }}</cnsl-label> <cnsl-label>{{ 'IDP.IDPDISPLAYNAMMAPPING' | translate }}</cnsl-label>
<mat-select formControlName="idpDisplayNameMapping"> <mat-select formControlName="idpDisplayNameMapping">
<mat-option *ngFor="let field of mappingFields" [value]="field"> <mat-option *ngFor="let field of mappingFields" [value]="field">
{{ 'IDP.MAPPINTFIELD.'+field | translate }} {{ 'IDP.MAPPINGFIELD.'+field | translate }}
</mat-option> </mat-option>
</mat-select> </mat-select>
</cnsl-form-field> </cnsl-form-field>
@ -63,7 +63,7 @@
<cnsl-label>{{ 'IDP.USERNAMEMAPPING' | translate }}</cnsl-label> <cnsl-label>{{ 'IDP.USERNAMEMAPPING' | translate }}</cnsl-label>
<mat-select formControlName="usernameMapping"> <mat-select formControlName="usernameMapping">
<mat-option *ngFor="let field of mappingFields" [value]="field"> <mat-option *ngFor="let field of mappingFields" [value]="field">
{{ 'IDP.MAPPINTFIELD.'+field | translate }} {{ 'IDP.MAPPINGFIELD.'+field | translate }}
</mat-option> </mat-option>
</mat-select> </mat-select>
</cnsl-form-field> </cnsl-form-field>

View File

@ -2,18 +2,15 @@
[emitRefreshOnPreviousRoutes]="['/iam/idp/create']" [timestamp]="idpResult?.details?.viewTimestamp" [emitRefreshOnPreviousRoutes]="['/iam/idp/create']" [timestamp]="idpResult?.details?.viewTimestamp"
[selection]="selection"> [selection]="selection">
<div actions> <div actions>
<button (click)="deactivateSelectedIdps()" matTooltip="{{'IDP.DEACTIVATE' | translate}}" class="icon-button" <button (click)="deactivateSelectedIdps()" matTooltip="{{'IDP.DEACTIVATE' | translate}}" class="ar-button"
mat-icon-button *ngIf="selection.hasValue()" [disabled]="disabled"> mat-stroked-button *ngIf="selection.hasValue()" [disabled]="disabled">
<mat-icon>block</mat-icon> {{'IDP.DEACTIVATE' | translate}}
</button> </button>
<button (click)="reactivateSelectedIdps()" matTooltip="{{'IDP.ACTIVATE' | translate}}" class="icon-button" <button (click)="reactivateSelectedIdps()" matTooltip="{{'IDP.ACTIVATE' | translate}}" class="ar-button"
mat-icon-button *ngIf="selection.hasValue()" [disabled]="disabled"> mat-stroked-button *ngIf="selection.hasValue()" [disabled]="disabled">
<mat-icon>play_circle_outline</mat-icon> {{'IDP.ACTIVATE' | translate}}
</button>
<button color="warn" (click)="removeSelectedIdps()" matTooltip="{{'IDP.DELETE' | translate}}"
class="icon-button" mat-icon-button *ngIf="selection.hasValue()" [disabled]="disabled">
<i class="las la-trash"></i>
</button> </button>
<a [routerLink]="createRouterLink" color="primary" mat-raised-button [disabled]="disabled"> <a [routerLink]="createRouterLink" color="primary" mat-raised-button [disabled]="disabled">
<mat-icon class="icon">add</mat-icon>{{ 'ACTIONS.NEW' | translate }} <mat-icon class="icon">add</mat-icon>{{ 'ACTIONS.NEW' | translate }}
</a> </a>
@ -31,7 +28,7 @@
</th> </th>
<td mat-cell *matCellDef="let idp"> <td mat-cell *matCellDef="let idp">
<mat-checkbox color="primary" (click)="$event.stopPropagation()" class="chbox" <mat-checkbox color="primary" (click)="$event.stopPropagation()" class="chbox"
[disabled]="serviceType==PolicyComponentServiceType.MGMT && idp?.providerType == IDPOwnerType.IDPPROVIDERTYPE_SYSTEM" [disabled]="serviceType==PolicyComponentServiceType.MGMT && idp?.owner == IDPOwnerType.IDP_OWNER_TYPE_SYSTEM"
(change)="$event ? selection.toggle(idp) : null" [checked]="selection.isSelected(idp)"> (change)="$event ? selection.toggle(idp) : null" [checked]="selection.isSelected(idp)">
<img src="../../../assets/images/google.png" <img src="../../../assets/images/google.png"
*ngIf="idp.stylingType == IdpStylingType.IDPSTYLINGTYPE_GOOGLE" alt="google" /> *ngIf="idp.stylingType == IdpStylingType.IDPSTYLINGTYPE_GOOGLE" alt="google" />

View File

@ -1,4 +1,6 @@
.ar-button {
margin-right: .5rem;
}
.table-wrapper { .table-wrapper {
overflow: auto; overflow: auto;
width: 100%; width: 100%;

View File

@ -110,34 +110,6 @@ export class IdpTableComponent implements OnInit {
}); });
} }
public removeSelectedIdps(): void {
const dialogRef = this.dialog.open(WarnDialogComponent, {
data: {
confirmKey: 'ACTIONS.DELETE',
cancelKey: 'ACTIONS.CANCEL',
titleKey: 'IDP.DELETE_SELECTION_TITLE',
descriptionKey: 'IDP.DELETE_SELECTION_DESCRIPTION',
},
width: '400px',
});
dialogRef.afterClosed().subscribe(resp => {
if (resp) {
this.selection.clear();
Promise.all(this.selection.selected.map(value => {
if (this.serviceType === PolicyComponentServiceType.MGMT) {
return (this.service as ManagementService).removeOrgIDP(value.id);
} else {
return (this.service as AdminService).removeIDP(value.id);
}
})).then(() => {
this.toast.showInfo('IDP.TOAST.SELECTEDDEACTIVATED', true);
this.refreshPage();
});
}
});
}
public removeIdp(idp: IDP.AsObject): void { public removeIdp(idp: IDP.AsObject): void {
const dialogRef = this.dialog.open(WarnDialogComponent, { const dialogRef = this.dialog.open(WarnDialogComponent, {
data: { data: {
@ -153,17 +125,21 @@ export class IdpTableComponent implements OnInit {
if (resp) { if (resp) {
if (this.serviceType === PolicyComponentServiceType.MGMT) { if (this.serviceType === PolicyComponentServiceType.MGMT) {
(this.service as ManagementService).removeOrgIDP(idp.id).then(() => { (this.service as ManagementService).removeOrgIDP(idp.id).then(() => {
this.toast.showInfo('IDP.TOAST.REMOVED', true); this.toast.showInfo('IDP.TOAST.DELETED', true);
setTimeout(() => { setTimeout(() => {
this.refreshPage(); this.refreshPage();
}, 1000); }, 1000);
}, error => {
this.toast.showError(error);
}); });
} else { } else {
(this.service as AdminService).removeIDP(idp.id).then(() => { (this.service as AdminService).removeIDP(idp.id).then(() => {
this.toast.showInfo('IDP.TOAST.REMOVED', true); this.toast.showInfo('IDP.TOAST.DELETED', true);
setTimeout(() => { setTimeout(() => {
this.refreshPage(); this.refreshPage();
}, 1000); }, 1000);
}, error => {
this.toast.showError(error);
}); });
} }
} }
@ -177,6 +153,7 @@ export class IdpTableComponent implements OnInit {
(this.service as ManagementService).listOrgIDPs(limit, offset).then(resp => { (this.service as ManagementService).listOrgIDPs(limit, offset).then(resp => {
this.idpResult = resp; this.idpResult = resp;
this.dataSource.data = resp.resultList; this.dataSource.data = resp.resultList;
console.log(resp.resultList);
this.loadingSubject.next(false); this.loadingSubject.next(false);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);
@ -186,6 +163,8 @@ export class IdpTableComponent implements OnInit {
(this.service as AdminService).listIDPs(limit, offset).then(resp => { (this.service as AdminService).listIDPs(limit, offset).then(resp => {
this.idpResult = resp; this.idpResult = resp;
this.dataSource.data = resp.resultList; this.dataSource.data = resp.resultList;
console.log(resp.resultList);
this.loadingSubject.next(false); this.loadingSubject.next(false);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);

View File

@ -8,7 +8,7 @@
<cnsl-label>{{ 'IDP.TYPE' | translate }}</cnsl-label> <cnsl-label>{{ 'IDP.TYPE' | translate }}</cnsl-label>
<mat-select [(ngModel)]="idpType" (selectionChange)="loadIdps()"> <mat-select [(ngModel)]="idpType" (selectionChange)="loadIdps()">
<mat-option *ngFor="let type of idpTypes" [value]="type"> <mat-option *ngFor="let type of idpTypes" [value]="type">
{{ 'IDP.TYPES.'+type | translate}} {{ 'IDP.OWNERTYPES.'+type | translate}}
</mat-option> </mat-option>
</mat-select> </mat-select>
</cnsl-form-field> </cnsl-form-field>

View File

@ -105,8 +105,9 @@
*ngIf="idp.stylingType == IDPStylingType.STYLING_TYPE_GOOGLE" alt="google" /> *ngIf="idp.stylingType == IDPStylingType.STYLING_TYPE_GOOGLE" alt="google" />
<div> <div>
<span class="name">{{idp.name}}</span> <span class="name">{{idp.name}}</span>
<span class="meta-info">{{ 'IDP.TYPE' | translate }}: {{ 'IDP.TYPES.'+idp.type | translate }}</span> <span class="meta-info">{{ 'IDP.TYPE' | translate }}: {{ 'IDP.OWNERTYPES.'+idp.idpType | translate
<span class="meta-info">{{ 'IDP.ID' | translate }}: {{idp.idpConfigId}}</span> }}</span>
<span class="meta-info">{{ 'IDP.ID' | translate }}: {{idp.idpId}}</span>
</div> </div>
</div> </div>
</div> </div>

View File

@ -9,7 +9,7 @@ import {
UpdateLoginPolicyRequest, UpdateLoginPolicyRequest,
UpdateLoginPolicyResponse, UpdateLoginPolicyResponse,
} from 'src/app/proto/generated/zitadel/admin_pb'; } from 'src/app/proto/generated/zitadel/admin_pb';
import { IDP, IDPLoginPolicyLink, IDPStylingType } from 'src/app/proto/generated/zitadel/idp_pb'; import { IDP, IDPLoginPolicyLink, IDPOwnerType, IDPStylingType } from 'src/app/proto/generated/zitadel/idp_pb';
import { import {
AddCustomLoginPolicyRequest, AddCustomLoginPolicyRequest,
GetLoginPolicyResponse as MgmtGetLoginPolicyResponse, GetLoginPolicyResponse as MgmtGetLoginPolicyResponse,
@ -101,6 +101,7 @@ export class LoginPolicyComponent implements OnDestroy {
}); });
this.getIdps().then(resp => { this.getIdps().then(resp => {
this.idps = resp; this.idps = resp;
console.log(resp);
}); });
} }
@ -199,7 +200,7 @@ export class LoginPolicyComponent implements OnDestroy {
dialogRef.afterClosed().subscribe(resp => { dialogRef.afterClosed().subscribe(resp => {
if (resp && resp.idp) { if (resp && resp.idp) {
this.addIdp(resp.idp).then(() => { this.addIdp(resp.idp, resp.type).then(() => {
this.loading = true; this.loading = true;
setTimeout(() => { setTimeout(() => {
this.fetchData(); this.fetchData();
@ -211,10 +212,12 @@ export class LoginPolicyComponent implements OnDestroy {
}); });
} }
private addIdp(idp: IDP.AsObject | IDP.AsObject): Promise<any> { private addIdp(idp: IDP.AsObject | IDP.AsObject, ownerType?: IDPOwnerType): Promise<any> {
switch (this.serviceType) { switch (this.serviceType) {
case PolicyComponentServiceType.MGMT: case PolicyComponentServiceType.MGMT:
return (this.service as ManagementService).addIDPToLoginPolicy(idp.id); if (ownerType) {
return (this.service as ManagementService).addIDPToLoginPolicy(idp.id, ownerType);
}
case PolicyComponentServiceType.ADMIN: case PolicyComponentServiceType.ADMIN:
return (this.service as AdminService).addIDPToLoginPolicy(idp.id); return (this.service as AdminService).addIDPToLoginPolicy(idp.id);
} }
@ -228,6 +231,8 @@ export class LoginPolicyComponent implements OnDestroy {
if (index > -1) { if (index > -1) {
this.idps.splice(index, 1); this.idps.splice(index, 1);
} }
}, error => {
this.toast.showError(error);
}); });
break; break;
case PolicyComponentServiceType.ADMIN: case PolicyComponentServiceType.ADMIN:
@ -236,6 +241,8 @@ export class LoginPolicyComponent implements OnDestroy {
if (index > -1) { if (index > -1) {
this.idps.splice(index, 1); this.idps.splice(index, 1);
} }
}, error => {
this.toast.showError(error);
}); });
break; break;
} }

View File

@ -174,8 +174,8 @@ export class UserGrantsComponent implements OnInit, AfterViewInit {
public loadGrantOptions(grant: UserGrant.AsObject): void { public loadGrantOptions(grant: UserGrant.AsObject): void {
this.grantToEdit = grant.grantId; this.grantToEdit = grant.grantId;
if (grant.grantId && grant.projectId) { if (grant.projectGrantId && grant.projectId) {
this.getGrantRoleOptions(grant.grantId, grant.projectId); this.getGrantRoleOptions(grant.projectGrantId, grant.projectId);
} else if (grant.projectId) { } else if (grant.projectId) {
this.getProjectRoleOptions(grant.projectId); this.getProjectRoleOptions(grant.projectId);
} }

View File

@ -6,7 +6,8 @@
</div> </div>
<ng-template appHasRole [appHasRole]="['iam.write']"> <ng-template appHasRole [appHasRole]="['iam.write']">
<mat-slide-toggle class="example-margin" color="primary" (change)="changeSelf($event)" [(ngModel)]="forSelf"> <mat-slide-toggle [disabled]="currentCreateStep != 1" class="example-margin" color="primary"
(change)="changeSelf($event)" [(ngModel)]="forSelf">
Use your personal account as organisation owner Use your personal account as organisation owner
</mat-slide-toggle> </mat-slide-toggle>

View File

@ -5,6 +5,7 @@ h1 {
.sub { .sub {
color: var(--grey); color: var(--grey);
margin-bottom: 2rem; margin-bottom: 2rem;
font-size: 14px;
} }
.max-width-container { .max-width-container {

View File

@ -35,22 +35,22 @@
<ng-container matColumnDef="grantedOrgName"> <ng-container matColumnDef="grantedOrgName">
<th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.GRANT.GRANTEDORG' | translate }} </th> <th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.GRANT.GRANTEDORG' | translate }} </th>
<td [routerLink]="['/projects',grant.projectId,'grant', grant.id]" class="pointer" mat-cell <td [routerLink]="['/projects',grant.projectId,'grant', grant.grantId]" class="pointer" mat-cell
*matCellDef="let grant"> *matCellDef="let grant">
{{grant.grantedOrgName}} </td> {{grant.grantedOrgName}} </td>
</ng-container> </ng-container>
<ng-container matColumnDef="dates"> <ng-container matColumnDef="dates">
<th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.GRANT.DATES' | translate }} </th> <th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.GRANT.DATES' | translate }} </th>
<td [routerLink]="['/projects',grant.projectId,'grant', grant.id]" class="pointer" mat-cell <td [routerLink]="['/projects',grant.projectId,'grant', grant.grantId]" class="pointer" mat-cell
*matCellDef="let grant"> *matCellDef="let grant">
<div class="date-block"> <div class="date-block">
<span class="date-sub">{{ 'PROJECT.GRANT.CREATIONDATE' | translate }}:</span> <span class="date-sub">{{ 'PROJECT.GRANT.CREATIONDATE' | translate }}:</span>
<span>{{grant.creationDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }}</span> <span>{{grant.details.creationDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }}</span>
</div> </div>
<div class="date-block"> <div class="date-block">
<span class="date-sub">{{ 'PROJECT.GRANT.CHANGEDATE' | translate }}</span> <span class="date-sub">{{ 'PROJECT.GRANT.CHANGEDATE' | translate }}</span>
<span>{{grant.changeDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }}</span> <span>{{grant.details.changeDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }}</span>
</div> </div>
</ng-container> </ng-container>

View File

@ -5,6 +5,7 @@ h1 {
.sub { .sub {
color: var(--grey); color: var(--grey);
margin-bottom: 2rem; margin-bottom: 2rem;
font-size: 14px;
} }
.max-width-container { .max-width-container {

View File

@ -106,7 +106,7 @@ export class ProjectGrantDetailComponent {
updateRoles(selectionChange: MatSelectChange): void { updateRoles(selectionChange: MatSelectChange): void {
this.mgmtService.updateProjectGrant(this.grant.grantId, this.grant.projectId, selectionChange.value) this.mgmtService.updateProjectGrant(this.grant.grantId, this.grant.projectId, selectionChange.value)
.then(() => { .then(() => {
this.toast.showInfo('PROJECT.TOAST.GRANTUPDATED'); this.toast.showInfo('PROJECT.GRANT.TOAST.PROJECTGRANTUPDATED', true);
}).catch(error => { }).catch(error => {
this.toast.showError(error); this.toast.showError(error);
}); });

View File

@ -19,7 +19,7 @@
<ng-container matColumnDef="idpConfigId"> <ng-container matColumnDef="idpConfigId">
<th mat-header-cell *matHeaderCellDef> {{ 'USER.EXTERNALIDP.IDPCONFIGID' | translate }} </th> <th mat-header-cell *matHeaderCellDef> {{ 'USER.EXTERNALIDP.IDPCONFIGID' | translate }} </th>
<td mat-cell *matCellDef="let idp"> {{idp?.idpConfigId}} </td> <td mat-cell *matCellDef="let idp"> {{idp?.idpId}} </td>
</ng-container> </ng-container>
<ng-container matColumnDef="idpName"> <ng-container matColumnDef="idpName">

View File

@ -52,6 +52,7 @@ export class UserDetailComponent implements OnInit {
this.mgmtUserService.getUserByID(id).then(resp => { this.mgmtUserService.getUserByID(id).then(resp => {
if (resp.user) { if (resp.user) {
this.user = resp.user; this.user = resp.user;
console.log(this.user);
} }
}).catch(err => { }).catch(err => {
console.error(err); console.error(err);
@ -158,6 +159,7 @@ export class UserDetailComponent implements OnInit {
this.mgmtUserService.updateHumanEmail(this.user.id, email).then(() => { this.mgmtUserService.updateHumanEmail(this.user.id, email).then(() => {
this.toast.showInfo('USER.TOAST.EMAILSAVED', true); this.toast.showInfo('USER.TOAST.EMAILSAVED', true);
if (this.user.state == UserState.USER_STATE_INITIAL) { if (this.user.state == UserState.USER_STATE_INITIAL) {
console.log('init');
this.mgmtUserService.resendHumanInitialization(this.user.id, email ?? '').then(() => { this.mgmtUserService.resendHumanInitialization(this.user.id, email ?? '').then(() => {
this.toast.showInfo('USER.TOAST.INITEMAILSENT', true); this.toast.showInfo('USER.TOAST.INITEMAILSENT', true);
this.refreshChanges$.emit(); this.refreshChanges$.emit();

View File

@ -5,6 +5,7 @@ import { BehaviorSubject } from 'rxjs';
import { AppQuery } from '../proto/generated/zitadel/app_pb'; import { AppQuery } from '../proto/generated/zitadel/app_pb';
import { KeyType } from '../proto/generated/zitadel/auth_n_key_pb'; import { KeyType } from '../proto/generated/zitadel/auth_n_key_pb';
import { IDPOwnerType } from '../proto/generated/zitadel/idp_pb';
import { import {
AddAPIAppRequest, AddAPIAppRequest,
AddAPIAppResponse, AddAPIAppResponse,
@ -387,9 +388,10 @@ export class ManagementService {
return this.grpcService.mgmt.resetLoginPolicyToDefault(req, null).then(resp => resp.toObject()); return this.grpcService.mgmt.resetLoginPolicyToDefault(req, null).then(resp => resp.toObject());
} }
public addIDPToLoginPolicy(idpId: string): Promise<AddIDPToLoginPolicyResponse.AsObject> { public addIDPToLoginPolicy(idpId: string, ownerType: IDPOwnerType): Promise<AddIDPToLoginPolicyResponse.AsObject> {
const req = new AddIDPToLoginPolicyRequest(); const req = new AddIDPToLoginPolicyRequest();
req.setIdpId(idpId); req.setIdpId(idpId);
req.setOwnertype(ownerType);
return this.grpcService.mgmt.addIDPToLoginPolicy(req, null).then(resp => resp.toObject()); return this.grpcService.mgmt.addIDPToLoginPolicy(req, null).then(resp => resp.toObject());
} }

View File

@ -3,5 +3,5 @@
"mgmtServiceUrl": "https://api.zitadel.io", "mgmtServiceUrl": "https://api.zitadel.io",
"adminServiceUrl":"https://api.zitadel.io", "adminServiceUrl":"https://api.zitadel.io",
"issuer": "https://issuer.zitadel.io", "issuer": "https://issuer.zitadel.io",
"clientid": "100129365194565743@zitadel" "clientid": "100851239960569938@zitadel"
} }

View File

@ -775,7 +775,8 @@
"PROJECTGRANTCHANGED":"Projektberechtigung geändert.", "PROJECTGRANTCHANGED":"Projektberechtigung geändert.",
"PROJECTGRANTMEMBERADDED":"Berechtigungsmanager hinzugefügt.", "PROJECTGRANTMEMBERADDED":"Berechtigungsmanager hinzugefügt.",
"PROJECTGRANTMEMBERCHANGED":"Berechtigungsmanager verändert.", "PROJECTGRANTMEMBERCHANGED":"Berechtigungsmanager verändert.",
"PROJECTGRANTMEMBERREMOVED":"Berechtigungsmanager entfernt." "PROJECTGRANTMEMBERREMOVED":"Berechtigungsmanager entfernt.",
"PROJECTGRANTUPDATED":"Projectberechtigung geändert."
}, },
"ROLES":"Projektrollen" "ROLES":"Projektrollen"
}, },

View File

@ -773,7 +773,8 @@
"PROJECTGRANTCHANGED":"Project grant changed.", "PROJECTGRANTCHANGED":"Project grant changed.",
"PROJECTGRANTMEMBERADDED":"Grant manager added.", "PROJECTGRANTMEMBERADDED":"Grant manager added.",
"PROJECTGRANTMEMBERCHANGED":"Grant manager changed.", "PROJECTGRANTMEMBERCHANGED":"Grant manager changed.",
"PROJECTGRANTMEMBERREMOVED":"Grant manager removed." "PROJECTGRANTMEMBERREMOVED":"Grant manager removed.",
"PROJECTGRANTUPDATED":"Project Grant updated"
}, },
"ROLES":"Project Roles" "ROLES":"Project Roles"
}, },