]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Default frontend to current owner, allow setting no owner on create 3347/head
authorshamoon <4887959+shamoon@users.noreply.github.com>
Mon, 8 May 2023 08:56:28 +0000 (01:56 -0700)
committershamoon <4887959+shamoon@users.noreply.github.com>
Wed, 10 May 2023 02:53:34 +0000 (19:53 -0700)
src-ui/src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.ts
src-ui/src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.ts
src-ui/src/app/components/common/edit-dialog/edit-dialog.component.ts
src-ui/src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.ts
src-ui/src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts
src-ui/src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts
src-ui/src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts
src-ui/src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.ts
src-ui/src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts
src/documents/serialisers.py
src/documents/tests/test_api.py

index 2ac7f2d99aca2f2e097c4a176e7132b0e64f68a3..89aa68f84261ce66f5e78931086fb47907b5203a 100644 (file)
@@ -6,6 +6,7 @@ import { DEFAULT_MATCHING_ALGORITHM } from 'src/app/data/matching-model'
 import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent'
 import { CorrespondentService } from 'src/app/services/rest/correspondent.service'
 import { UserService } from 'src/app/services/rest/user.service'
+import { SettingsService } from 'src/app/services/settings.service'
 
 @Component({
   selector: 'app-correspondent-edit-dialog',
@@ -16,9 +17,10 @@ export class CorrespondentEditDialogComponent extends EditDialogComponent<Paperl
   constructor(
     service: CorrespondentService,
     activeModal: NgbActiveModal,
-    userService: UserService
+    userService: UserService,
+    settingsService: SettingsService
   ) {
-    super(service, activeModal, userService)
+    super(service, activeModal, userService, settingsService)
   }
 
   getCreateTitle() {
index a1d3e4fc43a471b431a04d5db7cd2de14d322c50..e469cdd003b6a0535d03f31bfd394c14b7217746 100644 (file)
@@ -6,6 +6,7 @@ import { DEFAULT_MATCHING_ALGORITHM } from 'src/app/data/matching-model'
 import { PaperlessDocumentType } from 'src/app/data/paperless-document-type'
 import { DocumentTypeService } from 'src/app/services/rest/document-type.service'
 import { UserService } from 'src/app/services/rest/user.service'
+import { SettingsService } from 'src/app/services/settings.service'
 
 @Component({
   selector: 'app-document-type-edit-dialog',
@@ -16,9 +17,10 @@ export class DocumentTypeEditDialogComponent extends EditDialogComponent<Paperle
   constructor(
     service: DocumentTypeService,
     activeModal: NgbActiveModal,
-    userService: UserService
+    userService: UserService,
+    settingsService: SettingsService
   ) {
-    super(service, activeModal, userService)
+    super(service, activeModal, userService, settingsService)
   }
 
   getCreateTitle() {
index a2612ccfd80ab31bdd740889f7e80d3c693c3bab..0a65ba464737b71d7f69eb3ebdad9d975091a25f 100644 (file)
@@ -13,6 +13,7 @@ import { PaperlessUser } from 'src/app/data/paperless-user'
 import { AbstractPaperlessService } from 'src/app/services/rest/abstract-paperless-service'
 import { UserService } from 'src/app/services/rest/user.service'
 import { PermissionsFormObject } from '../input/permissions/permissions-form/permissions-form.component'
+import { SettingsService } from 'src/app/services/settings.service'
 
 @Directive()
 export abstract class EditDialogComponent<
@@ -22,7 +23,8 @@ export abstract class EditDialogComponent<
   constructor(
     protected service: AbstractPaperlessService<T>,
     private activeModal: NgbActiveModal,
-    private userService: UserService
+    private userService: UserService,
+    private settingsService: SettingsService
   ) {}
 
   users: PaperlessUser[]
@@ -64,7 +66,14 @@ export abstract class EditDialogComponent<
       this.closeEnabled = true
     })
 
-    this.userService.listAll().subscribe((r) => (this.users = r.results))
+    this.userService.listAll().subscribe((r) => {
+      this.users = r.results
+      if (this.dialogMode === 'create') {
+        this.objectForm.get('permissions_form').setValue({
+          owner: this.settingsService.currentUser.id,
+        })
+      }
+    })
   }
 
   getCreateTitle() {
index 785d6c20d8da0506d9ecc38c9135272804211623..85f6d9efdb745e164f33727a2f7c4432aa8f4c21 100644 (file)
@@ -5,6 +5,7 @@ import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-
 import { PaperlessGroup } from 'src/app/data/paperless-group'
 import { GroupService } from 'src/app/services/rest/group.service'
 import { UserService } from 'src/app/services/rest/user.service'
+import { SettingsService } from 'src/app/services/settings.service'
 
 @Component({
   selector: 'app-group-edit-dialog',
@@ -15,9 +16,10 @@ export class GroupEditDialogComponent extends EditDialogComponent<PaperlessGroup
   constructor(
     service: GroupService,
     activeModal: NgbActiveModal,
-    userService: UserService
+    userService: UserService,
+    settingsService: SettingsService
   ) {
-    super(service, activeModal, userService)
+    super(service, activeModal, userService, settingsService)
   }
 
   getCreateTitle() {
index 9f37906237b9f2620e70d133f190e852841cd214..d19c422413c4b305cd7ea203e2d7ab4ebb8a1791 100644 (file)
@@ -8,6 +8,7 @@ import {
 } from 'src/app/data/paperless-mail-account'
 import { MailAccountService } from 'src/app/services/rest/mail-account.service'
 import { UserService } from 'src/app/services/rest/user.service'
+import { SettingsService } from 'src/app/services/settings.service'
 
 const IMAP_SECURITY_OPTIONS = [
   { id: IMAPSecurity.None, name: $localize`No encryption` },
@@ -30,9 +31,10 @@ export class MailAccountEditDialogComponent extends EditDialogComponent<Paperles
   constructor(
     service: MailAccountService,
     activeModal: NgbActiveModal,
-    userService: UserService
+    userService: UserService,
+    settingsService: SettingsService
   ) {
-    super(service, activeModal, userService)
+    super(service, activeModal, userService, settingsService)
   }
 
   getCreateTitle() {
index 5e0ce49a70e0b6324d9402394d320cec33660b6e..d26c882754c92cdee8febe34874f16d6b3c08919 100644 (file)
@@ -19,6 +19,7 @@ import { DocumentTypeService } from 'src/app/services/rest/document-type.service
 import { MailAccountService } from 'src/app/services/rest/mail-account.service'
 import { MailRuleService } from 'src/app/services/rest/mail-rule.service'
 import { UserService } from 'src/app/services/rest/user.service'
+import { SettingsService } from 'src/app/services/settings.service'
 
 const ATTACHMENT_TYPE_OPTIONS = [
   {
@@ -115,9 +116,10 @@ export class MailRuleEditDialogComponent extends EditDialogComponent<PaperlessMa
     accountService: MailAccountService,
     correspondentService: CorrespondentService,
     documentTypeService: DocumentTypeService,
-    userService: UserService
+    userService: UserService,
+    settingsService: SettingsService
   ) {
-    super(service, activeModal, userService)
+    super(service, activeModal, userService, settingsService)
 
     accountService
       .listAll()
index edb144a59fe97bd43268d04980275bf76711e717..3c78b41cfc2be25529eefa5bca7f78c7246ff931 100644 (file)
@@ -6,6 +6,7 @@ import { DEFAULT_MATCHING_ALGORITHM } from 'src/app/data/matching-model'
 import { PaperlessStoragePath } from 'src/app/data/paperless-storage-path'
 import { StoragePathService } from 'src/app/services/rest/storage-path.service'
 import { UserService } from 'src/app/services/rest/user.service'
+import { SettingsService } from 'src/app/services/settings.service'
 
 @Component({
   selector: 'app-storage-path-edit-dialog',
@@ -16,9 +17,10 @@ export class StoragePathEditDialogComponent extends EditDialogComponent<Paperles
   constructor(
     service: StoragePathService,
     activeModal: NgbActiveModal,
-    userService: UserService
+    userService: UserService,
+    settingsService: SettingsService
   ) {
-    super(service, activeModal, userService)
+    super(service, activeModal, userService, settingsService)
   }
 
   get pathHint() {
index a0d0dd17da92ab550fd96e92a1efb1c6bffe2cff..0efea146b17b59c3b6fc1cac6ab1ed9f929fefe9 100644 (file)
@@ -7,6 +7,7 @@ import { TagService } from 'src/app/services/rest/tag.service'
 import { randomColor } from 'src/app/utils/color'
 import { DEFAULT_MATCHING_ALGORITHM } from 'src/app/data/matching-model'
 import { UserService } from 'src/app/services/rest/user.service'
+import { SettingsService } from 'src/app/services/settings.service'
 
 @Component({
   selector: 'app-tag-edit-dialog',
@@ -17,9 +18,10 @@ export class TagEditDialogComponent extends EditDialogComponent<PaperlessTag> {
   constructor(
     service: TagService,
     activeModal: NgbActiveModal,
-    userService: UserService
+    userService: UserService,
+    settingsService: SettingsService
   ) {
-    super(service, activeModal, userService)
+    super(service, activeModal, userService, settingsService)
   }
 
   getCreateTitle() {
index 9b3bd9bd8b329456f80d8edcfb06c5e36fe84731..afe23ac1bc1a0764e2a6aa26a57faa9d55e75e59 100644 (file)
@@ -7,6 +7,7 @@ import { PaperlessGroup } from 'src/app/data/paperless-group'
 import { PaperlessUser } from 'src/app/data/paperless-user'
 import { GroupService } from 'src/app/services/rest/group.service'
 import { UserService } from 'src/app/services/rest/user.service'
+import { SettingsService } from 'src/app/services/settings.service'
 
 @Component({
   selector: 'app-user-edit-dialog',
@@ -23,9 +24,10 @@ export class UserEditDialogComponent
   constructor(
     service: UserService,
     activeModal: NgbActiveModal,
-    groupsService: GroupService
+    groupsService: GroupService,
+    settingsService: SettingsService
   ) {
-    super(service, activeModal, service)
+    super(service, activeModal, service, settingsService)
 
     groupsService
       .listAll()
index ad2b5d0f642fef170eae46ff9c08b9cdc8f23290..71ffe7be216f545751fc007b745ba1d43af642ec 100644 (file)
@@ -220,6 +220,8 @@ class OwnedObjectSerializer(serializers.ModelSerializer, SetPermissionsMixin):
         permissions = None
         if "set_permissions" in validated_data:
             permissions = validated_data.pop("set_permissions")
+            if "user" not in permissions or permissions["user"] is None:
+                validated_data["owner"] = None
         instance = super().create(validated_data)
         if permissions is not None:
             self._set_permissions(permissions, instance)
index e8c6dee7c4b4248cbaf1c8416f4fa303a3736c52..325ba3814722a01a8794ec39530c202984057a05 100644 (file)
@@ -3532,6 +3532,77 @@ class TestApiAuth(DirectoriesMixin, APITestCase):
             status.HTTP_404_NOT_FOUND,
         )
 
+    def test_api_set_permissions(self):
+        """
+        GIVEN:
+            - API request to create an object (Tag) that supplies set_permissions object
+        WHEN:
+            - owner is passed as null or as a user id
+            - view > users is set
+        THEN:
+            - Object permissions are set appropriately
+        """
+        user1 = User.objects.create_superuser(username="user1")
+        user2 = User.objects.create(username="user2")
+
+        self.client.force_authenticate(user1)
+
+        response = self.client.post(
+            "/api/tags/",
+            json.dumps(
+                {
+                    "name": "test1",
+                    "matching_algorithm": MatchingModel.MATCH_AUTO,
+                    "set_permissions": {
+                        "owner": None,
+                        "view": {
+                            "users": None,
+                            "groups": None,
+                        },
+                        "change": {
+                            "users": None,
+                            "groups": None,
+                        },
+                    },
+                },
+            ),
+            content_type="application/json",
+        )
+
+        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
+
+        tag1 = Tag.objects.filter(name="test1").first()
+        self.assertEqual(tag1.owner, None)
+
+        response = self.client.post(
+            "/api/tags/",
+            json.dumps(
+                {
+                    "name": "test2",
+                    "matching_algorithm": MatchingModel.MATCH_AUTO,
+                    "set_permissions": {
+                        "owner": user1.id,
+                        "view": {
+                            "users": [user2.id],
+                            "groups": None,
+                        },
+                        "change": {
+                            "users": None,
+                            "groups": None,
+                        },
+                    },
+                },
+            ),
+            content_type="application/json",
+        )
+
+        tag2 = Tag.objects.filter(name="test2").first()
+
+        from guardian.core import ObjectPermissionChecker
+
+        checker = ObjectPermissionChecker(user2)
+        self.assertEqual(checker.has_perm("view_tag", tag2), True)
+
     def test_dynamic_permissions_fields(self):
         Document.objects.create(title="Test", content="content 1", checksum="1")