Projet

Général

Profil

0001-add-rest_framework-authentication-module-for-authent.patch

Benjamin Dauvergne, 13 novembre 2015 11:25

Télécharger (5,11 ko)

Voir les différences:

Subject: [PATCH] add rest_framework authentication module for authentic2

 hobo/rest_authentication.py                 | 42 +++++++++++++++++++++++++++++
 tests_authentic/conftest.py                 |  3 +++
 tests_authentic/test_rest_authentication.py | 41 ++++++++++++++++++++++++++++
 3 files changed, 86 insertions(+)
 create mode 100644 hobo/rest_authentication.py
 create mode 100644 tests_authentic/test_rest_authentication.py
hobo/rest_authentication.py
1
from rest_framework import authentication, exceptions
2

  
3
from hobo import signature
4

  
5
from authentic2.saml import models as saml_models
6
from django.contrib.auth import get_user_model
7
from django.conf import settings
8

  
9
class PublikAuthentication(authentication.BaseAuthentication):
10
    def resolve_user(self, request):
11
        if 'NameID' in request.GET:
12
            name_id = request.GET['NameID']
13
            User = get_user_model()
14
            try:
15
                return User.objects.get(uuid=name_id)
16
            except User.DoesNotExist:
17
                raise exceptions.AuthenticationFailed('No user matches uuid=%r' % uuid)
18
        else:
19
            raise exceptions.AuthenticationFailed('No user reference')
20
        return None
21

  
22
    def get_orig_key(self, orig):
23
        if not hasattr(settings, 'KNOWN_SERVICES'):
24
            raise exceptions.AuthenticationFailed('No KNOWN_SERVICES setting')
25
        for service_id in settings.KNOWN_SERVICES:
26
            for slug, service in settings.KNOWN_SERVICES[service_id].iteritems():
27
                if service.get('verif_orig') == orig and service.get('secret'):
28
                    return service['secret']
29
        raise exceptions.AuthenticationFailed('no secret found for origin %r' % orig)
30

  
31
    def authenticate(self, request):
32
        full_path = request.get_full_path()
33
        if not request.GET.get('orig') or not request.GET.get('signature'):
34
            return None
35
        key = self.get_orig_key(request.GET['orig'])
36
        if not signature.check_url(full_path, key):
37
            raise exceptions.AuthenticationFailed('Invalid signature')
38
        user = self.resolve_user(request)
39
        if not user:
40
            raise exceptions.AuthenticationFailed('No user reference or vuser unknown')
41
        if user:
42
            return (user, None)
tests_authentic/conftest.py
31 31
                },
32 32
                'services': [
33 33
                    {'slug': 'test',
34
                     'service-id': 'authentic',
34 35
                     'title': 'Test',
35 36
                     'this': True,
36 37
                     'secret_key': '12345',
......
41 42
                    },
42 43
                    {'slug': 'other',
43 44
                     'title': 'Other',
45
                     'service-id': 'welco',
46
                     'secret_key': 'abcdef',
44 47
                     'base_url': 'http://other.example.net'},
45 48
                    ]}, fd)
46 49
        t = Tenant(domain_url=name,
tests_authentic/test_rest_authentication.py
1
import pytest
2
import urllib
3

  
4
from rest_framework.exceptions import AuthenticationFailed
5
from django.contrib.auth import get_user_model
6
from django.test import RequestFactory
7
from tenant_schemas.utils import tenant_context
8

  
9
from hobo import signature, rest_authentication
10

  
11
pytestmark = pytest.mark.django_db
12

  
13
def test_publik_authentication(tenant, settings):
14
    with tenant_context(tenant):
15
        key = settings.KNOWN_SERVICES['welco']['other']['secret']
16

  
17
        settings.HOBO_ROLE_EXPORT = False
18
        User = get_user_model()
19
        user = User.objects.create(username='foo', password='foo')
20
        ORIG = 'other.example.net'
21
        AUTH_QUERY = '&NameID=%s&&orig=%s' % (user.uuid, urllib.quote(ORIG))
22

  
23
        URL = '/api/?coucou=zob'
24
        factory = RequestFactory()
25
        request = factory.get(signature.sign_url(URL + AUTH_QUERY, key))
26

  
27
        publik_authentication = rest_authentication.PublikAuthentication()
28
        result = publik_authentication.authenticate(request)
29
        assert result is not None
30
        assert isinstance(result, tuple)
31
        assert len(result) == 2
32
        assert result[0] == user
33
        assert result[1] == None
34

  
35
        # Failure
36
        request = factory.get(signature.sign_url(URL + AUTH_QUERY, key+'zob'))
37

  
38
        publik_authentication = rest_authentication.PublikAuthentication()
39
        with pytest.raises(AuthenticationFailed):
40
            publik_authentication.authenticate(request)
41

  
0
-