SUPPORT-9363: permissions

This commit is contained in:
adel.ka 2025-08-29 17:20:12 +03:00
parent 44681d41d3
commit 3fef27e79e
28 changed files with 227 additions and 115 deletions

View file

@ -1,4 +1,4 @@
import {AnalyticalScope, Behavior, Source, Visible} from "@webbpm/base-package";
import {AnalyticalScope, Behavior, Visible} from "@webbpm/base-package";
import {AuthorizationService} from "../modules/app/service/authorization.service";
@AnalyticalScope(Behavior)
@ -11,7 +11,7 @@ export class ErvuCheckUserRole extends Behavior{
}
@Visible()
public hasRole(@Source("roles") role: string): boolean {
return this.authService.hasRole(role);
public hasAnyPermission(permission: string []): boolean {
return this.authService.hasAnyPermission(permission);
}
}

View file

@ -4,7 +4,13 @@ import {NgModuleRef} from "@angular/core";
let childEventHandlerFromContainer = null;
export type ChildEventType = 'navigate' | 'token-request' | 'ws-request'
export type ChildEventType =
'navigate'
| 'token-request'
| 'ws-request'
| 'oidc-user-request'
| 'permissions-request'
export type ParentEventType = 'navigate';
export function fireMfeEventToContainer(eventType: ChildEventType, eventData: any): Promise<any> {

View file

@ -0,0 +1,28 @@
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from "@angular/common/http";
import {from, Observable} from "rxjs";
import { Injectable } from "@angular/core";
import {PermissionProvider} from "../provider/permission.provider";
@Injectable({ providedIn: 'root' })
export class PermissionInterceptor implements HttpInterceptor {
constructor(protected permissionProvider: PermissionProvider) {
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return from(this.handlePermissions(request, next));
}
private async handlePermissions(request: HttpRequest<any>,
next: HttpHandler): Promise<HttpEvent<any>> {
const permissions = await this.permissionProvider.getUserPermissions();
if (permissions.length > 0) {
request = request.clone({
setHeaders: {
'X-User-Permissions': permissions.join(',')
}
});
}
return next.handle(request).toPromise();
}
}

View file

@ -0,0 +1,5 @@
export class PermissionProvider {
getUserPermissions(): Promise<string[]> {
return null;
}
}

View file

@ -9,7 +9,7 @@ export interface UserSession {
name: string,
realm: string,
domainId: string,
roles: string[]
permissions: string[]
}
@Injectable({providedIn: 'root'})
@ -30,7 +30,7 @@ export class AuthorizationService implements OnDestroy {
this.session = session;
this.onSessionUpdate.next(session);
if (this.hasRole('security_administrator')) {
if (this.hasPermission('security_administrator')) {
this.websocketService.subscribe(({data}) => {
let parsedObj = JSON.parse(data);
@ -49,12 +49,12 @@ export class AuthorizationService implements OnDestroy {
return !!this.session;
}
hasAnyRole(roles: string[]): boolean {
return this.isAuthorized() && roles.some(role => this.getRoles().includes(role));
hasAnyPermission(permissions: string[]): boolean {
return this.isAuthorized() && permissions.some(role => this.getPermissions().includes(role));
}
hasRole(role: string): boolean {
return this.isAuthorized() && this.getRoles().includes(role);
hasPermission(permission: string): boolean {
return this.isAuthorized() && this.getPermissions().includes(permission);
}
getUserId(): string{
@ -73,8 +73,8 @@ export class AuthorizationService implements OnDestroy {
return this.isAuthorized() ? this.session.domainId : null;
}
getRoles(): string[] {
return this.isAuthorized() ? this.session.roles : null;
getPermissions(): string[] {
return this.isAuthorized() ? this.session.permissions : null;
}
ngOnDestroy(): void {

View file

@ -5,11 +5,13 @@ import {
HttpSecurityInterceptor
} from "@webbpm/base-package";
import {TokenInterceptor} from "../../app/interceptor/token.interceptor.service";
import {PermissionInterceptor} from "../../app/interceptor/permission.interceptor.service";
export const DEFAULT_HTTP_INTERCEPTOR_PROVIDERS = [
{provide: HTTP_INTERCEPTORS, useClass: HttpSecurityInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: HttpSecurityErrorInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: FormDirtyInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true}
{provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: PermissionInterceptor, multi: true}
];

View file

@ -28,6 +28,8 @@ import {TokenProvider} from "../app/provider/token.provider";
import {MfeTokenProvider} from "./provider/mfe-token.provider";
import {DEFAULT_HTTP_INTERCEPTOR_PROVIDERS} from "./interceptor/mfe-default-interceptors.prod";
import {MfeOverlayContainer} from "./overlay/mfe-overlay-container.service";
import {PermissionProvider} from "../app/provider/permission.provider";
import {MfePermissionProvider} from "./provider/mfe-permission.provider";
let IMPORTS = [
@ -61,6 +63,7 @@ let IMPORTS = [
{provide: RolesGuard, useClass: MfeRolesGuard},
{provide: TokenProvider, useClass: MfeTokenProvider},
{provide: OverlayContainer, useClass: MfeOverlayContainer},
{provide: PermissionProvider, useClass: MfePermissionProvider},
DEFAULT_HTTP_INTERCEPTOR_PROVIDERS
],
bootstrap: [

View file

@ -0,0 +1,8 @@
import {PermissionProvider} from "../../app/provider/permission.provider";
import {fireMfeEventToContainer} from "../../../mfe-app-tools";
export class MfePermissionProvider extends PermissionProvider {
getUserPermissions(): Promise<string[]> {
return fireMfeEventToContainer('permissions-request', {});
}
}