auth: improve loading of oidc provider data, provide and check in test
This commit is contained in:
		
							parent
							
								
									b2d1c7888b
								
							
						
					
					
						commit
						87310b9798
					
				
					 6 changed files with 60 additions and 45 deletions
				
			
		|  | @ -34,7 +34,7 @@ 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 data_auth # add oidc URIs and keys to dummy_requests data | ||||
| from scopes.tests import dummy_requests | ||||
| sys.modules['requests'] = dummy_requests | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										32
									
								
								scopes/tests/data_auth.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								scopes/tests/data_auth.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | |||
| # scopes.tests.data_auth | ||||
| 
 | ||||
| """provide response data for testing (via dummy_requests)""" | ||||
| 
 | ||||
| oidc_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"}]} | ||||
| } | ||||
| 
 | ||||
| from scopes.tests.dummy_requests import response_data | ||||
| response_data.update(oidc_data) | ||||
|  | @ -19,28 +19,4 @@ class FakeResponse: | |||
|         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"}]} | ||||
| } | ||||
| response_data = {} | ||||
|  |  | |||
|  | @ -32,6 +32,7 @@ class Test(unittest.TestCase): | |||
| 
 | ||||
|     def test_013_web(self): | ||||
|         tlib_web.test_app(self, config) | ||||
|         tlib_web.test_auth(self, config) | ||||
| 
 | ||||
| 
 | ||||
| def suite(): | ||||
|  |  | |||
|  | @ -21,10 +21,13 @@ def publishRequest(config, storage, path): | |||
| 
 | ||||
| def test_app(self, config): | ||||
|     logger = logging.getLogger('tlib_web') | ||||
|     logger.info('test_app') | ||||
|     storage = config.storageFactory(config.dbschema) | ||||
|     response = publishRequest(config, storage, '/top') | ||||
|     print('***', response.getStatus(), response.getHeaders()) | ||||
|     logger.info('test_app: response %s %s', response.getStatus(), response.getHeaders()) | ||||
|     result = json.loads(response.consumeBody()) | ||||
|     self.assertEqual(result['items'][0]['head']['name'], 'level2-item1') | ||||
| 
 | ||||
| def test_auth(self, config): | ||||
|     from scopes.web.auth import oidc | ||||
|     oidc.loadOidcProviderData() | ||||
|     self.assertEqual(len(config.oidc_params['op_uris']), 8) | ||||
|  |  | |||
|  | @ -81,17 +81,11 @@ class Authenticator(DummyFolder): | |||
| 
 | ||||
|     prefix = 'auth.oidc' | ||||
| 
 | ||||
|     oidcProviderUris = ['authorization_endpoint', 'token_endpoint',  | ||||
|                         'introspection_endpoint', 'userinfo_endpoint', | ||||
|                         'revocation_endpoint', 'end_session_endpoint', | ||||
|                         'device_authorization_endpoint', 'jwks_uri'] | ||||
| 
 | ||||
|     def __init__(self, request): | ||||
|         self.request = request | ||||
|         self.params = config.oidc_params | ||||
|         self.reqUrl = config.base_url | ||||
|         self.setCrypt(self.params.get('cookie_crypt')) | ||||
|         self.loadOidcProviderData() | ||||
| 
 | ||||
|     def setReqUrl(self, base, path): | ||||
|         self.reqUrl = '/'.join((base, path)) | ||||
|  | @ -109,6 +103,7 @@ class Authenticator(DummyFolder): | |||
|         return None | ||||
| 
 | ||||
|     def login(self): | ||||
|         loadOidcProviderData() | ||||
|         req = self.request | ||||
|         #print('***', dir(req)) | ||||
|         state = util.rndstr() | ||||
|  | @ -202,17 +197,6 @@ class Authenticator(DummyFolder): | |||
|         data = json.loads(cookie) | ||||
|         return data | ||||
| 
 | ||||
|     def loadOidcProviderData(self, force=False): | ||||
|         if config.oidc_provider.startswith('test'): | ||||
|             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()['keys'] | ||||
| 
 | ||||
| 
 | ||||
| @register('auth', Root) | ||||
| def authView(context, request): | ||||
|  | @ -232,3 +216,22 @@ def callback(context, request): | |||
| def logout(context, request): | ||||
|     context.logout() | ||||
|     return DefaultView(context, request) | ||||
| 
 | ||||
| 
 | ||||
| oidcProviderUris = ['authorization_endpoint', 'token_endpoint',  | ||||
|                     'introspection_endpoint', 'userinfo_endpoint', | ||||
|                     'revocation_endpoint', 'end_session_endpoint', | ||||
|                     'device_authorization_endpoint', 'jwks_uri'] | ||||
| 
 | ||||
| def loadOidcProviderData(force=False): | ||||
|     params = config.oidc_params | ||||
|     if force or params.get('op_uris') is None: | ||||
|         uris = params['op_uris'] = {} | ||||
|         opData = requests.get(params['op_config_url']).json() | ||||
|         for key in oidcProviderUris: | ||||
|             uris[key] = opData[key] | ||||
|     if force or params.get('op_keys') is None: | ||||
|         params['op_keys'] = requests.get(uris['jwks_uri']).json()['keys'] | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue