From b2d1c7888b4baf9d91ddc4361505711868f93dfa Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Tue, 22 Apr 2025 11:10:43 +0200 Subject: [PATCH] work in progress: dummy oidc data handler for testing --- scopes/tests/config.py | 9 ++++++- scopes/tests/dummy_requests.py | 46 ++++++++++++++++++++++++++++++++++ scopes/tests/tlib_web.py | 1 + scopes/web/auth/oidc.py | 5 ++-- 4 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 scopes/tests/dummy_requests.py diff --git a/scopes/tests/config.py b/scopes/tests/config.py index a4731fe..8ffdcc4 100644 --- a/scopes/tests/config.py +++ b/scopes/tests/config.py @@ -2,6 +2,7 @@ import logging from os import getenv +import sys #from scopes.web.app import demo_app, zope_app @@ -32,8 +33,14 @@ dbuser = None dbpassword = None dbschema = None +# special testing stuff +#from scopes.tests import oidc_data # add oidc URIs and keys to dummy_requests data +from scopes.tests import dummy_requests +sys.modules['requests'] = dummy_requests + + # authentication settings -oidc_provider = 'test://testing' +oidc_provider = 'test://oidc' oidc_client_id = getenv('OIDC_CLIENT_ID', '12345') oidc_params = dict( op_config_url=oidc_provider + '/.well-known/openid-configuration', diff --git a/scopes/tests/dummy_requests.py b/scopes/tests/dummy_requests.py new file mode 100644 index 0000000..d586094 --- /dev/null +++ b/scopes/tests/dummy_requests.py @@ -0,0 +1,46 @@ +# scopes.tests.requests + +"""Dummy requests implementation for testing.""" + +from logging import getLogger +logger = getLogger('tests.dummy_requests') + +def get(url, *args, **kw): + logger.info(f'get: %s - %s - %s', url, args, kw) + return FakeResponse(response_data[url]) + + +class FakeResponse: + + def __init__(self, data): + self.data = data + + def json(self): + return self.data + + +response_data = { + 'test://oidc/.well-known/openid-configuration': { + "issuer": "test://oidc", + "authorization_endpoint": "test://oidc/oauth/v2/authorize", + "token_endpoint": "test://oidc/oauth/v2/token", + "introspection_endpoint": "test://oidc/oauth/v2/introspect", + "userinfo_endpoint": "test://oidc/oidc/v1/userinfo", + "revocation_endpoint": "test://oidc/oauth/v2/revoke", + "end_session_endpoint": "test://oidc/oidc/v1/end_session", + "device_authorization_endpoint": "test://oidc/oauth/v2/device_authorization", + "jwks_uri": "test://oidc/oauth/v2/keys"}, + 'test://oidc/oauth/v2/keys': { "keys": [ + {"use": "sig", + "kty": "RSA", + "kid": "316638486247563085", + "alg": "RS256", + "n": "167qFCfRa0tRR0MZv-PQVwdiVFf0NtfN-zFAogRASm6437sbXfsfxkpbh1F77TwQdl4qlR5Na_Ecs8VTxOuyHmuhIJ4FyZV4M0h71KRw7LCTVuNw7mWLpbjKPBzidyhctbkJrkcKtJymnHELsct0CdT16Lb27phd_0cBJexGbwhVNQBs10VbkvUJHHOJe6A_JVS9Q3_3MEWyCyFoHPeMchlk_Gd6yMiH4aJ1ql3GZD6c2JB9crloTH_oPWWFQObGoXTKcFonEBdkrwuCQfRVOfGh8UIhIcTM0JNgqtQOCcIkf0emfI30SoWSc6Qz8lU70Vpmb3qQgsqATFICgzgABw", + "e": "AQAB"}, + {"use": "sig", + "kty": "RSA", + "kid": "316766976250797901", + "alg": "RS256", + "n": "yZKIsrUWT2fEj4OtUUFYQbEe_Clodz464tn5vMAQ0q8zV07bqFaA7WKuBflowYctDNxoxdbiFNISpKEOx6yFnx7_g6Zd46DWsj5ggGZvNkgOa9SqTIsA7ho9nk7LDLQRpV0k5N1HkiG66GUqUCV2llJhstpTDQQLDvhI3qussG2HyylpTQSu-9b6gry0rb397yjAnXQu6tFOubEDteTN0fLNMblcdd2AvZKpGA2o_-M5U6AckezfmBCBdHWmrwxpjGGf7KWqGg8j6bJkV3sMg4XfD2x0KNog_3D-0pSx6k8dSWZGkNlDxB5AdWvNDYg1stkvjeNEbIJAhv0-awLs9Q", + "e": "AQAB"}]} +} diff --git a/scopes/tests/tlib_web.py b/scopes/tests/tlib_web.py index 3e84bb1..c9efdcf 100644 --- a/scopes/tests/tlib_web.py +++ b/scopes/tests/tlib_web.py @@ -24,6 +24,7 @@ def test_app(self, config): logger.info('test_app') storage = config.storageFactory(config.dbschema) response = publishRequest(config, storage, '/top') + print('***', response.getStatus(), response.getHeaders()) result = json.loads(response.consumeBody()) self.assertEqual(result['items'][0]['head']['name'], 'level2-item1') diff --git a/scopes/web/auth/oidc.py b/scopes/web/auth/oidc.py index fcd65f8..690f68b 100644 --- a/scopes/web/auth/oidc.py +++ b/scopes/web/auth/oidc.py @@ -110,7 +110,6 @@ class Authenticator(DummyFolder): def login(self): req = self.request - logger.debug('login: %s %s %s', self, req.getTraversalStack(), req['PATH_INFO']) #print('***', dir(req)) state = util.rndstr() nonce = util.rndstr() @@ -205,14 +204,14 @@ class Authenticator(DummyFolder): def loadOidcProviderData(self, force=False): if config.oidc_provider.startswith('test'): - return + pass if force or self.params.get('op_uris') is None: uris = self.params['op_uris'] = {} opData = requests.get(self.params['op_config_url']).json() for key in self.oidcProviderUris: uris[key] = opData[key] if force or self.params.get('op_keys') is None: - self.params['op_keys'] = requests.get(uris['jwks_uri']).json() + self.params['op_keys'] = requests.get(uris['jwks_uri']).json()['keys'] @register('auth', Root)