141 lines
4.4 KiB
Python
141 lines
4.4 KiB
Python
import json
|
|
|
|
import pytest
|
|
import requests
|
|
from httmock import HTTMock, urlmatch
|
|
from mellon.models import Issuer
|
|
from rest_framework import permissions
|
|
from rest_framework.response import Response
|
|
from rest_framework.views import APIView
|
|
|
|
from hobo import rest_authentication, signature
|
|
from hobo.provisionning.utils import (
|
|
NotificationProcessing,
|
|
ProvisionningTemporaryError,
|
|
get_or_create_user_from_name_id,
|
|
get_user_from_name_id,
|
|
)
|
|
|
|
|
|
def test_truncate_role_name():
|
|
seen = set()
|
|
max_length = NotificationProcessing.group_name_max_length
|
|
|
|
assert max_length == 150 # value on Django 2.2
|
|
|
|
for length in range(max_length - 10, max_length):
|
|
name = 'a' * length
|
|
truncated = NotificationProcessing.truncate_role_name(name)
|
|
assert len(truncated) == length
|
|
assert truncated not in seen
|
|
seen.add(truncated)
|
|
|
|
for length in range(max_length + 1, max_length + 10):
|
|
name = 'a' * length
|
|
truncated = NotificationProcessing.truncate_role_name(name)
|
|
assert len(truncated) == max_length
|
|
assert truncated not in seen
|
|
seen.add(truncated)
|
|
|
|
|
|
@urlmatch()
|
|
def request_exception(url, request):
|
|
raise requests.ConnectionError
|
|
|
|
|
|
NAME_ID = '1234' * 8
|
|
|
|
|
|
@urlmatch(path='/api/users/')
|
|
def user_payload(url, request):
|
|
return {
|
|
'status_code': 200,
|
|
'content': json.dumps(
|
|
{
|
|
'uuid': NAME_ID,
|
|
'first_name': 'John',
|
|
'last_name': 'Doe',
|
|
'email': 'john.doe@example.net',
|
|
'is_superuser': False,
|
|
'is_active': True,
|
|
}
|
|
),
|
|
}
|
|
|
|
|
|
@urlmatch(path='/api/users/')
|
|
def error_404(url, request):
|
|
return {
|
|
'status_code': 404,
|
|
}
|
|
|
|
|
|
def test_get_or_create_user_from_name_id(tenant, django_user_model):
|
|
Issuer.objects.create(entity_id='https://idp.examle.net/idp/saml2/metadata')
|
|
|
|
assert get_user_from_name_id(NAME_ID) is None
|
|
with pytest.raises(django_user_model.DoesNotExist):
|
|
get_user_from_name_id(NAME_ID, raise_on_missing=True)
|
|
|
|
with HTTMock(request_exception):
|
|
assert get_or_create_user_from_name_id(NAME_ID) is None
|
|
with pytest.raises(ProvisionningTemporaryError):
|
|
get_or_create_user_from_name_id(NAME_ID, raise_on_missing=True)
|
|
|
|
with HTTMock(error_404):
|
|
assert get_or_create_user_from_name_id(NAME_ID) is None
|
|
with pytest.raises(django_user_model.DoesNotExist):
|
|
get_or_create_user_from_name_id(NAME_ID, raise_on_missing=True)
|
|
|
|
with HTTMock(user_payload):
|
|
user = get_or_create_user_from_name_id(NAME_ID)
|
|
assert user is not None
|
|
assert user.first_name == 'John'
|
|
assert user.username == NAME_ID
|
|
assert user.saml_identifiers.get().name_id == NAME_ID
|
|
assert django_user_model.objects.count() == 1
|
|
|
|
|
|
class DummyAPIView(APIView):
|
|
authentication_classes = (rest_authentication.PublikAuthentication,)
|
|
permission_classes = (permissions.IsAuthenticated,)
|
|
|
|
def get(self, request, format=None):
|
|
return Response({'err': 0})
|
|
|
|
|
|
def test_rest_authentication_provisionning_ok(tenant, settings, rf, django_user_model):
|
|
key = settings.KNOWN_SERVICES['combo']['another2']['secret']
|
|
request = rf.get(signature.sign_url('/api/misc/?param1=2&NameID=%s&orig=portal-user.example.net', key))
|
|
|
|
view = DummyAPIView.as_view()
|
|
|
|
with HTTMock(user_payload):
|
|
response = view(request)
|
|
assert response.status_code == 200
|
|
assert response.data == {'err': 0}
|
|
user = django_user_model.objects.get()
|
|
assert user.first_name == 'John'
|
|
assert user.username == NAME_ID
|
|
assert user.saml_identifiers.get().name_id == NAME_ID
|
|
|
|
|
|
def test_rest_authentication_provisionning_nok(tenant, settings, rf):
|
|
key = settings.KNOWN_SERVICES['combo']['another2']['secret']
|
|
request = rf.get(signature.sign_url('/api/misc/?param1=2&NameID=abcd&orig=portal-user.example.net', key))
|
|
|
|
view = DummyAPIView.as_view()
|
|
|
|
with HTTMock(request_exception):
|
|
response = view(request)
|
|
assert response.status_code == 500
|
|
assert response.data['err'] == 1
|
|
assert response.data['err_class'] == 'idp-not-reachable'
|
|
assert 'ConnectionError' in response.data['err_desc']
|
|
|
|
with HTTMock(error_404):
|
|
response = view(request)
|
|
assert response.status_code == 401
|
|
assert response.data['err'] == 1
|
|
assert response.data['err_class'] == 'user-not-found'
|