RED-5482: wip permissions

This commit is contained in:
Dan Percic 2022-11-14 14:39:52 +02:00
parent 271a29d656
commit 8ce945a459
9 changed files with 40 additions and 23 deletions

View File

@ -53,9 +53,13 @@ const dossierTemplateIdRoutes: IqserRoutes = [
{ {
path: 'rules', path: 'rules',
component: BaseDossierTemplateScreenComponent, component: BaseDossierTemplateScreenComponent,
canActivate: [CompositeRouteGuard], canActivate: [CompositeRouteGuard, IqserPermissionsGuard],
data: { data: {
routeGuards: [IqserAuthGuard, RedRoleGuard], routeGuards: [IqserAuthGuard, RedRoleGuard],
permissions: {
allow: [ROLES.rules.read],
redirectTo: 'info',
},
}, },
loadChildren: () => import('./screens/rules/rules.module').then(m => m.RulesModule), loadChildren: () => import('./screens/rules/rules.module').then(m => m.RulesModule),
}, },

View File

@ -87,7 +87,7 @@ export class AdminSideNavComponent implements OnInit {
{ {
screen: 'rules', screen: 'rules',
label: _('admin-side-nav.rule-editor'), label: _('admin-side-nav.rule-editor'),
hideIf: !this.userPreferenceService.areDevFeaturesEnabled, hideIf: !this.userPreferenceService.areDevFeaturesEnabled || !this._permissionsService.has(ROLES.rules.read),
}, },
{ {
screen: 'default-colors', screen: 'default-colors',

View File

@ -1,6 +1,6 @@
<ngx-monaco-editor (init)="onCodeEditorInit($event)" [(ngModel)]="codeEditorText" [options]="editorOptions"></ngx-monaco-editor> <ngx-monaco-editor (init)="onCodeEditorInit($event)" [(ngModel)]="codeEditorText" [options]="editorOptions"></ngx-monaco-editor>
<div *ngIf="changed && permissionsService.isAdmin() && !isLeaving" class="changes-box"> <div *ngIf="changed && permissionsService.canEditRules() && !isLeaving" class="changes-box">
<iqser-icon-button <iqser-icon-button
(action)="save()" (action)="save()"
[label]="'rules-screen.save-changes' | translate" [label]="'rules-screen.save-changes' | translate"

View File

@ -7,6 +7,7 @@ import { RulesService } from '../../../services/rules.service';
import { firstValueFrom } from 'rxjs'; import { firstValueFrom } from 'rxjs';
import { DOSSIER_TEMPLATE_ID } from '@red/domain'; import { DOSSIER_TEMPLATE_ID } from '@red/domain';
import { EditorThemeService } from '@services/editor-theme.service'; import { EditorThemeService } from '@services/editor-theme.service';
import { ComponentCanDeactivate } from '@guards/can-deactivate.guard';
import ICodeEditor = monaco.editor.ICodeEditor; import ICodeEditor = monaco.editor.ICodeEditor;
import IModelDeltaDecoration = monaco.editor.IModelDeltaDecoration; import IModelDeltaDecoration = monaco.editor.IModelDeltaDecoration;
import IStandaloneEditorConstructionOptions = monaco.editor.IStandaloneEditorConstructionOptions; import IStandaloneEditorConstructionOptions = monaco.editor.IStandaloneEditorConstructionOptions;
@ -17,13 +18,13 @@ import IStandaloneEditorConstructionOptions = monaco.editor.IStandaloneEditorCon
styleUrls: ['./rules-screen.component.scss'], styleUrls: ['./rules-screen.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class RulesScreenComponent implements OnInit { export class RulesScreenComponent implements OnInit, ComponentCanDeactivate {
readonly iconButtonTypes = IconButtonTypes; readonly iconButtonTypes = IconButtonTypes;
readonly editorOptions: IStandaloneEditorConstructionOptions = { readonly editorOptions: IStandaloneEditorConstructionOptions = {
theme: 'vs', theme: 'vs',
language: 'java', language: 'java',
automaticLayout: true, automaticLayout: true,
readOnly: !this.permissionsService.isAdmin(), readOnly: !this.permissionsService.canEditRules(),
}; };
initialLines: string[] = []; initialLines: string[] = [];

View File

@ -2,7 +2,7 @@ import { Inject, Injectable } from '@angular/core';
import { IHeaderElement, RotationTypes } from '@red/domain'; import { IHeaderElement, RotationTypes } from '@red/domain';
import { HeaderElements, HeaderElementType } from '../../file-preview/utils/constants'; import { HeaderElements, HeaderElementType } from '../../file-preview/utils/constants';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { BASE_HREF_FN, BaseHrefFn } from '@iqser/common-ui'; import { BASE_HREF_FN, BaseHrefFn, IqserPermissionsService } from '@iqser/common-ui';
import { TooltipsService } from './tooltips.service'; import { TooltipsService } from './tooltips.service';
import { PageRotationService } from './page-rotation.service'; import { PageRotationService } from './page-rotation.service';
import { PdfViewer } from './pdf-viewer.service'; import { PdfViewer } from './pdf-viewer.service';
@ -10,10 +10,10 @@ import { ROTATION_ACTION_BUTTONS, ViewerEvents } from '../utils/constants';
import { FilesMapService } from '@services/files/files-map.service'; import { FilesMapService } from '@services/files/files-map.service';
import { REDDocumentViewer } from './document-viewer.service'; import { REDDocumentViewer } from './document-viewer.service';
import { UserPreferenceService } from '@users/user-preference.service'; import { UserPreferenceService } from '@users/user-preference.service';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable, Subject } from 'rxjs'; import { Observable, Subject } from 'rxjs';
import { ViewerEvent } from '../utils/types'; import { ViewerEvent } from '../utils/types';
import { ReadableRedactionsService } from './readable-redactions.service'; import { ReadableRedactionsService } from './readable-redactions.service';
import { ROLES } from '@users/roles';
const divider: IHeaderElement = { const divider: IHeaderElement = {
type: 'divider', type: 'divider',
@ -30,8 +30,8 @@ export class ViewerHeaderService {
[HeaderElements.LOAD_ALL_ANNOTATIONS, false], [HeaderElements.LOAD_ALL_ANNOTATIONS, false],
[HeaderElements.COMPARE_BUTTON, true], [HeaderElements.COMPARE_BUTTON, true],
[HeaderElements.CLOSE_COMPARE_BUTTON, false], [HeaderElements.CLOSE_COMPARE_BUTTON, false],
[HeaderElements.ROTATE_LEFT_BUTTON, true], [HeaderElements.ROTATE_LEFT_BUTTON, false],
[HeaderElements.ROTATE_RIGHT_BUTTON, true], [HeaderElements.ROTATE_RIGHT_BUTTON, false],
[HeaderElements.APPLY_ROTATION, false], [HeaderElements.APPLY_ROTATION, false],
[HeaderElements.DISCARD_ROTATION, false], [HeaderElements.DISCARD_ROTATION, false],
]); ]);
@ -48,8 +48,7 @@ export class ViewerHeaderService {
private readonly _tooltipsService: TooltipsService, private readonly _tooltipsService: TooltipsService,
private readonly _readableRedactionsService: ReadableRedactionsService, private readonly _readableRedactionsService: ReadableRedactionsService,
private readonly _userPreferenceService: UserPreferenceService, private readonly _userPreferenceService: UserPreferenceService,
private readonly _activatedRoute: ActivatedRoute, private readonly _iqserPermissionsService: IqserPermissionsService,
private readonly _router: Router,
) { ) {
this.events$ = this.#events$.asObservable(); this.events$ = this.#events$.asObservable();
} }
@ -216,6 +215,10 @@ export class ViewerHeaderService {
this.updateElements(); this.updateElements();
if (this._iqserPermissionsService.has(ROLES.files.rotatePage)) {
this.enable([HeaderElements.ROTATE_LEFT_BUTTON, HeaderElements.ROTATE_RIGHT_BUTTON]);
}
if (this._userPreferenceService.areDevFeaturesEnabled) { if (this._userPreferenceService.areDevFeaturesEnabled) {
this.enable([HeaderElements.LOAD_ALL_ANNOTATIONS]); this.enable([HeaderElements.LOAD_ALL_ANNOTATIONS]);
} }

View File

@ -6,11 +6,7 @@ export const ROTATION_ACTION_BUTTONS = [HeaderElements.APPLY_ROTATION, HeaderEle
export const TEXT_POPUPS_TO_TOGGLE = [TextPopups.ADD_REDACTION, TextPopups.ADD_RECTANGLE, TextPopups.ADD_FALSE_POSITIVE]; export const TEXT_POPUPS_TO_TOGGLE = [TextPopups.ADD_REDACTION, TextPopups.ADD_RECTANGLE, TextPopups.ADD_FALSE_POSITIVE];
export const HEADER_ITEMS_TO_TOGGLE = [ export const HEADER_ITEMS_TO_TOGGLE = [HeaderElements.SHAPE_TOOL_GROUP_BUTTON];
HeaderElements.SHAPE_TOOL_GROUP_BUTTON,
HeaderElements.ROTATE_LEFT_BUTTON,
HeaderElements.ROTATE_RIGHT_BUTTON,
];
export const ALLOWED_ACTIONS_WHEN_PAGE_EXCLUDED: string[] = [ export const ALLOWED_ACTIONS_WHEN_PAGE_EXCLUDED: string[] = [
TextPopups.ADD_RECTANGLE, TextPopups.ADD_RECTANGLE,

View File

@ -154,10 +154,10 @@ export class FileActionsComponent implements OnChanges {
}, },
{ {
type: ActionTypes.downloadBtn, type: ActionTypes.downloadBtn,
show: true,
files: [this.file], files: [this.file],
dossier: this.dossier, dossier: this.dossier,
tooltipClass: 'small', tooltipClass: 'small',
show: this._permissionsService.canDownloadRedactedFile(),
}, },
{ {
type: ActionTypes.circleBtn, type: ActionTypes.circleBtn,

View File

@ -151,7 +151,7 @@ export class PermissionsService {
canOcrFile(file: File | File[], dossier: Dossier): boolean { canOcrFile(file: File | File[], dossier: Dossier): boolean {
const files = file instanceof File ? [file] : file; const files = file instanceof File ? [file] : file;
return ( return (
this._iqserPermissionsService.has(ROLES.files.delete) && this._iqserPermissionsService.has(ROLES.files.reanalyze) &&
files.reduce((acc, _file) => this._canOcrFile(_file, dossier) && acc, true) files.reduce((acc, _file) => this._canOcrFile(_file, dossier) && acc, true)
); );
} }
@ -200,7 +200,10 @@ export class PermissionsService {
isReadyForApproval(file: File | File[], dossier: Dossier): boolean { isReadyForApproval(file: File | File[], dossier: Dossier): boolean {
const files = file instanceof File ? [file] : file; const files = file instanceof File ? [file] : file;
return files.reduce((acc, _file) => this._isReadyForApproval(_file, dossier) && acc, true); return (
this._iqserPermissionsService.has(ROLES.files.setApproved) &&
files.reduce((acc, _file) => this._isReadyForApproval(_file, dossier) && acc, true)
);
} }
canSetUnderApproval(file: File | File[], dossier: Dossier): boolean { canSetUnderApproval(file: File | File[], dossier: Dossier): boolean {
@ -333,6 +336,14 @@ export class PermissionsService {
); );
} }
canDownloadRedactedFile() {
return this._iqserPermissionsService.has(ROLES.files.processDownload);
}
canEditRules() {
return this._iqserPermissionsService.has(ROLES.rules.write) && this.isAdmin();
}
private _canDeleteEntity(entity: Dictionary): boolean { private _canDeleteEntity(entity: Dictionary): boolean {
return !entity.systemManaged; return !entity.systemManaged;
} }

View File

@ -2,13 +2,9 @@ export const ROLES = {
RED_CREATE_TENANT: 'red-create-tenant', RED_CREATE_TENANT: 'red-create-tenant',
RED_DEPLOYMENT_INFO: 'red-deployment-info', RED_DEPLOYMENT_INFO: 'red-deployment-info',
RED_GET_TENANTS: 'red-get-tenants', RED_GET_TENANTS: 'red-get-tenants',
RED_PROCESS_DOWNLOAD: 'red-process-download',
RED_PROCESS_MANUAL_REDACTION_REQUEST: 'red-process-manual-redaction-request', RED_PROCESS_MANUAL_REDACTION_REQUEST: 'red-process-manual-redaction-request',
RED_READ_RULES: 'red-read-rules',
RED_READ_VERSIONS: 'red-read-versions', RED_READ_VERSIONS: 'red-read-versions',
RED_REINDEX: 'red-reindex', RED_REINDEX: 'red-reindex',
RED_ROTATE_PAGE: 'red-rotate-page',
RED_WRITE_RULES: 'red-write-rules',
managePreferences: 'red-manage-user-preferences', managePreferences: 'red-manage-user-preferences',
updateMyProfile: 'red-update-my-profile', updateMyProfile: 'red-update-my-profile',
getRss: 'red-get-rss', getRss: 'red-get-rss',
@ -21,6 +17,10 @@ export const ROLES = {
search: 'red-search', search: 'red-search',
searchAudit: 'red-search-audit-log', searchAudit: 'red-search-audit-log',
manageAclPermissions: 'red-manage-acl-permissions', manageAclPermissions: 'red-manage-acl-permissions',
rules: {
read: 'red-read-rules',
write: 'red-write-rules',
},
redactions: { redactions: {
write: 'red-add-redaction', write: 'red-add-redaction',
readManual: 'red-read-manual-redactions', readManual: 'red-read-manual-redactions',
@ -89,6 +89,7 @@ export const ROLES = {
files: { files: {
delete: 'red-delete-file', delete: 'red-delete-file',
readStatus: 'red-read-file-status', readStatus: 'red-read-file-status',
processDownload: 'red-process-download',
downloadAnnotated: 'red-download-annotated-file', downloadAnnotated: 'red-download-annotated-file',
downloadOriginal: 'red-download-original-file', downloadOriginal: 'red-download-original-file',
downloadRedacted: 'red-download-redacted-file', downloadRedacted: 'red-download-redacted-file',
@ -97,6 +98,7 @@ export const ROLES = {
upload: 'red-upload-file', upload: 'red-upload-file',
setApproved: 'red-set-status-approved', setApproved: 'red-set-status-approved',
setUnderApproval: 'red-set-status-under-approval', setUnderApproval: 'red-set-status-under-approval',
rotatePage: 'red-rotate-page',
}, },
templates: { templates: {
read: 'red-read-dossier-templates', read: 'red-read-dossier-templates',