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,
|
AbstractBaseUser,
|
||||||
BaseUserManager,
|
BaseUserManager,
|
||||||
Group,
|
Group,
|
||||||
|
Permission,
|
||||||
PermissionsMixin,
|
PermissionsMixin,
|
||||||
)
|
)
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.db.models import Q
|
||||||
|
|
||||||
from openslides.utils.search import user_name_helper
|
from openslides.utils.search import user_name_helper
|
||||||
|
|
||||||
from ..core.config import config
|
from ..core.config import config
|
||||||
from ..utils.models import RESTModelMixin
|
from ..utils.models import RESTModelMixin
|
||||||
from .access_permissions import UserAccessPermissions
|
from .access_permissions import UserAccessPermissions
|
||||||
from .exceptions import UsersError
|
|
||||||
|
|
||||||
|
|
||||||
class UserManager(BaseUserManager):
|
class UserManager(BaseUserManager):
|
||||||
@ -35,13 +36,17 @@ class UserManager(BaseUserManager):
|
|||||||
"""
|
"""
|
||||||
Creates an user with the username 'admin'. If such a user already
|
Creates an user with the username 'admin'. If such a user already
|
||||||
exists, resets it. The password is (re)set to 'admin'. The user
|
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:
|
query_can_see_name = Q(content_type__app_label='users') & Q(codename='can_see_name')
|
||||||
staff = Group.objects.get(pk=3)
|
query_can_manage = Q(content_type__app_label='users') & Q(codename='can_manage')
|
||||||
except Group.DoesNotExist:
|
|
||||||
raise UsersError("Admin user can not be created or reset because "
|
staff, _ = Group.objects.get_or_create(name='Staff')
|
||||||
"the group 'Staff' (pk=3) is not available.")
|
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(
|
admin, created = self.get_or_create(
|
||||||
username='admin',
|
username='admin',
|
||||||
defaults={'last_name': 'Administrator'})
|
defaults={'last_name': 'Administrator'})
|
||||||
|
@ -10,9 +10,9 @@ def create_builtin_groups_and_admin(**kwargs):
|
|||||||
|
|
||||||
Creates the builtin user: admin.
|
Creates the builtin user: admin.
|
||||||
"""
|
"""
|
||||||
# Check whether the group pk's 1 to 4 are free.
|
# Check whether there are groups in the database.
|
||||||
if Group.objects.filter(pk__in=range(1, 5)).exists():
|
if Group.objects.exists():
|
||||||
# Do completely nothing if there are already some of our groups in the database.
|
# Do completely nothing if there are already some groups in the database.
|
||||||
return
|
return
|
||||||
|
|
||||||
permission_strings = (
|
permission_strings = (
|
||||||
|
@ -286,30 +286,26 @@ class UserManagerGeneratePassword(TestCase):
|
|||||||
for _ in range(8)])
|
for _ in range(8)])
|
||||||
|
|
||||||
|
|
||||||
|
@patch('openslides.users.models.Permission')
|
||||||
@patch('openslides.users.models.Group')
|
@patch('openslides.users.models.Group')
|
||||||
class UserManagerCreateOrResetAdminUser(TestCase):
|
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()
|
admin_user = MagicMock()
|
||||||
manager = UserManager()
|
manager = UserManager()
|
||||||
manager.get_or_create = MagicMock(return_value=(admin_user, False))
|
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()
|
manager.create_or_reset_admin_user()
|
||||||
|
|
||||||
mock_group.objects.get.assert_called_once_with(pk=3)
|
admin_user.groups.add.assert_called_once_with(staff_group)
|
||||||
admin_user.groups.add.assert_called_once_with('mock_staff')
|
|
||||||
|
|
||||||
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'.
|
Tests that the password of the admin is set to 'admin'.
|
||||||
"""
|
"""
|
||||||
@ -317,6 +313,10 @@ class UserManagerCreateOrResetAdminUser(TestCase):
|
|||||||
manager = UserManager()
|
manager = UserManager()
|
||||||
manager.get_or_create = MagicMock(return_value=(admin_user, False))
|
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()
|
manager.create_or_reset_admin_user()
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@ -325,7 +325,7 @@ class UserManagerCreateOrResetAdminUser(TestCase):
|
|||||||
admin_user.save.assert_called_once_with()
|
admin_user.save.assert_called_once_with()
|
||||||
|
|
||||||
@patch('openslides.users.models.User')
|
@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.
|
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.get_or_create = MagicMock(return_value=(admin_user, True))
|
||||||
manager.model = mock_user
|
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(
|
self.assertEqual(
|
||||||
manager.create_or_reset_admin_user(),
|
manager.create_or_reset_admin_user(),
|
||||||
True,
|
True,
|
||||||
@ -341,7 +345,7 @@ class UserManagerCreateOrResetAdminUser(TestCase):
|
|||||||
"new user is created.")
|
"new user is created.")
|
||||||
|
|
||||||
@patch('openslides.users.models.User')
|
@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.
|
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.get_or_create = MagicMock(return_value=(admin_user, True))
|
||||||
manager.model = mock_user
|
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()
|
manager.create_or_reset_admin_user()
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@ -360,3 +368,24 @@ class UserManagerCreateOrResetAdminUser(TestCase):
|
|||||||
admin_user.last_name,
|
admin_user.last_name,
|
||||||
'Administrator',
|
'Administrator',
|
||||||
"The last_name of a new created admin should be '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