Merge pull request #4704 from FinnStutzenstein/setPermissionRequest

Request for settings a permission in a group (closes #4698)
This commit is contained in:
Emanuel Schütze 2019-05-16 14:14:33 +02:00 committed by GitHub
commit 65dbf37106
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 119 additions and 48 deletions

View File

@ -9,6 +9,7 @@ import { Group } from 'app/shared/models/users/group';
import { ViewGroup } from 'app/site/users/models/view-group';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { TranslateService } from '@ngx-translate/core';
import { HttpService } from 'app/core/core-services/http.service';
/**
* Shape of a permission
@ -53,7 +54,8 @@ export class GroupRepositoryService extends BaseRepository<ViewGroup, Group> {
mapperService: CollectionStringMapperService,
viewModelStoreService: ViewModelStoreService,
translate: TranslateService,
private constants: ConstantsService
private constants: ConstantsService,
private http: HttpService
) {
super(DS, dataSend, mapperService, viewModelStoreService, translate, Group);
this.sortPermsPerApp();
@ -69,6 +71,20 @@ export class GroupRepositoryService extends BaseRepository<ViewGroup, Group> {
return viewGroup;
}
/**
* Toggles the given permisson.
*
* @param group The group
* @param perm The permission to toggle
*/
public async togglePerm(group: ViewGroup, perm: string): Promise<void> {
const set = !group.permissions.includes(perm);
return await this.http.post(`rest/${group.collectionString}/${group.id}/set_permission/`, {
perm: perm,
set: set
});
}
/**
* Add an entry to appPermissions
*

View File

@ -153,8 +153,7 @@ export class GroupListComponent extends BaseViewComponent implements OnInit {
* @param perm
*/
public togglePerm(viewGroup: ViewGroup, perm: string): void {
const updateData = new Group({ permissions: viewGroup.getAlteredPermissions(perm) });
this.repo.update(updateData, viewGroup).then(null, this.raiseError);
this.repo.togglePerm(viewGroup, perm);
}
/**

View File

@ -41,33 +41,6 @@ export class ViewGroup extends BaseViewModel {
this._group = group;
}
/**
* Returns an array of permissions where the given perm is included
* or removed.
*
* Avoids touching the local DataStore.
*
* @param perm
*/
public getAlteredPermissions(perm: string): string[] {
// clone the array, avoids altering the local dataStore
const currentPermissions = this.permissions.slice();
if (this.hasPermission(perm)) {
// remove the permission from currentPermissions-List
const indexOfPerm = currentPermissions.indexOf(perm);
if (indexOfPerm !== -1) {
currentPermissions.splice(indexOfPerm, 1);
return currentPermissions;
} else {
return currentPermissions;
}
} else {
currentPermissions.push(perm);
return currentPermissions;
}
}
public hasPermission(perm: string): boolean {
return this.permissions.includes(perm);
}
@ -80,7 +53,5 @@ export class ViewGroup extends BaseViewModel {
return this.group;
}
public updateDependencies(update: BaseViewModel): void {
console.log('ViewGroups wants to update Values with : ', update);
}
public updateDependencies(update: BaseViewModel): void {}
}

View File

@ -10,6 +10,7 @@ from django.contrib.auth import (
update_session_auth_hash,
)
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.models import Permission
from django.contrib.auth.password_validation import validate_password
from django.contrib.auth.tokens import default_token_generator
from django.contrib.sites.shortcuts import get_current_site
@ -314,7 +315,13 @@ class GroupViewSet(ModelViewSet):
# Every authenticated user can see the metadata.
# Anonymous users can do so if they are enabled.
result = self.request.user.is_authenticated or anonymous_is_enabled()
elif self.action in ("create", "partial_update", "update", "destroy"):
elif self.action in (
"create",
"partial_update",
"update",
"destroy",
"set_permission",
):
# Users with all app permissions can edit groups.
result = (
has_perm(self.request.user, "users.can_see_name")
@ -410,6 +417,42 @@ class GroupViewSet(ModelViewSet):
inform_changed_data(affected_users)
return Response(status=status.HTTP_204_NO_CONTENT)
@detail_route(methods=["post"])
@transaction.atomic
def set_permission(self, request, *args, **kwargs):
"""
Send {perm: <permissionstring> set: <True/False>} to set or
remove the permission from a group
"""
perm = request.data.get("perm")
if not isinstance(perm, str):
raise ValidationError("You have to give a permission as string.")
set = request.data.get("set")
if not isinstance(set, bool):
raise ValidationError("You have to give a set value.")
# check if perm is a valid permission
try:
app_label, codename = perm.split(".")
except ValueError:
raise ValidationError("Incorrect permission string")
try:
permission = Permission.objects.get(
content_type__app_label=app_label, codename=codename
)
except Permission.DoesNotExist:
raise ValidationError("Incorrect permission string")
# add/remove the permission
group = self.get_object()
if set:
group.permissions.add(permission)
else:
group.permissions.remove(permission)
inform_changed_data(group)
return Response()
class PersonalNoteViewSet(ModelViewSet):
"""

View File

@ -10,6 +10,7 @@ from openslides.users.serializers import UserFullSerializer
from openslides.utils.autoupdate import inform_changed_data
from openslides.utils.test import TestCase
from ...common_groups import GROUP_DEFAULT_PK, GROUP_DELEGATE_PK, GROUP_STAFF_PK
from ..helpers import count_queries
@ -93,8 +94,7 @@ class UserCreate(TestCase):
def test_creation_with_group(self):
self.client.login(username="admin", password="admin")
# These are the builtin groups 'Delegates' and 'Staff'. The pks are valid.
group_pks = (2, 3)
group_pks = (GROUP_DELEGATE_PK, GROUP_STAFF_PK)
self.client.post(
reverse("user-list"),
@ -107,9 +107,7 @@ class UserCreate(TestCase):
def test_creation_with_default_group(self):
self.client.login(username="admin", password="admin")
# This is the builtin groups 'default'.
# The pk is valid. But this group can not be added to users.
group_pk = (1,)
group_pk = (GROUP_DEFAULT_PK,)
response = self.client.post(
reverse("user-list"),
@ -382,7 +380,7 @@ class GroupReceive(TestCase):
user = User(username="test")
user.set_password("test")
user.save()
default_group = Group.objects.get(pk=1)
default_group = Group.objects.get(pk=GROUP_DEFAULT_PK)
default_group.permissions.all().delete()
self.client.login(username="test", password="test")
@ -463,8 +461,7 @@ class GroupUpdate(TestCase):
def test_simple_update_via_patch(self):
admin_client = APIClient()
admin_client.login(username="admin", password="admin")
# This is the builtin group 'Delegates'. The pk is valid.
group_pk = 2
group_pk = GROUP_DELEGATE_PK
# This contains one valid permission of the users app.
permissions = ("users.can_see_name",)
@ -485,13 +482,12 @@ class GroupUpdate(TestCase):
def test_simple_update_via_put(self):
admin_client = APIClient()
admin_client.login(username="admin", password="admin")
# This is the builtin group 'Delegates'. The pk is valid.
group_pk = 2
# This contains one valid permission of the users app.
permissions = ("users.can_see_name",)
response = admin_client.put(
reverse("group-detail", args=[group_pk]), {"permissions": permissions}
reverse("group-detail", args=[GROUP_DELEGATE_PK]),
{"permissions": permissions},
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
@ -545,6 +541,54 @@ class GroupUpdate(TestCase):
)
)
def test_set_single_permission(self):
admin_client = APIClient()
admin_client.login(username="admin", password="admin")
response = admin_client.post(
reverse("group-set-permission", args=[GROUP_DEFAULT_PK]),
{"perm": "users.can_manage", "set": True},
format="json",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
group = Group.objects.get(pk=GROUP_DEFAULT_PK)
self.assertTrue(
group.permissions.get(
content_type__app_label="users", codename="can_manage"
)
)
def test_add_single_permission_wrong_permission(self):
admin_client = APIClient()
admin_client.login(username="admin", password="admin")
response = admin_client.post(
reverse("group-set-permission", args=[GROUP_DEFAULT_PK]),
{"perm": "not_existing.permission", "set": True},
format="json",
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
def test_remove_single_permission(self):
admin_client = APIClient()
admin_client.login(username="admin", password="admin")
response = admin_client.post(
reverse("group-set-permission", args=[GROUP_DEFAULT_PK]),
{"perm": "users.can_see_name", "set": False},
format="json",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
group = Group.objects.get(pk=GROUP_DEFAULT_PK)
self.assertFalse(
group.permissions.filter(
content_type__app_label="users", codename="can_see"
).exists()
)
class GroupDelete(TestCase):
"""
@ -566,10 +610,8 @@ class GroupDelete(TestCase):
def test_delete_builtin_groups(self):
admin_client = APIClient()
admin_client.login(username="admin", password="admin")
# The pk of builtin group 'Default'
group_pk = 1
response = admin_client.delete(reverse("group-detail", args=[group_pk]))
response = admin_client.delete(reverse("group-detail", args=[GROUP_DEFAULT_PK]))
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)