Enforce global permissions for bulk edit objects on frontend
This commit is contained in:
parent
162d121e2b
commit
9b091f1134
@ -2,10 +2,10 @@
|
|||||||
<button class="btn btn-sm btn-outline-secondary me-2" (click)="clearSelection()" [hidden]="selectedObjects.size === 0">
|
<button class="btn btn-sm btn-outline-secondary me-2" (click)="clearSelection()" [hidden]="selectedObjects.size === 0">
|
||||||
<i-bs name="x"></i-bs> <ng-container i18n>Clear selection</ng-container>
|
<i-bs name="x"></i-bs> <ng-container i18n>Clear selection</ng-container>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-sm btn-outline-primary me-2" (click)="setPermissions()" [disabled]="!userOwnsAll || selectedObjects.size === 0">
|
<button type="button" class="btn btn-sm btn-outline-primary me-2" (click)="setPermissions()" [disabled]="!userCanBulkEdit(PermissionAction.Change) || selectedObjects.size === 0">
|
||||||
<i-bs name="person-fill-lock"></i-bs> <ng-container i18n>Permissions</ng-container>
|
<i-bs name="person-fill-lock"></i-bs> <ng-container i18n>Permissions</ng-container>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-sm btn-outline-danger me-5" (click)="delete()" [disabled]="!userOwnsAll || selectedObjects.size === 0">
|
<button type="button" class="btn btn-sm btn-outline-danger me-5" (click)="delete()" [disabled]="!userCanBulkEdit(PermissionAction.Delete) || selectedObjects.size === 0">
|
||||||
<i-bs name="trash"></i-bs> <ng-container i18n>Delete</ng-container>
|
<i-bs name="trash"></i-bs> <ng-container i18n>Delete</ng-container>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-sm btn-outline-primary" (click)="openCreateDialog()" *pngxIfPermissions="{ action: PermissionAction.Add, type: permissionType }">
|
<button type="button" class="btn btn-sm btn-outline-primary" (click)="openCreateDialog()" *pngxIfPermissions="{ action: PermissionAction.Add, type: permissionType }">
|
||||||
|
@ -23,7 +23,10 @@ import { TagService } from 'src/app/services/rest/tag.service'
|
|||||||
import { PageHeaderComponent } from '../../common/page-header/page-header.component'
|
import { PageHeaderComponent } from '../../common/page-header/page-header.component'
|
||||||
import { TagListComponent } from '../tag-list/tag-list.component'
|
import { TagListComponent } from '../tag-list/tag-list.component'
|
||||||
import { ManagementListComponent } from './management-list.component'
|
import { ManagementListComponent } from './management-list.component'
|
||||||
import { PermissionsService } from 'src/app/services/permissions.service'
|
import {
|
||||||
|
PermissionAction,
|
||||||
|
PermissionsService,
|
||||||
|
} from 'src/app/services/permissions.service'
|
||||||
import { ToastService } from 'src/app/services/toast.service'
|
import { ToastService } from 'src/app/services/toast.service'
|
||||||
import { EditDialogComponent } from '../../common/edit-dialog/edit-dialog.component'
|
import { EditDialogComponent } from '../../common/edit-dialog/edit-dialog.component'
|
||||||
import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component'
|
import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component'
|
||||||
@ -65,6 +68,7 @@ describe('ManagementListComponent', () => {
|
|||||||
let modalService: NgbModal
|
let modalService: NgbModal
|
||||||
let toastService: ToastService
|
let toastService: ToastService
|
||||||
let documentListViewService: DocumentListViewService
|
let documentListViewService: DocumentListViewService
|
||||||
|
let permissionsService: PermissionsService
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
@ -77,18 +81,7 @@ describe('ManagementListComponent', () => {
|
|||||||
ConfirmDialogComponent,
|
ConfirmDialogComponent,
|
||||||
PermissionsDialogComponent,
|
PermissionsDialogComponent,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [DatePipe, PermissionsGuard],
|
||||||
{
|
|
||||||
provide: PermissionsService,
|
|
||||||
useValue: {
|
|
||||||
currentUserCan: () => true,
|
|
||||||
currentUserHasObjectPermissions: () => true,
|
|
||||||
currentUserOwnsObject: () => true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
DatePipe,
|
|
||||||
PermissionsGuard,
|
|
||||||
],
|
|
||||||
imports: [
|
imports: [
|
||||||
HttpClientTestingModule,
|
HttpClientTestingModule,
|
||||||
NgbPaginationModule,
|
NgbPaginationModule,
|
||||||
@ -115,6 +108,14 @@ describe('ManagementListComponent', () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
permissionsService = TestBed.inject(PermissionsService)
|
||||||
|
jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(true)
|
||||||
|
jest
|
||||||
|
.spyOn(permissionsService, 'currentUserHasObjectPermissions')
|
||||||
|
.mockReturnValue(true)
|
||||||
|
jest
|
||||||
|
.spyOn(permissionsService, 'currentUserOwnsObject')
|
||||||
|
.mockReturnValue(true)
|
||||||
modalService = TestBed.inject(NgbModal)
|
modalService = TestBed.inject(NgbModal)
|
||||||
toastService = TestBed.inject(ToastService)
|
toastService = TestBed.inject(ToastService)
|
||||||
documentListViewService = TestBed.inject(DocumentListViewService)
|
documentListViewService = TestBed.inject(DocumentListViewService)
|
||||||
@ -312,4 +313,10 @@ describe('ManagementListComponent', () => {
|
|||||||
expect(bulkEditSpy).toHaveBeenCalled()
|
expect(bulkEditSpy).toHaveBeenCalled()
|
||||||
expect(successToastSpy).toHaveBeenCalled()
|
expect(successToastSpy).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should disallow bulk permissions or delete objects if no global perms', () => {
|
||||||
|
jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(false)
|
||||||
|
expect(component.userCanBulkEdit(PermissionAction.Delete)).toBeFalsy()
|
||||||
|
expect(component.userCanBulkEdit(PermissionAction.Change)).toBeFalsy()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -15,16 +15,14 @@ import {
|
|||||||
MATCH_NONE,
|
MATCH_NONE,
|
||||||
} from 'src/app/data/matching-model'
|
} from 'src/app/data/matching-model'
|
||||||
import { ObjectWithId } from 'src/app/data/object-with-id'
|
import { ObjectWithId } from 'src/app/data/object-with-id'
|
||||||
import {
|
import { ObjectWithPermissions } from 'src/app/data/object-with-permissions'
|
||||||
ObjectWithPermissions,
|
|
||||||
PermissionsObject,
|
|
||||||
} from 'src/app/data/object-with-permissions'
|
|
||||||
import {
|
import {
|
||||||
SortableDirective,
|
SortableDirective,
|
||||||
SortEvent,
|
SortEvent,
|
||||||
} from 'src/app/directives/sortable.directive'
|
} from 'src/app/directives/sortable.directive'
|
||||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
||||||
import {
|
import {
|
||||||
|
PermissionAction,
|
||||||
PermissionsService,
|
PermissionsService,
|
||||||
PermissionType,
|
PermissionType,
|
||||||
} from 'src/app/services/permissions.service'
|
} from 'src/app/services/permissions.service'
|
||||||
@ -250,7 +248,9 @@ export abstract class ManagementListComponent<T extends ObjectWithId>
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
get userOwnsAll(): boolean {
|
userCanBulkEdit(action: PermissionAction): boolean {
|
||||||
|
if (!this.permissionsService.currentUserCan(action, this.permissionType))
|
||||||
|
return false
|
||||||
let ownsAll: boolean = true
|
let ownsAll: boolean = true
|
||||||
const objects = this.data.filter((o) => this.selectedObjects.has(o.id))
|
const objects = this.data.filter((o) => this.selectedObjects.has(o.id))
|
||||||
ownsAll = objects.every((o) =>
|
ownsAll = objects.every((o) =>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user