RED-5482: wip new permissions

This commit is contained in:
Dan Percic 2022-10-29 18:55:57 +03:00
parent 17100b3c1b
commit 2933e4d45f
8 changed files with 104 additions and 39 deletions

View File

@ -1,8 +1,8 @@
import { AuthErrorComponent } from '@components/auth-error/auth-error.component';
import { CompositeRouteGuard, CustomRouteReuseStrategy, IqserAuthGuard } from '@iqser/common-ui';
import { CompositeRouteGuard, CustomRouteReuseStrategy, IqserAuthGuard, IqserPermissionsGuard, IqserRoutes } from '@iqser/common-ui';
import { RedRoleGuard } from '@users/red-role.guard';
import { BaseScreenComponent } from '@components/base-screen/base-screen.component';
import { RouteReuseStrategy, RouterModule, Routes } from '@angular/router';
import { RouteReuseStrategy, RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { DownloadsListScreenComponent } from '@components/downloads-list-screen/downloads-list-screen.component';
import { DossiersGuard } from '@guards/dossiers.guard';
@ -15,8 +15,9 @@ import { TrashGuard } from '@guards/trash.guard';
import { ARCHIVE_ROUTE, BreadcrumbTypes, DOSSIER_ID, DOSSIER_TEMPLATE_ID, DOSSIERS_ARCHIVE, DOSSIERS_ROUTE, FILE_ID } from '@red/domain';
import { DossierFilesGuard } from '@guards/dossier-files-guard';
import { WebViewerLoadedGuard } from './modules/pdf-viewer/services/webviewer-loaded.guard';
import { ROLES } from '@users/roles';
const routes: Routes = [
const routes: IqserRoutes = [
{
path: '',
redirectTo: 'main',
@ -42,10 +43,21 @@ const routes: Routes = [
{
path: 'dashboard',
loadChildren: () => import('./modules/dashboard/dashboard.module').then(m => m.DashboardModule),
canActivate: [CompositeRouteGuard],
canActivate: [CompositeRouteGuard, IqserPermissionsGuard],
data: {
routeGuards: [IqserAuthGuard, RedRoleGuard, DossierTemplatesGuard, DashboardGuard],
requiredRoles: ['RED_USER'],
permissions: {
allow: [
ROLES.templates.read,
ROLES.fileAttributes.readConfig,
ROLES.watermarks.read,
ROLES.dictionaryTypes.read,
ROLES.colors.read,
ROLES.states.read,
ROLES.notifications.read,
],
redirectTo: '/auth-error',
},
},
},
{
@ -134,10 +146,22 @@ const routes: Routes = [
pathMatch: 'full',
},
],
canActivate: [CompositeRouteGuard],
canActivate: [CompositeRouteGuard, IqserPermissionsGuard],
data: {
routeGuards: [IqserAuthGuard, RedRoleGuard, DossierTemplatesGuard, DashboardGuard, DossierTemplateExistsGuard],
requiredRoles: ['RED_USER'],
permissions: {
allow: [
ROLES.templates.read,
ROLES.fileAttributes.readConfig,
ROLES.watermarks.read,
ROLES.dictionaryTypes.read,
ROLES.colors.read,
ROLES.states.read,
ROLES.notifications.read,
ROLES.dossiers.read,
],
redirectTo: '/',
},
},
},
],

View File

@ -13,6 +13,7 @@ import {
IqserHelpModeModule,
IqserLoadingModule,
IqserPermissionsModule,
IqserPermissionsService,
IqserTranslateModule,
IqserUsersModule,
LanguageService,
@ -164,6 +165,7 @@ export const appModuleFactory = (config: AppConfig) => {
UserService,
UserPreferenceService,
LicenseService,
IqserPermissionsService,
],
},
{

View File

@ -14,7 +14,6 @@ import { RouterHistoryService } from '@services/router-history.service';
const PAGE_SIZE = 50;
@Component({
selector: 'redaction-audit-screen',
templateUrl: './audit-screen.component.html',
styleUrls: ['./audit-screen.component.scss'],
providers: listingProvidersFactory(AuditScreenComponent),

View File

@ -1,18 +1,20 @@
import { inject, Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { UserService } from './user.service';
import { IqserRoleGuard } from '@iqser/common-ui';
import { IqserPermissionsService, IqserRoleGuard } from '@iqser/common-ui';
import { ROLES } from '@users/roles';
@Injectable({
providedIn: 'root',
})
export class RedRoleGuard extends IqserRoleGuard {
protected readonly _userService = inject(UserService);
protected readonly _permissionsService = inject(IqserPermissionsService);
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
const currentUser = this._userService.currentUser;
if (!currentUser.hasAnyREDRoles) {
if (!this._permissionsService.has(ROLES.any)) {
await this._router.navigate(['/auth-error']);
this._loadingService.stop();
return false;

View File

@ -1,17 +1,9 @@
export const ROLES = {
RED_ADD_COMMENT: 'red-add-comment',
RED_ADD_DICTIONARY_ENTRY: 'red-add-dictionary-entry',
RED_ADD_DOSSIER_DICTIONARY_ENTRY: 'red-add-dossier-dictionary-entry',
RED_ADD_REDACTION: 'red-add-redaction',
RED_ADD_UPDATE_DICTIONARY_TYPE: 'red-add-update-dictionary-type',
RED_ADD_UPDATE_DOSSIER_DICTIONARY_TYPE: 'red-add-update-dossier-dictionary-type',
RED_CONVERT_HIGHLIGHTS: 'red-convert-highlights',
RED_CREATE_TENANT: 'red-create-tenant',
RED_DELETE_COMMENT: 'red-delete-comment',
RED_DELETE_DICTIONARY_ENTRY: 'red-delete-dictionary-entry',
RED_DELETE_DICTIONARY_TYPE: 'red-delete-dictionary-type',
RED_DELETE_DOSSIER_DICTIONARY_ENTRY: 'red-delete-dossier-dictionary-entry',
RED_DELETE_DOSSIER_DICTIONARY_TYPE: 'red-delete-dossier-dictionary-type',
RED_DELETE_FILE: 'red-delete-file',
RED_DELETE_HIGHLIGHTS: 'red-delete-highlights',
RED_DELETE_IMPORTED_REDACTIONS: 'red-delete-imported-redactions',
@ -35,22 +27,15 @@ export const ROLES = {
RED_PROCESS_DOWNLOAD: 'red-process-download',
RED_PROCESS_MANUAL_REDACTION_REQUEST: 'red-process-manual-redaction-request',
RED_PROCESS_TEXTHIGHLIGHTS: 'red-process-texthighlights',
RED_READ_APP_CONFIGURATION: 'red-read-app-configuration',
RED_READ_COLORS: 'red-read-colors',
RED_READ_DICTIONARY_TYPES: 'red-read-dictionary-types',
RED_READ_DIGITAL_SIGNATURE: 'red-read-digital-signature',
RED_READ_DOSSIER_ATTRIBUTES: 'red-read-dossier-attributes',
RED_READ_DOSSIER_ATTRIBUTES_CONFIG: 'red-read-dossier-attributes-config',
RED_READ_DOSSIER_TEMPLATES: 'red-read-dossier-templates',
RED_READ_DOWNLOAD_STATUS: 'red-read-download-status',
RED_READ_FILE_ATTRIBUTES_CONFIG: 'red-read-file-attributes-config',
RED_READ_FILE_STATUS: 'red-read-file-status',
RED_READ_GENERAL_CONFIGURATION: 'red-read-general-configuration',
RED_READ_LEGAL_BASIS: 'red-read-legal-basis',
RED_READ_LICENSE: 'red-read-license',
RED_READ_LICENSE_REPORT: 'red-read-license-report',
RED_READ_MANUAL_REDACTIONS: 'red-read-manual-redactions',
RED_READ_NOTIFICATION: 'red-read-notification',
RED_READ_REDACTION_LOG: 'red-read-redaction-log',
RED_READ_RULES: 'red-read-rules',
RED_READ_SMTP_CONFIGURATION: 'red-read-smtp-configuration',
@ -65,18 +50,11 @@ export const ROLES = {
RED_SET_STATUS_APPROVED: 'red-set-status-approved',
RED_SET_STATUS_UNDER_APPROVAL: 'red-set-status-under-approval',
RED_UPDATE_MY_PROFILE: 'red-update-my-profile',
RED_UPDATE_NOTIFICATION: 'red-update-notification',
RED_UPLOAD_FILE: 'red-upload-file',
RED_UPLOAD_REPORT_TEMPLATE: 'red-upload-report-template',
RED_WRITE_APP_CONFIGURATION: 'red-write-app-configuration',
RED_WRITE_COLORS: 'red-write-colors',
RED_WRITE_DIGITAL_SIGNATURE: 'red-write-digital-signature',
RED_WRITE_DOSSIER_ATTRIBUTES: 'red-write-dossier-attributes',
RED_WRITE_DOSSIER_ATTRIBUTES_CONFIG: 'red-write-dossier-attributes-config',
RED_WRITE_DOSSIER_TEMPLATES: 'red-write-dossier-templates',
RED_WRITE_FILE_ATTRIBUTES: 'red-write-file-attributes',
RED_WRITE_FILE_ATTRIBUTES_CONFIG: 'red-write-file-attributes-config',
RED_WRITE_GENERAL_CONFIGURATION: 'red-write-general-configuration',
RED_WRITE_LEGAL_BASIS: 'red-write-legal-basis',
RED_WRITE_RULES: 'red-write-rules',
RED_WRITE_SMTP_CONFIGURATION: 'red-write-smtp-configuration',
@ -96,9 +74,52 @@ export const ROLES = {
delete: 'red-delete-dossier',
archived: 'red-archived-dossier',
reanalyze: 'red-reanalyze-dossier',
dictionaryTypes: {
write: 'red-add-update-dossier-dictionary-type',
delete: 'red-delete-dossier-dictionary-type',
},
dictionaryEntries: {
write: 'red-add-dossier-dictionary-entry',
delete: 'red-delete-dossier-dictionary-entry',
},
},
templates: {
read: 'red-read-dossier-templates',
write: 'red-write-dossier-templates',
},
states: {
read: 'red-read-dossier-status',
write: 'red-write-dossier-status',
},
fileAttributes: {
write: 'red-write-file-attributes',
readConfig: 'red-read-file-attributes-config',
writeConfig: 'red-write-file-attributes-config',
},
dictionaryEntries: {
write: 'red-add-dictionary-entry',
delete: 'red-delete-dictionary-entry',
},
dictionaryTypes: {
read: 'red-read-dictionary-types',
write: 'red-add-update-dictionary-type',
delete: 'red-delete-dictionary-type',
},
colors: {
read: 'red-read-colors',
write: 'red-write-colors',
},
notifications: {
read: 'red-read-notification',
write: 'red-update-notification',
},
appConfiguration: {
read: 'red-read-app-configuration',
write: 'red-write-app-configuration',
},
generalConfiguration: {
read: 'red-read-general-configuration',
write: 'red-write-general-configuration',
},
any: 'any',
} as const;

View File

@ -1,6 +1,8 @@
import { inject, Injectable } from '@angular/core';
import { User } from '@red/domain';
import { IIqserUser, IqserUserService, List, QueryParam } from '@iqser/common-ui';
import { ROLES } from '@users/roles';
import { of } from 'rxjs';
@Injectable({
providedIn: 'root',
@ -17,14 +19,27 @@ export class UserService extends IqserUserService<IIqserUser, User> {
return this.all.filter(user => user.isUser || user.isManager);
}
async loadCurrentUser(): Promise<User | undefined> {
const currentUser = await super.loadCurrentUser();
this._permissionsService.add({
[ROLES.any]: (permission, all) => {
console.log('all roles: ', Object.keys(all));
return Object.keys(all).some(key => key.startsWith('red-'));
},
});
return currentUser;
}
loadAll() {
if (this.currentUser.isUserAdmin || this.currentUser.isUser || this.currentUser.isAdmin) {
return super.loadAll();
}
const canReadUsers = this._permissionsService.has(ROLES.users.read);
return canReadUsers ? super.loadAll() : of([]);
}
getAll() {
const url = this.currentUser.isUserAdmin ? this._defaultModelPath : `${this._defaultModelPath}/red`;
const canReadAllUsers = this._permissionsService.has(ROLES.users.readAll);
const url = canReadAllUsers ? this._defaultModelPath : `${this._defaultModelPath}/red`;
return super.getAll(url);
}

View File

@ -3,12 +3,13 @@ import { ConfigService } from '@services/config.service';
import { firstValueFrom, map, of, throwError } from 'rxjs';
import { KeycloakEventType, KeycloakService } from 'keycloak-angular';
import { GeneralSettingsService } from '@services/general-settings.service';
import { LanguageService } from '@iqser/common-ui';
import { IqserPermissionsService, LanguageService } from '@iqser/common-ui';
import { UserPreferenceService } from '@users/user-preference.service';
import { UserService } from '@users/user.service';
import { FeaturesService } from '@services/features.service';
import { SystemPreferencesService } from '@services/system-preferences.service';
import { LicenseService } from '@services/license.service';
import { ROLES } from '@users/roles';
function lastDossierTemplateRedirect(baseHref: string, userPreferenceService: UserPreferenceService) {
const url = window.location.href.split('/').filter(s => s.length > 0);
@ -29,6 +30,7 @@ export function configurationInitializer(
userService: UserService,
userPreferenceService: UserPreferenceService,
licenseService: LicenseService,
permissionsService: IqserPermissionsService,
) {
const setup = keycloakService.keycloakEvents$.pipe(
filter(event => event.type === KeycloakEventType.OnReady),
@ -36,7 +38,7 @@ export function configurationInitializer(
switchMap(() => keycloakService.isLoggedIn()),
switchMap(loggedIn => (!loggedIn ? throwError(() => 'Not Logged In') : of({}))),
switchMap(() => userService.initialize()),
switchMap(() => (!userService.currentUser.hasAnyREDRoles ? throwError(() => 'Not user has no red roles') : of({}))),
switchMap(() => (!permissionsService.has(ROLES.any) ? throwError(() => 'User has no red roles') : of({}))),
switchMap(() => generalSettingsService.getGeneralConfigurations()),
tap(configuration => configService.updateDisplayName(configuration.displayName)),
switchMap(() => systemPreferencesService.loadPreferences()),

@ -1 +1 @@
Subproject commit 7367c31d37b19c2e3a73c886cc743b12dcccc71f
Subproject commit 45627ed3338011c64d1b328e12bdcac107a19280