Skip to content

Commit

Permalink
Management command to refresh permission objects.
Browse files Browse the repository at this point in the history
  • Loading branch information
schwarzkrieger committed Sep 20, 2020
1 parent 108df51 commit aaa3040
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 28 deletions.
8 changes: 8 additions & 0 deletions docs/source/admin.rst
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ created
``management``, ``testcases``, ``testplans`` and ``testruns`` applications.
These are the permissions required for normal usage of Kiwi TCMS!

To ensure that all necessary permissions are assigned to the default
group (Tester) and that the stale permission objects are removed, after
the system installation or upgrade use the following management
command::

./manage.py refresh_permissions


.. important::

*Tester* is the default group to which new user accounts are assigned!
Expand Down
9 changes: 9 additions & 0 deletions docs/source/installing_docker.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ Then you need to create the first user account::

docker exec -it kiwi_web /Kiwi/manage.py createsuperuser


A special group called Tester is created during the installation. This
is the default group for testers and we do not recommend to alter or
delete it. It needs certain permissions which can be assigned by the
command::

docker exec -it kiwi_web /Kiwi/manage.py refresh_permissions


.. warning::

In the command ``docker exec`` the option ``-i`` keeps STDIN open
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
tcms.core.management.commands.refresh\_permissions module
=========================================================

.. automodule:: tcms.core.management.commands.refresh_permissions
:members:
:undoc-members:
:show-inheritance:
1 change: 1 addition & 0 deletions docs/source/modules/tcms.core.management.commands.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ Submodules
:maxdepth: 4

tcms.core.management.commands.migrations_order
tcms.core.management.commands.refresh_permissions
tcms.core.management.commands.set_domain
113 changes: 113 additions & 0 deletions tcms/core/management/commands/refresh_permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
from django.apps import apps
from django.contrib.auth.models import Group, Permission
from django.core.management import call_command
from django.core.management.base import BaseCommand


class Command(BaseCommand):
help = ('Refresh permissions for Tester group '
'(set by DEFAULT_GROUPS setting) and remove stale ones.'
)

@staticmethod
def get_all_permissions():
"""
Returns a set of all available permissions in format
app_label.perm_codename
"""
permissions = list()
for perm in Permission.objects.all():
permissions.append("%s.%s" %
(perm.content_type.app_label, perm.codename))
return set(permissions)

@staticmethod
def get_all_installed_apps():
"""
Returns a set of currently installed applications as app_labels
"""
applications = list()
for app_config in apps.get_app_configs():
applications.append(app_config.label)
return set(applications)

@staticmethod
def kiwi_apps():
"""
Returns a list of Kiwi TCMS related applications with permissions
to be assigned to Tester group
"""
kiwi_apps = ['bugs', 'django_comments', 'linkreference', 'management',
'testcases', 'testplans', 'testruns', 'attachments']
return kiwi_apps

@staticmethod
def permissions_exclude():
"""
Returns a set of permissions NOT to be assigned to Tester group
"""
perm_exclude = {'attachments.delete_foreign_attachments', }
return perm_exclude

@staticmethod
def assign_default_group_permissions(output=None, call_on_usercreate=False):
"""
Assigns default permissions for Kiwi TCMS apps to Tester group
"""
admin = Group.objects.get(name='Administrator')
all_perms = Permission.objects.all()
if call_on_usercreate and admin.permissions.count() == 0:
admin.permissions.add(*all_perms)

tester = Group.objects.get(name='Tester')
if output:
output.write('Adding permissions to Tester group\n')

permissions_to_add = list()
modify_tester = call_on_usercreate and tester.permissions.count() == 0
if modify_tester or not call_on_usercreate:
permissions_to_add = Command.get_all_permissions().difference(
Command.permissions_exclude())
for perm in permissions_to_add:
app, permission = perm.split('.')
if app in Command.kiwi_apps():
perm_obj = Permission.objects.filter(content_type__app_label=app,
codename=permission)
if tester.permissions.filter(content_type__app_label=app,
codename=permission).count() != 0:
if output:
output.write('Tester already has %s \n' % perm)
else:
tester.permissions.add(*perm_obj)
if output:
output.write('%s added' % perm)
if output:
output.write('Done.\n')

def add_arguments(self, parser):
parser.add_argument(
'--noinput', '--no-input', action='store_false',
dest='interactive',
help='Automatic mode. Does not require user input',
)

def handle(self, *args, **kwargs):
output = None
loglevel = 0
if kwargs['verbosity']:
output = self.stdout
loglevel = 2

call_command('update_permissions', '--verbosity=%i' % loglevel)

# Assign permissions to Tester group
self.assign_default_group_permissions(output=output)

# Removing stale permissions
if output:
self.stdout.write('\nRemoving stale permissions\n')
call_command('remove_stale_contenttypes', '--include-stale-apps',
'--verbosity=%i' % loglevel,
interactive=kwargs['interactive'])
if output:
self.stdout.write('Done.\n')
31 changes: 3 additions & 28 deletions tcms/utils/permissions.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,7 @@
# -*- coding: utf-8 -*-
from django.conf import settings
from django.contrib.auth.models import Group, Permission


def assign_default_group_permissions():
"""
Adds the default permissions for Administrator and Tester
groups!
"""
admin = Group.objects.get(name='Administrator')
if admin.permissions.count() == 0:
all_perms = Permission.objects.all()
admin.permissions.add(*all_perms)

tester = Group.objects.get(name='Tester')
if tester.permissions.count() == 0:
# apply all permissions for test case & product management
for app_name in ['bugs', 'django_comments', 'linkreference', 'management',
'testcases', 'testplans', 'testruns']:
app_perms = Permission.objects.filter(content_type__app_label__contains=app_name)
tester.permissions.add(*app_perms)

# this app was introduced later and we don't want all of its permissions
if tester.permissions.filter(content_type__app_label='attachments').count() == 0:
attachment_perms = Permission.objects.filter(
content_type__app_label='attachments'
).exclude(codename='delete_foreign_attachments')
tester.permissions.add(*attachment_perms)
from django.contrib.auth.models import Group
from tcms.core.management.commands.refresh_permissions import Command


def initiate_user_with_default_setups(user):
Expand All @@ -35,7 +10,7 @@ def initiate_user_with_default_setups(user):
created user.
"""
# create default permissions if not already set
assign_default_group_permissions()
Command.assign_default_group_permissions(call_on_usercreate=True)

default_groups = Group.objects.filter(name__in=settings.DEFAULT_GROUPS)
for grp in default_groups:
Expand Down

0 comments on commit aaa3040

Please sign in to comment.