Projet

Général

Profil

0001-WIP-add-role-creation-api-20706.patch

Paul Marillonnet, 16 janvier 2018 18:06

Télécharger (6,21 ko)

Voir les différences:

Subject: [PATCH] WIP add role creation api (#20706)

 src/authentic2/api_urls.py  |  2 ++
 src/authentic2/api_views.py | 83 ++++++++++++++++++++++++++++++++++++++++++++-
 tests/test_api.py           | 22 ++++++++++++
 3 files changed, 106 insertions(+), 1 deletion(-)
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_id_or_slug>[\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
......
444 444
        exclude = ('date_joined', 'user_permissions', 'groups', 'last_login')
445 445

  
446 446

  
447
class RoleSerializer(serializers.ModelSerializer):
448
    """
449
    TODO
450
    ou = serializers.SlugRelatedField(
451
        queryset=get_ou_model().objects.all(),
452
        serializer=BaseOrganizationalUnitSerializer,
453
        slug_field='slug',
454
        default=get_default_ou)
455
    """
456
    ou_id_or_slug = serializers.CharField(required=True)
457
    uuid = serializers.CharField(required=True)
458
    name = serializers.CharField(required=True)
459
    slug = serializers.CharField(required=True)  # TODO? slugify from name?
460
    # service = serializers.CharField(required=True, allow_null=True) # TODO
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_id_or_slug = request.parser_context.get('kwargs', {}).get('ou_id_or_slug')
469
        kwargs['data']['ou_id_or_slug'] = ou_id_or_slug
470

  
471
    def create(self, validated_data):
472
        logger = logging.getLogger(__name__)
473
        try:
474
            Role = get_role_model()
475
            ou_id_or_slug = validated_data['ou_id_or_slug']
476

  
477
            if len(Role.objects.filter(slug=validated_data['slug'])):
478
                logger.error('error: role already existing in the A2 database')
479
                return
480

  
481
            role = Role.objects.create()
482

  
483
            for role_field in set(self.Meta.fields) - {'service', 'ou', 'admin_scope_ct'}:
484
                setattr(role, role_field, validated_data.get(role_field))
485

  
486
            OU = get_ou_model()
487
            # try first on the OU uuid then on its slug
488
            try:
489
                ou = OU.objects.get(uuid=ou_id_or_slug)
490
            except (MultipleObjectsReturned, ObjectDoesNotExist) as e:
491
                ou = OU.objects.get(slug=ou_id_or_slug)
492
            role.ou = ou
493
            self.instance = role
494
            self.instance.save()
495
            logger.info('Role %r created.', role)
496

  
497
        except Exception as e:
498
            logger.error('couldn\'t create role: %r', e)
499
            return None
500
        return role
501

  
502
    def validate(self, data, *args, **kwargs):
503
        Role = get_role_model()
504
        qs = Role.objects.all()
505
        ou = None
506
        if self.instance:
507
            ou = self.instance.ou
508
        if 'ou' in data and not ou:
509
            ou = data['ou']
510
        # XXX which role-specific validation?
511
        #     admin-scope content type & identifier ?
512
        return data
513

  
514
    class Meta:
515
        model = get_role_model()
516
        fields = ['uuid', 'name', 'slug', 'ou_id_or_slug',
517
                  'admin_scope_id']
518
        # exclude = ['admin_scope_ct', 'service']
519

  
520

  
447 521
class UsersFilter(FilterSet):
448 522
    class Meta:
449 523
        model = get_user_model()
......
576 650
        return Response({'result': 1})
577 651

  
578 652

  
653
class RolesAPI(ExceptionHandlerMixin, ModelViewSet):
654
    permission_classes = (permissions.IsAuthenticated,)
655
    serializer_class = RoleSerializer
656

  
657
roles = RolesAPI.as_view({'post': 'create'})
658

  
659

  
579 660
class RoleMembershipsAPI(ExceptionHandlerMixin, APIView):
580 661
    permission_classes = (permissions.IsAuthenticated,)
581 662

  
tests/test_api.py
30 30
    assert 'username' in resp.json
31 31

  
32 32

  
33
def test_api_role_simple(app, user):
34
    OU = get_ou_model()
35
    epsilon = OU.objects.create(name='OU Epsilon', slug='epsilon')
36
    role_data = {
37
        'slug': 'soma-officer',
38
        'uuid': 'H1GH',
39
        'name': 'Soma Officer',
40
        'admin_scope_id': 2
41
        }
42
    # 'service': 'default', # TODO
43
    # 'admin_scope_ct': 1, # TODO
44
    app.authorization = ('Basic', (user.username, user.username))
45
    resp = app.post_json('/api/ous/epsilon/roles/', params=role_data)
46
    assert isinstance(resp.json, dict)
47
    Role = get_role_model()
48
    posted_role = Role.objects.get(slug='soma-officer')
49
    for key, value in role_data.items():
50
        assert key in resp.json.keys()
51
        assert value in resp.json.values()
52
        assert getattr(posted_role, key) == value
53

  
54

  
33 55
def test_api_user(client):
34 56
    # create an user, an ou role, a service and a service role
35 57
    ou = get_default_ou()
36
-