Skip to content

Commit d1433df

Browse files
committed
Add endpoints for types and permissions
1 parent 0517e71 commit d1433df

File tree

6 files changed

+122
-0
lines changed

6 files changed

+122
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from ansible_base.lib.routers import AssociationResourceRouter
2+
3+
from . import views
4+
5+
service_router = AssociationResourceRouter()
6+
7+
service_router.register(r'role-types', views.RoleContentTypeViewSet)
8+
service_router.register(r'role-permissions', views.RolePermissionTypeViewSet)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from rest_framework import serializers
2+
3+
from ..models import DABContentType, DABPermission
4+
5+
6+
class DABContentTypeSerializer(serializers.ModelSerializer):
7+
parent_content_type = serializers.SlugRelatedField(read_only=True, slug_field='api_slug')
8+
9+
class Meta:
10+
model = DABContentType
11+
fields = ['api_slug', 'service', 'app_label', 'model', 'parent_content_type', 'pk_field_type']
12+
13+
14+
class DABPermissionSerializer(serializers.ModelSerializer):
15+
content_type = serializers.SlugRelatedField(read_only=True, slug_field='api_slug')
16+
17+
class Meta:
18+
model = DABPermission
19+
fields = ['api_slug', 'codename', 'content_type', 'name']
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from rest_framework.viewsets import GenericViewSet, mixins
2+
3+
from ansible_base.lib.utils.views.django_app_api import AnsibleBaseDjangoAppApiView
4+
5+
from ..models import DABContentType, DABPermission
6+
from . import serializers as service_serializers
7+
8+
9+
class RoleContentTypeViewSet(
10+
AnsibleBaseDjangoAppApiView,
11+
mixins.ListModelMixin,
12+
GenericViewSet,
13+
):
14+
"""List of types registered with the RBAC system, or loaded in from external system"""
15+
16+
queryset = DABContentType.objects.prefetch_related('parent_content_type').all()
17+
serializer_class = service_serializers.DABContentTypeSerializer
18+
19+
20+
class RolePermissionTypeViewSet(
21+
AnsibleBaseDjangoAppApiView,
22+
mixins.ListModelMixin,
23+
GenericViewSet,
24+
):
25+
"""List of permissions managed with the RBAC system"""
26+
27+
queryset = DABPermission.objects.prefetch_related('content_type').all()
28+
serializer_class = service_serializers.DABPermissionSerializer

ansible_base/rbac/urls.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,18 @@
44
from ansible_base.rbac.api.views import RoleMetadataView
55
from ansible_base.rbac.apps import AnsibleRBACConfig
66

7+
from .service_api.router import service_router
8+
79
app_name = AnsibleRBACConfig.label
810

11+
12+
service_urls = [
13+
path('', include(service_router.urls)),
14+
]
15+
916
api_version_urls = [
1017
path('', include(router.urls)),
18+
path('service-index/', include(service_urls)),
1119
path(r'role_metadata/', RoleMetadataView.as_view(), name="role-metadata"),
1220
]
1321

test_app/tests/rbac/remote/test_public_api_compat.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,28 @@ def test_create_remote_role_definition(admin_api_client, foo_type, foo_permissio
2828
assert response.status_code == 201, response.data
2929
assert response.data['name'] == 'foo-foo-foo-custom'
3030
assert response.data['permissions'] == ['foo.foo_foo']
31+
32+
33+
# TODO: check that assignment endpoint works
34+
35+
# @pytest.mark.django_db
36+
# def test_give_remote_permission(rando, foo_type, foo_permission, foo_rd):
37+
# assert foo_type.service == 'foo' # a place, a domain, a server, known as foo
38+
# assert foo_type.api_slug == 'foo.foo' # there lives a foo in foo
39+
40+
# assert foo_permission.api_slug == 'foo.foo_foo' # expression of the ability that one may foo a foo
41+
42+
# a_foo = RemoteObject(content_type=foo_type, object_id=42)
43+
# assignment = foo_rd.give_permission(rando, a_foo)
44+
45+
# assignment = RoleUserAssignment.objects.get(pk=assignment.pk)
46+
# assert isinstance(assignment.content_object, RemoteObject)
47+
48+
# # We can do evaluation querysets, but these can not return objects, just id values
49+
# assert set(foo_type.model_class().access_ids_qs(actor=rando, codename='foo')) == {(int(assignment.object_id),)}
50+
51+
# # Test that user-attached methods also work
52+
# assert rando.has_obj_perm(a_foo, 'foo')
53+
# with pytest.raises(RuntimeError) as exc:
54+
# assert not rando.has_obj_perm(a_foo, 'bar') # not a valid permission
55+
# assert 'The permission bar_foo is not valid for model foo' in str(exc)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import pytest
2+
3+
from ansible_base.lib.utils.response import get_relative_url
4+
5+
6+
@pytest.mark.django_db
7+
def test_get_resource_list(admin_api_client):
8+
url = get_relative_url('dabcontenttype-list')
9+
response = admin_api_client.get(url, format="json")
10+
assert response.status_code == 200, response.data
11+
type_data = {t['api_slug']: t for t in response.data['results']}
12+
13+
assert 'shared.organization' in type_data
14+
org_data = type_data['shared.organization']
15+
assert org_data['parent_content_type'] is None
16+
assert org_data['service'] == 'shared'
17+
assert org_data['model'] == 'organization'
18+
19+
assert 'aap.inventory' in type_data
20+
inv_data = type_data['aap.inventory']
21+
assert inv_data['parent_content_type'] == 'shared.organization'
22+
23+
24+
@pytest.mark.django_db
25+
def test_get_permission_list(admin_api_client):
26+
url = get_relative_url('dabpermission-list')
27+
response = admin_api_client.get(url + '?page_size=200', format="json")
28+
assert response.status_code == 200, response.data
29+
type_data = {t['api_slug']: t for t in response.data['results']}
30+
31+
assert 'shared.change_organization' in type_data
32+
change_org_data = type_data['shared.change_organization']
33+
assert change_org_data['content_type'] == 'shared.organization'
34+
assert change_org_data['codename'] == 'change_organization'

0 commit comments

Comments
 (0)