Support edit permissions for mail rules and accounts

This commit is contained in:
shamoon
2023-09-22 01:01:35 -07:00
parent 56c15f6642
commit a9ab344678
8 changed files with 273 additions and 108 deletions

View File

@@ -343,6 +343,7 @@
<div class="col">
<div class="btn-group">
<button *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.MailAccount }" [disabled]="!userCanEdit(account)" class="btn btn-sm btn-primary" type="button" (click)="editMailAccount(account)" i18n>Edit</button>
<button *pngxIfOwner="rule" class="btn btn-sm btn-primary" type="button" (click)="editPermissions(account)" i18n>Permissions</button>
<button *pngxIfPermissions="{ action: PermissionAction.Delete, type: PermissionType.MailAccount }" [disabled]="!userIsOwner(account)" class="btn btn-sm btn-outline-danger" type="button" (click)="deleteMailAccount(account)" i18n>Delete</button>
</div>
</div>
@@ -380,6 +381,7 @@
<div class="col">
<div class="btn-group">
<button *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.MailRule }" [disabled]="!userCanEdit(rule)" class="btn btn-sm btn-primary" type="button" (click)="editMailRule(rule)" i18n>Edit</button>
<button *pngxIfOwner="rule" class="btn btn-sm btn-primary" type="button" (click)="editPermissions(rule)" i18n>Permissions</button>
<button *pngxIfPermissions="{ action: PermissionAction.Delete, type: PermissionType.MailRule }" [disabled]="!userIsOwner(rule)" class="btn btn-sm btn-outline-danger" type="button" (click)="deleteMailRule(rule)" i18n>Delete</button>
</div>
</div>

View File

@@ -52,6 +52,9 @@ import { TagsComponent } from '../../common/input/tags/tags.component'
import { TextComponent } from '../../common/input/text/text.component'
import { PageHeaderComponent } from '../../common/page-header/page-header.component'
import { SettingsComponent } from './settings.component'
import { PermissionsDialogComponent } from '../../common/permissions-dialog/permissions-dialog.component'
import { PermissionsFormComponent } from '../../common/input/permissions/permissions-form/permissions-form.component'
import { IfOwnerDirective } from 'src/app/directives/if-owner.directive'
const savedViews = [
{ id: 1, name: 'view1' },
@@ -70,8 +73,8 @@ const mailAccounts = [
{ id: 2, name: 'account2' },
]
const mailRules = [
{ id: 1, name: 'rule1', owner: 1 },
{ id: 2, name: 'rule2', owner: 2 },
{ id: 1, name: 'rule1', owner: 1, account: 1 },
{ id: 2, name: 'rule2', owner: 2, account: 2 },
]
describe('SettingsComponent', () => {
@@ -110,6 +113,9 @@ describe('SettingsComponent', () => {
MailRuleEditDialogComponent,
PermissionsUserComponent,
PermissionsGroupComponent,
IfOwnerDirective,
PermissionsDialogComponent,
PermissionsFormComponent,
],
providers: [CustomDatePipe, DatePipe, PermissionsGuard],
imports: [
@@ -591,4 +597,69 @@ describe('SettingsComponent', () => {
expect(listAllSpy).toHaveBeenCalled()
expect(toastInfoSpy).toHaveBeenCalledWith('Deleted mail rule')
})
it('should support edit permissions on mail rule objects', () => {
completeSetup()
const perms = {
owner: 99,
set_permissions: {
view: {
users: [1],
groups: [2],
},
change: {
users: [3],
groups: [4],
},
},
}
let modal: NgbModalRef
modalService.activeInstances.subscribe((refs) => (modal = refs[0]))
const toastErrorSpy = jest.spyOn(toastService, 'showError')
const toastInfoSpy = jest.spyOn(toastService, 'showInfo')
const rulePatchSpy = jest.spyOn(mailRuleService, 'patch')
component.editPermissions(mailRules[0] as PaperlessMailRule)
expect(modal).not.toBeUndefined()
let dialog = modal.componentInstance as PermissionsDialogComponent
expect(dialog.object).toEqual(mailRules[0])
rulePatchSpy.mockReturnValueOnce(
throwError(() => new Error('error saving perms'))
)
dialog.confirmClicked.emit(perms)
expect(rulePatchSpy).toHaveBeenCalled()
expect(toastErrorSpy).toHaveBeenCalled()
rulePatchSpy.mockReturnValueOnce(of(mailRules[0] as PaperlessMailRule))
dialog.confirmClicked.emit(perms)
expect(toastInfoSpy).toHaveBeenCalledWith('Permissions updated')
modalService.dismissAll()
})
it('should support edit permissions on mail account objects', () => {
completeSetup()
const perms = {
owner: 99,
set_permissions: {
view: {
users: [1],
groups: [2],
},
change: {
users: [3],
groups: [4],
},
},
}
let modal: NgbModalRef
modalService.activeInstances.subscribe((refs) => (modal = refs[0]))
const accountPatchSpy = jest.spyOn(mailAccountService, 'patch')
component.editPermissions(mailAccounts[0] as PaperlessMailAccount)
expect(modal).not.toBeUndefined()
let dialog = modal.componentInstance as PermissionsDialogComponent
expect(dialog.object).toEqual(mailAccounts[0])
dialog = modal.componentInstance as PermissionsDialogComponent
dialog.confirmClicked.emit(perms)
expect(accountPatchSpy).toHaveBeenCalled()
})
})

View File

@@ -51,6 +51,8 @@ import {
PermissionType,
PermissionsService,
} from 'src/app/services/permissions.service'
import { PermissionsDialogComponent } from '../../common/permissions-dialog/permissions-dialog.component'
import { AbstractPaperlessService } from 'src/app/services/rest/abstract-paperless-service'
enum SettingsNavIDs {
General = 1,
@@ -307,14 +309,14 @@ export class SettingsComponent
(!this.mailAccounts || !this.mailRules)
) {
this.mailAccountService
.listAll()
.listAll(null, null, { full_perms: true })
.pipe(first())
.subscribe({
next: (r) => {
this.mailAccounts = r.results
this.mailRuleService
.listAll()
.listAll(null, null, { full_perms: true })
.pipe(first())
.subscribe({
next: (r) => {
@@ -889,10 +891,12 @@ export class SettingsComponent
$localize`Saved account "${newMailAccount.name}".`
)
this.mailAccountService.clearCache()
this.mailAccountService.listAll().subscribe((r) => {
this.mailAccounts = r.results
this.initialize()
})
this.mailAccountService
.listAll(null, null, { full_perms: true })
.subscribe((r) => {
this.mailAccounts = r.results
this.initialize()
})
})
modal.componentInstance.failed
.pipe(takeUntil(this.unsubscribeNotifier))
@@ -917,10 +921,12 @@ export class SettingsComponent
modal.close()
this.toastService.showInfo($localize`Deleted mail account`)
this.mailAccountService.clearCache()
this.mailAccountService.listAll().subscribe((r) => {
this.mailAccounts = r.results
this.initialize(true)
})
this.mailAccountService
.listAll(null, null, { full_perms: true })
.subscribe((r) => {
this.mailAccounts = r.results
this.initialize(true)
})
},
error: (e) => {
this.toastService.showError(
@@ -946,11 +952,13 @@ export class SettingsComponent
.subscribe((newMailRule) => {
this.toastService.showInfo($localize`Saved rule "${newMailRule.name}".`)
this.mailRuleService.clearCache()
this.mailRuleService.listAll().subscribe((r) => {
this.mailRules = r.results
this.mailRuleService
.listAll(null, null, { full_perms: true })
.subscribe((r) => {
this.mailRules = r.results
this.initialize(true)
})
this.initialize(true)
})
})
modal.componentInstance.failed
.pipe(takeUntil(this.unsubscribeNotifier))
@@ -975,10 +983,12 @@ export class SettingsComponent
modal.close()
this.toastService.showInfo($localize`Deleted mail rule`)
this.mailRuleService.clearCache()
this.mailRuleService.listAll().subscribe((r) => {
this.mailRules = r.results
this.initialize(true)
})
this.mailRuleService
.listAll(null, null, { full_perms: true })
.subscribe((r) => {
this.mailRules = r.results
this.initialize(true)
})
},
error: (e) => {
this.toastService.showError($localize`Error deleting mail rule.`, e)
@@ -986,4 +996,30 @@ export class SettingsComponent
})
})
}
editPermissions(object: PaperlessMailRule | PaperlessMailAccount) {
const modal = this.modalService.open(PermissionsDialogComponent, {
backdrop: 'static',
})
const dialog: PermissionsDialogComponent =
modal.componentInstance as PermissionsDialogComponent
dialog.object = object
modal.componentInstance.confirmClicked.subscribe((permissions) => {
modal.componentInstance.buttonsEnabled = false
const service: AbstractPaperlessService<
PaperlessMailRule | PaperlessMailAccount
> = 'account' in object ? this.mailRuleService : this.mailAccountService
object.owner = permissions['owner']
object['set_permissions'] = permissions['set_permissions']
service.patch(object).subscribe({
next: () => {
this.toastService.showInfo($localize`Permissions updated`)
modal.close()
},
error: (e) => {
this.toastService.showError($localize`Error updating permissions`, e)
},
})
})
}
}