Skip to content

Commit

Permalink
Send post_migrate signal from DAB RBAC (#556)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlanCoding authored Aug 8, 2024
1 parent 6ff14f8 commit 56ead20
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 2 deletions.
11 changes: 9 additions & 2 deletions ansible_base/rbac/triggers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from django.db.models import Model, Q
from django.db.models.signals import m2m_changed, post_delete, post_init, post_save, pre_delete, pre_save
from django.db.utils import ProgrammingError
from django.dispatch import Signal

from ansible_base.rbac.caching import compute_object_role_permissions, compute_team_member_roles
from ansible_base.rbac.models import ObjectRole, RoleDefinition, RoleEvaluation, get_evaluation_model
Expand All @@ -22,6 +23,9 @@
"""


dab_post_migrate = Signal()


def team_ancestor_roles(team):
"""
Return a queryset of all roles that directly or indirectly grant any form of permission to a team.
Expand Down Expand Up @@ -270,11 +274,14 @@ def rbac_post_user_delete(instance, *args, **kwargs):
ObjectRole.objects.filter(users__isnull=True, teams__isnull=True).delete()


def post_migration_rbac_setup(*args, **kwargs):
def post_migration_rbac_setup(sender, *args, **kwargs):
try:
RoleDefinition.objects.first()
except ProgrammingError:
return # this happens when migrating backwards, tables do not exist at prior states
logger.info('Not running DAB RBAC post_migrate logic because of suspected reverse migration')
return

dab_post_migrate.send(sender=sender)

compute_team_member_roles()
compute_object_role_permissions()
Expand Down
21 changes: 21 additions & 0 deletions docs/apps/rbac/for_app_developers.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,27 @@ link via generic foreign key.
Your permission model is needed to respect your existing permissions setup,
and it needs relational links to your "actor" models (user/team).

#### Post-migrate Actions

The DAB RBAC app will create permission entries in a `post_migrate` signal.
This is expected to run _after_ any post_migrate signals from _your_ app,
because "ansible_base.rbac" needs to come later in `INSTALLED_APPS`.

Because of this, DAB RBAC sends a special signal so you can run logic after
permissions are created.

```python
from ansible_base.rbac.triggers import dab_post_migrate

dab_post_migrate.connect(my_logic, dispatch_uid="my_logic")
```

By doing this, you can write code in `my_logic` that references `DABPermission`
entries. This would be a common place to create managed RoleDefinitions, for example.

This will still rebuild the role evaluation entries afterwards.
This is so that DAB RBAC will be in a consistent state after any logic you run.

### Using in an REST API

Instead of calling methods from DAB RBAC directly, you can connect your
Expand Down
13 changes: 13 additions & 0 deletions test_app/tests/rbac/test_triggers.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
from unittest.mock import MagicMock

import pytest
from django.apps import apps
from django.test.utils import override_settings

from ansible_base.rbac.models import ObjectRole, RoleEvaluation, RoleTeamAssignment, RoleUserAssignment
from ansible_base.rbac.permission_registry import permission_registry
from ansible_base.rbac.triggers import dab_post_migrate, post_migration_rbac_setup
from test_app.models import Inventory, Organization


@pytest.mark.django_db
def test_post_migrate_signals():
mck = MagicMock()
# corresponds to docs/apps/rbac/for_app_developers.md, Post-migrate Actions
dab_post_migrate.connect(mck.ad_hoc_func, dispatch_uid="my_logic")
post_migration_rbac_setup(apps.get_app_config('dab_rbac'))
mck.ad_hoc_func.assert_called_once_with(sender=apps.get_app_config('dab_rbac'), signal=dab_post_migrate)


@pytest.mark.django_db
def test_change_parent_field(team, rando, inventory, org_inv_rd, member_rd):
member_rd.give_permission(rando, team)
Expand Down

0 comments on commit 56ead20

Please sign in to comment.