Projet

Général

Profil

0001-role-api-add-extra-role-attributes-21488.patch

Paul Marillonnet, 18 avril 2018 10:29

Télécharger (6,81 ko)

Voir les différences:

Subject: [PATCH] role api: add extra role attributes (#21488)

 src/authentic2/api_views.py | 26 +++++++++++++++++++++++--
 tests/conftest.py           | 13 +++++++++++++
 tests/test_api.py           | 38 +++++++++++++++++++++++++++++++++++++
 3 files changed, 75 insertions(+), 2 deletions(-)
src/authentic2/api_views.py
22 22
from rest_framework.exceptions import PermissionDenied, AuthenticationFailed
23 23
from rest_framework.fields import CreateOnlyDefault
24 24
from rest_framework.decorators import list_route, detail_route
25
from rest_framework.utils import model_meta
25 26

  
26 27
from django_filters.rest_framework import FilterSet
27 28

  
28 29
from .custom_user.models import User
29 30
from . import utils, decorators, attribute_kinds, app_settings, hooks
30 31
from .models import Attribute, PasswordReset
32
from .a2_rbac.models import RoleAttribute
31 33
from .a2_rbac.utils import get_default_ou
32 34

  
33 35

  
......
444 446
        exclude = ('date_joined', 'user_permissions', 'groups', 'last_login')
445 447

  
446 448

  
449
class RoleAttributeSerializer(serializers.ModelSerializer):
450
    class Meta:
451
        model = RoleAttribute
452
        fields = ('name', 'kind', 'value')
453

  
454

  
447 455
class RoleSerializer(serializers.ModelSerializer):
448 456
    ou = serializers.SlugRelatedField(
449 457
        many=False,
......
451 459
        default=CreateOnlyDefault(get_default_ou),
452 460
        queryset=get_ou_model().objects.all(),
453 461
        slug_field='slug')
462
    role_attributes = RoleAttributeSerializer(
463
        many=True,
464
        read_only=False,
465
        required=False)
454 466

  
455 467
    @property
456 468
    def user(self):
......
463 475

  
464 476
    def create(self, validated_data):
465 477
        ou = validated_data.get('ou')
478
        if 'role_attributes' in validated_data:
479
            role_attributes_data = validated_data.pop('role_attributes')
480
        else:
481
            role_attributes_data = ()
466 482
        # Creating roles also means being allowed to within the OU:
467 483
        if not self.user.has_ou_perm('a2_rbac.add_role', ou):
468 484
            raise PermissionDenied(u'User %s can\'t create role in OU %s' % (self.user, ou))
469
        return super(RoleSerializer, self).create(validated_data)
485

  
486
        instance = self.Meta.model.objects.create(**validated_data)
487

  
488
        # Create additional RoleAttribute objects:
489
        for attribute_data in role_attributes_data:
490
            RoleAttribute.objects.create(role=instance, **attribute_data)
491
        return instance
470 492

  
471 493
    def update(self, instance, validated_data):
472 494
        # Check role-updating permissions:
......
484 506

  
485 507
    class Meta:
486 508
        model = get_role_model()
487
        fields = ('uuid', 'name', 'slug', 'ou',)
509
        fields = ('uuid', 'name', 'slug', 'ou', 'role_attributes')
488 510
        extra_kwargs = {'uuid': {'read_only': True}}
489 511

  
490 512

  
tests/conftest.py
13 13
from pytest_django.migrations import DisableMigrations
14 14

  
15 15
from authentic2.a2_rbac.utils import get_default_ou
16
from authentic2.a2_rbac.models import RoleAttribute
16 17
from authentic2_idp_oidc.models import OIDCClient
17 18
from authentic2.authentication import OIDCUser
18 19

  
......
144 145
    return Role.objects.create(name='rando', slug='rando', ou=ou_rando)
145 146

  
146 147

  
148
@pytest.fixture
149
def role_attribute_details(db, role_random):
150
    return RoleAttribute.objects.create(role=role_random, name='details',
151
            kind='string', value='list')
152

  
153

  
154
@pytest.fixture
155
def role_attribute_emails(db, role_random):
156
    return RoleAttribute.objects.create(role=role_random, name='emails',
157
            kind='string', value='list')
158

  
159

  
147 160
@pytest.fixture
148 161
def role_ou1(db, ou1):
149 162
    return Role.objects.create(name='role_ou1', slug='role_ou1', ou=ou1)
tests/test_api.py
10 10
from django.contrib.auth import get_user_model
11 11
from django.contrib.contenttypes.models import ContentType
12 12
from authentic2.a2_rbac.utils import get_default_ou
13
from authentic2.a2_rbac.models import RoleAttribute
13 14
from django_rbac.utils import get_role_model, get_ou_model
14 15
from django_rbac.models import SEARCH_OP
15 16
from authentic2.models import Service
......
18 19

  
19 20
from authentic2_idp_oidc.models import OIDCClient
20 21

  
22

  
21 23
from utils import login, basic_authorization_header, get_link_from_mail
22 24

  
23 25
pytestmark = pytest.mark.django_db
......
767 769
    assert role.ou.slug == role_data['ou']
768 770

  
769 771

  
772
def test_api_role_extra_attributes(app, admin_ou1, ou1):
773
    app.authorization = ('Basic', (admin_ou1.username, admin_ou1.username))
774

  
775
    role_data = {
776
        'slug': 'coffee-manager',
777
        'name': 'Coffee Manager',
778
        'ou': 'ou1',
779
        'role_attributes': [{
780
            'name': 'details',
781
            'kind': 'string',
782
            'value': 'nodetails'
783
        },
784
        {
785
            'name': 'emails',
786
            'kind': 'string',
787
            'value': 'foo@email.none'
788
        }]
789
    }
790
    resp = app.post_json('/api/roles/', params=role_data)
791
    assert isinstance(resp.json, dict)
792

  
793
    uuid = resp.json['uuid']
794
    role = get_role_model().objects.get(uuid=uuid)
795
    role_attributes = RoleAttribute.objects.filter(role=role)
796

  
797
    # Check extra role attributes :
798
    assert len(role_attributes) == 2
799

  
800

  
770 801
def test_api_post_role_no_ou(app, superuser):
771 802
    app.authorization = ('Basic', (superuser.username, superuser.username))
772 803
    Role = get_role_model()
......
803 834
    assert resp.json['ou'] == 'ou_rando'
804 835

  
805 836

  
837
def test_api_get_role_attributes(app, admin_rando_role, role_random, role_attribute_details, role_attribute_emails):
838
    app.authorization = ('Basic', (admin_rando_role.username, admin_rando_role.username))
839
    resp = app.get('/api/roles/{}/'.format(role_random.uuid))
840

  
841
    assert len(RoleAttribute.objects.filter(role=role_random)) == 2
842

  
843

  
806 844
def test_api_get_role_not_found(app, superuser):
807 845
    app.authorization = ('Basic', (superuser.username, superuser.username))
808 846
    app.get('/api/roles/thisisnotavalidroleslug/', status=404)
809
-