Projet

Général

Profil

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

Paul Marillonnet, 25 janvier 2018 14:41

Télécharger (8,8 ko)

Voir les différences:

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

 src/authentic2/api_views.py |  59 ++++++++++++++++++
 tests/test_api.py           | 146 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 205 insertions(+)
src/authentic2/api_views.py
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=False,
451
        default=get_default_ou,
452
        queryset=get_ou_model().objects.all(),
453
        slug_field='slug')
454

  
455
    def check_perm(self, perm, ou=None):
456
        self.context['view'].check_perm(perm, ou)
457

  
458
    def create(self, validated_data):
459
        self.check_perm('a2_rbac.add_role', validated_data.get('ou'))
460
        return super(RoleSerializer, self).create(validated_data)
461

  
462
    def update(self, instance, validated_data):
463
        self.check_perm('a2_rbac.change_role', validated_data.get('ou'))
464
        super(RoleSerializer, self).update(instance, validated_data)
465
        return instance
466

  
467
    def partial_update(self, instance, validated_data):
468
        self.check_perm('a2_rbac.change_role', validated_data.get('ou'))
469
        super(RoleSerializer, self).partial_update(instance, validated_data)
470
        return instance
471

  
472
    class Meta:
473
        model = get_role_model()
474
        exclude = ('service', 'admin_scope_id', 'admin_scope_ct',)
475
        extra_kwargs = {'uuid': {'read_only': True}}
476

  
477

  
447 478
class UsersFilter(FilterSet):
448 479
    class Meta:
449 480
        model = get_user_model()
......
576 607
        return Response({'result': 1})
577 608

  
578 609

  
610
class RolesAPI(ExceptionHandlerMixin, ModelViewSet):
611
    permission_classes = (permissions.IsAuthenticated,)
612
    serializer_class = RoleSerializer
613
    lookup_field = 'slug'
614
    queryset = get_role_model().objects.all()
615

  
616
    def check_perm(self, perm, ou=None):
617
        if ou:
618
            if not self.request.user.has_ou_perm(perm, ou):
619
                raise PermissionDenied(u'User %s does not have permission %s in %s' % (user, perm, ou))
620
        else:
621
            if not self.request.user.has_perm(perm):
622
                raise PermissionDenied(u'User %s do not have permission %s' % (user, perm))
623

  
624
    def retrieve(self, request, *args, **kwargs):
625
        self.check_perm('a2_rbac.view_role', None)
626
        return super(RolesAPI, self).retrieve(request, *args, **kwargs)
627

  
628
    def list(self, request, *args, **kwargs):
629
        self.check_perm('a2_rbac.view_role', None)
630
        return super(RolesAPI, self).list(request, *args, **kwargs)
631

  
632
    def perform_destroy(self, instance):
633
        self.check_perm('a2_rbac.delete_role', instance.ou)
634
        super(RolesAPI, self).perform_destroy(instance)
635

  
636

  
579 637
class RoleMembershipsAPI(ExceptionHandlerMixin, APIView):
580 638
    permission_classes = (permissions.IsAuthenticated,)
581 639

  
......
620 678
router = SimpleRouter()
621 679
router.register(r'users', UsersAPI, base_name='a2-api-users')
622 680
router.register(r'ous', OrganizationalUnitAPI, base_name='a2-api-ous')
681
router.register(r'roles', RolesAPI, base_name='a2-api-roles')
623 682

  
624 683

  
625 684
class CheckPasswordSerializer(serializers.Serializer):
tests/test_api.py
668 668

  
669 669
    assert mail.to[0] == new_email
670 670
    assert 'http://testserver/accounts/change-email/verify/' in mail.body
671

  
672

  
673
def test_api_delete_role(app, superuser, simple_role):
674
    app.authorization = ('Basic', (superuser.username, superuser.username))
675
    Role = get_role_model()
676

  
677
    app.delete('/api/roles/simple-role/')
678
    assert not len(Role.objects.filter(slug='simple-role'))
679

  
680

  
681
def test_api_delete_role_unauthorized(app, simple_user, simple_role):
682
    app.authorization = ('Basic', (simple_user.username, simple_user.username))
683
    Role = get_role_model()
684

  
685
    app.delete('/api/roles/simple-role/', status=403)
686
    assert len(Role.objects.filter(slug='simple-role'))
687

  
688

  
689
def test_api_patch_role(app, superuser, simple_role):
690
    app.authorization = ('Basic', (superuser.username, superuser.username))
691
    Role = get_role_model()
692

  
693
    role_data = {
694
        'slug': 'updated-role',
695
    }
696
    resp = app.patch_json('/api/roles/simple-role/', params=role_data)
697
    assert not len(Role.objects.filter(slug='simple-role'))
698
    assert len(Role.objects.filter(slug='updated-role'))
699

  
700

  
701
def test_api_patch_role_unauthorized(app, simple_user, simple_role):
702
    app.authorization = ('Basic', (simple_user.username, simple_user.username))
703
    Role = get_role_model()
704

  
705
    role_data = {
706
        'slug': 'updated-role',
707
    }
708
    resp = app.patch_json('/api/roles/simple-role/', params=role_data, status=403)
709
    assert len(Role.objects.filter(slug='simple-role'))
710
    assert not len(Role.objects.filter(slug='updated-role'))
711

  
712

  
713
def test_api_put_role(app, superuser, simple_role, ou1):
714
    app.authorization = ('Basic', (superuser.username, superuser.username))
715
    Role = get_role_model()
716

  
717
    role_data = {
718
        'name': 'updated-role',
719
        'slug': 'updated-role',
720
        'ou': 'ou1'
721
    }
722
    resp = app.put_json('/api/roles/simple-role/', params=role_data)
723
    assert not len(Role.objects.filter(slug='simple-role'))
724
    assert len(Role.objects.filter(slug='updated-role'))
725

  
726

  
727
def test_api_put_role_unauthorized(app, simple_user, simple_role, ou1):
728
    app.authorization = ('Basic', (simple_user.username, simple_user.username))
729
    Role = get_role_model()
730

  
731
    role_data = {
732
        'name': 'updated-role',
733
        'slug': 'updated-role',
734
        'ou': 'ou1'
735
    }
736
    resp = app.put_json('/api/roles/simple-role/', params=role_data, status=403)
737
    assert len(Role.objects.filter(slug='simple-role'))
738
    assert not len(Role.objects.filter(slug='updated-role'))
739

  
740

  
741
def test_api_post_role(app, superuser, ou1):
742
    app.authorization = ('Basic', (superuser.username, superuser.username))
743

  
744
    role_data = {
745
        'slug': 'coffee-manager',
746
        'name': 'Coffee Manager',
747
        'ou': 'ou1'
748
        }
749
    resp = app.post_json('/api/roles/', params=role_data)
750
    assert isinstance(resp.json, dict)
751
    Role = get_role_model()
752

  
753
    # Check attribute values against the server's response:
754
    for key, value in role_data.items():
755
        assert key in resp.json.keys()
756
        assert value in resp.json.values()
757

  
758
    # Check attributes values against the DB:
759
    posted_role = Role.objects.get(slug='coffee-manager')
760
    assert posted_role.slug == role_data['slug']
761
    assert posted_role.name == role_data['name']
762
    assert posted_role.ou.slug == 'ou1'
763

  
764

  
765
def test_api_post_role_no_ou(app, superuser):
766
    app.authorization = ('Basic', (superuser.username, superuser.username))
767
    Role = get_role_model()
768

  
769
    role_data = {
770
        'slug': 'tea-manager',
771
        'name': 'Tea Manager',
772
        }
773
    resp = app.post_json('/api/roles/', params=role_data)
774
    new_role = Role.objects.get(slug='tea-manager')
775
    default_ou = get_default_ou()
776
    assert new_role.ou == default_ou
777

  
778

  
779
def test_api_post_role_unauthorized(app, simple_user, ou1):
780
    app.authorization = ('Basic', (simple_user.username, simple_user.username))
781
    Role = get_role_model()
782

  
783
    role_data = {
784
        'slug': 'mocca-manager',
785
        'name': 'Mocca Manager',
786
        'ou': 'ou1'
787
        }
788

  
789
    resp = app.post_json('/api/roles/', params=role_data, status=403)
790
    assert not len(Role.objects.filter(slug='mocca-manager'))
791

  
792

  
793
def test_api_get_role_description(app, superuser, role_random):
794
    app.authorization = ('Basic', (superuser.username, superuser.username))
795
    resp = app.get('/api/roles/rando/')
796

  
797
    assert resp.json['slug'] == 'rando'
798
    assert resp.json['ou'] == 'ou_rando'
799

  
800

  
801
def test_api_get_role_not_found(app, superuser):
802
    app.authorization = ('Basic', (superuser.username, superuser.username))
803
    resp = app.get('/api/roles/thisisnotavalidroleslug/', status=404)
804

  
805

  
806
def test_api_get_role_list(app, superuser, simple_role, role_random):
807
    app.authorization = ('Basic', (superuser.username, superuser.username))
808
    resp = app.get('/api/roles/')
809

  
810
    role_fields = ['slug', 'uuid', 'name', 'ou']
811

  
812
    assert len(resp.json['results'])
813

  
814
    for role_dict in resp.json['results']:
815
        for field in role_fields:
816
            assert field in role_dict
671
-