mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-07-28 18:24:38 -05:00
Inherited permissions
This commit is contained in:
@@ -12,13 +12,13 @@
|
||||
<li class="list-group-item d-flex" *ngFor="let type of PermissionType | keyvalue" [formGroupName]="type.key">
|
||||
<div class="col-3">{{type.key}}:</div>
|
||||
|
||||
<div class="col form-check form-check-inline form-switch">
|
||||
<input type="checkbox" class="form-check-input" id="{{type.key}}_all" (change)="toggleAll($event, type.key)" [checked]="typesWithAllActions.has(type.key)" [attr.disabled]="disabled ? true : null">
|
||||
<div class="col form-check form-check-inline form-switch" [ngbPopover]="inheritedWarning" [disablePopover]="!isInherited(type.key)" placement="left" triggers="mouseenter:mouseleave">
|
||||
<input type="checkbox" class="form-check-input" id="{{type.key}}_all" (change)="toggleAll($event, type.key)" [checked]="typesWithAllActions.has(type.key)" [attr.disabled]="disabled || isInherited(type.key) ? true : null">
|
||||
<label class="form-check-label visually-hidden" for="{{type.key}}_all" i18n>All</label>
|
||||
</div>
|
||||
|
||||
<div *ngFor="let action of PermissionAction | keyvalue" class="col form-check form-check-inline">
|
||||
<input type="checkbox" class="form-check-input" id="{{type.key}}_{{action.key}}" formControlName="{{action.key}}" [attr.disabled]="typesWithAllActions.has(type.key) || disabled ? true : null">
|
||||
<div *ngFor="let action of PermissionAction | keyvalue" class="col form-check form-check-inline" [ngbPopover]="inheritedWarning" [disablePopover]="!isInherited(type.key, action.key)" placement="left" triggers="mouseenter:mouseleave">
|
||||
<input type="checkbox" class="form-check-input" id="{{type.key}}_{{action.key}}" formControlName="{{action.key}}" [attr.disabled]="isDisabled(type.key, action.key)">
|
||||
<label class="form-check-label visually-hidden" for="{{type.key}}_{{action.key}}" i18n>{{action.key}}</label>
|
||||
</div>
|
||||
</li>
|
||||
|
@@ -41,6 +41,18 @@ export class PermissionsSelectComponent
|
||||
|
||||
typesWithAllActions: Set<string> = new Set()
|
||||
|
||||
_inheritedPermissions: string[] = []
|
||||
|
||||
@Input()
|
||||
set inheritedPermissions(inherited: string[]) {
|
||||
// remove <app_label>. from permission strings
|
||||
this._inheritedPermissions = inherited?.length
|
||||
? inherited.map((p) => p.replace(/.+\./, ''))
|
||||
: []
|
||||
}
|
||||
|
||||
inheritedWarning: string = $localize`Inerhited from group`
|
||||
|
||||
constructor(private readonly permissionsService: PermissionsService) {
|
||||
for (const type in PermissionType) {
|
||||
const control = new FormGroup({})
|
||||
@@ -53,18 +65,24 @@ export class PermissionsSelectComponent
|
||||
|
||||
writeValue(permissions: string[]): void {
|
||||
this.permissions = permissions
|
||||
this.permissions?.forEach((permissionStr) => {
|
||||
const allPerms = this._inheritedPermissions.concat(permissions)
|
||||
allPerms.forEach((permissionStr) => {
|
||||
const { actionKey, typeKey } =
|
||||
this.permissionsService.getPermissionKeys(permissionStr)
|
||||
|
||||
if (actionKey && typeKey) {
|
||||
if (this.form.get(typeKey)?.get(actionKey)) {
|
||||
this.form.get(typeKey).get(actionKey).setValue(true)
|
||||
this.form
|
||||
.get(typeKey)
|
||||
.get(actionKey)
|
||||
.patchValue(true, { emitEvent: false })
|
||||
}
|
||||
}
|
||||
})
|
||||
Object.keys(PermissionType).forEach((type) => {
|
||||
if (Object.values(this.form.get(type).value).every((val) => val)) {
|
||||
if (
|
||||
Object.values(this.form.get(type).value).every((val) => val == true)
|
||||
) {
|
||||
this.typesWithAllActions.add(type)
|
||||
} else {
|
||||
this.typesWithAllActions.delete(type)
|
||||
@@ -96,7 +114,7 @@ export class PermissionsSelectComponent
|
||||
Object.entries(newValue).forEach(([typeKey, typeValue]) => {
|
||||
// e.g. [Document, { Add: true, View: true ... }]
|
||||
const selectedActions = Object.entries(typeValue).filter(
|
||||
([actionKey, actionValue]) => actionValue
|
||||
([actionKey, actionValue]) => actionValue == true
|
||||
)
|
||||
|
||||
selectedActions.forEach(([actionKey, actionValue]) => {
|
||||
@@ -129,4 +147,34 @@ export class PermissionsSelectComponent
|
||||
this.typesWithAllActions.delete(type)
|
||||
}
|
||||
}
|
||||
|
||||
isInherited(typeKey: string, actionKey: string = null) {
|
||||
if (this._inheritedPermissions.length == 0) return false
|
||||
else if (actionKey) {
|
||||
return this._inheritedPermissions.includes(
|
||||
this.permissionsService.getPermissionCode({
|
||||
action: PermissionAction[actionKey],
|
||||
type: PermissionType[typeKey],
|
||||
})
|
||||
)
|
||||
} else {
|
||||
return Object.values(PermissionAction).every((action) => {
|
||||
return this._inheritedPermissions.includes(
|
||||
this.permissionsService.getPermissionCode({
|
||||
action: action as PermissionAction,
|
||||
type: PermissionType[typeKey],
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// if checkbox is disabled either because "All", inhereted or entire component disabled
|
||||
isDisabled(typeKey: string, actionKey: string) {
|
||||
return this.typesWithAllActions.has(typeKey) ||
|
||||
this.isInherited(typeKey, actionKey) ||
|
||||
this.disabled
|
||||
? true
|
||||
: null
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user