0001-WIP-add-role-creation-api-20706.patch
src/authentic2/api_urls.py | ||
---|---|---|
13 | 13 |
api_views.role_memberships, name='a2-api-role-member'), |
14 | 14 |
url(r'^check-password/$', api_views.check_password, |
15 | 15 |
name='a2-api-check-password'), |
16 |
url(r'^ous/(?P<ou>[\w+]*)/roles/', |
|
17 |
api_views.roles, name='a2-api-role'), |
|
16 | 18 |
) |
17 | 19 |
urlpatterns += api_views.router.urls |
src/authentic2/api_views.py | ||
---|---|---|
4 | 4 | |
5 | 5 |
from django.db import models |
6 | 6 |
from django.contrib.auth import get_user_model |
7 |
from django.core.exceptions import MultipleObjectsReturned |
|
7 |
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
|
|
8 | 8 |
from django.utils.translation import ugettext as _ |
9 | 9 |
from django.views.decorators.vary import vary_on_headers |
10 | 10 |
from django.views.decorators.cache import cache_control |
... | ... | |
27 | 27 | |
28 | 28 |
from .custom_user.models import User |
29 | 29 |
from . import utils, decorators, attribute_kinds, app_settings, hooks |
30 |
from .models import Attribute, PasswordReset |
|
30 |
from .models import Attribute, PasswordReset, Service
|
|
31 | 31 |
from .a2_rbac.utils import get_default_ou |
32 | 32 | |
33 | 33 | |
... | ... | |
444 | 444 |
exclude = ('date_joined', 'user_permissions', 'groups', 'last_login') |
445 | 445 | |
446 | 446 | |
447 |
class RoleSerializer(serializers.ModelSerializer): |
|
448 |
ou = serializers.SlugRelatedField( |
|
449 |
many=False, |
|
450 |
required=True, |
|
451 |
queryset=get_ou_model().objects.all(), |
|
452 |
slug_field='slug') |
|
453 |
uuid = serializers.CharField(required=True) |
|
454 |
name = serializers.CharField(required=True) |
|
455 |
slug = serializers.CharField(required=True) # TODO? slugify from name? |
|
456 |
service = serializers.SlugRelatedField( |
|
457 |
many=False, |
|
458 |
required=False, |
|
459 |
queryset=Service.objects.all(), |
|
460 |
slug_field='slug') |
|
461 |
admin_scope_id = serializers.IntegerField(required=True, allow_null=True) |
|
462 |
# admin_scope_ct = serializers.IntegerField(required=True, allow_null=True) # XXX todo |
|
463 | ||
464 |
def __init__(self, *args, **kwargs): |
|
465 |
super(RoleSerializer, self).__init__(*args, **kwargs) |
|
466 |
request = kwargs['context'].get('request') |
|
467 |
if hasattr(request, 'parser_context'): |
|
468 |
ou = request.parser_context.get('kwargs', {}).get('ou') |
|
469 |
kwargs['data']['ou'] = ou |
|
470 | ||
471 |
""" |
|
472 |
# XXX That one won't fix the OU FK dereferencing issue while saving |
|
473 |
def create(self, validated_data): |
|
474 |
Role = get_role_model() |
|
475 |
role = Role(**validated_data) # Necessary to created to FK linking to OU? Nope |
|
476 |
self.instance = role |
|
477 |
self.instance.save() # XXX Broken!! role.ou not saved in DB?! |
|
478 |
return role |
|
479 |
""" |
|
480 | ||
481 |
""" |
|
482 |
# XXX That one won't fix it either, as it's not a data validation issue |
|
483 |
def validate(self, data, *args, **kwargs): |
|
484 |
logger = logging.getLogger(__name__) |
|
485 |
data = super(RoleSerializer, self).validate(data, *args, **kwargs) |
|
486 |
Role = get_role_model() |
|
487 |
if len(Role.objects.filter(slug=data['slug'])): |
|
488 |
logger.error('error: role already existing in the A2 database') |
|
489 |
return |
|
490 |
import pdb; pdb.set_trace() |
|
491 |
return data |
|
492 |
""" |
|
493 | ||
494 |
class Meta: |
|
495 |
model = get_role_model() |
|
496 |
fields = ['uuid', 'name', 'slug', 'ou', |
|
497 |
'admin_scope_id', 'service'] |
|
498 | ||
499 | ||
447 | 500 |
class UsersFilter(FilterSet): |
448 | 501 |
class Meta: |
449 | 502 |
model = get_user_model() |
... | ... | |
576 | 629 |
return Response({'result': 1}) |
577 | 630 | |
578 | 631 | |
632 |
class RolesAPI(ExceptionHandlerMixin, ModelViewSet): |
|
633 |
permission_classes = (permissions.IsAuthenticated,) |
|
634 |
serializer_class = RoleSerializer |
|
635 | ||
636 |
roles = RolesAPI.as_view({'post': 'create'}) |
|
637 | ||
638 | ||
579 | 639 |
class RoleMembershipsAPI(ExceptionHandlerMixin, APIView): |
580 | 640 |
permission_classes = (permissions.IsAuthenticated,) |
581 | 641 |
tests/conftest.py | ||
---|---|---|
14 | 14 |
from authentic2.a2_rbac.utils import get_default_ou |
15 | 15 |
from authentic2_idp_oidc.models import OIDCClient |
16 | 16 |
from authentic2.authentication import OIDCUser |
17 |
from authentic2.models import Service |
|
17 | 18 | |
18 | 19 |
import utils |
19 | 20 | |
... | ... | |
46 | 47 |
return OU.objects.create(name='ou_rando', slug='ou_rando') |
47 | 48 | |
48 | 49 | |
50 |
@pytest.fixture |
|
51 |
def service1(db): |
|
52 |
return Service.objects.create(name='Service1', slug='service1') |
|
53 | ||
54 | ||
49 | 55 |
def create_user(**kwargs): |
50 | 56 |
User = get_user_model() |
51 | 57 |
password = kwargs.pop('password', None) or kwargs['username'] |
tests/test_api.py | ||
---|---|---|
30 | 30 |
assert 'username' in resp.json |
31 | 31 | |
32 | 32 | |
33 |
def test_api_role_simple(app, user, ou1, service1): |
|
34 |
role_data = { |
|
35 |
'slug': 'coffee-manager', |
|
36 |
'service': 'service1', |
|
37 |
'uuid': 'RhFactor001', |
|
38 |
'name': 'Coffee Manager', |
|
39 |
'admin_scope_id': 2 |
|
40 |
} |
|
41 |
# 'admin_scope_ct': 1, # TODO |
|
42 |
app.authorization = ('Basic', (user.username, user.username)) |
|
43 |
resp = app.post_json('/api/ous/ou1/roles/', params=role_data) |
|
44 |
assert isinstance(resp.json, dict) |
|
45 |
Role = get_role_model() |
|
46 |
posted_role = Role.objects.get(slug='coffee-manager') |
|
47 |
for key, value in role_data.items(): |
|
48 |
assert key in resp.json.keys() |
|
49 |
assert value in resp.json.values() |
|
50 | ||
51 |
assert posted_role.slug == role_data['slug'] |
|
52 |
assert posted_role.uuid == role_data['uuid'] |
|
53 |
assert posted_role.name == role_data['name'] |
|
54 |
assert posted_role.admin_scope_id == role_data['admin_scope_id'] |
|
55 | ||
56 |
assert posted_role.ou.slug == 'ou1' |
|
57 |
assert posted_role.service.slug == role_data['service'] |
|
58 | ||
59 | ||
33 | 60 |
def test_api_user(client): |
34 | 61 |
# create an user, an ou role, a service and a service role |
35 | 62 |
ou = get_default_ou() |
36 |
- |