fix(console): hide granted project navigation if none, cache zitadel permissions, emit refresh on org change, cleanup contributors, styling (#511)

* fix iam member model

* fix org member model

* fix auth user loading

* copytoclipboard directive

* directive logs, load bar on init, create user

* typo

* welcome section, contributor spinner

* fix home link

* fix stepper flow

* show dialog on invalid token

* fix app table refresh, pin icons light theme

* cleanup contributor

* inherit parent color, animations

* use localized date pipe everywhere

* cmp styles refactor, dont show granted p if none

* fix navitem desc, fixed header

* change permissions, caching

* roles on org emit, use prom instead of hot obs

* dont calc 100vh
This commit is contained in:
Max Peintner
2020-07-28 09:09:18 +02:00
committed by GitHub
parent 2d8f934a07
commit 531060ab67
37 changed files with 442 additions and 296 deletions
+2 -46
View File
@@ -1,8 +1,6 @@
import { Injectable } from '@angular/core';
import { Empty } from 'google-protobuf/google/protobuf/empty_pb';
import { Metadata } from 'grpc-web';
import { from, Observable, of } from 'rxjs';
import { catchError, switchMap } from 'rxjs/operators';
import { AuthServicePromiseClient } from '../proto/generated/auth_grpc_web_pb';
import {
@@ -11,6 +9,7 @@ import {
Gender,
MfaOtpResponse,
MultiFactors,
MyPermissions,
MyProjectOrgSearchQuery,
MyProjectOrgSearchRequest,
MyProjectOrgSearchResponse,
@@ -38,8 +37,6 @@ import { GrpcService, RequestFactory, ResponseMapper } from './grpc.service';
providedIn: 'root',
})
export class AuthUserService {
private _roleCache: string[] = [];
constructor(private readonly grpcClient: GrpcService,
private grpcBackendService: GrpcBackendService,
) { }
@@ -75,7 +72,6 @@ export class AuthUserService {
);
}
public async GetMyUser(): Promise<UserView> {
return await this.request(
c => c.getMyUser,
@@ -175,7 +171,7 @@ export class AuthUserService {
);
}
private async getMyzitadelPermissions(): Promise<any> {
public async GetMyzitadelPermissions(): Promise<MyPermissions> {
return await this.request(
c => c.getMyZitadelPermissions,
new Empty(),
@@ -183,19 +179,6 @@ export class AuthUserService {
);
}
public GetMyzitadelPermissions(): Observable<any> {
return from(this.getMyzitadelPermissions());
}
public hasRoles(userRoles: string[], requestedRoles: string[], each: boolean = false): boolean {
return each ?
requestedRoles.every(role => userRoles.includes(role)) :
requestedRoles.findIndex(role => {
return userRoles.findIndex(i => i.includes(role)) > -1;
// return userRoles.includes(role);
}) > -1;
}
public async GetMyUserPhone(): Promise<UserPhone> {
// return this.grpcClient.auth.getMyUserPhone(new Empty());
return await this.request(
@@ -312,31 +295,4 @@ export class AuthUserService {
f => f,
);
}
public isAllowed(roles: string[], each: boolean = false): Observable<boolean> {
if (roles && roles.length > 0) {
if (this._roleCache.length > 0) {
return of(this.hasRoles(this._roleCache, roles));
}
return this.GetMyzitadelPermissions().pipe(
switchMap(response => {
let userRoles = [];
if (response.toObject().permissionsList) {
userRoles = response.toObject().permissionsList;
} else {
userRoles = ['user.resourceowner'];
}
this._roleCache = userRoles;
return of(this.hasRoles(userRoles, roles, each));
}),
catchError((err) => {
return of(false);
}),
);
} else {
return of(false);
}
}
}
+45 -2
View File
@@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { AuthConfig, OAuthService } from 'angular-oauth2-oidc';
import { BehaviorSubject, from, merge, Observable, of, Subject } from 'rxjs';
import { catchError, filter, map, mergeMap, take, timeout } from 'rxjs/operators';
import { catchError, filter, finalize, first, map, mergeMap, switchMap, take, timeout } from 'rxjs/operators';
import { Org, UserProfileView } from '../proto/generated/auth_pb';
import { AuthUserService } from './auth-user.service';
@@ -22,6 +22,8 @@ export class AuthService {
boolean
> = new BehaviorSubject(this.authenticated);
private zitadelPermissions: BehaviorSubject<string[]> = new BehaviorSubject(['user.resourceowner']);
constructor(
private grpcService: GrpcService,
private config: AuthConfig,
@@ -44,9 +46,50 @@ export class AuthService {
).pipe(
take(1),
mergeMap(token => {
return from(this.userService.GetMyUserProfile()).pipe(map(userprofile => userprofile.toObject()));
console.log(token);
return from(this.userService.GetMyUserProfile().then(userprofile => userprofile.toObject()));
}),
finalize(() => {
this.loadPermissions();
}),
);
this.activeOrgChanged.subscribe(() => {
console.log('org change');
this.loadPermissions();
});
}
private loadPermissions(): void {
console.log('load permissions');
merge([
// this.authenticationChanged,
this.activeOrgChanged.pipe(map(org => !!org)),
]).pipe(
first(),
switchMap(() => from(this.userService.GetMyzitadelPermissions())),
map(rolesResp => rolesResp.toObject().permissionsList),
).subscribe(roles => this.zitadelPermissions.next(roles));
}
public isAllowed(roles: string[], each: boolean = false): Observable<boolean> {
if (roles && roles.length > 0) {
return this.zitadelPermissions.pipe(switchMap(zroles => {
return of(this.hasRoles(zroles, roles, each));
}));
} else {
return of(false);
}
}
public hasRoles(userRoles: string[], requestedRoles: string[], each: boolean = false): boolean {
// console.log('has', userRoles);
// console.log('needs', requestedRoles);
return each ?
requestedRoles.every(role => userRoles.includes(role)) :
requestedRoles.findIndex(role => {
return userRoles.findIndex(i => i.includes(role)) > -1;
}) > -1;
}
public get authenticated(): boolean {