Fix: Dont attempt to retrieve objects for which user doesnt have global permissions (#5612)

This commit is contained in:
shamoon 2024-02-01 01:20:14 -08:00 committed by GitHub
parent 4996b7e5f7
commit 5e3d1b26e7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 375 additions and 143 deletions

View File

@ -62,22 +62,24 @@
<i-bs width="1em" height="1em" name="check"></i-bs>
}
</div>
<div class="me-1 w-100">
<ng-select
name="user"
class="user-select small"
[(ngModel)]="selectionModel.includeUsers"
[disabled]="disabled"
[clearable]="false"
[items]="users"
bindLabel="username"
multiple="true"
bindValue="id"
placeholder="Users"
i18n-placeholder
(change)="onUserSelect()">
</ng-select>
</div>
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.User)) {
<div class="me-1 w-100">
<ng-select
name="user"
class="user-select small"
[(ngModel)]="selectionModel.includeUsers"
[disabled]="disabled"
[clearable]="false"
[items]="users"
bindLabel="username"
multiple="true"
bindValue="id"
placeholder="Users"
i18n-placeholder
(change)="onUserSelect()">
</ng-select>
</div>
}
</button>
@if (selectionModel.ownerFilter === OwnerFilterType.NONE || selectionModel.ownerFilter === OwnerFilterType.NOT_SELF) {
<div class="list-group-item list-group-item-action d-flex align-items-center p-2 ps-3 border-bottom-0 border-start-0 border-end-0">

View File

@ -67,7 +67,7 @@ export class PermissionsFilterDropdownComponent extends ComponentWithPermissions
}
constructor(
permissionsService: PermissionsService,
public permissionsService: PermissionsService,
userService: UserService,
private settingsService: SettingsService
) {

View File

@ -15,8 +15,14 @@
<tr>
<th scope="col" i18n>Created</th>
<th scope="col" i18n>Title</th>
<th scope="col" class="d-none d-md-table-cell" i18n>Tags</th>
<th scope="col" class="d-none d-md-table-cell" i18n>Correspondent</th>
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.Tag)) {
<th scope="col" class="d-none d-md-table-cell" i18n>Tags</th>
}
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.Correspondent)) {
<th scope="col" class="d-none d-md-table-cell" i18n>Correspondent</th>
} @else {
<th scope="col" class="d-none d-md-table-cell"></th>
}
</tr>
</thead>
<tbody>
@ -26,13 +32,15 @@
<td class="py-2 py-md-3">
<a routerLink="/documents/{{doc.id}}" title="Edit" i18n-title class="btn-link text-dark text-decoration-none py-2 py-md-3">{{doc.title | documentTitle}}</a>
</td>
<td class="py-2 py-md-3 d-none d-md-table-cell">
@for (t of doc.tags$ | async; track t) {
<pngx-tag [tag]="t" class="ms-1" (click)="clickTag(t, $event)"></pngx-tag>
}
</td>
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.Tag)) {
<td class="py-2 py-md-3 d-none d-md-table-cell">
@for (t of doc.tags$ | async; track t) {
<pngx-tag [tag]="t" class="ms-1" (click)="clickTag(t, $event)"></pngx-tag>
}
</td>
}
<td class="position-relative py-2 py-md-3 d-none d-md-table-cell">
@if (doc.correspondent !== null) {
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.Correspondent) && doc.correspondent !== null) {
<a class="btn-link text-dark text-decoration-none py-2 py-md-3" routerLink="/documents" [queryParams]="getCorrespondentQueryParams(doc.correspondent)">{{(doc.correspondent$ | async)?.name}}</a>
}
<div class="btn-group position-absolute top-50 end-0 translate-middle-y">

View File

@ -22,6 +22,7 @@ import { DocumentListViewService } from 'src/app/services/document-list-view.ser
import { ComponentWithPermissions } from 'src/app/components/with-permissions/with-permissions.component'
import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'
import { queryParamsFromFilterRules } from 'src/app/utils/query-params'
import { PermissionsService } from 'src/app/services/permissions.service'
@Component({
selector: 'pngx-saved-view-widget',
@ -40,7 +41,8 @@ export class SavedViewWidgetComponent
private list: DocumentListViewService,
private consumerStatusService: ConsumerStatusService,
public openDocumentsService: OpenDocumentsService,
public documentListViewService: DocumentListViewService
public documentListViewService: DocumentListViewService,
public permissionsService: PermissionsService
) {
super()
}

View File

@ -1,5 +1,8 @@
import { DatePipe } from '@angular/common'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import {
HttpClientTestingModule,
HttpTestingController,
} from '@angular/common/http/testing'
import {
ComponentFixture,
TestBed,
@ -71,6 +74,7 @@ import { CustomFieldDataType } from 'src/app/data/custom-field'
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
import { PdfViewerComponent } from '../common/pdf-viewer/pdf-viewer.component'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { environment } from 'src/environments/environment'
const doc: Document = {
id: 3,
@ -136,6 +140,7 @@ describe('DocumentDetailComponent', () => {
let documentListViewService: DocumentListViewService
let settingsService: SettingsService
let customFieldsService: CustomFieldsService
let httpTestingController: HttpTestingController
let currentUserCan = true
let currentUserHasObjectPermissions = true
@ -266,6 +271,7 @@ describe('DocumentDetailComponent', () => {
settingsService.currentUser = { id: 1 }
customFieldsService = TestBed.inject(CustomFieldsService)
fixture = TestBed.createComponent(DocumentDetailComponent)
httpTestingController = TestBed.inject(HttpTestingController)
component = fixture.componentInstance
})
@ -350,6 +356,26 @@ describe('DocumentDetailComponent', () => {
expect(component.documentForm.disabled).toBeTruthy()
})
it('should not attempt to retrieve objects if user does not have permissions', () => {
currentUserCan = false
initNormally()
expect(component.correspondents).toBeUndefined()
expect(component.documentTypes).toBeUndefined()
expect(component.storagePaths).toBeUndefined()
expect(component.users).toBeUndefined()
httpTestingController.expectNone(`${environment.apiBaseUrl}documents/tags/`)
httpTestingController.expectNone(
`${environment.apiBaseUrl}documents/correspondents/`
)
httpTestingController.expectNone(
`${environment.apiBaseUrl}documents/document_types/`
)
httpTestingController.expectNone(
`${environment.apiBaseUrl}documents/storage_paths/`
)
currentUserCan = true
})
it('should support creating document type', () => {
initNormally()
let openModal: NgbModalRef

View File

@ -250,25 +250,50 @@ export class DocumentDetailComponent
Object.assign(this.document, docValues)
})
this.correspondentService
.listAll()
.pipe(first(), takeUntil(this.unsubscribeNotifier))
.subscribe((result) => (this.correspondents = result.results))
this.documentTypeService
.listAll()
.pipe(first(), takeUntil(this.unsubscribeNotifier))
.subscribe((result) => (this.documentTypes = result.results))
this.storagePathService
.listAll()
.pipe(first(), takeUntil(this.unsubscribeNotifier))
.subscribe((result) => (this.storagePaths = result.results))
this.userService
.listAll()
.pipe(first(), takeUntil(this.unsubscribeNotifier))
.subscribe((result) => (this.users = result.results))
if (
this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.Correspondent
)
) {
this.correspondentService
.listAll()
.pipe(first(), takeUntil(this.unsubscribeNotifier))
.subscribe((result) => (this.correspondents = result.results))
}
if (
this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.DocumentType
)
) {
this.documentTypeService
.listAll()
.pipe(first(), takeUntil(this.unsubscribeNotifier))
.subscribe((result) => (this.documentTypes = result.results))
}
if (
this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.StoragePath
)
) {
this.storagePathService
.listAll()
.pipe(first(), takeUntil(this.unsubscribeNotifier))
.subscribe((result) => (this.storagePaths = result.results))
}
if (
this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.User
)
) {
this.userService
.listAll()
.pipe(first(), takeUntil(this.unsubscribeNotifier))
.subscribe((result) => (this.users = result.results))
}
this.getCustomFields()

View File

@ -17,51 +17,59 @@
</div>
<div class="d-flex align-items-center gap-2" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.Document }">
<label class="me-2" i18n>Edit:</label>
<pngx-filterable-dropdown title="Tags" icon="tag-fill" i18n-title
filterPlaceholder="Filter tags" i18n-filterPlaceholder
[items]="tags"
[disabled]="!userCanEditAll"
[editing]="true"
[manyToOne]="true"
[applyOnClose]="applyOnClose"
(opened)="openTagsDropdown()"
[(selectionModel)]="tagSelectionModel"
[documentCounts]="tagDocumentCounts"
(apply)="setTags($event)">
</pngx-filterable-dropdown>
<pngx-filterable-dropdown title="Correspondent" icon="person-fill" i18n-title
filterPlaceholder="Filter correspondents" i18n-filterPlaceholder
[items]="correspondents"
[disabled]="!userCanEditAll"
[editing]="true"
[applyOnClose]="applyOnClose"
(opened)="openCorrespondentDropdown()"
[(selectionModel)]="correspondentSelectionModel"
[documentCounts]="correspondentDocumentCounts"
(apply)="setCorrespondents($event)">
</pngx-filterable-dropdown>
<pngx-filterable-dropdown title="Document type" icon="file-earmark-fill" i18n-title
filterPlaceholder="Filter document types" i18n-filterPlaceholder
[items]="documentTypes"
[disabled]="!userCanEditAll"
[editing]="true"
[applyOnClose]="applyOnClose"
(opened)="openDocumentTypeDropdown()"
[(selectionModel)]="documentTypeSelectionModel"
[documentCounts]="documentTypeDocumentCounts"
(apply)="setDocumentTypes($event)">
</pngx-filterable-dropdown>
<pngx-filterable-dropdown title="Storage path" icon="folder-fill" i18n-title
filterPlaceholder="Filter storage paths" i18n-filterPlaceholder
[items]="storagePaths"
[disabled]="!userCanEditAll"
[editing]="true"
[applyOnClose]="applyOnClose"
(opened)="openStoragePathDropdown()"
[(selectionModel)]="storagePathsSelectionModel"
[documentCounts]="storagePathDocumentCounts"
(apply)="setStoragePaths($event)">
</pngx-filterable-dropdown>
@if (permissionService.currentUserCan(PermissionAction.View, PermissionType.Tag)) {
<pngx-filterable-dropdown title="Tags" icon="tag-fill" i18n-title
filterPlaceholder="Filter tags" i18n-filterPlaceholder
[items]="tags"
[disabled]="!userCanEditAll"
[editing]="true"
[manyToOne]="true"
[applyOnClose]="applyOnClose"
(opened)="openTagsDropdown()"
[(selectionModel)]="tagSelectionModel"
[documentCounts]="tagDocumentCounts"
(apply)="setTags($event)">
</pngx-filterable-dropdown>
}
@if (permissionService.currentUserCan(PermissionAction.View, PermissionType.Correspondent)) {
<pngx-filterable-dropdown title="Correspondent" icon="person-fill" i18n-title
filterPlaceholder="Filter correspondents" i18n-filterPlaceholder
[items]="correspondents"
[disabled]="!userCanEditAll"
[editing]="true"
[applyOnClose]="applyOnClose"
(opened)="openCorrespondentDropdown()"
[(selectionModel)]="correspondentSelectionModel"
[documentCounts]="correspondentDocumentCounts"
(apply)="setCorrespondents($event)">
</pngx-filterable-dropdown>
}
@if (permissionService.currentUserCan(PermissionAction.View, PermissionType.DocumentType)) {
<pngx-filterable-dropdown title="Document type" icon="file-earmark-fill" i18n-title
filterPlaceholder="Filter document types" i18n-filterPlaceholder
[items]="documentTypes"
[disabled]="!userCanEditAll"
[editing]="true"
[applyOnClose]="applyOnClose"
(opened)="openDocumentTypeDropdown()"
[(selectionModel)]="documentTypeSelectionModel"
[documentCounts]="documentTypeDocumentCounts"
(apply)="setDocumentTypes($event)">
</pngx-filterable-dropdown>
}
@if (permissionService.currentUserCan(PermissionAction.View, PermissionType.StoragePath)) {
<pngx-filterable-dropdown title="Storage path" icon="folder-fill" i18n-title
filterPlaceholder="Filter storage paths" i18n-filterPlaceholder
[items]="storagePaths"
[disabled]="!userCanEditAll"
[editing]="true"
[applyOnClose]="applyOnClose"
(opened)="openStoragePathDropdown()"
[(selectionModel)]="storagePathsSelectionModel"
[documentCounts]="storagePathDocumentCounts"
(apply)="setStoragePaths($event)">
</pngx-filterable-dropdown>
}
</div>
<div class="d-flex align-items-center gap-2 ms-auto">
<div class="btn-toolbar">

View File

@ -868,4 +868,22 @@ describe('BulkEditorComponent', () => {
`${environment.apiBaseUrl}documents/?page=1&page_size=100000&fields=id`
) // listAllFilteredIds
})
it('should not attempt to retrieve objects if user does not have permissions', () => {
jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(true)
expect(component.tags).toBeUndefined()
expect(component.correspondents).toBeUndefined()
expect(component.documentTypes).toBeUndefined()
expect(component.storagePaths).toBeUndefined()
httpTestingController.expectNone(`${environment.apiBaseUrl}documents/tags/`)
httpTestingController.expectNone(
`${environment.apiBaseUrl}documents/correspondents/`
)
httpTestingController.expectNone(
`${environment.apiBaseUrl}documents/document_types/`
)
httpTestingController.expectNone(
`${environment.apiBaseUrl}documents/storage_paths/`
)
})
})

View File

@ -115,22 +115,50 @@ export class BulkEditorComponent
}
ngOnInit() {
this.tagService
.listAll()
.pipe(first())
.subscribe((result) => (this.tags = result.results))
this.correspondentService
.listAll()
.pipe(first())
.subscribe((result) => (this.correspondents = result.results))
this.documentTypeService
.listAll()
.pipe(first())
.subscribe((result) => (this.documentTypes = result.results))
this.storagePathService
.listAll()
.pipe(first())
.subscribe((result) => (this.storagePaths = result.results))
if (
this.permissionService.currentUserCan(
PermissionAction.View,
PermissionType.Tag
)
) {
this.tagService
.listAll()
.pipe(first())
.subscribe((result) => (this.tags = result.results))
}
if (
this.permissionService.currentUserCan(
PermissionAction.View,
PermissionType.Correspondent
)
) {
this.correspondentService
.listAll()
.pipe(first())
.subscribe((result) => (this.correspondents = result.results))
}
if (
this.permissionService.currentUserCan(
PermissionAction.View,
PermissionType.DocumentType
)
) {
this.documentTypeService
.listAll()
.pipe(first())
.subscribe((result) => (this.documentTypes = result.results))
}
if (
this.permissionService.currentUserCan(
PermissionAction.View,
PermissionType.StoragePath
)
) {
this.storagePathService
.listAll()
.pipe(first())
.subscribe((result) => (this.storagePaths = result.results))
}
this.downloadForm
.get('downloadFileTypeArchive')

View File

@ -79,7 +79,7 @@ export class DocumentCardSmallComponent extends ComponentWithPermissions {
getTagsLimited$() {
const limit = this.document.notes.length > 0 ? 6 : 7
return this.document.tags$.pipe(
return this.document.tags$?.pipe(
map((tags) => {
if (tags.length > limit) {
this.moreTags = tags.length - (limit - 1)

View File

@ -29,7 +29,8 @@
<div class="col-auto">
<div class="d-flex flex-wrap gap-3">
<div class="d-flex flex-wrap gap-2">
<pngx-filterable-dropdown class="flex-fill" title="Tags" icon="tag-fill" i18n-title
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.Tag)) {
<pngx-filterable-dropdown class="flex-fill" title="Tags" icon="tag-fill" i18n-title
filterPlaceholder="Filter tags" i18n-filterPlaceholder
[items]="tags"
[manyToOne]="true"
@ -37,31 +38,38 @@
(selectionModelChange)="updateRules()"
(opened)="onTagsDropdownOpen()"
[documentCounts]="tagDocumentCounts"
[allowSelectNone]="true"></pngx-filterable-dropdown>
<pngx-filterable-dropdown class="flex-fill" title="Correspondent" icon="person-fill" i18n-title
[allowSelectNone]="true"></pngx-filterable-dropdown>
}
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.Correspondent)) {
<pngx-filterable-dropdown class="flex-fill" title="Correspondent" icon="person-fill" i18n-title
filterPlaceholder="Filter correspondents" i18n-filterPlaceholder
[items]="correspondents"
[(selectionModel)]="correspondentSelectionModel"
(selectionModelChange)="updateRules()"
(opened)="onCorrespondentDropdownOpen()"
[documentCounts]="correspondentDocumentCounts"
[allowSelectNone]="true"></pngx-filterable-dropdown>
<pngx-filterable-dropdown class="flex-fill" title="Document type" icon="file-earmark-fill" i18n-title
filterPlaceholder="Filter document types" i18n-filterPlaceholder
[items]="documentTypes"
[(selectionModel)]="documentTypeSelectionModel"
(selectionModelChange)="updateRules()"
(opened)="onDocumentTypeDropdownOpen()"
[documentCounts]="documentTypeDocumentCounts"
[allowSelectNone]="true"></pngx-filterable-dropdown>
<pngx-filterable-dropdown class="flex-fill" title="Storage path" icon="folder-fill" i18n-title
[allowSelectNone]="true"></pngx-filterable-dropdown>
}
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.DocumentType)) {
<pngx-filterable-dropdown class="flex-fill" title="Document type" icon="file-earmark-fill" i18n-title
filterPlaceholder="Filter document types" i18n-filterPlaceholder
[items]="documentTypes"
[(selectionModel)]="documentTypeSelectionModel"
(selectionModelChange)="updateRules()"
(opened)="onDocumentTypeDropdownOpen()"
[documentCounts]="documentTypeDocumentCounts"
[allowSelectNone]="true"></pngx-filterable-dropdown>
}
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.StoragePath)) {
<pngx-filterable-dropdown class="flex-fill" title="Storage path" icon="folder-fill" i18n-title
filterPlaceholder="Filter storage paths" i18n-filterPlaceholder
[items]="storagePaths"
[(selectionModel)]="storagePathSelectionModel"
(selectionModelChange)="updateRules()"
(opened)="onStoragePathDropdownOpen()"
[documentCounts]="storagePathDocumentCounts"
[allowSelectNone]="true"></pngx-filterable-dropdown>
[allowSelectNone]="true"></pngx-filterable-dropdown>
}
</div>
<div class="d-flex flex-wrap gap-2">
<pngx-date-dropdown

View File

@ -1,5 +1,8 @@
import { DatePipe } from '@angular/common'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import {
HttpClientTestingModule,
HttpTestingController,
} from '@angular/common/http/testing'
import {
ComponentFixture,
fakeAsync,
@ -78,6 +81,11 @@ import {
} from '../../common/permissions-filter-dropdown/permissions-filter-dropdown.component'
import { FilterEditorComponent } from './filter-editor.component'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import {
PermissionType,
PermissionsService,
} from 'src/app/services/permissions.service'
import { environment } from 'src/environments/environment'
const tags: Tag[] = [
{
@ -135,6 +143,8 @@ describe('FilterEditorComponent', () => {
let fixture: ComponentFixture<FilterEditorComponent>
let documentService: DocumentService
let settingsService: SettingsService
let permissionsService: PermissionsService
let httpTestingController: HttpTestingController
beforeEach(fakeAsync(() => {
TestBed.configureTestingModule({
@ -199,6 +209,15 @@ describe('FilterEditorComponent', () => {
documentService = TestBed.inject(DocumentService)
settingsService = TestBed.inject(SettingsService)
settingsService.currentUser = users[0]
permissionsService = TestBed.inject(PermissionsService)
jest
.spyOn(permissionsService, 'currentUserCan')
.mockImplementation((action, type) => {
// a little hack-ish, permissions filter dropdown causes reactive forms issue due to ng-select
// trying to apply formControlName
return type !== PermissionType.User
})
httpTestingController = TestBed.inject(HttpTestingController)
fixture = TestBed.createComponent(FilterEditorComponent)
component = fixture.componentInstance
component.filterRules = []
@ -206,6 +225,24 @@ describe('FilterEditorComponent', () => {
tick()
}))
it('should not attempt to retrieve objects if user does not have permissions', () => {
jest.spyOn(permissionsService, 'currentUserCan').mockReset()
jest
.spyOn(permissionsService, 'currentUserCan')
.mockImplementation((action, type) => false)
component.ngOnInit()
httpTestingController.expectNone(`${environment.apiBaseUrl}documents/tags/`)
httpTestingController.expectNone(
`${environment.apiBaseUrl}documents/correspondents/`
)
httpTestingController.expectNone(
`${environment.apiBaseUrl}documents/document_types/`
)
httpTestingController.expectNone(
`${environment.apiBaseUrl}documents/storage_paths/`
)
})
// SET filterRules
it('should ingest text filter rules for doc title', fakeAsync(() => {

View File

@ -70,6 +70,12 @@ import {
OwnerFilterType,
PermissionsSelectionModel,
} from '../../common/permissions-filter-dropdown/permissions-filter-dropdown.component'
import {
PermissionAction,
PermissionType,
PermissionsService,
} from 'src/app/services/permissions.service'
import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component'
const TEXT_FILTER_TARGET_TITLE = 'title'
const TEXT_FILTER_TARGET_TITLE_CONTENT = 'title-content'
@ -155,7 +161,10 @@ const DEFAULT_TEXT_FILTER_MODIFIER_OPTIONS = [
templateUrl: './filter-editor.component.html',
styleUrls: ['./filter-editor.component.scss'],
})
export class FilterEditorComponent implements OnInit, OnDestroy {
export class FilterEditorComponent
extends ComponentWithPermissions
implements OnInit, OnDestroy
{
generateFilterName() {
if (this.filterRules.length == 1) {
let rule = this.filterRules[0]
@ -224,8 +233,11 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
private tagService: TagService,
private correspondentService: CorrespondentService,
private documentService: DocumentService,
private storagePathService: StoragePathService
) {}
private storagePathService: StoragePathService,
public permissionsService: PermissionsService
) {
super()
}
@ViewChild('textFilterInput')
textFilterInput: ElementRef
@ -872,18 +884,46 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
subscription: Subscription
ngOnInit() {
this.tagService
.listAll()
.subscribe((result) => (this.tags = result.results))
this.correspondentService
.listAll()
.subscribe((result) => (this.correspondents = result.results))
this.documentTypeService
.listAll()
.subscribe((result) => (this.documentTypes = result.results))
this.storagePathService
.listAll()
.subscribe((result) => (this.storagePaths = result.results))
if (
this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.Tag
)
) {
this.tagService
.listAll()
.subscribe((result) => (this.tags = result.results))
}
if (
this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.Correspondent
)
) {
this.correspondentService
.listAll()
.subscribe((result) => (this.correspondents = result.results))
}
if (
this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.DocumentType
)
) {
this.documentTypeService
.listAll()
.subscribe((result) => (this.documentTypes = result.results))
}
if (
this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.StoragePath
)
) {
this.storagePathService
.listAll()
.subscribe((result) => (this.storagePaths = result.results))
}
this.textFilterDebounce = new Subject<string>()

View File

@ -13,6 +13,11 @@ import { TagService } from './tag.service'
import { DocumentSuggestions } from 'src/app/data/document-suggestions'
import { queryParamsFromFilterRules } from '../../utils/query-params'
import { StoragePathService } from './storage-path.service'
import {
PermissionAction,
PermissionType,
PermissionsService,
} from '../permissions.service'
export const DOCUMENT_SORT_FIELDS = [
{ field: 'archive_serial_number', name: $localize`ASN` },
@ -57,21 +62,40 @@ export class DocumentService extends AbstractPaperlessService<Document> {
private correspondentService: CorrespondentService,
private documentTypeService: DocumentTypeService,
private tagService: TagService,
private storagePathService: StoragePathService
private storagePathService: StoragePathService,
private permissionsService: PermissionsService
) {
super(http, 'documents')
}
addObservablesToDocument(doc: Document) {
if (doc.correspondent) {
if (
doc.correspondent &&
this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.Correspondent
)
) {
doc.correspondent$ = this.correspondentService.getCached(
doc.correspondent
)
}
if (doc.document_type) {
if (
doc.document_type &&
this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.DocumentType
)
) {
doc.document_type$ = this.documentTypeService.getCached(doc.document_type)
}
if (doc.tags) {
if (
doc.tags &&
this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.Tag
)
) {
doc.tags$ = this.tagService
.getCachedMany(doc.tags)
.pipe(
@ -80,7 +104,13 @@ export class DocumentService extends AbstractPaperlessService<Document> {
)
)
}
if (doc.storage_path) {
if (
doc.storage_path &&
this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.StoragePath
)
) {
doc.storage_path$ = this.storagePathService.getCached(doc.storage_path)
}
return doc