fix: added a service to check permissions
this fixes the problem that the permission check was applied global and not per organization
Closes
MODIFY
src/app/components/my-apps/my-apps.component.html
src/app/components/my-apps/my-apps.component.html
</div>
<div class="app-client-header-label">
<button
- *ngIf="
- cliCon.value[0].client.status === 'Registered' &&
- clientAdminProfile
- "
+ *ngIf="cliCon.value[0].deletable"
(click)="unregister(cliCon.value[0], cliCon.key)"
mat-icon-button
color="primary"

MODIFY
src/app/components/my-apps/my-apps.component.ts
src/app/components/my-apps/my-apps.component.ts
@@ -16,8 +16,7 @@ import {
IContractSummary,
IPermission,
ISearchCriteria,
- ISearchResultsApiSummary,
- IUserPermissions
+ ISearchResultsApiSummary
} from '../../interfaces/ICommunication';
import { IContractExt } from '../../interfaces/IContractExt';
import { PolicyService } from '../../services/policy/policy.service';
@@ -33,6 +32,7 @@ import { UnregisterClientComponent } from '../dialogs/unregister-client/unregist
import { SnackbarService } from '../../services/snackbar/snackbar.service';
import { ConfigService } from '../../services/config/config.service';
import { IPolicyExt, IPolicyProbe } from '../../interfaces/IPolicy';
+import { PermissionsService } from '../../services/permissions/permissions.service';
@Component({
selector: 'app-my-apps',
@@ -49,8 +49,6 @@ export class MyAppsComponent implements OnInit {
error = false;
- clientAdminProfile = false;
-
constructor(
private spinnerService: SpinnerService,
private heroService: HeroService,
@@ -62,12 +60,12 @@ export class MyAppsComponent implements OnInit {
private dialog: MatDialog,
private snackbarService: SnackbarService,
public configService: ConfigService,
- private cdr: ChangeDetectorRef
+ private cdr: ChangeDetectorRef,
+ private permissionsService: PermissionsService
) {}
ngOnInit(): void {
this.setUpHero();
- this.fetchProfiles();
this.fetchContracts();
}
@@ -156,7 +154,8 @@ export class MyAppsComponent implements OnInit {
policies: planPolicies.concat(apiPolicies),
section: 'summary',
managedEndpoint: endpoint.managedEndpoint,
- docsAvailable: docsAvailable
+ docsAvailable: docsAvailable,
+ deletable: this.isDeleteAllowed(contract)
} as IContractExt;
})
);
@@ -351,12 +350,15 @@ export class MyAppsComponent implements OnInit {
});
}
- private fetchProfiles() {
- this.backend.getPermissions().subscribe((response: IUserPermissions) => {
- this.clientAdminProfile = response.permissions.some((p: IPermission) => {
- return p.name === 'clientAdmin';
- });
- });
+ private isDeleteAllowed(contract: IContract): boolean {
+ const clientAdminOrganizations =
+ this.permissionsService.getAllowedOrganizations({
+ name: 'clientAdmin'
+ } as IPermission);
+ return (
+ contract.client.status === 'Registered' &&
+ clientAdminOrganizations.includes(contract.client.client.organization.id)
+ );
}
onSetSection($event: { contract: IContractExt; section: ISection }): void {

MODIFY
src/app/guards/auth.guard.ts
src/app/guards/auth.guard.ts
@@ -6,6 +6,7 @@ import { BackendService } from '../services/backend/backend.service';
import { ICurrentUser } from '../interfaces/ICommunication';
import { catchError } from 'rxjs/operators';
import { EMPTY } from 'rxjs';
+import { PermissionsService } from '../services/permissions/permissions.service';
@Injectable({
providedIn: 'root'
@@ -15,7 +16,8 @@ export class AuthGuard extends KeycloakAuthGuard {
protected readonly router: Router,
protected readonly keycloakAngular: KeycloakService,
private keycloakHelper: KeycloakHelperService,
- private backend: BackendService
+ private backend: BackendService,
+ private permissionsService: PermissionsService
) {
super(router, keycloakAngular);
}
@@ -40,6 +42,7 @@ export class AuthGuard extends KeycloakAuthGuard {
)
.subscribe((user: ICurrentUser) => {
console.log('Logged in with user: ', user);
+ this.permissionsService.setPermissions(user.permissions);
});
}
return Promise.resolve(this.authenticated);

MODIFY
src/app/interfaces/IContractExt.ts
src/app/interfaces/IContractExt.ts
@@ -11,4 +11,5 @@ export interface IContractExt extends IContract {
section: 'summary' | 'use-api' | 'policies' | 'manage-api';
policies: IPolicyExt[];
docsAvailable: boolean;
+ deletable: boolean;
}

MODIFY
src/app/services/backend/backend.service.ts
src/app/services/backend/backend.service.ts
@@ -23,8 +23,7 @@ import {
IPolicy,
IPolicySummary,
ISearchCriteria,
- ISearchResultsApiSummary,
- IUserPermissions
+ ISearchResultsApiSummary
} from '../../interfaces/ICommunication';
import { IPolicySummaryExt } from '../../interfaces/IPolicySummaryExt';
import { KeycloakHelperService } from '../keycloak-helper/keycloak-helper.service';
@@ -280,16 +279,6 @@ export class BackendService {
) as Observable<never>;
}
- public getPermissions(): Observable<IUserPermissions> {
- const userId = this.keycloakHelper.getUsername();
-
- const path = `users/${userId}/permissions`;
- return this.http.get<IUserPermissions>(
- this.generateUrl(path),
- this.httpOptions
- );
- }
-
public sendAction(action: IAction): Observable<void> {
console.log('sendAction');

ADD
src/app/services/permissions/permissions.service.spec.ts
+import { TestBed } from '@angular/core/testing';
+
+import { PermissionsService } from './permissions.service';
+
+describe('PermissionsService', () => {
+ let service: PermissionsService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(PermissionsService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});

ADD
src/app/services/permissions/permissions.service.ts
+import { Injectable } from '@angular/core';
+import { IPermission } from '../../interfaces/ICommunication';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class PermissionsService {
+ private permissions: IPermission[] = [];
+
+ constructor() {}
+
+ public setPermissions(permissions: IPermission[]): void {
+ this.permissions = permissions;
+ }
+
+ public getPermissions(): IPermission[] {
+ return this.permissions;
+ }
+
+ /**
+ * This will return an array of organizationIds where the permission applies
+ * @param requestedPermission the permission to be checked
+ */
+ public getAllowedOrganizations(requestedPermission: IPermission): string[] {
+ const organizations: string[] = [];
+ this.permissions.forEach((permission: IPermission) => {
+ if (permission.name === requestedPermission.name) {
+ organizations.push(permission.organizationId);
+ }
+ });
+ return organizations;
+ }
+}

fix: added a service to check permissions

this fixes the problem that the permission check was applied global and not per organization

Closes #53