Skip to content

Commit 9c5cdcc

Browse files
committed
Add user and team sync endpoints
1 parent 6910c02 commit 9c5cdcc

File tree

4 files changed

+94
-2
lines changed

4 files changed

+94
-2
lines changed

ansible_base/rbac/service_api/router.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@
66

77
service_router.register(r'role-types', views.RoleContentTypeViewSet)
88
service_router.register(r'role-permissions', views.RolePermissionTypeViewSet)
9+
# Different basenames used to distinguish between the duplicate, public, endpoints
10+
service_router.register(r'role-user-assignments', views.ServiceRoleUserAssignmentViewSet, basename='serviceuserassignment')
11+
service_router.register(r'role-team-assignments', views.ServiceRoleTeamAssignmentViewSet, basename='serviceteamassignment')

ansible_base/rbac/service_api/serializers.py

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from rest_framework import serializers
22

3-
from ..models import DABContentType, DABPermission
3+
from ..models import DABContentType, DABPermission, RoleTeamAssignment, RoleUserAssignment
4+
from ..remote import RemoteObject
45

56

67
class DABContentTypeSerializer(serializers.ModelSerializer):
@@ -17,3 +18,46 @@ class DABPermissionSerializer(serializers.ModelSerializer):
1718
class Meta:
1819
model = DABPermission
1920
fields = ['api_slug', 'codename', 'content_type', 'name']
21+
22+
23+
assignment_common_fields = ('created', 'created_by_ansible_id', 'object_id', 'object_ansible_id', 'content_type', 'role_definition')
24+
25+
26+
class BaseAssignmentSerializer(serializers.ModelSerializer):
27+
content_type = serializers.SlugRelatedField(read_only=True, slug_field='api_slug')
28+
role_definition = serializers.SlugRelatedField(read_only=True, slug_field='name')
29+
created_by_ansible_id = serializers.SerializerMethodField()
30+
object_ansible_id = serializers.SerializerMethodField()
31+
32+
def get_created_by_ansible_id(self, obj):
33+
return str(obj.created_by.resource.ansible_id)
34+
35+
def get_object_ansible_id(self, obj):
36+
content_object = obj.content_object
37+
if isinstance(content_object, RemoteObject):
38+
return None
39+
if hasattr(content_object, 'resource'):
40+
return str(content_object.resource.ansible_id)
41+
return None
42+
43+
44+
class RoleUserAssignmentSerializer(BaseAssignmentSerializer):
45+
user_ansible_id = serializers.SerializerMethodField()
46+
47+
class Meta:
48+
model = RoleUserAssignment
49+
fields = assignment_common_fields + ('user_ansible_id',)
50+
51+
def get_user_ansible_id(self, obj):
52+
return str(obj.user.resource.ansible_id)
53+
54+
55+
class RoleTeamAssignmentSerializer(BaseAssignmentSerializer):
56+
user_ansible_id = serializers.SerializerMethodField()
57+
58+
class Meta:
59+
model = RoleTeamAssignment
60+
fields = assignment_common_fields + ('team_ansible_id',)
61+
62+
def get_team_ansible_id(self, obj):
63+
return str(obj.team.resource.ansible_id)

ansible_base/rbac/service_api/views.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from ansible_base.lib.utils.views.django_app_api import AnsibleBaseDjangoAppApiView
44

5-
from ..models import DABContentType, DABPermission
5+
from ..models import DABContentType, DABPermission, RoleTeamAssignment, RoleUserAssignment
66
from . import serializers as service_serializers
77

88

@@ -26,3 +26,31 @@ class RolePermissionTypeViewSet(
2626

2727
queryset = DABPermission.objects.prefetch_related('content_type').all()
2828
serializer_class = service_serializers.DABPermissionSerializer
29+
30+
31+
# NOTE: role definitions are exchanged via the resources endpoint, so not included here
32+
33+
34+
prefetch_related = ('created_by__resource', 'content_type', 'role_definition')
35+
36+
37+
class ServiceRoleUserAssignmentViewSet(
38+
AnsibleBaseDjangoAppApiView,
39+
mixins.ListModelMixin,
40+
GenericViewSet,
41+
):
42+
"""List of assignments for cross-service communication"""
43+
44+
queryset = RoleUserAssignment.objects.prefetch_related('user__resource', *prefetch_related)
45+
serializer_class = service_serializers.RoleUserAssignmentSerializer
46+
47+
48+
class ServiceRoleTeamAssignmentViewSet(
49+
AnsibleBaseDjangoAppApiView,
50+
mixins.ListModelMixin,
51+
GenericViewSet,
52+
):
53+
"""List of team role assignments for cross-service communication"""
54+
55+
queryset = RoleTeamAssignment.objects.prefetch_related('team__resource', *prefetch_related)
56+
serializer_class = service_serializers.RoleTeamAssignmentSerializer

test_app/tests/rbac/remote/test_service_api.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,20 @@ def test_reload_permissions(admin_api_client):
9999
assert response.status_code == 200, response.data
100100

101101
assert response.data['results'] == original
102+
103+
104+
@pytest.mark.django_db
105+
def test_list_role_user_assignments(admin_api_client, rando, inv_rd, inventory):
106+
inv_rd.give_permission(rando, inventory)
107+
108+
url = get_relative_url('serviceuserassignment-list')
109+
response = admin_api_client.get(url + '?page_size=200', format="json")
110+
assert response.status_code == 200, response.data
111+
112+
candidates = [assignment for assignment in response.data['results'] if assignment['role_definition'] == inv_rd.name]
113+
assert len(candidates) == 1, response.data
114+
from_api = candidates[0]
115+
116+
assert int(from_api['object_id']) == inventory.id
117+
assert from_api['user_ansible_id'] == str(rando.resource.ansible_id)
118+
assert from_api['content_type'] == 'aap.inventory'

0 commit comments

Comments
 (0)