Skip to content

Commit

Permalink
✅ [#1920] Add tests for DigiD/eHerkenning OIDC errors
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenbal committed Jan 9, 2024
1 parent 621d117 commit 846132f
Showing 1 changed file with 321 additions and 2 deletions.
323 changes: 321 additions & 2 deletions src/open_inwoner/accounts/tests/test_oidc_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,24 @@
from unittest.mock import patch

from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError
from django.test import TestCase, modify_settings, override_settings
from django.urls import reverse
from django.utils.translation import gettext as _

import requests_mock
from furl import furl
from mozilla_django_oidc_db.models import OpenIDConnectConfig
from pyquery import PyQuery as PQ

from digid_eherkenning_oidc_generics.models import (
OpenIDConnectDigiDConfig,
OpenIDConnectEHerkenningConfig,
)
from digid_eherkenning_oidc_generics.views import (
GENERIC_DIGID_ERROR_MSG,
GENERIC_EHERKENNING_ERROR_MSG,
)
from open_inwoner.kvk.branches import KVK_BRANCH_SESSION_VARIABLE

from ..choices import LoginTypeChoices
Expand Down Expand Up @@ -370,12 +377,12 @@ def test_logout(self, mock_get_solo):
self.assertNotIn("oidc_states", self.client.session)
self.assertNotIn("oidc_id_token", self.client.session)

def test_error_page_direct_access_forbidden(self):
def test_error_page_direct_access(self):
error_url = reverse("oidc-error")

response = self.client.get(error_url)

self.assertEqual(response.status_code, 403)
self.assertRedirects(response, reverse("login"), fetch_redirect_response=False)

@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.get_userinfo")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.store_tokens")
Expand Down Expand Up @@ -426,6 +433,162 @@ def test_error_first_cleared_after_succesful_login(

self.assertEqual(response.status_code, 403)

@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.get_userinfo")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.store_tokens")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.verify_token")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.get_token")
@patch(
"digid_eherkenning_oidc_generics.models.OpenIDConnectDigiDConfig.get_solo",
return_value=OpenIDConnectDigiDConfig(
id=1,
enabled=True,
error_message_mapping={"some mapped message": "Some Error"},
),
)
def test_login_error_message_mapped_in_config(
self,
mock_get_solo,
mock_get_token,
mock_verify_token,
mock_store_tokens,
mock_get_userinfo,
):
mock_get_userinfo.return_value = {
"sub": "some_username",
"bsn": "123456782",
}

session = self.client.session
session["oidc_states"] = {"mock": {"nonce": "nonce"}}
session.save()
callback_url = reverse("digid_oidc:callback")

# enter the login flow
callback_response = self.client.get(
callback_url,
{
"error": "access_denied",
"error_description": "some mapped message",
"state": "mock",
},
)

self.assertRedirects(
callback_response, reverse("oidc-error"), fetch_redirect_response=False
)

error_response = self.client.get(callback_response.url)

self.assertRedirects(
error_response, reverse("login"), fetch_redirect_response=False
)

login_response = self.client.get(error_response.url)
doc = PQ(login_response.content)
error_msg = doc.find(".notification__content").text()

self.assertEqual(error_msg, "Some Error")

@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.get_userinfo")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.store_tokens")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.verify_token")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.get_token")
@patch(
"digid_eherkenning_oidc_generics.models.OpenIDConnectDigiDConfig.get_solo",
return_value=OpenIDConnectDigiDConfig(id=1, enabled=True),
)
def test_login_error_message_not_mapped_in_config(
self,
mock_get_solo,
mock_get_token,
mock_verify_token,
mock_store_tokens,
mock_get_userinfo,
):
mock_get_userinfo.return_value = {
"sub": "some_username",
"bsn": "123456782",
}

session = self.client.session
session["oidc_states"] = {"mock": {"nonce": "nonce"}}
session.save()
callback_url = reverse("digid_oidc:callback")

# enter the login flow
callback_response = self.client.get(
callback_url,
{
"error": "access_denied",
"error_description": "some unmapped message",
"state": "mock",
},
)

self.assertRedirects(
callback_response, reverse("oidc-error"), fetch_redirect_response=False
)

error_response = self.client.get(callback_response.url)

self.assertRedirects(
error_response, reverse("login"), fetch_redirect_response=False
)

login_response = self.client.get(error_response.url)
doc = PQ(login_response.content)
error_msg = doc.find(".notification__content").text()

self.assertEqual(error_msg, str(GENERIC_DIGID_ERROR_MSG))

@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.get_userinfo")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.store_tokens")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.verify_token")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.get_token")
@patch(
"digid_eherkenning_oidc_generics.models.OpenIDConnectDigiDConfig.get_solo",
return_value=OpenIDConnectDigiDConfig(id=1, enabled=True),
)
def test_login_validation_error(
self,
mock_get_solo,
mock_get_token,
mock_verify_token,
mock_store_tokens,
mock_get_userinfo,
):
mock_verify_token.side_effect = ValidationError("Something went wrong")
mock_get_userinfo.return_value = {
"sub": "some_username",
"bsn": "123456782",
}

session = self.client.session
session["oidc_states"] = {"mock": {"nonce": "nonce"}}
session.save()
callback_url = reverse("digid_oidc:callback")

# enter the login flow
callback_response = self.client.get(
callback_url, {"code": "mock", "state": "mock"}
)

self.assertRedirects(
callback_response, reverse("oidc-error"), fetch_redirect_response=False
)

error_response = self.client.get(callback_response.url)

self.assertRedirects(
error_response, reverse("login"), fetch_redirect_response=False
)

login_response = self.client.get(error_response.url)
doc = PQ(login_response.content)
error_msg = doc.find(".notification__content").text()

self.assertEqual(error_msg, str(GENERIC_DIGID_ERROR_MSG))


@override_settings(ROOT_URLCONF="open_inwoner.cms.tests.urls")
class eHerkenningOIDCFlowTests(TestCase):
Expand Down Expand Up @@ -650,3 +813,159 @@ def test_error_first_cleared_after_succesful_login(
response = self.client.get(error_url)

self.assertEqual(response.status_code, 403)

@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.get_userinfo")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.store_tokens")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.verify_token")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.get_token")
@patch(
"digid_eherkenning_oidc_generics.models.OpenIDConnectEHerkenningConfig.get_solo",
return_value=OpenIDConnectEHerkenningConfig(
id=1,
enabled=True,
error_message_mapping={"some mapped message": "Some Error"},
),
)
def test_login_error_message_mapped_in_config(
self,
mock_get_solo,
mock_get_token,
mock_verify_token,
mock_store_tokens,
mock_get_userinfo,
):
mock_get_userinfo.return_value = {
"sub": "some_username",
"bsn": "123456782",
}

session = self.client.session
session["oidc_states"] = {"mock": {"nonce": "nonce"}}
session.save()
callback_url = reverse("eherkenning_oidc:callback")

# enter the login flow
callback_response = self.client.get(
callback_url,
{
"error": "access_denied",
"error_description": "some mapped message",
"state": "mock",
},
)

self.assertRedirects(
callback_response, reverse("oidc-error"), fetch_redirect_response=False
)

error_response = self.client.get(callback_response.url)

self.assertRedirects(
error_response, reverse("login"), fetch_redirect_response=False
)

login_response = self.client.get(error_response.url)
doc = PQ(login_response.content)
error_msg = doc.find(".notification__content").text()

self.assertEqual(error_msg, "Some Error")

@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.get_userinfo")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.store_tokens")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.verify_token")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.get_token")
@patch(
"digid_eherkenning_oidc_generics.models.OpenIDConnectEHerkenningConfig.get_solo",
return_value=OpenIDConnectEHerkenningConfig(id=1, enabled=True),
)
def test_login_error_message_not_mapped_in_config(
self,
mock_get_solo,
mock_get_token,
mock_verify_token,
mock_store_tokens,
mock_get_userinfo,
):
mock_get_userinfo.return_value = {
"sub": "some_username",
"bsn": "123456782",
}

session = self.client.session
session["oidc_states"] = {"mock": {"nonce": "nonce"}}
session.save()
callback_url = reverse("eherkenning_oidc:callback")

# enter the login flow
callback_response = self.client.get(
callback_url,
{
"error": "access_denied",
"error_description": "some unmapped message",
"state": "mock",
},
)

self.assertRedirects(
callback_response, reverse("oidc-error"), fetch_redirect_response=False
)

error_response = self.client.get(callback_response.url)

self.assertRedirects(
error_response, reverse("login"), fetch_redirect_response=False
)

login_response = self.client.get(error_response.url)
doc = PQ(login_response.content)
error_msg = doc.find(".notification__content").text()

self.assertEqual(error_msg, str(GENERIC_EHERKENNING_ERROR_MSG))

@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.get_userinfo")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.store_tokens")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.verify_token")
@patch("mozilla_django_oidc_db.backends.OIDCAuthenticationBackend.get_token")
@patch(
"digid_eherkenning_oidc_generics.models.OpenIDConnectEHerkenningConfig.get_solo",
return_value=OpenIDConnectEHerkenningConfig(id=1, enabled=True),
)
def test_login_validation_error(
self,
mock_get_solo,
mock_get_token,
mock_verify_token,
mock_store_tokens,
mock_get_userinfo,
):
mock_verify_token.side_effect = ValidationError("Something went wrong")
mock_get_userinfo.return_value = {
"sub": "some_username",
"bsn": "123456782",
}

session = self.client.session
session["oidc_states"] = {"mock": {"nonce": "nonce"}}
session.save()
callback_url = reverse("eherkenning_oidc:callback")

# enter the login flow
callback_response = self.client.get(
callback_url, {"code": "mock", "state": "mock"}
)

self.assertRedirects(
callback_response, reverse("oidc-error"), fetch_redirect_response=False
)

error_response = self.client.get(callback_response.url)

self.assertRedirects(
error_response, reverse("login"), fetch_redirect_response=False
)

login_response = self.client.get(error_response.url)
doc = PQ(login_response.content)
error_msg = doc.find(".notification__content").text()

self.assertEqual(error_msg, str(GENERIC_EHERKENNING_ERROR_MSG))

0 comments on commit 846132f

Please sign in to comment.