Skip to content

Commit e97bbac

Browse files
committed
Allow running loading method twice
1 parent bc50221 commit e97bbac

File tree

3 files changed

+37
-22
lines changed

3 files changed

+37
-22
lines changed

ansible_base/rbac/models/content_type.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@ def get_for_id(self, id: int) -> django_models.Model:
176176

177177
def load_remote_objects(self, remote_data: list[dict]):
178178
parent_mapping: dict[django_models.Model, str] = {}
179-
for remote_type in remote_data:
179+
for remote_type_raw in remote_data:
180+
remote_type = remote_type_raw.copy()
180181
service = remote_type.pop('service')
181182
model = remote_type.pop('model')
182183
pct_slug = remote_type.pop('parent_content_type')
@@ -281,7 +282,12 @@ def model_class(self) -> Union[Type[django_models.Model], Type[RemoteObject]]:
281282

282283
return get_remote_standin_class(self)
283284

284-
return apps.get_model(self.app_label, self.model)
285+
try:
286+
return apps.get_model(self.app_label, self.model)
287+
except LookupError as exc:
288+
raise LookupError(
289+
f'Could not find ({self.app_label}, {self.model}), expected in local service={get_local_resource_prefix()} ' f'object service={self.service}'
290+
) from exc
285291

286292
def get_object_for_this_type(self, **kwargs: Any) -> Union[django_models.Model, RemoteObject]:
287293
"""Return the object referenced by this content type."""

ansible_base/rbac/models/permission.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ def load_remote_objects(self, remote_data: list[dict], update_managed=False):
1616
update_managed being True will refresh the managed roles like Organization Admin
1717
so that if the algorithm includes any new permissions, those are added.
1818
"""
19-
for remote_type in remote_data:
20-
codename = remote_type.pop('codename')
21-
ct_slug = remote_type.pop('content_type')
19+
for remote_perm_raw in remote_data:
20+
remote_perm = remote_perm_raw.copy()
21+
codename = remote_perm.pop('codename')
22+
ct_slug = remote_perm.pop('content_type')
2223
ct = DABContentType.objects.get(api_slug=ct_slug)
23-
ct, _ = self.get_or_create(codename=codename, content_type=ct, defaults=remote_type)
24+
ct, _ = self.get_or_create(codename=codename, content_type=ct, defaults=remote_perm)
2425

2526
if update_managed:
2627
from ansible_base.rbac import permission_registry

test_app/tests/rbac/remote/test_managed_role_remote_perms.py

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,43 +16,51 @@ def test_remote_permissions_on_create(foo_permission):
1616

1717
@pytest.mark.django_db
1818
def test_remote_permission_refresh(foo_type):
19-
rd = RoleDefinition.objects.managed.org_admin
19+
org_admin_rd = RoleDefinition.objects.managed.org_admin
20+
auditor_rd = RoleDefinition.objects.managed.sys_auditor
2021

2122
foo_permission = DABPermission.objects.create(codename='foo_foo', content_type=foo_type)
23+
view_foo = DABPermission.objects.create(codename='view_foo', content_type=foo_type)
2224

2325
# the foo_permission was created after the managed role
2426
# so the role is not explicitly created
25-
assert foo_permission not in rd.permissions.all()
27+
assert foo_permission not in org_admin_rd.permissions.all()
28+
assert view_foo not in auditor_rd.permissions.all()
2629

2730
# Loading it requires the refresh call
2831
permission_registry.create_managed_roles(apps, update_perms=True)
29-
assert foo_permission in rd.permissions.all()
32+
assert foo_permission in org_admin_rd.permissions.all()
33+
assert view_foo in auditor_rd.permissions.all()
34+
35+
# calling multiple times should be okay
36+
permission_registry.create_managed_roles(apps, update_perms=True)
3037

3138

3239
@pytest.mark.django_db
3340
def test_remote_permission_load_update_roles():
3441
rd = RoleDefinition.objects.managed.org_admin
35-
DABContentType.objects.load_remote_objects(
36-
[
37-
{'service': 'fooland', 'app_label': 'foo', 'model': 'foo', 'api_slug': 'fooland.foo', 'parent_content_type': 'shared.organization'},
38-
{'service': 'fooland', 'app_label': 'foo', 'model': 'bar', 'api_slug': 'fooland.bar', 'parent_content_type': None},
39-
]
40-
)
42+
remote_types = [
43+
{'service': 'fooland', 'app_label': 'foo', 'model': 'foo', 'api_slug': 'fooland.foo', 'parent_content_type': 'shared.organization'},
44+
{'service': 'fooland', 'app_label': 'foo', 'model': 'bar', 'api_slug': 'fooland.bar', 'parent_content_type': None},
45+
]
46+
DABContentType.objects.load_remote_objects(remote_types)
4147
assert not DABPermission.objects.filter(codename='foo_foo').exists()
42-
DABPermission.objects.load_remote_objects(
43-
[
44-
{'codename': 'foo_foo', 'content_type': 'fooland.foo', 'api_slug': "fooland.foo_foo"},
45-
{'codename': 'bar_bar', 'content_type': 'fooland.bar', 'api_slug': "fooland.bar_bar"},
46-
],
47-
update_managed=True,
48-
)
48+
remote_perms = [
49+
{'codename': 'foo_foo', 'content_type': 'fooland.foo', 'api_slug': "fooland.foo_foo"},
50+
{'codename': 'bar_bar', 'content_type': 'fooland.bar', 'api_slug': "fooland.bar_bar"},
51+
]
52+
DABPermission.objects.load_remote_objects(remote_perms, update_managed=True)
4953
assert DABPermission.objects.filter(codename='foo_foo').exists()
5054

5155
foo_permission = DABPermission.objects.get(codename='foo_foo')
5256
bar_permission = DABPermission.objects.get(codename='bar_bar')
5357
assert foo_permission in rd.permissions.all()
5458
assert bar_permission not in rd.permissions.all() # not child type of organization
5559

60+
# calling twice should be fine
61+
DABContentType.objects.load_remote_objects(remote_types)
62+
DABPermission.objects.load_remote_objects(remote_perms, update_managed=True)
63+
5664

5765
@pytest.mark.django_db
5866
def test_remote_permission_duplicate_name():

0 commit comments

Comments
 (0)