Skip to content

Commit 12b210e

Browse files
committed
Add methods to import types and permissions from API
1 parent b9fce77 commit 12b210e

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed

ansible_base/rbac/models/content_type.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,21 @@ def get_for_id(self, id: int) -> "DABContentType":
165165
self._add_to_cache(self.db, ct)
166166
return ct
167167

168+
def load_remote_types(self, remote_data: list[dict]):
169+
parent_mapping: dict[django_models.Model, str] = {}
170+
for remote_type in remote_data:
171+
service = remote_type.pop('service')
172+
model = remote_type.pop('model')
173+
pct_slug = remote_type.pop('parent_content_type')
174+
ct, _ = self.get_or_create(service=service, model=model, defaults=remote_type)
175+
parent_mapping[ct] = pct_slug
176+
177+
# The parent type link needs to be filled in via a second pass
178+
for ct, pct_slug in parent_mapping.items():
179+
if pct_slug and (ct.parent_content_type_id is None or ct.parent_content_type.api_slug != pct_slug):
180+
ct.parent_content_type = DABContentType.objects.get(api_slug=pct_slug)
181+
ct.save()
182+
168183

169184
class DABContentType(django_models.Model):
170185
"""Like Django ContentType model but scoped by service."""

ansible_base/rbac/models/permission.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44
from .content_type import DABContentType
55

66

7+
class DABPermissionManager(models.Manager):
8+
def load_remote_types(self, remote_data: list[dict]):
9+
for remote_type in remote_data:
10+
codename = remote_type.pop('codename')
11+
ct_slug = remote_type.pop('content_type')
12+
ct = DABContentType.objects.get(api_slug=ct_slug)
13+
ct, _ = self.get_or_create(codename=codename, content_type=ct, defaults=remote_type)
14+
15+
716
class DABPermission(models.Model):
817
"This is a minimal copy of auth.Permission for internal use"
918

@@ -33,6 +42,8 @@ class DABPermission(models.Model):
3342
help_text=_("String to use for references to this type from other models in the API."),
3443
)
3544

45+
objects = DABPermissionManager()
46+
3647
class Meta:
3748
app_label = 'dab_rbac'
3849
verbose_name = "permission"

test_app/tests/rbac/remote/test_service_api.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
from copy import deepcopy
2+
13
import pytest
24

35
from ansible_base.lib.utils.response import get_relative_url
6+
from ansible_base.rbac.models import DABContentType, DABPermission
47

58

69
@pytest.mark.django_db
@@ -51,3 +54,48 @@ def test_role_definition_listed_as_resource(admin_api_client, org_admin_rd):
5154
assert resource_data['content_type'] == 'shared.organization'
5255
assert 'permissions' in detail.data['additional_data']
5356
assert 'aap.add_inventory' in detail.data['additional_data']['permissions']
57+
58+
59+
@pytest.mark.django_db
60+
def test_reload_types(admin_api_client):
61+
url = get_relative_url('dabcontenttype-list')
62+
response = admin_api_client.get(url + '?page_size=200', format="json")
63+
assert response.status_code == 200, response.data
64+
65+
type_list = response.data['results']
66+
original = deepcopy(type_list)
67+
68+
DABContentType.objects.all().delete() # Delete all types, see if we get them back
69+
70+
DABContentType.objects.load_remote_types(type_list)
71+
72+
response = admin_api_client.get(url + '?page_size=200', format="json")
73+
assert response.status_code == 200, response.data
74+
75+
assert response.data['results'] == original
76+
77+
78+
@pytest.mark.django_db
79+
def test_load_child_of_org():
80+
DABContentType.objects.load_remote_types([{'service': 'fooland', 'app_label': 'foop', 'model': 'fooser', 'parent_content_type': 'shared.organization'}])
81+
ct = DABContentType.objects.get(api_slug='fooland.fooser')
82+
assert ct.parent_content_type.app_label == 'test_app' # proves connection to existing
83+
84+
85+
@pytest.mark.django_db
86+
def test_reload_permissions(admin_api_client):
87+
url = get_relative_url('dabpermission-list')
88+
response = admin_api_client.get(url + '?page_size=200', format="json")
89+
assert response.status_code == 200, response.data
90+
91+
perm_list = response.data['results']
92+
original = deepcopy(perm_list)
93+
94+
DABPermission.objects.all().delete() # Delete all permissions, see if we get them back
95+
96+
DABPermission.objects.load_remote_types(perm_list)
97+
98+
response = admin_api_client.get(url + '?page_size=200', format="json")
99+
assert response.status_code == 200, response.data
100+
101+
assert response.data['results'] == original

0 commit comments

Comments
 (0)