mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-06 14:22:15 +00:00
feat: console feature api (#1480)
This commit is contained in:
@@ -19,12 +19,16 @@ import {
|
||||
DeactivateIDPResponse,
|
||||
GetCustomOrgIAMPolicyRequest,
|
||||
GetCustomOrgIAMPolicyResponse,
|
||||
GetDefaultFeaturesRequest,
|
||||
GetDefaultFeaturesResponse,
|
||||
GetIDPByIDRequest,
|
||||
GetIDPByIDResponse,
|
||||
GetLabelPolicyRequest,
|
||||
GetLabelPolicyResponse,
|
||||
GetLoginPolicyRequest,
|
||||
GetLoginPolicyResponse,
|
||||
GetOrgFeaturesRequest,
|
||||
GetOrgFeaturesResponse,
|
||||
GetOrgIAMPolicyRequest,
|
||||
GetOrgIAMPolicyResponse,
|
||||
GetPasswordAgePolicyRequest,
|
||||
@@ -66,6 +70,12 @@ import {
|
||||
RemoveSecondFactorFromLoginPolicyResponse,
|
||||
ResetCustomOrgIAMPolicyToDefaultRequest,
|
||||
ResetCustomOrgIAMPolicyToDefaultResponse,
|
||||
ResetOrgFeaturesRequest,
|
||||
ResetOrgFeaturesResponse,
|
||||
SetDefaultFeaturesRequest,
|
||||
SetDefaultFeaturesResponse,
|
||||
SetOrgFeaturesRequest,
|
||||
SetOrgFeaturesResponse,
|
||||
SetUpOrgRequest,
|
||||
SetUpOrgResponse,
|
||||
UpdateCustomOrgIAMPolicyRequest,
|
||||
@@ -167,6 +177,33 @@ export class AdminService {
|
||||
return this.grpcService.admin.removeFailedEvent(req, null).then(resp => resp.toObject());;
|
||||
}
|
||||
|
||||
// Features
|
||||
|
||||
public getOrgFeatures(orgId: string): Promise<GetOrgFeaturesResponse.AsObject> {
|
||||
const req = new GetOrgFeaturesRequest();
|
||||
req.setOrgId(orgId);
|
||||
return this.grpcService.admin.getOrgFeatures(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public setOrgFeatures(req: SetOrgFeaturesRequest): Promise<SetOrgFeaturesResponse.AsObject> {
|
||||
return this.grpcService.admin.setOrgFeatures(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public resetOrgFeatures(orgId: string): Promise<ResetOrgFeaturesResponse.AsObject> {
|
||||
const req = new ResetOrgFeaturesRequest();
|
||||
req.setOrgId(orgId);
|
||||
return this.grpcService.admin.resetOrgFeatures(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public getDefaultFeatures(): Promise<GetDefaultFeaturesResponse.AsObject> {
|
||||
const req = new GetDefaultFeaturesRequest();
|
||||
return this.grpcService.admin.getDefaultFeatures(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public setDefaultFeatures(req: SetDefaultFeaturesRequest): Promise<SetDefaultFeaturesResponse.AsObject> {
|
||||
return this.grpcService.admin.setDefaultFeatures(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
/* Policies */
|
||||
|
||||
/* complexity */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { OAuthService } from 'angular-oauth2-oidc';
|
||||
import { BehaviorSubject, from, merge, Observable, of, Subject } from 'rxjs';
|
||||
import { catchError, filter, finalize, first, map, mergeMap, switchMap, take, timeout } from 'rxjs/operators';
|
||||
import { catchError, filter, finalize, map, mergeMap, switchMap, take, timeout } from 'rxjs/operators';
|
||||
|
||||
import {
|
||||
AddMyAuthFactorOTPRequest,
|
||||
@@ -34,6 +34,8 @@ import {
|
||||
ListMyUserGrantsResponse,
|
||||
ListMyUserSessionsRequest,
|
||||
ListMyUserSessionsResponse,
|
||||
ListMyZitadelFeaturesRequest,
|
||||
ListMyZitadelFeaturesResponse,
|
||||
ListMyZitadelPermissionsRequest,
|
||||
ListMyZitadelPermissionsResponse,
|
||||
RemoveMyAuthFactorOTPRequest,
|
||||
@@ -81,7 +83,10 @@ export class GrpcAuthService {
|
||||
private _activeOrgChanged: Subject<Org.AsObject> = new Subject();
|
||||
public user!: Observable<User.AsObject | undefined>;
|
||||
private zitadelPermissions: BehaviorSubject<string[]> = new BehaviorSubject(['user.resourceowner']);
|
||||
private zitadelFeatures: BehaviorSubject<string[]> = new BehaviorSubject(['']);
|
||||
|
||||
public readonly fetchedZitadelPermissions: BehaviorSubject<boolean> = new BehaviorSubject(false as boolean);
|
||||
public readonly fetchedZitadelFeatures: BehaviorSubject<boolean> = new BehaviorSubject(false as boolean);
|
||||
|
||||
private cachedOrgs: Org.AsObject[] = [];
|
||||
|
||||
@@ -114,11 +119,13 @@ export class GrpcAuthService {
|
||||
}),
|
||||
finalize(() => {
|
||||
this.loadPermissions();
|
||||
this.loadFeatures();
|
||||
}),
|
||||
);
|
||||
|
||||
this.activeOrgChanged.subscribe(() => {
|
||||
this.loadPermissions();
|
||||
this.loadFeatures();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -164,12 +171,7 @@ export class GrpcAuthService {
|
||||
}
|
||||
|
||||
private loadPermissions(): void {
|
||||
merge([
|
||||
// this.authenticationChanged,
|
||||
this.activeOrgChanged.pipe(map(org => !!org)),
|
||||
]).pipe(
|
||||
first(),
|
||||
switchMap(() => from(this.listMyZitadelPermissions())),
|
||||
from(this.listMyZitadelPermissions()).pipe(
|
||||
map(rolesResp => rolesResp.resultList),
|
||||
catchError(_ => {
|
||||
return of([]);
|
||||
@@ -182,6 +184,20 @@ export class GrpcAuthService {
|
||||
});
|
||||
}
|
||||
|
||||
private loadFeatures(): void {
|
||||
from(this.listMyZitadelFeatures()).pipe(
|
||||
map(featuresResp => featuresResp.resultList),
|
||||
catchError(_ => {
|
||||
return of([]);
|
||||
}),
|
||||
finalize(() => {
|
||||
this.fetchedZitadelFeatures.next(true);
|
||||
}),
|
||||
).subscribe(features => {
|
||||
this.zitadelFeatures.next(features);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if user has one of the provided roles
|
||||
* @param roles roles of the user
|
||||
@@ -207,6 +223,31 @@ export class GrpcAuthService {
|
||||
}) > -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if user has one of the provided features
|
||||
* @param features regex of the user
|
||||
*/
|
||||
public canUseFeature(features: string[] | RegExp[]): Observable<boolean> {
|
||||
if (features && features.length > 0) {
|
||||
return this.zitadelPermissions.pipe(switchMap(zFeatures => of(this.hasFeature(zFeatures, features))));
|
||||
} else {
|
||||
return of(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if user has one of the provided features
|
||||
* @param userFeature features of the user
|
||||
* @param requestedFeature required features for accessing the respective component
|
||||
*/
|
||||
public hasFeature(userFeatures: string[], requestedFeatures: string[] | RegExp[]): boolean {
|
||||
return requestedFeatures.findIndex((regexp: any) => {
|
||||
return userFeatures.findIndex(feature => {
|
||||
return new RegExp(regexp).test(feature);
|
||||
}) > -1;
|
||||
}) > -1;
|
||||
}
|
||||
|
||||
public getMyProfile(): Promise<GetMyProfileResponse.AsObject> {
|
||||
return this.grpcService.auth.getMyProfile(new GetMyProfileRequest(), null).then(resp => resp.toObject());
|
||||
}
|
||||
@@ -329,6 +370,12 @@ export class GrpcAuthService {
|
||||
).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public listMyZitadelFeatures(): Promise<ListMyZitadelFeaturesResponse.AsObject> {
|
||||
return this.grpcService.auth.listMyZitadelFeatures(
|
||||
new ListMyZitadelFeaturesRequest(), null
|
||||
).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public getMyPhone(): Promise<GetMyPhoneResponse.AsObject> {
|
||||
return this.grpcService.auth.getMyPhone(
|
||||
new GetMyPhoneRequest(), null
|
||||
|
||||
@@ -75,6 +75,8 @@ import {
|
||||
GetAppByIDResponse,
|
||||
GetDefaultPasswordComplexityPolicyRequest,
|
||||
GetDefaultPasswordComplexityPolicyResponse,
|
||||
GetFeaturesRequest,
|
||||
GetFeaturesResponse,
|
||||
GetGrantedProjectByIDRequest,
|
||||
GetGrantedProjectByIDResponse,
|
||||
GetHumanEmailRequest,
|
||||
@@ -701,6 +703,13 @@ export class ManagementService {
|
||||
return this.grpcService.mgmt.listOrgMemberRoles(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
// Features
|
||||
|
||||
public getFeatures(): Promise<GetFeaturesResponse.AsObject> {
|
||||
const req = new GetFeaturesRequest();
|
||||
return this.grpcService.mgmt.getFeatures(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
// Policy
|
||||
|
||||
public getOrgIAMPolicy(): Promise<GetOrgIAMPolicyResponse.AsObject> {
|
||||
|
||||
Reference in New Issue
Block a user