Merge pull request #2370 from normanjaeckel/Issue2315
Migration for new permission matrix
This commit is contained in:
commit
b661a6e215
@ -1,5 +0,0 @@
|
||||
from ..utils.exceptions import OpenSlidesError
|
||||
|
||||
|
||||
class UsersError(OpenSlidesError):
|
||||
pass
|
62
openslides/users/migrations/0004_groups.py
Normal file
62
openslides/users/migrations/0004_groups.py
Normal file
@ -0,0 +1,62 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.7 on 2016-08-01 14:54
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
def migrate_groups_and_user_permissions(apps, schema_editor):
|
||||
"""
|
||||
This function migrates the database to the new groups logic:
|
||||
- Rename group 'Anonymous' (pk=1) to 'Default'
|
||||
- Rename group 'Registered users' (pk=2) to 'Previous group Registered'
|
||||
- Add all users who are not in any group to this group (pk=2)
|
||||
- Add all permissions of 'Previous group Registered' to all other groups (except 'Default')
|
||||
|
||||
But only run this migration if:
|
||||
- there are groups in the database,
|
||||
- the name of the first group is 'Guests',
|
||||
- the name of the second group is 'Registered users'.
|
||||
"""
|
||||
# Disconnect autoupdate. We do not want to trigger it here.
|
||||
models.signals.post_save.disconnect(dispatch_uid='inform_changed_data_receiver')
|
||||
|
||||
User = apps.get_model('users', 'User')
|
||||
Group = apps.get_model('auth', 'Group')
|
||||
|
||||
try:
|
||||
group_default = Group.objects.get(pk=1)
|
||||
group_registered = Group.objects.get(pk=2)
|
||||
except Group.DoesNotExist:
|
||||
# One of the groups does not exist. Just do nothing.
|
||||
pass
|
||||
else:
|
||||
if group_default.name == 'Guests' and group_registered.name == 'Registered users':
|
||||
# Rename groups pk 1 and 2.
|
||||
group_default.name = 'Default'
|
||||
group_default.save()
|
||||
group_registered.name = 'Previous group Registered'
|
||||
group_registered.save()
|
||||
|
||||
# Move users without groups to group pk 2.
|
||||
users = User.objects.all()
|
||||
for user in users:
|
||||
if not user.groups.exists():
|
||||
user.groups.add(group_registered)
|
||||
|
||||
# Copy permissions of group pk 2 to all other groups except pk 1.
|
||||
groups = Group.objects.filter(pk__gt=2)
|
||||
for group in groups:
|
||||
for permission in group_registered.permissions.all():
|
||||
group.permissions.add(permission)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0003_user_number'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(migrate_groups_and_user_permissions),
|
||||
]
|
@ -5,16 +5,17 @@ from django.contrib.auth.models import (
|
||||
AbstractBaseUser,
|
||||
BaseUserManager,
|
||||
Group,
|
||||
Permission,
|
||||
PermissionsMixin,
|
||||
)
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
|
||||
from openslides.utils.search import user_name_helper
|
||||
|
||||
from ..core.config import config
|
||||
from ..utils.models import RESTModelMixin
|
||||
from .access_permissions import UserAccessPermissions
|
||||
from .exceptions import UsersError
|
||||
|
||||
|
||||
class UserManager(BaseUserManager):
|
||||
@ -35,13 +36,17 @@ class UserManager(BaseUserManager):
|
||||
"""
|
||||
Creates an user with the username 'admin'. If such a user already
|
||||
exists, resets it. The password is (re)set to 'admin'. The user
|
||||
becomes member of the group 'Staff' (pk=3).
|
||||
becomes member of the group 'Staff'. The two important permissions
|
||||
'users.can_see_name' and 'users.can_manage' are added to this group,
|
||||
so that the admin can manage all other permissions.
|
||||
"""
|
||||
try:
|
||||
staff = Group.objects.get(pk=3)
|
||||
except Group.DoesNotExist:
|
||||
raise UsersError("Admin user can not be created or reset because "
|
||||
"the group 'Staff' (pk=3) is not available.")
|
||||
query_can_see_name = Q(content_type__app_label='users') & Q(codename='can_see_name')
|
||||
query_can_manage = Q(content_type__app_label='users') & Q(codename='can_manage')
|
||||
|
||||
staff, _ = Group.objects.get_or_create(name='Staff')
|
||||
staff.permissions.add(Permission.objects.get(query_can_see_name))
|
||||
staff.permissions.add(Permission.objects.get(query_can_manage))
|
||||
|
||||
admin, created = self.get_or_create(
|
||||
username='admin',
|
||||
defaults={'last_name': 'Administrator'})
|
||||
|
@ -10,9 +10,9 @@ def create_builtin_groups_and_admin(**kwargs):
|
||||
|
||||
Creates the builtin user: admin.
|
||||
"""
|
||||
# Check whether the group pk's 1 to 4 are free.
|
||||
if Group.objects.filter(pk__in=range(1, 5)).exists():
|
||||
# Do completely nothing if there are already some of our groups in the database.
|
||||
# Check whether there are groups in the database.
|
||||
if Group.objects.exists():
|
||||
# Do completely nothing if there are already some groups in the database.
|
||||
return
|
||||
|
||||
permission_strings = (
|
||||
|
@ -286,30 +286,26 @@ class UserManagerGeneratePassword(TestCase):
|
||||
for _ in range(8)])
|
||||
|
||||
|
||||
@patch('openslides.users.models.Permission')
|
||||
@patch('openslides.users.models.Group')
|
||||
class UserManagerCreateOrResetAdminUser(TestCase):
|
||||
def test_get_admin_group(self, mock_group):
|
||||
def test_add_admin_group(self, mock_group, mock_permission):
|
||||
"""
|
||||
Tests that the Group with pk=3 is added to the admin.
|
||||
Tests that the Group with name='Staff' is added to the admin.
|
||||
"""
|
||||
def mock_side_effect(pk):
|
||||
if pk == 3:
|
||||
result = 'mock_staff'
|
||||
else:
|
||||
result = ''
|
||||
return result
|
||||
|
||||
admin_user = MagicMock()
|
||||
manager = UserManager()
|
||||
manager.get_or_create = MagicMock(return_value=(admin_user, False))
|
||||
mock_group.objects.get.side_effect = mock_side_effect
|
||||
|
||||
staff_group = MagicMock(name="Staff")
|
||||
mock_group.objects.get_or_create = MagicMock(return_value=(staff_group, True))
|
||||
mock_permission.get = MagicMock()
|
||||
|
||||
manager.create_or_reset_admin_user()
|
||||
|
||||
mock_group.objects.get.assert_called_once_with(pk=3)
|
||||
admin_user.groups.add.assert_called_once_with('mock_staff')
|
||||
admin_user.groups.add.assert_called_once_with(staff_group)
|
||||
|
||||
def test_password_set_to_admin(self, mock_group):
|
||||
def test_password_set_to_admin(self, mock_group, mock_permission):
|
||||
"""
|
||||
Tests that the password of the admin is set to 'admin'.
|
||||
"""
|
||||
@ -317,6 +313,10 @@ class UserManagerCreateOrResetAdminUser(TestCase):
|
||||
manager = UserManager()
|
||||
manager.get_or_create = MagicMock(return_value=(admin_user, False))
|
||||
|
||||
staff_group = MagicMock(name="Staff")
|
||||
mock_group.objects.get_or_create = MagicMock(return_value=(staff_group, True))
|
||||
mock_permission.get = MagicMock()
|
||||
|
||||
manager.create_or_reset_admin_user()
|
||||
|
||||
self.assertEqual(
|
||||
@ -325,7 +325,7 @@ class UserManagerCreateOrResetAdminUser(TestCase):
|
||||
admin_user.save.assert_called_once_with()
|
||||
|
||||
@patch('openslides.users.models.User')
|
||||
def test_return_value(self, mock_user, mock_group):
|
||||
def test_return_value(self, mock_user, mock_group, mock_permission):
|
||||
"""
|
||||
Tests that the method returns True when a user is created.
|
||||
"""
|
||||
@ -334,6 +334,10 @@ class UserManagerCreateOrResetAdminUser(TestCase):
|
||||
manager.get_or_create = MagicMock(return_value=(admin_user, True))
|
||||
manager.model = mock_user
|
||||
|
||||
staff_group = MagicMock(name="Staff")
|
||||
mock_group.objects.get_or_create = MagicMock(return_value=(staff_group, True))
|
||||
mock_permission.get = MagicMock()
|
||||
|
||||
self.assertEqual(
|
||||
manager.create_or_reset_admin_user(),
|
||||
True,
|
||||
@ -341,7 +345,7 @@ class UserManagerCreateOrResetAdminUser(TestCase):
|
||||
"new user is created.")
|
||||
|
||||
@patch('openslides.users.models.User')
|
||||
def test_attributes_of_created_user(self, mock_user, mock_group):
|
||||
def test_attributes_of_created_user(self, mock_user, mock_group, mock_permission):
|
||||
"""
|
||||
Tests username and last_name of the created admin user.
|
||||
"""
|
||||
@ -350,6 +354,10 @@ class UserManagerCreateOrResetAdminUser(TestCase):
|
||||
manager.get_or_create = MagicMock(return_value=(admin_user, True))
|
||||
manager.model = mock_user
|
||||
|
||||
staff_group = MagicMock(name="Staff")
|
||||
mock_group.objects.get_or_create = MagicMock(return_value=(staff_group, True))
|
||||
mock_permission.get = MagicMock()
|
||||
|
||||
manager.create_or_reset_admin_user()
|
||||
|
||||
self.assertEqual(
|
||||
@ -360,3 +368,24 @@ class UserManagerCreateOrResetAdminUser(TestCase):
|
||||
admin_user.last_name,
|
||||
'Administrator',
|
||||
"The last_name of a new created admin should be 'Administrator'.")
|
||||
|
||||
def test_get_permissions(self, mock_group, mock_permission):
|
||||
"""
|
||||
Tests if two permissions are get
|
||||
"""
|
||||
admin_user = MagicMock()
|
||||
manager = UserManager()
|
||||
manager.get_or_create = MagicMock(return_value=(admin_user, True))
|
||||
|
||||
staff_group = MagicMock(name="Staff")
|
||||
mock_group.objects.get_or_create = MagicMock(return_value=(staff_group, True))
|
||||
|
||||
permission_mock = MagicMock(name="test permission")
|
||||
mock_permission.objects.get = MagicMock(return_value=permission_mock)
|
||||
|
||||
manager.create_or_reset_admin_user()
|
||||
|
||||
self.assertEqual(
|
||||
mock_permission.objects.get.call_count,
|
||||
2,
|
||||
"Permission.get should be called two times")
|
||||
|
Loading…
Reference in New Issue
Block a user