hobo/tests_multitenant/test_provisionning.py

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'