Changeset View
Changeset View
Standalone View
Standalone View
swh/web/tests/auth/test_api_auth.py
# Copyright (C) 2020 The Software Heritage developers | # Copyright (C) 2020 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU Affero General Public License version 3, or any later version | # License: GNU Affero General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
import pytest | import pytest | ||||
from django.contrib.auth.models import AnonymousUser, User | from django.contrib.auth.models import AnonymousUser, User | ||||
from swh.web.auth.models import OIDCUser | from swh.web.auth.models import OIDCUser | ||||
from swh.web.common.utils import reverse | from swh.web.common.utils import reverse | ||||
from swh.web.tests.utils import check_api_get_responses, check_http_get_response | |||||
from . import sample_data | from . import sample_data | ||||
from .keycloak_mock import mock_keycloak | from .keycloak_mock import mock_keycloak | ||||
@pytest.mark.django_db | @pytest.mark.django_db | ||||
def test_drf_django_session_auth_success(mocker, client): | def test_drf_django_session_auth_success(mocker, client): | ||||
""" | """ | ||||
Check user gets authenticated when querying the web api | Check user gets authenticated when querying the web api | ||||
through a web browser. | through a web browser. | ||||
""" | """ | ||||
url = reverse("api-1-stat-counters") | url = reverse("api-1-stat-counters") | ||||
mock_keycloak(mocker) | mock_keycloak(mocker) | ||||
client.login(code="", code_verifier="", redirect_uri="") | client.login(code="", code_verifier="", redirect_uri="") | ||||
response = client.get(url) | response = check_http_get_response(client, url, status_code=200) | ||||
request = response.wsgi_request | request = response.wsgi_request | ||||
assert response.status_code == 200 | |||||
# user should be authenticated | # user should be authenticated | ||||
assert isinstance(request.user, OIDCUser) | assert isinstance(request.user, OIDCUser) | ||||
# check remoter used has not been saved to Django database | # check remoter used has not been saved to Django database | ||||
with pytest.raises(User.DoesNotExist): | with pytest.raises(User.DoesNotExist): | ||||
User.objects.get(username=request.user.username) | User.objects.get(username=request.user.username) | ||||
@pytest.mark.django_db | @pytest.mark.django_db | ||||
def test_drf_oidc_bearer_token_auth_success(mocker, api_client): | def test_drf_oidc_bearer_token_auth_success(mocker, api_client): | ||||
""" | """ | ||||
Check user gets authenticated when querying the web api | Check user gets authenticated when querying the web api | ||||
through an HTTP client using bearer token authentication. | through an HTTP client using bearer token authentication. | ||||
""" | """ | ||||
url = reverse("api-1-stat-counters") | url = reverse("api-1-stat-counters") | ||||
refresh_token = sample_data.oidc_profile["refresh_token"] | refresh_token = sample_data.oidc_profile["refresh_token"] | ||||
mock_keycloak(mocker) | mock_keycloak(mocker) | ||||
api_client.credentials(HTTP_AUTHORIZATION=f"Bearer {refresh_token}") | api_client.credentials(HTTP_AUTHORIZATION=f"Bearer {refresh_token}") | ||||
response = api_client.get(url) | response = check_api_get_responses(api_client, url, status_code=200) | ||||
request = response.wsgi_request | request = response.wsgi_request | ||||
assert response.status_code == 200 | |||||
# user should be authenticated | # user should be authenticated | ||||
assert isinstance(request.user, OIDCUser) | assert isinstance(request.user, OIDCUser) | ||||
# check remoter used has not been saved to Django database | # check remoter used has not been saved to Django database | ||||
with pytest.raises(User.DoesNotExist): | with pytest.raises(User.DoesNotExist): | ||||
User.objects.get(username=request.user.username) | User.objects.get(username=request.user.username) | ||||
@pytest.mark.django_db | @pytest.mark.django_db | ||||
def test_drf_oidc_bearer_token_auth_failure(mocker, api_client): | def test_drf_oidc_bearer_token_auth_failure(mocker, api_client): | ||||
url = reverse("api-1-stat-counters") | url = reverse("api-1-stat-counters") | ||||
refresh_token = sample_data.oidc_profile["refresh_token"] | refresh_token = sample_data.oidc_profile["refresh_token"] | ||||
# check for failed authentication but with expected token format | # check for failed authentication but with expected token format | ||||
mock_keycloak(mocker, auth_success=False) | mock_keycloak(mocker, auth_success=False) | ||||
api_client.credentials(HTTP_AUTHORIZATION=f"Bearer {refresh_token}") | api_client.credentials(HTTP_AUTHORIZATION=f"Bearer {refresh_token}") | ||||
response = api_client.get(url) | response = check_api_get_responses(api_client, url, status_code=403) | ||||
request = response.wsgi_request | request = response.wsgi_request | ||||
assert response.status_code == 403 | |||||
assert isinstance(request.user, AnonymousUser) | assert isinstance(request.user, AnonymousUser) | ||||
# check for failed authentication when token format is invalid | # check for failed authentication when token format is invalid | ||||
api_client.credentials(HTTP_AUTHORIZATION="Bearer invalid-token-format-ééàà") | api_client.credentials(HTTP_AUTHORIZATION="Bearer invalid-token-format-ééàà") | ||||
response = api_client.get(url) | response = check_api_get_responses(api_client, url, status_code=400) | ||||
request = response.wsgi_request | request = response.wsgi_request | ||||
assert response.status_code == 400 | |||||
assert isinstance(request.user, AnonymousUser) | assert isinstance(request.user, AnonymousUser) | ||||
def test_drf_oidc_auth_invalid_or_missing_authorization_type(api_client): | def test_drf_oidc_auth_invalid_or_missing_authorization_type(api_client): | ||||
url = reverse("api-1-stat-counters") | url = reverse("api-1-stat-counters") | ||||
refresh_token = sample_data.oidc_profile["refresh_token"] | refresh_token = sample_data.oidc_profile["refresh_token"] | ||||
# missing authorization type | # missing authorization type | ||||
api_client.credentials(HTTP_AUTHORIZATION=f"{refresh_token}") | api_client.credentials(HTTP_AUTHORIZATION=f"{refresh_token}") | ||||
response = api_client.get(url) | response = check_api_get_responses(api_client, url, status_code=403) | ||||
request = response.wsgi_request | request = response.wsgi_request | ||||
assert response.status_code == 403 | |||||
assert isinstance(request.user, AnonymousUser) | assert isinstance(request.user, AnonymousUser) | ||||
# invalid authorization type | # invalid authorization type | ||||
api_client.credentials(HTTP_AUTHORIZATION="Foo token") | api_client.credentials(HTTP_AUTHORIZATION="Foo token") | ||||
response = api_client.get(url) | response = check_api_get_responses(api_client, url, status_code=403) | ||||
request = response.wsgi_request | request = response.wsgi_request | ||||
assert response.status_code == 403 | |||||
assert isinstance(request.user, AnonymousUser) | assert isinstance(request.user, AnonymousUser) |