forked from jazzband/django-oauth-toolkit
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make OIDC support optional by not requiring OIDC_RSA_PRIVATE_KEY to be set in the settings, and using the standard oauthlib.oauth2.Server class when an OIDC private key is not configured. Add a test fixture wrapping oauth2_settings. This allows individual tests / test suites to override oauth2 settings and have them reset at the end of the test. This avoids configuration leaking from one test to another, and allows us to test multiple different configurations in one test run. When using the oauth2_settings fixture, allow configuration for the test case to be loaded from a pytest marker called oauth2_settings. Split out OIDC specific tests requiring specific OIDC configuration into separate TestCase. Adjust the OAuthLibMixin to fallback to using the server, validator and core classes specified in oauth2_settings when not hardcoded in to the class. These classes can still be specified as hard-coded attributes in sub-classes, but it's no longer required if you just want what is configured in oauth2_settings, so remove all attributes that are just pointing at the configuration anyway. Add a setting ALWAYS_RELOAD_OAUTHLIB_CORE, which causes OAuthLibMixin to reload the OAuthLibCore object on each request. This is only intended to be used during testing, to allow the views to recognise changes in configuration. Show missing coverage lines in the coverage report. Fixes: jazzband#873
- Loading branch information
Showing
27 changed files
with
478 additions
and
422 deletions.
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
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
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,67 @@ | ||
import pytest | ||
from django.conf import settings as test_settings | ||
from jwcrypto import jwk | ||
|
||
from oauth2_provider.settings import oauth2_settings as _oauth2_settings | ||
|
||
|
||
class OAuthSettingsWrapper: | ||
""" | ||
A wrapper around oauth2_settings to ensure that when an overridden value is | ||
set, it also records it in _cached_attrs, so that the settings can be reset. | ||
""" | ||
|
||
def __init__(self, settings, user_settings): | ||
if user_settings: | ||
settings.OAUTH2_PROVIDER = user_settings | ||
_oauth2_settings.reload() | ||
self.settings = settings | ||
# Reload OAuthlibCore for every view request during tests | ||
self.ALWAYS_RELOAD_OAUTHLIB_CORE = True | ||
|
||
def __setattr__(self, attr, value): | ||
setattr(_oauth2_settings, attr, value) | ||
_oauth2_settings._cached_attrs.add(attr) | ||
|
||
def __delattr__(self, attr): | ||
delattr(_oauth2_settings, attr) | ||
if attr in _oauth2_settings._cached_attrs: | ||
_oauth2_settings._cached_attrs.remove(attr) | ||
|
||
def __getattr__(self, attr): | ||
return getattr(_oauth2_settings, attr) | ||
|
||
def finalize(self): | ||
self.settings.finalize() | ||
_oauth2_settings.reload() | ||
|
||
|
||
@pytest.fixture | ||
def oauth2_settings(request, settings): | ||
""" | ||
A fixture that provides a simple way to override OAUTH2_PROVIDER settings. | ||
It can be used two ways - either setting things on the fly, or by reading | ||
configuration data from the pytest marker oauth2_settings. | ||
If used on a standard pytest function, you can use argument dependency | ||
injection to get the wrapper. If used on a unittest.TestCase, the wrapper | ||
is made available on the class instance, as `oauth2_settings`. | ||
Anything overridden will be restored at the end of the test case, ensuring | ||
that there is no configuration leakage between test cases. | ||
""" | ||
marker = request.node.get_closest_marker("oauth2_settings") | ||
user_settings = {} | ||
if marker is not None: | ||
user_settings = marker.args[0] | ||
wrapper = OAuthSettingsWrapper(settings, user_settings) | ||
if request.instance is not None: | ||
request.instance.oauth2_settings = wrapper | ||
yield wrapper | ||
wrapper.finalize() | ||
|
||
|
||
@pytest.fixture(scope="class") | ||
def oidc_key(request): | ||
request.cls.key = jwk.JWK.from_pem(test_settings.OIDC_RSA_PRIVATE_KEY.encode("utf8")) |
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,42 @@ | ||
from copy import deepcopy | ||
|
||
from django.conf import settings | ||
|
||
|
||
# A set of OAUTH2_PROVIDER settings dicts that can be used in tests | ||
|
||
DEFAULT_SCOPES_RW = {"DEFAULT_SCOPES": ["read", "write"]} | ||
DEFAULT_SCOPES_RO = {"DEFAULT_SCOPES": ["read"]} | ||
OIDC_SETTINGS_RW = { | ||
"OIDC_ISS_ENDPOINT": "http://localhost", | ||
"OIDC_USERINFO_ENDPOINT": "http://localhost/userinfo/", | ||
"OIDC_RSA_PRIVATE_KEY": settings.OIDC_RSA_PRIVATE_KEY, | ||
"SCOPES": { | ||
"read": "Reading scope", | ||
"write": "Writing scope", | ||
"openid": "OpenID connect", | ||
}, | ||
"DEFAULT_SCOPES": ["read", "write"], | ||
} | ||
OIDC_SETTINGS_RO = deepcopy(OIDC_SETTINGS_RW) | ||
OIDC_SETTINGS_RO["DEFAULT_SCOPES"] = ["read"] | ||
REST_FRAMEWORK_SCOPES = { | ||
"SCOPES": { | ||
"read": "Read scope", | ||
"write": "Write scope", | ||
"scope1": "Scope 1", | ||
"scope2": "Scope 2", | ||
"resource1": "Resource 1", | ||
}, | ||
} | ||
INTROSPECTION_SETTINGS = { | ||
"SCOPES": { | ||
"read": "Read scope", | ||
"write": "Write scope", | ||
"introspection": "Introspection scope", | ||
"dolphin": "eek eek eek scope", | ||
}, | ||
"RESOURCE_SERVER_INTROSPECTION_URL": "http://example.org/introspection", | ||
"READ_SCOPE": "read", | ||
"WRITE_SCOPE": "write", | ||
} |
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
Oops, something went wrong.