From 4603813896bc6eba5550cb3db24b348822315165 Mon Sep 17 00:00:00 2001 From: Kaaybi Date: Fri, 11 Nov 2022 18:33:04 +0000 Subject: [PATCH 01/96] feat: reflect django permissions on UI --- src-ui/src/app/app-routing.module.ts | 63 ++++++++++-- src-ui/src/app/app.component.ts | 35 +++++-- src-ui/src/app/app.module.ts | 4 + .../app-frame/app-frame.component.html | 99 ++++++++++--------- .../dashboard/dashboard.component.html | 14 +-- .../saved-view-widget.component.html | 4 +- .../upload-file-widget.component.html | 18 ++-- .../document-comments.component.html | 4 +- .../document-detail.component.html | 4 +- .../document-detail.component.ts | 7 +- .../bulk-editor/bulk-editor.component.html | 4 +- .../document-card-large.component.html | 2 +- .../document-card-small.component.html | 2 +- .../document-list.component.html | 8 +- .../management-list.component.html | 14 +-- .../management-list.component.ts | 6 ++ .../manage/settings/settings.component.html | 4 +- .../manage/tasks/tasks.component.html | 16 +-- src-ui/src/app/data/paperless-uisettings.ts | 4 +- .../if-permissions.directive.spec.ts | 9 ++ .../directives/if-permissions.directive.ts | 60 +++++++++++ src-ui/src/app/guards/auth.gard.ts | 23 +++++ src-ui/src/app/services/settings.service.ts | 8 +- src/documents/views.py | 2 + 24 files changed, 301 insertions(+), 113 deletions(-) create mode 100644 src-ui/src/app/directives/if-permissions.directive.spec.ts create mode 100644 src-ui/src/app/directives/if-permissions.directive.ts create mode 100644 src-ui/src/app/guards/auth.gard.ts diff --git a/src-ui/src/app/app-routing.module.ts b/src-ui/src/app/app-routing.module.ts index 4dad24c51..297637aa4 100644 --- a/src-ui/src/app/app-routing.module.ts +++ b/src-ui/src/app/app-routing.module.ts @@ -14,6 +14,7 @@ import { DocumentAsnComponent } from './components/document-asn/document-asn.com import { DirtyFormGuard } from './guards/dirty-form.guard' import { StoragePathListComponent } from './components/manage/storage-path-list/storage-path-list.component' import { TasksComponent } from './components/manage/tasks/tasks.component' +import { AuthGard } from './guards/auth.gard' import { DirtyDocGuard } from './guards/dirty-doc.guard' import { DirtySavedViewGuard } from './guards/dirty-saved-view.guard' @@ -29,25 +30,71 @@ const routes: Routes = [ path: 'documents', component: DocumentListComponent, canDeactivate: [DirtySavedViewGuard], + canActivate: [AuthGard], + data: { requiredPermission: 'documents.view_document' }, }, { path: 'view/:id', component: DocumentListComponent, canDeactivate: [DirtySavedViewGuard], + canActivate: [AuthGard], + data: { requiredPermission: 'documents.view_savedview' }, + }, + { + path: 'documents/:id', + component: DocumentDetailComponent, + canActivate: [AuthGard], + data: { requiredPermission: 'documents.view_document' }, + }, + { + path: 'asn/:id', + component: DocumentAsnComponent, + canActivate: [AuthGard], + data: { requiredPermission: 'documents.view_document' }, + }, + { + path: 'tags', + component: TagListComponent, + canActivate: [AuthGard], + data: { requiredPermission: 'documents.view_tag' }, + }, + { + path: 'documenttypes', + component: DocumentTypeListComponent, + canActivate: [AuthGard], + data: { requiredPermission: 'documents.view_documenttype' }, + }, + { + path: 'correspondents', + component: CorrespondentListComponent, + canActivate: [AuthGard], + data: { requiredPermission: 'documents.view_correspondent' }, + }, + { + path: 'storagepaths', + component: StoragePathListComponent, + canActivate: [AuthGard], + data: { requiredPermission: 'documents.view_storagepath' }, + }, + { + path: 'logs', + component: LogsComponent, + canActivate: [AuthGard], + data: { requiredPermission: 'documents.view_log' }, }, - { path: 'documents/:id', component: DocumentDetailComponent }, - { path: 'asn/:id', component: DocumentAsnComponent }, - { path: 'tags', component: TagListComponent }, - { path: 'documenttypes', component: DocumentTypeListComponent }, - { path: 'correspondents', component: CorrespondentListComponent }, - { path: 'storagepaths', component: StoragePathListComponent }, - { path: 'logs', component: LogsComponent }, { path: 'settings', component: SettingsComponent, canDeactivate: [DirtyFormGuard], + canActivate: [AuthGard], + data: { requiredPermission: 'documents.view_uisettings' }, + }, + { + path: 'tasks', + component: TasksComponent, + canActivate: [AuthGard], + data: { requiredPermission: 'documents.view_paperlesstask' }, }, - { path: 'tasks', component: TasksComponent }, ], }, diff --git a/src-ui/src/app/app.component.ts b/src-ui/src/app/app.component.ts index 1d1280eaa..8973d54e5 100644 --- a/src-ui/src/app/app.component.ts +++ b/src-ui/src/app/app.component.ts @@ -74,15 +74,27 @@ export class AppComponent implements OnInit, OnDestroy { if ( this.showNotification(SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUCCESS) ) { - this.toastService.show({ - title: $localize`Document added`, - delay: 10000, - content: $localize`Document ${status.filename} was added to paperless.`, - actionName: $localize`Open document`, - action: () => { - this.router.navigate(['documents', status.documentId]) - }, + // TODO - Is this the only way to allow/disallow from permissions? + var canOpenDocuments = false + this.settings.permissions().subscribe((perm) => { + canOpenDocuments = perm.includes('documents.view_document') }) + if (canOpenDocuments) + this.toastService.show({ + title: $localize`Document added`, + delay: 10000, + content: $localize`Document ${status.filename} was added to paperless.`, + actionName: $localize`Open document`, + action: () => { + this.router.navigate(['documents', status.documentId]) + }, + }) + else + this.toastService.show({ + title: $localize`Document added`, + delay: 10000, + content: $localize`Document ${status.filename} was added to paperless.`, + }) } }) @@ -199,7 +211,12 @@ export class AppComponent implements OnInit, OnDestroy { } public get dragDropEnabled(): boolean { - return !this.router.url.includes('dashboard') + // TODO - Is this the only way to allow/disallow from permissions? + var canAddDocuments = false + this.settings.permissions().subscribe((perm) => { + canAddDocuments = perm.includes('documents.add_document') + }) + return !this.router.url.includes('dashboard') && canAddDocuments } public fileOver() { diff --git a/src-ui/src/app/app.module.ts b/src-ui/src/app/app.module.ts index 3d0a7e3c7..9af4a581b 100644 --- a/src-ui/src/app/app.module.ts +++ b/src-ui/src/app/app.module.ts @@ -41,6 +41,7 @@ import { SelectComponent } from './components/common/input/select/select.compone import { CheckComponent } from './components/common/input/check/check.component' import { SaveViewConfigDialogComponent } from './components/document-list/save-view-config-dialog/save-view-config-dialog.component' import { TagsComponent } from './components/common/input/tags/tags.component' +import { IfPermissionsDirective } from './directives/if-permissions.directive' import { SortableDirective } from './directives/sortable.directive' import { CookieService } from 'ngx-cookie-service' import { CsrfInterceptor } from './interceptors/csrf.interceptor' @@ -69,6 +70,7 @@ import { ColorSliderModule } from 'ngx-color/slider' import { ColorComponent } from './components/common/input/color/color.component' import { DocumentAsnComponent } from './components/document-asn/document-asn.component' import { DocumentCommentsComponent } from './components/document-comments/document-comments.component' +import { AuthGard } from './guards/auth.gard' import { DirtyDocGuard } from './guards/dirty-doc.guard' import { DirtySavedViewGuard } from './guards/dirty-saved-view.guard' import { StoragePathListComponent } from './components/manage/storage-path-list/storage-path-list.component' @@ -159,6 +161,7 @@ function initializeApp(settings: SettingsService) { CheckComponent, SaveViewConfigDialogComponent, TagsComponent, + IfPermissionsDirective, SortableDirective, SavedViewWidgetComponent, StatisticsWidgetComponent, @@ -217,6 +220,7 @@ function initializeApp(settings: SettingsService) { DocumentTitlePipe, { provide: NgbDateAdapter, useClass: ISODateAdapter }, { provide: NgbDateParserFormatter, useClass: LocalizedDateParserFormatter }, + AuthGard, DirtyDocGuard, DirtySavedViewGuard, ], diff --git a/src-ui/src/app/components/app-frame/app-frame.component.html b/src-ui/src/app/components/app-frame/app-frame.component.html index 41bd50970..57f730104 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.html +++ b/src-ui/src/app/components/app-frame/app-frame.component.html @@ -10,7 +10,7 @@ Paperless-ngx -
+
@@ -39,7 +39,7 @@

Logged in as {{this.settingsService.displayName}}

- + Settings @@ -72,7 +72,7 @@  Dashboard - +
+ + +
- - - - - +