55import requests
66
77from xcube .webapi .auth import AuthMixin
8- from xcube .webapi .errors import ServiceConfigError , ServiceAuthError
8+ from xcube .webapi .auth import assert_scopes
9+ from xcube .webapi .auth import check_scopes
10+ from xcube .webapi .errors import ServiceAuthError
11+ from xcube .webapi .errors import ServiceConfigError
912
1013
1114class ServiceContextMock :
@@ -77,7 +80,6 @@ def _fetch_access_token(self):
7780 access_token = token_data ['access_token' ]
7881 return access_token
7982
80-
8183 def test_missing_auth_config (self ):
8284 auth_mixin = AuthMixin ()
8385 auth_mixin .service_context = ServiceContextMock (config = {})
@@ -86,7 +88,7 @@ def test_missing_auth_config(self):
8688 )
8789
8890 with self .assertRaises (ServiceAuthError ) as cm :
89- id_token = auth_mixin .get_id_token (require_auth = True )
91+ auth_mixin .get_id_token (require_auth = True )
9092
9193 self .assertEqual ('HTTP 401: Invalid header (Received access token, '
9294 'but this server doesn\' t support authentication.)' ,
@@ -251,3 +253,80 @@ def test_not_ok(self):
251253 self .assertEqual ('HTTP 500: Value for key "Algorithms"'
252254 ' in section "Authentication" must not be empty' ,
253255 f'{ cm .exception } ' )
256+
257+
258+ class ScopesTest (unittest .TestCase ):
259+
260+ def test_check_scopes_ok (self ):
261+ self .assertEqual (
262+ True ,
263+ check_scopes ({'read:dataset:test1.zarr' },
264+ set (),
265+ is_substitute = False )
266+ )
267+ self .assertEqual (
268+ True ,
269+ check_scopes ({'read:dataset:test1.zarr' },
270+ set (),
271+ is_substitute = True )
272+ )
273+ self .assertEqual (
274+ True ,
275+ check_scopes ({'read:dataset:test1.zarr' },
276+ {'read:dataset:test1.zarr' })
277+ )
278+ self .assertEqual (
279+ True ,
280+ check_scopes ({'read:dataset:test1.zarr' },
281+ {'read:dataset:test?.zarr' })
282+ )
283+ self .assertEqual (
284+ True ,
285+ check_scopes ({'read:dataset:test1.zarr' },
286+ {'read:dataset:test1.*' })
287+ )
288+
289+ def test_check_scopes_fails (self ):
290+ self .assertEqual (
291+ False ,
292+ check_scopes ({'read:dataset:test1.zarr' },
293+ {'read:dataset:test1.zarr' },
294+ is_substitute = True )
295+ )
296+ self .assertEqual (
297+ False ,
298+ check_scopes ({'read:dataset:test2.zarr' },
299+ {'read:dataset:test1.zarr' })
300+ )
301+ self .assertEqual (
302+ False ,
303+ check_scopes ({'read:dataset:test2.zarr' },
304+ {'read:dataset:test1.zarr' },
305+ is_substitute = True )
306+ )
307+
308+ def test_assert_scopes_ok (self ):
309+ assert_scopes ({'read:dataset:test1.zarr' },
310+ set ())
311+ assert_scopes ({'read:dataset:test1.zarr' },
312+ {'read:dataset:test1.zarr' })
313+ assert_scopes ({'read:dataset:test1.zarr' },
314+ {'read:dataset:*' })
315+ assert_scopes ({'read:dataset:test1.zarr' },
316+ {'read:dataset:test?.zarr' })
317+ assert_scopes ({'read:dataset:test1.zarr' },
318+ {'read:dataset:test1.*' })
319+ assert_scopes ({'read:dataset:test1.zarr' },
320+ {'read:dataset:test2.zarr' ,
321+ 'read:dataset:test3.zarr' ,
322+ 'read:dataset:test1.zarr' })
323+
324+ def test_assert_scopes_fails (self ):
325+ with self .assertRaises (ServiceAuthError ) as cm :
326+ assert_scopes ({'read:dataset:test1.zarr' },
327+ {'read:dataset:test2.zarr' })
328+ self .assertEquals (
329+ 'HTTP 401: Missing permission'
330+ ' (Missing permission read:dataset:test1.zarr)' ,
331+ f'{ cm .exception } '
332+ )
0 commit comments