def test_permission_collection(): perms = { DefaultPermission('domain_a:action_a'), DefaultPermission('domain_b:action_b'), DefaultPermission('domain_c:action_c') } return perms
def test_ipv_get_authzd_permissions(indexed_permission_verifier, monkeypatch, indexed_authz_info): """ unit tested: get_authzd_permissions test case: returns the permissions from the authzinfo that are relevant to the permission argument """ ipv = indexed_permission_verifier perm = DefaultPermission('domain4:action4') domainperms = frozenset([ DefaultPermission(domain={'domain4'}, action={'action1', 'action2'}), DefaultPermission(domain={'domain4'}, action={'action3'}, target={'target1'}) ]) monkeypatch.setattr(indexed_authz_info, 'get_permission', lambda x: domainperms) result = ipv.get_authzd_permissions(indexed_authz_info, perm) assert domainperms == result
def test_ipv_is_permitted(indexed_permission_verifier, monkeypatch, indexed_authz_info): """ unit tested: get_authzd_permissions test case: - gets authorized permissions based on the requested permission - for each permission requested, confirm whether the related authorized permissions implies permission - yield the results as a tuple """ ipv = indexed_permission_verifier dp1 = DefaultPermission('domain6:action1') monkeypatch.setattr(dp1, 'implies', lambda x: False) dp2 = DefaultPermission('domain7:action1') monkeypatch.setattr(dp2, 'implies', lambda x: True) authz_perms = frozenset([dp1, dp2]) monkeypatch.setattr(ipv, 'get_authzd_permissions', lambda x, y: authz_perms) perm1 = DefaultPermission('domain1:action1') perm2 = DefaultPermission('domain2:action1') result = list(ipv.is_permitted('authz_info', [perm1, perm2])) assert result == [(perm1, True), (perm2, True)]
def walter_testpermissions(): perm1 = DefaultPermission('leatherduffelbag:transport:theringer') perm2 = DefaultPermission('leatherduffelbag:access:theringer') perm3 = DefaultPermission('*:bowl:*') perms = [perm1, perm2, perm3] expected_results = frozenset([(perm1, True), (perm2, False), (perm3, True)]) return dict(perms=perms, expected_results=expected_results)
def jackie_testpermissions(): perm1 = DefaultPermission('money:access:ransom') perm2 = DefaultPermission('leatherduffelbag:access:theringer') perm3 = DefaultPermission('money:withdrawal') perms = [perm1, perm2, perm3] expected_results = frozenset([(perm1, True), (perm2, True), (perm3, False)]) return dict(perms=perms, expected_results=expected_results)
def thedude_testpermissions(): perm1 = DefaultPermission('money:write:bankcheck_19911109069') perm2 = DefaultPermission('money:withdrawal') perm3 = DefaultPermission('leatherduffelbag:transport:theringer') perm4 = DefaultPermission('leatherduffelbag:access:theringer') perms = [perm1, perm2, perm3, perm4] expected_results = frozenset([(perm1, True), (perm2, False), (perm3, True), (perm4, False)]) return dict(perms=perms, expected_results=expected_results)
def test_account_store(self): cc = CryptContext(schemes=['argon2']) with session_scope() as session: mgr = identities.manager_factory.for_session(session) accnt = mgr.create_account(account_name='accountAbc', account_type=AccountTypes.user, email='someemail') user1 = mgr.create_user(account_name=accnt['name'], username='******', password='******') print('user 1: {}'.format(user1)) user2 = mgr.create_user(account_name=accnt['name'], username='******', password='******') print('user 2: {}'.format(user2)) accnt2 = mgr.create_account(account_name='admin1', account_type=AccountTypes.admin, email='someemail',) user3 = mgr.create_user(account_name=accnt2['name'], username='******', password='******') print('user 3: {}'.format(user3)) store = basic_accountstore.DbAccountStore() # Authc stuff token = UsernamePasswordToken(username='******', password=user1['credentials'][UserAccessCredentialTypes.password]['value']) print(token.credentials) resp = store.get_authc_info(token.identifier) print(resp) self.assertTrue(token.credentials == bytes(resp['authc_info']['password']['credential'], 'utf8')) # Authz stuff authz_resp = store.get_authz_permissions(token.identifier) print(authz_resp) # Standard user self.assertTrue(DefaultPermission(parts=json.loads(authz_resp[user1['account_name']])[0]).implies( DefaultPermission(parts={'domain': user1['account_name'], 'action': '*', 'target': '*'}))) self.assertIsNone(authz_resp.get('*')) self.assertTrue(DefaultPermission(parts=json.loads(authz_resp[user1['account_name']])[0]).implies( DefaultPermission(parts={'domain': user1['account_name'], 'action': 'listImages', 'target': '*'}))) admin_token = UsernamePasswordToken(username='******', password=user3['credentials'][UserAccessCredentialTypes.password]['value']) # Authz stuff authz_resp = store.get_authz_permissions(admin_token.identifier) print(authz_resp) # Admin user self.assertIsNotNone(authz_resp.get('*')) self.assertIsNone(authz_resp.get(user3['account_name'])) self.assertTrue(DefaultPermission(parts=json.loads(authz_resp['*'])[0]).implies(DefaultPermission(parts={'domain': '*', 'action': '*', 'target': '*'})))
def is_permitted(self, identifiers, permission_s): """ If the authorization info cannot be obtained from the accountstore, permission check tuple yields False. :type identifiers: subject_abcs.IdentifierCollection :param permission_s: a collection of one or more permissions, represented as string-based permissions or Permission objects and NEVER comingled types :type permission_s: list of string(s) :yields: tuple(Permission, Boolean) """ identifier = identifiers.primary_identifier for required_perm in permission_s: required_permission = DefaultPermission(wildcard_string=required_perm) # get_authzd_permissions returns a list of DefaultPermission instances, # requesting from cache using '*' and permission.domain as hash keys: domain = next(iter(required_permission.domain)) assigned_permission_s = self.get_authzd_permissions(identifier, domain) is_permitted = False for authorized_permission in assigned_permission_s: if authorized_permission.implies(required_permission): is_permitted = True break yield (required_perm, is_permitted)
def get_authzd_permissions(self, identifier, perm_domain): """ :type identifier: str :type domain: str :returns: a list of relevant DefaultPermission instances (permission_s) """ permission_s = [] related_perms = [] keys = ['*', perm_domain] def query_permissions(self): msg = ("Could not obtain cached permissions for [{0}]. " "Will try to acquire permissions from account store." .format(identifier)) logger.debug(msg) permissions = self.account_store.get_authz_permissions(identifier) if not permissions: msg = "Could not get permissions from account_store for {0}".\ format(identifier) raise ValueError(msg) return permissions try: msg2 = ("Attempting to get cached authz_info for [{0}]" .format(identifier)) logger.debug(msg2) domain = 'authorization:permissions:' + self.name related_perms = self.cache_handler.\ hmget_or_create(domain=domain, identifier=identifier, keys=keys, creator_func=query_permissions, creator=self) except ValueError: msg3 = ("No permissions found for identifiers [{0}]. " "Returning None.".format(identifier)) logger.warning(msg3) except AttributeError: # this means the cache_handler isn't configured queried_permissions = query_permissions(self) related_perms = [queried_permissions.get('*'), queried_permissions.get(perm_domain)] for perms in related_perms: # must account for None values: try: for parts in rapidjson.loads(perms): permission_s.append(DefaultPermission(parts=parts)) except (TypeError, ValueError): pass return permission_s
def test_dp_normal_init(actions, targets, actionset, targetset): """ unit tested: __init__ test case: confirm that the DefaultPermission initializes as expected """ ddp = DefaultPermission(action=actions, target=targets) assert (ddp.action == actionset and ddp.target == targetset)
def test_dp_setstate(): parts = {'domain': 'domain1', 'action': ['action1'], 'target': ['target1']} state = {'parts': parts} expected_parts = {'domain': {'domain1'}, 'action': {'action1'}, 'target': {'target1'}} dp = DefaultPermission.__new__(DefaultPermission) dp.__setstate__(state) assert dp.parts == expected_parts
def test_asr_get_authz_permissions_from_cache(account_store_realm, monkeypatch, simple_identifier_collection, sample_parts): asr = account_store_realm dp = DefaultPermission(parts=sample_parts) mock_cache = mock.Mock() mock_cache.hmget_or_create.return_value = [rapidjson.dumps([sample_parts])] monkeypatch.setattr(asr, 'cache_handler', mock_cache) result = asr.get_authzd_permissions('thedude', 'domain1') assert result == [dp]
def test_asr_get_authz_perms_without_cache_from_accountstore( account_store_realm, monkeypatch, simple_identifier_collection, sample_acct_info, sample_parts): asr = account_store_realm dp = DefaultPermission(parts=sample_parts) monkeypatch.setattr(asr, 'cache_handler', None) sample = {'domain1': rapidjson.dumps([sample_parts])} monkeypatch.setattr(asr.account_store, 'get_authz_permissions', lambda x: sample) result = asr.get_authzd_permissions('thedude', 'domain1') assert result == [dp]
def test_is_permitted_account_doesnt_exist(modular_realm_authorizer, event_bus): """ when an account cannot be obtained from the account_store, all permissions checked return False """ mra = modular_realm_authorizer perm1 = DefaultPermission('money:write:bankcheck_19911109069') perm2 = DefaultPermission('money:withdrawal') perm3 = DefaultPermission('leatherduffelbag:transport:theringer') perm4 = DefaultPermission('leatherduffelbag:access:theringer') perms = [perm1, perm2, perm3, perm4] expected_results = frozenset([(perm1, False), (perm2, False), (perm3, False), (perm4, False)]) unrecognized_identifier = \ SimpleIdentifierCollection(source_name='AccountStoreRealm', identifier='jackietreehorn') event_detected = None def event_listener(identifiers=None, items=None, logical_operator=None, topic=EVENT_TOPIC): nonlocal event_detected event_detected = items event_bus.subscribe(event_listener, 'AUTHORIZATION.RESULTS') results = mra.is_permitted(unrecognized_identifier, perms) assert (expected_results == results and frozenset(event_detected) == results)
def test_iai_permissions_setter(indexed_authz_info): """ unit tested: permissions.setter test case: clears the existing permissions index and then indexes the new set of perms """ info = indexed_authz_info with mock.patch.object(IndexedAuthorizationInfo, 'index_permission') as ip: ip.return_value = None testperm = DefaultPermission('domain1:action1') info.permissions = {testperm} ip.assert_called_once_with({testperm}) # _permissions will be empty since index_permission was mocked assert not info._permissions
def permission_collection(): return { DefaultPermission(domain={'domain1'}, action={'action1'}), DefaultPermission(domain={'domain2'}, action={'action1', 'action2'}), DefaultPermission(domain={'domain3'}, action={'action1', 'action2', 'action3'}, target={'target1'}), DefaultPermission(domain={'domain4'}, action={'action1', 'action2'}), DefaultPermission(domain={'domain4'}, action={'action3'}, target={'target1'}), DefaultPermission(wildcard_string='*:action5') }
def is_permitted(self, identifiers, permission_s): """ :type identifiers: SimpleRealmCollection """ # If a service account or admin account user, use the default handler, not external calls if ExternalAuthzRealm.__account_type_provider__ and callable(ExternalAuthzRealm.__account_type_provider__) and \ ExternalAuthzRealm.__account_type_provider__(identifiers.primary_identifier) in [AccountTypes.service, AccountTypes.admin]: logger.debug( 'Detected admin or service account, using internal authz') return super().is_permitted(identifiers, permission_s) result_list = [] # List of tuples (required_perm, is_permitted) identifier = identifiers.primary_identifier actions = {} for required_perm in permission_s: required_permission = DefaultPermission( wildcard_string=required_perm) actions[Action(domain=','.join(required_permission.domain), action=','.join(required_permission.action), target=','.join( required_permission.target))] = required_perm if actions: try: resp = self.__client__.authorize(principal=identifier, action_s=list(actions.keys())) for i in resp.allowed: result_list.append((actions[i], True)) for i in resp.denied: result_list.append((actions[i], False)) except Exception as e: logger.exception( 'Unexpected error invoking authorization plugin via client: {}' .format(e)) logger.error( 'Authorization plugin invocation error. Could not perform a proper authz check. Please check configuration and/or authz service status: {}' .format(self.__client__.url)) raise e return result_list
def test_account_store(self): cc = CryptContext(schemes=["argon2"]) with session_scope() as session: mgr = identities.manager_factory.for_session(session) accnt = mgr.create_account( account_name="accountAbc", account_type=AccountTypes.user, email="someemail", ) user1 = mgr.create_user(account_name=accnt["name"], username="******", password="******") print("user 1: {}".format(user1)) user2 = mgr.create_user(account_name=accnt["name"], username="******", password="******") print("user 2: {}".format(user2)) accnt2 = mgr.create_account( account_name="admin1", account_type=AccountTypes.admin, email="someemail", ) user3 = mgr.create_user(account_name=accnt2["name"], username="******", password="******") print("user 3: {}".format(user3)) store = basic_accountstore.DbAccountStore() # Authc stuff token = UsernamePasswordToken( username="******", password=user1["credentials"][UserAccessCredentialTypes.password] ["value"], ) print(token.credentials) resp = store.get_authc_info(token.identifier) print(resp) self.assertTrue(token.credentials == bytes( resp["authc_info"]["password"]["credential"], "utf8")) # Authz stuff authz_resp = store.get_authz_permissions(token.identifier) print(authz_resp) # Standard user self.assertTrue( DefaultPermission(parts=json.loads(authz_resp[ user1["account_name"]])[0]).implies( DefaultPermission( parts={ "domain": user1["account_name"], "action": "*", "target": "*", }))) self.assertIsNone(authz_resp.get("*")) self.assertTrue( DefaultPermission(parts=json.loads(authz_resp[ user1["account_name"]])[0]).implies( DefaultPermission( parts={ "domain": user1["account_name"], "action": "listImages", "target": "*", }))) admin_token = UsernamePasswordToken( username="******", password=user3["credentials"][UserAccessCredentialTypes.password] ["value"], ) # Authz stuff authz_resp = store.get_authz_permissions(admin_token.identifier) print(authz_resp) # Admin user self.assertIsNotNone(authz_resp.get("*")) self.assertIsNone(authz_resp.get(user3["account_name"])) self.assertTrue( DefaultPermission(parts=json.loads(authz_resp["*"])[0]).implies( DefaultPermission(parts={ "domain": "*", "action": "*", "target": "*" })))
def default_permission(): return DefaultPermission()
with mock.patch.object(IndexedAuthorizationInfo, 'assert_permissions_indexed') as api: api.return_value = None info.index_permission(permission_s=tpc) api.assert_called_once_with(tpc) for permission in tpc: domain = next(iter(permission.domain)) assert {permission} <= info._permissions[domain] @pytest.mark.parametrize('domain, expected', [('domain1', {DefaultPermission('domain1:action1')}), ('domainQ', set())]) def test_iai_get_permission(indexed_authz_info, domain, expected): """ unit tested: get_permission test case: returns the permissions for a specified domain or an empty set if there arent any {DefaultPermission('domain4:action1,action2'), DefaultPermission('domain4:action3:target1')}), """ info = indexed_authz_info result = info.get_permission(domain)
def test_dp_init_wildcard(mock_wpi): result = DefaultPermission(wildcard_string='domain1:action1') mock_wpi.assert_called_once_with(wildcard_string='domain1:action1')
def test_dp_init_parts(): parts = {'domain': 'domain1', 'action': ['action1'], 'target': ['target1']} expected_parts = {'domain': {'domain1'}, 'action': {'action1'}, 'target': {'target1'}} dp = DefaultPermission(parts=parts) assert dp.parts == expected_parts