Skip to content

Commit

Permalink
Management command to refresh permission objects.
Browse files Browse the repository at this point in the history
Closes #1137
  • Loading branch information
schwarzkrieger committed Aug 21, 2020
1 parent e980a6f commit b788a46
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 28 deletions.
7 changes: 7 additions & 0 deletions docs/source/admin.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ created
``linkreference``, ``testcases``, ``testplans`` and ``testruns``
applications.

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


Adding a group
^^^^^^^^^^^^^^
Expand Down
10 changes: 10 additions & 0 deletions docs/source/installing_docker.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ 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 Expand Up @@ -121,6 +129,8 @@ To upgrade running Kiwi TCMS containers execute the following commands::
docker pull centos/mariadb-103-centos7 # to fetch the latest MariaDB
docker-compose up -d
docker exec -it kiwi_web /Kiwi/manage.py migrate
docker exec -it kiwi_web /Kiwi/manage.py refresh_permissions


.. warning::

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
115 changes: 115 additions & 0 deletions tcms/core/management/commands/refresh_permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
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 and remove '
'stale ones. Use -v 0 to suppress most of the '
'console output'
)

@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, assign_if_none=False):
"""
Assigns default permissions for Kiwi TCMS apps to Tester group
"""
if assign_if_none:
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')

for perm in Command.get_all_permissions().difference(
Command.permissions_exclude()):
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)

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

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

# Adding permissions to Tester group
self.stdout.write('Adding permissions to Tester group')
self.assign_default_group_permissions(output=output)
self.stdout.write('Done.')

# Removing stale permissions
self.stdout.write('\nRemoving stale permissions')
for perm in self.get_all_permissions():
app, permission = perm.split('.')
if app not in self.get_all_installed_apps():
confirm = ''
if not kwargs['noinput']:
confirm = input('%s seems stale. Delete? y/N: ' % perm) # nosec
if confirm.lower() == 'y' or kwargs['noinput']:
perm_obj = Permission.objects.filter(content_type__app_label=app,
codename=permission)
perm_obj.delete()
if kwargs['verbosity']:
self.stdout.write('%s removed\n' % perm)
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(assign_if_none=True)

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

0 comments on commit b788a46

Please sign in to comment.