-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #107 from maykinmedia/feature/102-system-checks
Add system checks to the library
- Loading branch information
Showing
5 changed files
with
202 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import inspect | ||
from collections.abc import Sequence | ||
from typing import Any | ||
|
||
from django.apps import AppConfig | ||
from django.conf import settings | ||
from django.core.checks import CheckMessage, Error, Warning, register | ||
from django.utils.module_loading import import_string | ||
|
||
from .views import OIDCCallbackView, OIDCInit | ||
|
||
|
||
def _do_check( | ||
app_configs: Sequence[AppConfig] | None, | ||
dotted_path: Any, | ||
type_error: Error, | ||
subclass_reference: type, | ||
subclass_warning: Warning, | ||
) -> list[CheckMessage]: | ||
if not ( | ||
app_configs is None | ||
or any(config.name == "mozilla_django_oidc_db" for config in app_configs) | ||
): | ||
return [] | ||
|
||
if not isinstance(dotted_path, str): | ||
return [type_error] | ||
|
||
view_cls = import_string(dotted_path) | ||
if not inspect.isclass(view_cls) or not issubclass(view_cls, subclass_reference): | ||
return [subclass_warning] | ||
|
||
return [] | ||
|
||
|
||
@register() | ||
def check_authenticate_class( | ||
*, app_configs: Sequence[AppConfig] | None, **kwargs | ||
) -> list[CheckMessage]: | ||
type_error = Error( | ||
"'settings.OIDC_AUTHENTICATE_CLASS' must be a string that can be imported.", | ||
hint=( | ||
"Use 'mozilla_django_oidc_db.views.OIDCAuthenticationRequestView' or a " | ||
"subclass of 'mozilla_django_oidc_db.views.OIDCInit'." | ||
), | ||
id="mozilla_django_oidc_db.E001", | ||
) | ||
subclass_warning = Warning( | ||
"'settings.OIDC_AUTHENTICATE_CLASS' should be a subclass of 'OIDCInit'.", | ||
hint=( | ||
"Use 'mozilla_django_oidc_db.views.OIDCAuthenticationRequestView' or a " | ||
"subclass of 'mozilla_django_oidc_db.views.OIDCInit'." | ||
), | ||
id="mozilla_django_oidc_db.W001", | ||
) | ||
|
||
return _do_check( | ||
app_configs, | ||
settings.OIDC_AUTHENTICATE_CLASS, | ||
type_error=type_error, | ||
subclass_reference=OIDCInit, | ||
subclass_warning=subclass_warning, | ||
) | ||
|
||
|
||
@register() | ||
def check_callback_class( | ||
*, app_configs: Sequence[AppConfig] | None, **kwargs | ||
) -> list[CheckMessage]: | ||
type_error = Error( | ||
"'settings.OIDC_CALLBACK_CLASS' must be a string that can be imported.", | ||
hint=( | ||
"Use 'mozilla_django_oidc_db.views.OIDCCallbackView' or a " | ||
"subclass of it." | ||
), | ||
id="mozilla_django_oidc_db.E002", | ||
) | ||
subclass_warning = Warning( | ||
"'settings.OIDC_CALLBACK_CLASS' should be a subclass of 'OIDCInit'.", | ||
hint=( | ||
"Use 'mozilla_django_oidc_db.views.OIDCCallbackView' or a " | ||
"subclass of it." | ||
), | ||
id="mozilla_django_oidc_db.W002", | ||
) | ||
|
||
return _do_check( | ||
app_configs, | ||
settings.OIDC_CALLBACK_CLASS, | ||
type_error=type_error, | ||
subclass_reference=OIDCCallbackView, | ||
subclass_warning=subclass_warning, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
from django.apps import apps | ||
from django.core.checks import Error, Warning | ||
|
||
import pytest | ||
|
||
from mozilla_django_oidc_db.checks import check_authenticate_class, check_callback_class | ||
|
||
|
||
@pytest.fixture(scope="session") | ||
def app_configs(): | ||
app_config = apps.get_app_config(app_label="mozilla_django_oidc_db") | ||
return [app_config] | ||
|
||
|
||
def test_nothing_reported_when_checking_other_app_label(settings): | ||
settings.OIDC_AUTHENTICATE_CLASS = object() # this is invalid | ||
app_config = apps.get_app_config(app_label="admin") | ||
|
||
messages = check_authenticate_class(app_configs=[app_config]) | ||
|
||
assert len(messages) == 0 | ||
|
||
|
||
def test_check_authenticate_class_ok(app_configs, settings): | ||
settings.OIDC_AUTHENTICATE_CLASS = ( | ||
"mozilla_django_oidc_db.views.OIDCAuthenticationRequestView" | ||
) | ||
|
||
messages = check_authenticate_class(app_configs=app_configs) | ||
|
||
assert len(messages) == 0 | ||
|
||
|
||
def test_check_authenticate_class_not_a_string(app_configs, settings): | ||
settings.OIDC_AUTHENTICATE_CLASS = object() | ||
|
||
messages = check_authenticate_class(app_configs=app_configs) | ||
|
||
assert len(messages) == 1 | ||
assert messages[0] == Error( | ||
"'settings.OIDC_AUTHENTICATE_CLASS' must be a string that can be imported.", | ||
hint=( | ||
"Use 'mozilla_django_oidc_db.views.OIDCAuthenticationRequestView' or a " | ||
"subclass of 'mozilla_django_oidc_db.views.OIDCInit'." | ||
), | ||
id="mozilla_django_oidc_db.E001", | ||
) | ||
|
||
|
||
def test_check_authenticate_class_invalid_view(app_configs, settings): | ||
settings.OIDC_AUTHENTICATE_CLASS = "django.views.View" | ||
|
||
messages = check_authenticate_class(app_configs=app_configs) | ||
|
||
assert len(messages) == 1 | ||
assert messages[0] == Warning( | ||
"'settings.OIDC_AUTHENTICATE_CLASS' should be a subclass of 'OIDCInit'.", | ||
hint=( | ||
"Use 'mozilla_django_oidc_db.views.OIDCAuthenticationRequestView' or a " | ||
"subclass of 'mozilla_django_oidc_db.views.OIDCInit'." | ||
), | ||
id="mozilla_django_oidc_db.W001", | ||
) | ||
|
||
|
||
def test_check_callback_class_ok(app_configs, settings): | ||
settings.OIDC_CALLBACK_CLASS = "mozilla_django_oidc_db.views.OIDCCallbackView" | ||
|
||
messages = check_callback_class(app_configs=app_configs) | ||
|
||
assert len(messages) == 0 | ||
|
||
|
||
def test_check_callback_class_not_a_string(app_configs, settings): | ||
settings.OIDC_CALLBACK_CLASS = object() | ||
|
||
messages = check_callback_class(app_configs=app_configs) | ||
|
||
assert len(messages) == 1 | ||
assert messages[0] == Error( | ||
"'settings.OIDC_CALLBACK_CLASS' must be a string that can be imported.", | ||
hint=( | ||
"Use 'mozilla_django_oidc_db.views.OIDCCallbackView' or a " | ||
"subclass of it." | ||
), | ||
id="mozilla_django_oidc_db.E002", | ||
) | ||
|
||
|
||
def test_check_callback_class_invalid_view(app_configs, settings): | ||
settings.OIDC_CALLBACK_CLASS = "django.views.View" | ||
|
||
messages = check_callback_class(app_configs=app_configs) | ||
|
||
assert len(messages) == 1 | ||
assert messages[0] == Warning( | ||
"'settings.OIDC_CALLBACK_CLASS' should be a subclass of 'OIDCInit'.", | ||
hint=( | ||
"Use 'mozilla_django_oidc_db.views.OIDCCallbackView' or a " | ||
"subclass of it." | ||
), | ||
id="mozilla_django_oidc_db.W002", | ||
) |