CentreForDigitalHumanities / CentreForDigitalHumanities/langpro-annotator

Missing permission warnings when migrating

Open
#65 1 comment 1 reaction 0 assignees View on GitHub
bug help wanted
Dominant language
TypeScript
Stars
0
Forks
0
Avg merge
7d 5h
Merged PRs (30d)
4

Description

If I start with an empty database and try to run [this migration](https://github.com/CentreForDigitalHumanities/langpro-annotator/blob/develop/backend/user/migrations/0004_create_user_groups.py), my console is flooded with warnings such as `ContentType for problem.knowledgebase does not exist. Cannot add permission ('problem', 'add_knowledgebase') to group Master Annotators.`

My guess is that this is because Django only creates the permissions after the migrations have run.

The migrations themselves 'pass' and there is an easy workaround for the now missing permissions: unapply and reapply the migration in question with

```py
python manage.py migrate user 0003
python manage.py migrate
```

Still, it would be nicer to avoid having to do this manual step, especially since the warnings are easily missed.

One solution would be to create the relevant permissions themselves within the migration, i.e. update `create_groups` to:

```py
def create_groups(apps, schema_editor):
"""
Creates user groups for annotators and master annotators and assigns permissions to them.
"""
Group = apps.get_model("auth", "Group")
Permission = apps.get_model("auth", "Permission")
ContentType = apps.get_model("contenttypes", "ContentType")

problem_model_name = apps.get_model("problem", "Problem")._meta.model_name
knowledgebase_model_name = apps.get_model("problem", "KnowledgeBase")._meta.model_name
ContentType.objects.get_or_create(app_label="problem", model=problem_model_name)
ContentType.objects.get_or_create(app_label="problem", model=knowledgebase_model_name)

for group_name, perms in PERMISSION_MAP.items():
group, created = Group.objects.get_or_create(name=group_name.value)
for perm_codename in perms:
app_label, codename = perm_codename

# Determine which model this permission is for
if 'knowledgebase' in codename:
model_name = knowledgebase_model_name
else:
model_name = problem_model_name

try:
content_type = ContentType.objects.get(app_label=app_label, model=model_name)
permission, _ = Permission.objects.get_or_create(
content_type=content_type,
codename=codename,
defaults={'name': f'Can {codename.replace("_", " ")}'},
)
group.permissions.add(permission)
except ContentType.DoesNotExist:
print(
f"ContentType for {app_label}.{model_name} does not exist. Cannot add permission {perm_codename} to group {group_name.value}."
)
except Exception as e:
print(
f"Error adding permission {perm_codename} to group {group_name.value}: {e}"
)
```

This works, but it requires maintenance if we add permissions for more models, for instance. It also feels clunky to create permissions ourselves when Django is about to do that for us.

An alternative would be to use fixtures instead of data migrations. We can store the permission data as JSON and use Django's `loaddata` to populate a new database after migrations have run. This is how we do it in DIAPP, for instance, and I think it works well for this static/initial data that we need to load in.

What do you think @jgonggrijp ?

Contributor guide

Open the contributing guide

Research direction

Read backend/user/migrations/0004_create_user_groups.py, especially create_groups and PERMISSION_MAP, then reproduce the warnings on an empty database with the migration commands described. Done means a fresh migration creates the groups and permissions without missing-permission warnings, without requiring manual unapplication and reapplication.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
authorization, backend, database
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.