Skip to content

Commit

Permalink
[config] Add a config file for permission groups
Browse files Browse the repository at this point in the history
Moves the configuration of the groups to sortinghat/config/permission_groups.json.
The location of the file can be changed with the
`SORTINGHAT_PERMISSION_GROUPS_LIST_PATH` environment variable.

Signed-off-by: Eva Millán <evamillan@bitergia.com>
  • Loading branch information
evamillan committed Jul 11, 2024
1 parent cc1fb16 commit 99faf1b
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 56 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,15 @@ Options:
--no-interactive Run the command in no interactive mode.
```

## Assign users to permission groups
A user in a group automatically has the permissions granted to that group. To assign users to a permission group use the following command:
```
$ sortinghat-admin set-user-group username group
```

The list of groups can be customized using the configuration file `sortinghat/config/permission_groups.json`. You can use a different json file using the environment variable `SORTINGHAT_PERMISSION_GROUPS_LIST_PATH`.


## Compatibility between versions
SortingHat 0.7.x is no longer supported. Any database using this version will not work.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: Assign users to permission groups
category: added
author: Eva Millán <evamillan@bitergia.com>
issue: 849
notes: |
Users can be assigned to a permission group using the command
`$ sortinghat-admin set-user-group username group`. A user in
a group automatically has the permissions granted to that group.
62 changes: 62 additions & 0 deletions sortinghat/config/permission_groups.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"groups": {
"admin": {
"core": {
"affiliationrecommendation": ["add", "change", "delete", "view"],
"alias": ["add", "change", "delete", "view"],
"country": ["add", "change", "delete", "view"],
"domain": ["add", "change", "delete", "view"],
"enrollment": ["add", "change", "delete", "view"],
"genderrecommendation": ["add", "change", "delete", "view"],
"group": ["add", "change", "delete", "view"],
"identity": ["add", "change", "delete", "view"],
"individual": ["add", "change", "delete", "view"],
"mergerecommendation": ["add", "change", "delete", "view"],
"organization": ["add", "change", "delete", "view"],
"profile": ["add", "change", "delete", "view"],
"recommenderexclusionterm": ["add", "change", "delete", "view"],
"scheduledtask": ["add", "change", "delete", "view"],
"team": ["add", "change", "delete", "view"],
"custompermissions": ["execute_job"]
}
},
"user": {
"core": {
"affiliationrecommendation": ["add", "change", "delete", "view"],
"alias": ["add", "change", "delete", "view"],
"country": ["add", "change", "delete", "view"],
"domain": ["add", "change", "delete", "view"],
"enrollment": ["add", "change", "delete", "view"],
"genderrecommendation": ["add", "change", "delete", "view"],
"group": ["add", "change", "delete", "view"],
"identity": ["add", "change", "delete", "view"],
"individual": ["add", "change", "delete", "view"],
"mergerecommendation": ["add", "change", "delete", "view"],
"organization": ["add", "change", "delete", "view"],
"profile": ["add", "change", "delete", "view"],
"recommenderexclusionterm": ["add", "change", "delete", "view"],
"scheduledtask": ["view"],
"team": ["add", "change", "delete", "view"]
}
},
"readonly": {
"core": {
"affiliationrecommendation": ["view"],
"alias": ["view"],
"country": ["view"],
"domain": ["view"],
"enrollment": ["view"],
"genderrecommendation": ["view"],
"group": ["view"],
"identity": ["view"],
"individual": ["view"],
"mergerecommendation": ["view"],
"organization": ["view"],
"profile": ["view"],
"recommenderexclusionterm": ["view"],
"scheduledtask": ["view"],
"team": ["view"]
}
}
}
}
9 changes: 9 additions & 0 deletions sortinghat/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,3 +364,12 @@
#

SORTINGHAT_GENDERIZE_API_KEY = os.environ.get('SORTINGHAT_GENDERIZE_API_KEY', None)

#
# Path of the permission groups configuration file
#
# https://docs.djangoproject.com/en/5.0/topics/auth/default/#groups
#

PERMISSION_GROUPS_LIST_PATH = os.environ.get('SORTINGHAT_PERMISSION_GROUPS_LIST_PATH',
os.path.join(BASE_DIR, 'config', 'permission_groups.json'))
80 changes: 25 additions & 55 deletions sortinghat/core/management/commands/create_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,48 +20,16 @@
#

import logging
import json

from django.conf import settings
from django.core.management import BaseCommand
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.db import DEFAULT_DB_ALIAS

logger = logging.getLogger(__name__)

SORTINGHAT_PERMISSION_GROUPS = {
"admin": {
"admin": {
"logentry": ["add", "change", "delete", "view"]
},
"auth": {
"group": ["add", "change", "delete", "view"],
"permission": ["add", "change", "delete", "view"],
"user": ["add", "change", "delete", "view"]
},
"contenttypes": {
"contenttype": ["add", "change", "delete", "view"]
},
"core": {
"country": ["add", "change", "delete", "view"],
"domain": ["add", "change", "delete", "view"],
"enrollment": ["add", "change", "delete", "view"],
"identity": ["add", "change", "delete", "view"],
"organization": ["add", "change", "delete", "view"],
"profile": ["add", "change", "delete", "view"],
"operation": ["add", "change", "delete", "view"],
"transaction": ["add", "change", "delete", "view"],
"individual": ["add", "change", "delete", "view"],
"team": ["add", "change", "delete", "view"],
"recommenderexclusionterm": ["add", "change", "delete", "view"],
"group": ["add", "change", "delete", "view"],
"custompermissions": ["execute_job"]
},
"sessions": {
"session": ["add", "change", "delete", "view"]
}
}
}


class Command(BaseCommand):
help = "Create groups with the chosen permissions"
Expand All @@ -74,25 +42,27 @@ def add_arguments(self, parser):
)

def handle(self, *args, **options):
for group_name, content_types in SORTINGHAT_PERMISSION_GROUPS.items():
new_group, created = Group.objects.using(options['database']).get_or_create(name=group_name)
with open(settings.PERMISSION_GROUPS_LIST_PATH, 'r') as f:
groups = json.load(f).get('groups', [])
for group_name, content_types in groups.items():
new_group, created = Group.objects.using(options['database']).get_or_create(name=group_name)

for app_label, models in content_types.items():
for model, permissions in models.items():
try:
content_type = ContentType.objects.using(options['database'])\
.get(app_label=app_label, model=model)
for permission_name in permissions:
codename = f"{permission_name}_{model}"
if model == "custompermissions":
codename = permission_name
try:
permission = Permission.objects.using(options['database'])\
.get(codename=codename, content_type=content_type)
new_group.permissions.add(permission)
except Permission.DoesNotExist:
logger.warning(f"Permission {permission_name} not found")
continue
except ContentType.DoesNotExist:
logger.warning(f"ContentType {model} not found in {app_label}")
continue
for app_label, models in content_types.items():
for model, permissions in models.items():
try:
content_type = ContentType.objects.using(options['database'])\
.get(app_label=app_label, model=model)
for permission_name in permissions:
codename = f"{permission_name}_{model}"
if model == "custompermissions":
codename = permission_name
try:
permission = Permission.objects.using(options['database'])\
.get(codename=codename, content_type=content_type)
new_group.permissions.add(permission)
except Permission.DoesNotExist:
logger.warning(f"Permission {permission_name} not found")
continue
except ContentType.DoesNotExist:
logger.warning(f"ContentType {model} not found in {app_label}")
continue
2 changes: 1 addition & 1 deletion sortinghat/core/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -1423,7 +1423,7 @@ class Arguments:

job_id = graphene.Field(lambda: graphene.String)

@check_permissions(['core.add_importidentitiestask'])
@check_permissions(['core.execute_job'])
def mutate(self, info, backend, url, params=None):
user = info.context.user
tenant = get_db_tenant()
Expand Down
1 change: 1 addition & 0 deletions sortinghat/server/sortinghat_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ def upgrade(no_database):
_setup_database(database=database)

_install_static_files()
_setup_group_permissions(database='default')

click.secho("SortingHat upgrade completed", fg='bright_cyan')

Expand Down

0 comments on commit 99faf1b

Please sign in to comment.