mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-11-04 03:27:12 -05:00 
			
		
		
		
	frontend permissions dialogs
This commit is contained in:
		
							parent
							
								
									b6f1ced455
								
							
						
					
					
						commit
						f461485aa0
					
				@ -127,7 +127,7 @@ const routes: Routes = [
 | 
				
			|||||||
        data: {
 | 
					        data: {
 | 
				
			||||||
          requiredPermission: {
 | 
					          requiredPermission: {
 | 
				
			||||||
            action: PermissionAction.View,
 | 
					            action: PermissionAction.View,
 | 
				
			||||||
            type: PermissionType.Log,
 | 
					            type: PermissionType.Admin,
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
				
			|||||||
@ -163,7 +163,7 @@
 | 
				
			|||||||
              </svg><span> <ng-container i18n>File Tasks<span *ngIf="tasksService.failedFileTasks.length > 0"><span class="badge bg-danger ms-2">{{tasksService.failedFileTasks.length}}</span></span></ng-container></span>
 | 
					              </svg><span> <ng-container i18n>File Tasks<span *ngIf="tasksService.failedFileTasks.length > 0"><span class="badge bg-danger ms-2">{{tasksService.failedFileTasks.length}}</span></span></ng-container></span>
 | 
				
			||||||
            </a>
 | 
					            </a>
 | 
				
			||||||
          </li>
 | 
					          </li>
 | 
				
			||||||
          <li class="nav-item" *ifPermissions="{ action: PermissionAction.View, type: PermissionType.Log }">
 | 
					          <li class="nav-item" *ifPermissions="{ action: PermissionAction.View, type: PermissionType.Admin }">
 | 
				
			||||||
            <a class="nav-link" routerLink="logs" routerLinkActive="active" (click)="closeMenu()" ngbPopover="Logs" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
 | 
					            <a class="nav-link" routerLink="logs" routerLinkActive="active" (click)="closeMenu()" ngbPopover="Logs" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end" container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
 | 
				
			||||||
              <svg class="sidebaricon" fill="currentColor">
 | 
					              <svg class="sidebaricon" fill="currentColor">
 | 
				
			||||||
                <use xlink:href="assets/bootstrap-icons.svg#text-left"/>
 | 
					                <use xlink:href="assets/bootstrap-icons.svg#text-left"/>
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,7 @@
 | 
				
			|||||||
      <div class="row">
 | 
					      <div class="row">
 | 
				
			||||||
        <div class="col">
 | 
					        <div class="col">
 | 
				
			||||||
          <app-input-text i18n-title title="Name" formControlName="name" [error]="error?.name"></app-input-text>
 | 
					          <app-input-text i18n-title title="Name" formControlName="name" [error]="error?.name"></app-input-text>
 | 
				
			||||||
          <app-permissions-select i18n-title title="Permissions" formControlName="permissions"></app-permissions-select>
 | 
					          <app-permissions-select i18n-title title="Permissions" formControlName="permissions" [error]="error?.permissions"></app-permissions-select>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -26,7 +26,7 @@ export class GroupEditDialogComponent extends EditDialogComponent<PaperlessGroup
 | 
				
			|||||||
  getForm(): FormGroup {
 | 
					  getForm(): FormGroup {
 | 
				
			||||||
    return new FormGroup({
 | 
					    return new FormGroup({
 | 
				
			||||||
      name: new FormControl(''),
 | 
					      name: new FormControl(''),
 | 
				
			||||||
      permissions: new FormControl(''),
 | 
					      permissions: new FormControl(null),
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -11,19 +11,21 @@
 | 
				
			|||||||
          <app-input-text i18n-title title="First name" formControlName="first_name" [error]="error?.first_name"></app-input-text>
 | 
					          <app-input-text i18n-title title="First name" formControlName="first_name" [error]="error?.first_name"></app-input-text>
 | 
				
			||||||
          <app-input-text i18n-title title="Last name" formControlName="last_name" [error]="error?.first_name"></app-input-text>
 | 
					          <app-input-text i18n-title title="Last name" formControlName="last_name" [error]="error?.first_name"></app-input-text>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <div class="form-check form-switch">
 | 
					          <div class="mb-2">
 | 
				
			||||||
 | 
					            <div class="form-check form-switch form-check-inline">
 | 
				
			||||||
              <input type="checkbox" class="form-check-input" id="is_active" formControlName="is_active">
 | 
					              <input type="checkbox" class="form-check-input" id="is_active" formControlName="is_active">
 | 
				
			||||||
              <label class="form-check-label" for="is_active" i18n>Active</label>
 | 
					              <label class="form-check-label" for="is_active" i18n>Active</label>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="form-check form-switch form-check-inline">
 | 
				
			||||||
          <div class="form-check form-switch">
 | 
					 | 
				
			||||||
              <input type="checkbox" class="form-check-input" id="is_superuser" formControlName="is_superuser">
 | 
					              <input type="checkbox" class="form-check-input" id="is_superuser" formControlName="is_superuser">
 | 
				
			||||||
              <label class="form-check-label" for="is_superuser" i18n>Superuser</label>
 | 
					              <label class="form-check-label" for="is_superuser" i18n>Superuser</label>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        <div class="col">
 | 
					
 | 
				
			||||||
          <app-input-select i18n-title title="Groups" [items]="groups" multiple="true" formControlName="groups"></app-input-select>
 | 
					          <app-input-select i18n-title title="Groups" [items]="groups" multiple="true" formControlName="groups"></app-input-select>
 | 
				
			||||||
          <app-permissions-select i18n-title title="Permissions" formControlName="permissions"></app-permissions-select>
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col">
 | 
				
			||||||
 | 
					          <app-permissions-select i18n-title title="Permissions" formControlName="user_permissions" [error]="error?.user_permissions"></app-permissions-select>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -42,10 +42,10 @@ export class UserEditDialogComponent extends EditDialogComponent<PaperlessUser>
 | 
				
			|||||||
      username: new FormControl(''),
 | 
					      username: new FormControl(''),
 | 
				
			||||||
      first_name: new FormControl(''),
 | 
					      first_name: new FormControl(''),
 | 
				
			||||||
      last_name: new FormControl(''),
 | 
					      last_name: new FormControl(''),
 | 
				
			||||||
      is_active: new FormControl(''),
 | 
					      is_active: new FormControl(null),
 | 
				
			||||||
      is_superuser: new FormControl(''),
 | 
					      is_superuser: new FormControl(null),
 | 
				
			||||||
      groups: new FormControl(''),
 | 
					      groups: new FormControl(null),
 | 
				
			||||||
      permissions: new FormControl(''),
 | 
					      user_permissions: new FormControl(null),
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,18 +1,27 @@
 | 
				
			|||||||
<form [formGroup]="form">
 | 
					<form [formGroup]="form">
 | 
				
			||||||
  <label>{{title}}</label>
 | 
					  <label class="form-label">{{title}}</label>
 | 
				
			||||||
  <ul class="list-group">
 | 
					  <ul class="list-group">
 | 
				
			||||||
    <li class="list-group-item" *ngFor="let type of PermissionType | keyvalue" [formGroupName]="type.key">
 | 
					    <li class="list-group-item d-flex">
 | 
				
			||||||
      {{type.key}}:
 | 
					      <div class="col-3" i18n>Type</div>
 | 
				
			||||||
 | 
					      <div class="col" i18n>All</div>
 | 
				
			||||||
 | 
					      <div class="col" i18n>Add</div>
 | 
				
			||||||
 | 
					      <div class="col" i18n>Change</div>
 | 
				
			||||||
 | 
					      <div class="col" i18n>Delete</div>
 | 
				
			||||||
 | 
					      <div class="col" i18n>View</div>
 | 
				
			||||||
 | 
					    </li>
 | 
				
			||||||
 | 
					    <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="form-check form-check-inline form-switch">
 | 
					      <div class="col form-check form-check-inline form-switch">
 | 
				
			||||||
        <input type="checkbox" class="form-check-input" id="{{type.key}}_all" formControlName="all">
 | 
					        <input type="checkbox" class="form-check-input" id="{{type.key}}_all" (change)="toggleAll($event, type.key)" [checked]="typesWithAllActions.has(type.key)">
 | 
				
			||||||
        <label class="form-check-label" for="{{type.key}}_all" i18n>All</label>
 | 
					        <label class="form-check-label visually-hidden" for="{{type.key}}_all" i18n>All</label>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      <div *ngFor="let action of PermissionAction | keyvalue" class="form-check form-check-inline" [disabled]="isAll(type.key)">
 | 
					      <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}}">
 | 
					        <input type="checkbox" class="form-check-input" id="{{type.key}}_{{action.key}}" formControlName="{{action.key}}" [attr.disabled]="typesWithAllActions.has(type.key) ? true : null">
 | 
				
			||||||
        <label class="form-check-label" for="{{type.key}}_{{action.key}}" i18n>{{action.key}}</label>
 | 
					        <label class="form-check-label visually-hidden" for="{{type.key}}_{{action.key}}" i18n>{{action.key}}</label>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </li>
 | 
					    </li>
 | 
				
			||||||
 | 
					    <div *ngIf="error" class="invalid-feedback d-block">{{error}}</div>
 | 
				
			||||||
  </ul>
 | 
					  </ul>
 | 
				
			||||||
</form>
 | 
					</form>
 | 
				
			||||||
 | 
				
			|||||||
@ -10,7 +10,6 @@ import {
 | 
				
			|||||||
  PermissionsService,
 | 
					  PermissionsService,
 | 
				
			||||||
  PermissionType,
 | 
					  PermissionType,
 | 
				
			||||||
} from 'src/app/services/permissions.service'
 | 
					} from 'src/app/services/permissions.service'
 | 
				
			||||||
import { AbstractInputComponent } from '../input/abstract-input'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
  providers: [
 | 
					  providers: [
 | 
				
			||||||
@ -33,14 +32,18 @@ export class PermissionsSelectComponent
 | 
				
			|||||||
  @Input()
 | 
					  @Input()
 | 
				
			||||||
  title: string = 'Permissions'
 | 
					  title: string = 'Permissions'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Input()
 | 
				
			||||||
 | 
					  error: string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  permissions: string[]
 | 
					  permissions: string[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  form = new FormGroup({})
 | 
					  form = new FormGroup({})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typesWithAllActions: Set<string> = new Set()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(private readonly permissionsService: PermissionsService) {
 | 
					  constructor(private readonly permissionsService: PermissionsService) {
 | 
				
			||||||
    for (const type in PermissionType) {
 | 
					    for (const type in PermissionType) {
 | 
				
			||||||
      const control = new FormGroup({})
 | 
					      const control = new FormGroup({})
 | 
				
			||||||
      control.addControl('all', new FormControl(null))
 | 
					 | 
				
			||||||
      for (const action in PermissionAction) {
 | 
					      for (const action in PermissionAction) {
 | 
				
			||||||
        control.addControl(action, new FormControl(null))
 | 
					        control.addControl(action, new FormControl(null))
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@ -50,7 +53,7 @@ export class PermissionsSelectComponent
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  writeValue(permissions: string[]): void {
 | 
					  writeValue(permissions: string[]): void {
 | 
				
			||||||
    this.permissions = permissions
 | 
					    this.permissions = permissions
 | 
				
			||||||
    this.permissions.forEach((permissionStr) => {
 | 
					    this.permissions?.forEach((permissionStr) => {
 | 
				
			||||||
      const { actionKey, typeKey } =
 | 
					      const { actionKey, typeKey } =
 | 
				
			||||||
        this.permissionsService.getPermissionKeys(permissionStr)
 | 
					        this.permissionsService.getPermissionKeys(permissionStr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -60,20 +63,70 @@ export class PermissionsSelectComponent
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					    Object.keys(PermissionType).forEach((type) => {
 | 
				
			||||||
 | 
					      if (Object.values(this.form.get(type).value).every((val) => val)) {
 | 
				
			||||||
 | 
					        this.typesWithAllActions.add(type)
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        this.typesWithAllActions.delete(type)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onChange = (newValue: string[]) => {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onTouched = () => {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  disabled: boolean = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  registerOnChange(fn: any): void {
 | 
					  registerOnChange(fn: any): void {
 | 
				
			||||||
    throw new Error('Method not implemented.')
 | 
					    this.onChange = fn
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  registerOnTouched(fn: any): void {
 | 
					  registerOnTouched(fn: any): void {
 | 
				
			||||||
    throw new Error('Method not implemented.')
 | 
					    this.onTouched = fn
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  setDisabledState?(isDisabled: boolean): void {
 | 
					  setDisabledState?(isDisabled: boolean): void {
 | 
				
			||||||
    throw new Error('Method not implemented.')
 | 
					    this.disabled = isDisabled
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnInit(): void {}
 | 
					  ngOnInit(): void {
 | 
				
			||||||
 | 
					    this.form.valueChanges.subscribe((newValue) => {
 | 
				
			||||||
 | 
					      let permissions = []
 | 
				
			||||||
 | 
					      Object.entries(newValue).forEach(([typeKey, typeValue]) => {
 | 
				
			||||||
 | 
					        // e.g. [Document, { Add: true, View: true ... }]
 | 
				
			||||||
 | 
					        const selectedActions = Object.entries(typeValue).filter(
 | 
				
			||||||
 | 
					          ([actionKey, actionValue]) => actionValue
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  isAll(key: string): boolean {
 | 
					        selectedActions.forEach(([actionKey, actionValue]) => {
 | 
				
			||||||
    return this.form.get(key).get('all').value == true
 | 
					          permissions.push(
 | 
				
			||||||
 | 
					            (PermissionType[typeKey] as string).replace(
 | 
				
			||||||
 | 
					              '%s',
 | 
				
			||||||
 | 
					              PermissionAction[actionKey]
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (selectedActions.length == Object.entries(typeValue).length) {
 | 
				
			||||||
 | 
					          this.typesWithAllActions.add(typeKey)
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          this.typesWithAllActions.delete(typeKey)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      this.onChange(permissions)
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  toggleAll(event, type) {
 | 
				
			||||||
 | 
					    const typeGroup = this.form.get(type)
 | 
				
			||||||
 | 
					    if (event.target.checked) {
 | 
				
			||||||
 | 
					      Object.keys(PermissionAction).forEach((action) => {
 | 
				
			||||||
 | 
					        typeGroup.get(action).patchValue(true)
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      this.typesWithAllActions.add(type)
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      this.typesWithAllActions.delete(type)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -245,7 +245,7 @@ export class SettingsComponent
 | 
				
			|||||||
          is_active: user.is_active,
 | 
					          is_active: user.is_active,
 | 
				
			||||||
          is_superuser: user.is_superuser,
 | 
					          is_superuser: user.is_superuser,
 | 
				
			||||||
          groups: user.groups,
 | 
					          groups: user.groups,
 | 
				
			||||||
          permissions: user.permissions,
 | 
					          user_permissions: user.user_permissions,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        this.usersGroup.addControl(
 | 
					        this.usersGroup.addControl(
 | 
				
			||||||
          user.id.toString(),
 | 
					          user.id.toString(),
 | 
				
			||||||
@ -257,7 +257,7 @@ export class SettingsComponent
 | 
				
			|||||||
            is_active: new FormControl(null),
 | 
					            is_active: new FormControl(null),
 | 
				
			||||||
            is_superuser: new FormControl(null),
 | 
					            is_superuser: new FormControl(null),
 | 
				
			||||||
            groups: new FormControl(null),
 | 
					            groups: new FormControl(null),
 | 
				
			||||||
            permissions: new FormControl(null),
 | 
					            user_permissions: new FormControl(null),
 | 
				
			||||||
          })
 | 
					          })
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@ -514,7 +514,21 @@ export class SettingsComponent
 | 
				
			|||||||
    modal.componentInstance.btnCaption = $localize`Proceed`
 | 
					    modal.componentInstance.btnCaption = $localize`Proceed`
 | 
				
			||||||
    modal.componentInstance.confirmClicked.subscribe(() => {
 | 
					    modal.componentInstance.confirmClicked.subscribe(() => {
 | 
				
			||||||
      modal.componentInstance.buttonsEnabled = false
 | 
					      modal.componentInstance.buttonsEnabled = false
 | 
				
			||||||
      this.usersService.delete(user)
 | 
					      this.usersService.delete(user).subscribe({
 | 
				
			||||||
 | 
					        next: () => {
 | 
				
			||||||
 | 
					          modal.close()
 | 
				
			||||||
 | 
					          this.toastService.showInfo($localize`Deleted user`)
 | 
				
			||||||
 | 
					          this.usersService.listAll().subscribe((r) => {
 | 
				
			||||||
 | 
					            this.users = r.results
 | 
				
			||||||
 | 
					            this.initialize()
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        error: (e) => {
 | 
				
			||||||
 | 
					          this.toastService.showError(
 | 
				
			||||||
 | 
					            $localize`Error deleting user: ${e.toString()}.`
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -554,7 +568,21 @@ export class SettingsComponent
 | 
				
			|||||||
    modal.componentInstance.btnCaption = $localize`Proceed`
 | 
					    modal.componentInstance.btnCaption = $localize`Proceed`
 | 
				
			||||||
    modal.componentInstance.confirmClicked.subscribe(() => {
 | 
					    modal.componentInstance.confirmClicked.subscribe(() => {
 | 
				
			||||||
      modal.componentInstance.buttonsEnabled = false
 | 
					      modal.componentInstance.buttonsEnabled = false
 | 
				
			||||||
      this.groupsService.delete(group)
 | 
					      this.groupsService.delete(group).subscribe({
 | 
				
			||||||
 | 
					        next: () => {
 | 
				
			||||||
 | 
					          modal.close()
 | 
				
			||||||
 | 
					          this.toastService.showInfo($localize`Deleted group`)
 | 
				
			||||||
 | 
					          this.groupsService.listAll().subscribe((r) => {
 | 
				
			||||||
 | 
					            this.groups = r.results
 | 
				
			||||||
 | 
					            this.initialize()
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        error: (e) => {
 | 
				
			||||||
 | 
					          this.toastService.showError(
 | 
				
			||||||
 | 
					            $localize`Error deleting group: ${e.toString()}.`
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -10,6 +10,6 @@ export interface PaperlessUser extends ObjectWithId {
 | 
				
			|||||||
  is_active?: boolean
 | 
					  is_active?: boolean
 | 
				
			||||||
  is_superuser?: boolean
 | 
					  is_superuser?: boolean
 | 
				
			||||||
  groups?: PaperlessGroup[]
 | 
					  groups?: PaperlessGroup[]
 | 
				
			||||||
  permissions?: string[]
 | 
					  user_permissions?: string[]
 | 
				
			||||||
  inherited_permissions?: string[]
 | 
					  inherited_permissions?: string[]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -8,20 +8,19 @@ export enum PermissionAction {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export enum PermissionType {
 | 
					export enum PermissionType {
 | 
				
			||||||
  Document = 'documents.%s_document',
 | 
					  Document = '%s_document',
 | 
				
			||||||
  Tag = 'documents.%s_tag',
 | 
					  Tag = '%s_tag',
 | 
				
			||||||
  Correspondent = 'documents.%s_correspondent',
 | 
					  Correspondent = '%s_correspondent',
 | 
				
			||||||
  DocumentType = 'documents.%s_documenttype',
 | 
					  DocumentType = '%s_documenttype',
 | 
				
			||||||
  StoragePath = 'documents.%s_storagepath',
 | 
					  StoragePath = '%s_storagepath',
 | 
				
			||||||
  SavedView = 'documents.%s_savedview',
 | 
					  SavedView = '%s_savedview',
 | 
				
			||||||
  PaperlessTask = 'documents.%s_paperlesstask',
 | 
					  PaperlessTask = '%s_paperlesstask',
 | 
				
			||||||
  UISettings = 'documents.%s_uisettings',
 | 
					  UISettings = '%s_uisettings',
 | 
				
			||||||
  Comment = 'documents.%s_comment',
 | 
					  Comment = '%s_comment',
 | 
				
			||||||
  Log = 'admin.%s_logentry',
 | 
					  MailAccount = '%s_mailaccount',
 | 
				
			||||||
  MailAccount = 'paperless_mail.%s_mailaccount',
 | 
					  MailRule = '%s_mailrule',
 | 
				
			||||||
  MailRule = 'paperless_mail.%s_mailrule',
 | 
					  User = '%s_user',
 | 
				
			||||||
  User = 'auth.%s_user',
 | 
					  Admin = '%s_logentry',
 | 
				
			||||||
  Admin = 'admin.%s_logentry',
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface PaperlessPermission {
 | 
					export interface PaperlessPermission {
 | 
				
			||||||
@ -51,7 +50,7 @@ export class PermissionsService {
 | 
				
			|||||||
    actionKey: string
 | 
					    actionKey: string
 | 
				
			||||||
    typeKey: string
 | 
					    typeKey: string
 | 
				
			||||||
  } {
 | 
					  } {
 | 
				
			||||||
    const matches = permissionStr.match(/\.(.+)_/)
 | 
					    const matches = permissionStr.match(/(.+)_/)
 | 
				
			||||||
    let typeKey
 | 
					    let typeKey
 | 
				
			||||||
    let actionKey
 | 
					    let actionKey
 | 
				
			||||||
    if (matches?.length > 0) {
 | 
					    if (matches?.length > 0) {
 | 
				
			||||||
 | 
				
			|||||||
@ -856,7 +856,7 @@ class UiSettingsView(GenericAPIView):
 | 
				
			|||||||
            ui_settings["update_checking"] = {
 | 
					            ui_settings["update_checking"] = {
 | 
				
			||||||
                "backend_setting": settings.ENABLE_UPDATE_CHECK,
 | 
					                "backend_setting": settings.ENABLE_UPDATE_CHECK,
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        roles = user.get_all_permissions()
 | 
					        roles = user.user_permissions.values_list("codename", flat=True)
 | 
				
			||||||
        return Response(
 | 
					        return Response(
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                "user_id": user.id,
 | 
					                "user_id": user.id,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,12 +1,21 @@
 | 
				
			|||||||
from django.contrib.auth.models import Group
 | 
					from django.contrib.auth.models import Group
 | 
				
			||||||
 | 
					from django.contrib.auth.models import Permission
 | 
				
			||||||
from django.contrib.auth.models import User
 | 
					from django.contrib.auth.models import User
 | 
				
			||||||
from rest_framework import serializers
 | 
					from rest_framework import serializers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class UserSerializer(serializers.ModelSerializer):
 | 
					class UserSerializer(serializers.ModelSerializer):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    groups = serializers.SerializerMethodField()
 | 
					    groups = serializers.SlugRelatedField(
 | 
				
			||||||
    permissions = serializers.SerializerMethodField()
 | 
					        many=True,
 | 
				
			||||||
 | 
					        queryset=Group.objects.all(),
 | 
				
			||||||
 | 
					        slug_field="name",
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    user_permissions = serializers.SlugRelatedField(
 | 
				
			||||||
 | 
					        many=True,
 | 
				
			||||||
 | 
					        queryset=Permission.objects.all(),
 | 
				
			||||||
 | 
					        slug_field="codename",
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    inherited_permissions = serializers.SerializerMethodField()
 | 
					    inherited_permissions = serializers.SerializerMethodField()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
@ -21,30 +30,21 @@ class UserSerializer(serializers.ModelSerializer):
 | 
				
			|||||||
            "is_active",
 | 
					            "is_active",
 | 
				
			||||||
            "is_superuser",
 | 
					            "is_superuser",
 | 
				
			||||||
            "groups",
 | 
					            "groups",
 | 
				
			||||||
            "permissions",
 | 
					            "user_permissions",
 | 
				
			||||||
            "inherited_permissions",
 | 
					            "inherited_permissions",
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_groups(self, obj):
 | 
					 | 
				
			||||||
        return list(obj.groups.values_list("name", flat=True))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_permissions(self, obj):
 | 
					 | 
				
			||||||
        # obj.get_user_permissions() returns more permissions than desired
 | 
					 | 
				
			||||||
        permission_natural_keys = []
 | 
					 | 
				
			||||||
        permissions = obj.user_permissions.all()
 | 
					 | 
				
			||||||
        for permission in permissions:
 | 
					 | 
				
			||||||
            permission_natural_keys.append(
 | 
					 | 
				
			||||||
                permission.natural_key()[1] + "." + permission.natural_key()[0],
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        return permission_natural_keys
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_inherited_permissions(self, obj):
 | 
					    def get_inherited_permissions(self, obj):
 | 
				
			||||||
        return obj.get_group_permissions()
 | 
					        return obj.get_group_permissions()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GroupSerializer(serializers.ModelSerializer):
 | 
					class GroupSerializer(serializers.ModelSerializer):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    permissions = serializers.SerializerMethodField()
 | 
					    permissions = serializers.SlugRelatedField(
 | 
				
			||||||
 | 
					        many=True,
 | 
				
			||||||
 | 
					        queryset=Permission.objects.all(),
 | 
				
			||||||
 | 
					        slug_field="codename",
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = Group
 | 
					        model = Group
 | 
				
			||||||
@ -53,12 +53,3 @@ class GroupSerializer(serializers.ModelSerializer):
 | 
				
			|||||||
            "name",
 | 
					            "name",
 | 
				
			||||||
            "permissions",
 | 
					            "permissions",
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_permissions(self, obj):
 | 
					 | 
				
			||||||
        permission_natural_keys = []
 | 
					 | 
				
			||||||
        permissions = obj.permissions.all()
 | 
					 | 
				
			||||||
        for permission in permissions:
 | 
					 | 
				
			||||||
            permission_natural_keys.append(
 | 
					 | 
				
			||||||
                permission.natural_key()[1] + "." + permission.natural_key()[0],
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        return permission_natural_keys
 | 
					 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user