mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-11-12 09:36:41 -05:00
Merge branch 'dev' into feature-remote-ocr-2
This commit is contained in:
commit
cc73ed8b86
@ -4539,32 +4539,32 @@
|
|||||||
<source>Create new user account</source>
|
<source>Create new user account</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">70</context>
|
<context context-type="linenumber">72</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2887331217965896363" datatype="html">
|
<trans-unit id="2887331217965896363" datatype="html">
|
||||||
<source>Edit user account</source>
|
<source>Edit user account</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">74</context>
|
<context context-type="linenumber">76</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5872286584705575476" datatype="html">
|
<trans-unit id="5872286584705575476" datatype="html">
|
||||||
<source>Totp deactivated</source>
|
<source>Totp deactivated</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">130</context>
|
<context context-type="linenumber">132</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="6439190193788239059" datatype="html">
|
<trans-unit id="6439190193788239059" datatype="html">
|
||||||
<source>Totp deactivation failed</source>
|
<source>Totp deactivation failed</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">133</context>
|
<context context-type="linenumber">135</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">138</context>
|
<context context-type="linenumber">140</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8419515490539218007" datatype="html">
|
<trans-unit id="8419515490539218007" datatype="html">
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import { GroupService } from 'src/app/services/rest/group.service'
|
|||||||
import { UserService } from 'src/app/services/rest/user.service'
|
import { UserService } from 'src/app/services/rest/user.service'
|
||||||
import { SettingsService } from 'src/app/services/settings.service'
|
import { SettingsService } from 'src/app/services/settings.service'
|
||||||
import { ToastService } from 'src/app/services/toast.service'
|
import { ToastService } from 'src/app/services/toast.service'
|
||||||
|
import { ConfirmButtonComponent } from '../../confirm-button/confirm-button.component'
|
||||||
import { PasswordComponent } from '../../input/password/password.component'
|
import { PasswordComponent } from '../../input/password/password.component'
|
||||||
import { SelectComponent } from '../../input/select/select.component'
|
import { SelectComponent } from '../../input/select/select.component'
|
||||||
import { TextComponent } from '../../input/text/text.component'
|
import { TextComponent } from '../../input/text/text.component'
|
||||||
@ -28,6 +29,7 @@ import { PermissionsSelectComponent } from '../../permissions-select/permissions
|
|||||||
SelectComponent,
|
SelectComponent,
|
||||||
TextComponent,
|
TextComponent,
|
||||||
PasswordComponent,
|
PasswordComponent,
|
||||||
|
ConfirmButtonComponent,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
],
|
],
|
||||||
|
|||||||
@ -2,9 +2,11 @@ import types
|
|||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from django.contrib.admin.sites import AdminSite
|
from django.contrib.admin.sites import AdminSite
|
||||||
|
from django.contrib.auth.models import Permission
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from rest_framework import status
|
||||||
|
|
||||||
from documents import index
|
from documents import index
|
||||||
from documents.admin import DocumentAdmin
|
from documents.admin import DocumentAdmin
|
||||||
@ -125,3 +127,36 @@ class TestPaperlessAdmin(DirectoriesMixin, TestCase):
|
|||||||
form.request = types.SimpleNamespace(user=superuser)
|
form.request = types.SimpleNamespace(user=superuser)
|
||||||
self.assertTrue(form.is_valid())
|
self.assertTrue(form.is_valid())
|
||||||
self.assertEqual({}, form.errors)
|
self.assertEqual({}, form.errors)
|
||||||
|
|
||||||
|
def test_superuser_can_only_be_modified_by_superuser(self):
|
||||||
|
superuser = User.objects.create_superuser(username="superuser", password="test")
|
||||||
|
user = User.objects.create(
|
||||||
|
username="test",
|
||||||
|
is_superuser=False,
|
||||||
|
is_staff=True,
|
||||||
|
)
|
||||||
|
change_user_perm = Permission.objects.get(codename="change_user")
|
||||||
|
user.user_permissions.add(change_user_perm)
|
||||||
|
|
||||||
|
self.client.force_login(user)
|
||||||
|
response = self.client.patch(
|
||||||
|
f"/api/users/{superuser.pk}/",
|
||||||
|
{"first_name": "Updated"},
|
||||||
|
content_type="application/json",
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
|
self.assertEqual(
|
||||||
|
response.content.decode(),
|
||||||
|
"Superusers can only be modified by other superusers",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.client.logout()
|
||||||
|
self.client.force_login(superuser)
|
||||||
|
response = self.client.patch(
|
||||||
|
f"/api/users/{superuser.pk}/",
|
||||||
|
{"first_name": "Updated"},
|
||||||
|
content_type="application/json",
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
superuser.refresh_from_db()
|
||||||
|
self.assertEqual(superuser.first_name, "Updated")
|
||||||
|
|||||||
@ -125,6 +125,10 @@ class UserViewSet(ModelViewSet):
|
|||||||
|
|
||||||
def update(self, request, *args, **kwargs):
|
def update(self, request, *args, **kwargs):
|
||||||
user_to_update: User = self.get_object()
|
user_to_update: User = self.get_object()
|
||||||
|
if not request.user.is_superuser and user_to_update.is_superuser:
|
||||||
|
return HttpResponseForbidden(
|
||||||
|
"Superusers can only be modified by other superusers",
|
||||||
|
)
|
||||||
if (
|
if (
|
||||||
not request.user.is_superuser
|
not request.user.is_superuser
|
||||||
and request.data.get("is_superuser") is not None
|
and request.data.get("is_superuser") is not None
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user