def check_set_namespace_publicly_mappable(pub_value, log_collector): storage = create_autospec(IDMappingStorage, spec_set=True, instance=True) handlers = create_autospec(UserLookupSet, spec_set=True, instance=True) idm = IDMapper(handlers, set([AuthsourceID('asone')]), storage) handlers.get_user.return_value = (User(AuthsourceID('asone'), Username('u')), False) storage.get_namespace.return_value = Namespace(NamespaceID('n'), False, set([ User(AuthsourceID('astwo'), Username('u2')), User(AuthsourceID('asone'), Username('u')), User(AuthsourceID('asthree'), Username('u'))])) idm.set_namespace_publicly_mappable( AuthsourceID('asone'), Token('t'), NamespaceID('n'), pub_value) assert handlers.get_user.call_args_list == [((AuthsourceID('asone'), Token('t'),), {})] assert storage.get_namespace.call_args_list == [((NamespaceID('n'),), {})] assert storage.set_namespace_publicly_mappable.call_args_list == \ [((NamespaceID('n'), pub_value), {})] print(log_collector) assert_logs_correct(log_collector, 'User asone/u set namespace n public map property to ' + str(pub_value))
def test_remove_user_from_namespace_fail_no_such_namespace(idstorage): idstorage.create_namespace(NamespaceID('foo')) idstorage.add_user_to_namespace(NamespaceID('foo'), User(AuthsourceID('as'), Username('u'))) fail_remove_namespace_user(idstorage, NamespaceID('bar'), User(AuthsourceID('as'), Username('u')), NoSuchNamespaceError('bar'))
def test_add_user_to_namespace_fail_duplicate(idstorage): idstorage.create_namespace(NamespaceID('foo')) idstorage.add_user_to_namespace(NamespaceID('foo'), User(AuthsourceID('as'), Username('u'))) fail_add_namespace_user( idstorage, NamespaceID('foo'), User(AuthsourceID('as'), Username('u')), UserExistsError('User as/u already administrates namespace foo'))
def check_set_is_valid_user_default_cache_ttl(hset, handler, timer, timervals): handler.is_valid_user.return_value = (True, None, None) timer.return_value = timervals[0] # user will not be in cache assert hset.is_valid_user(User(AuthsourceID('as'), Username('u'))) is True # user is now cached handler.is_valid_user.return_value = None # should cause error if called from now on timer.return_value = timervals[1] # just below default cache time assert hset.is_valid_user(User(AuthsourceID('as'), Username('u'))) is True # now expire the user handler.is_valid_user.return_value = (True, None, None) timer.return_value = timervals[2] assert hset.is_valid_user(User(AuthsourceID('as'), Username('u'))) is True # get the user again, should be cached handler.is_valid_user.return_value = None # should cause error if called from now on timer.return_value = timervals[3] assert hset.is_valid_user(User(AuthsourceID('as'), Username('u'))) is True assert handler.is_valid_user.call_args_list == [((Username('u'), ), {}), ((Username('u'), ), {})]
def check_set_is_valid_user_handler_ttl(epoch, rel, timervals): handler = create_autospec(UserLookup, spec_set=True, instance=True) timer = create_autospec(time.time, spec_set=True) handler.get_authsource_id.return_value = AuthsourceID('as') hset = UserLookupSet(set([handler]), timer) handler.is_valid_user.return_value = (True, epoch, rel) timer.return_value = timervals[0] # cache user for X secs assert hset.is_valid_user(User(AuthsourceID('as'), Username('u1'))) is True # force an error if the handler is called handler.is_valid_user.return_value = None timer.return_value = timervals[1] assert hset.is_valid_user(User(AuthsourceID('as'), Username('u1'))) is True # expect handler call at Y sec handler.is_valid_user.return_value = (True, epoch, rel) timer.return_value = timervals[2] assert hset.is_valid_user(User(AuthsourceID('as'), Username('u1'))) is True # check correct number of calls to get_user assert handler.is_valid_user.call_args_list == [((Username('u1'), ), {}), ((Username('u1'), ), {})]
def test_remove_user_from_namespace_fail_no_such_user(idstorage): idstorage.create_namespace(NamespaceID('foo')) idstorage.add_user_to_namespace(NamespaceID('foo'), User(AuthsourceID('as'), Username('u'))) fail_remove_namespace_user( idstorage, NamespaceID('foo'), User(AuthsourceID('as'), Username('u1')), NoSuchUserError('User as/u1 does not administrate namespace foo'))
def test_namespace_without_users(): ns = Namespace( NamespaceID('n'), True, set([ User(AuthsourceID('a'), Username('u')), User(AuthsourceID('b'), Username('b')) ])) assert ns.without_users() == Namespace(NamespaceID('n'), True, set()) assert ns.without_users() == Namespace(NamespaceID('n'), True, None)
def test_get_namespace_no_auth(): storage = create_autospec(IDMappingStorage, spec_set=True, instance=True) handlers = create_autospec(UserLookupSet, spec_set=True, instance=True) idm = IDMapper(handlers, set(), storage) storage.get_namespace.return_value = Namespace(NamespaceID('n'), True, set([ User(AuthsourceID('a'), Username('u')), User(AuthsourceID('a'), Username('u1'))])) assert idm.get_namespace(NamespaceID('n')) == Namespace(NamespaceID('n'), True) assert storage.get_namespace.call_args_list == [((NamespaceID('n'), ), {})]
def test_remove_user_from_namespace_fail_not_admin(): storage = create_autospec(IDMappingStorage, spec_set=True, instance=True) handlers = create_autospec(UserLookupSet, spec_set=True, instance=True) idm = IDMapper(handlers, set([AuthsourceID('as')]), storage) handlers.get_user.return_value = (User(AuthsourceID('as'), Username('foo')), False) fail_remove_user_from_namespace(idm, AuthsourceID('as'), Token('t'), NamespaceID('n'), User(AuthsourceID('as'), Username('u')), UnauthorizedError('User as/foo is not a system administrator'))
def test_add_user_to_namespace_fail_no_such_user(): storage = create_autospec(IDMappingStorage, spec_set=True, instance=True) handlers = create_autospec(UserLookupSet, spec_set=True, instance=True) idm = IDMapper(handlers, set([AuthsourceID('asone')]), storage) handlers.get_user.return_value = (User(AuthsourceID('asone'), Username('bar')), True) handlers.is_valid_user.return_value = False fail_add_user_to_namespace(idm, AuthsourceID('asone'), Token('t'), NamespaceID('n'), User(AuthsourceID('asone'), Username('u')), NoSuchUserError('asone/u'))
def test_set_get_user_cache_max_count(): # testing the default of 10k is just silly, not going to bother. handler = create_autospec(UserLookup, spec_set=True, instance=True) timer = create_autospec(time.time, spec_set=True) handler.get_authsource_id.return_value = AuthsourceID('as') hset = UserLookupSet(set([handler]), timer, cache_max_size=2) # add user 1 handler.get_user.return_value = (User(AuthsourceID('as'), Username('u1')), False, None, None) timer.return_value = 0 assert hset.get_user(AuthsourceID('as'), Token('t1')) == \ (User(AuthsourceID('as'), Username('u1')), False) # add user 2 handler.get_user.return_value = (User(AuthsourceID('as'), Username('u2')), True, None, None) timer.return_value = 1 assert hset.get_user(AuthsourceID('as'), Token('t2')) == \ (User(AuthsourceID('as'), Username('u2')), True) # add user 3, user 1 should now be evicted from the cache handler.get_user.return_value = (User(AuthsourceID('as'), Username('u3')), False, None, None) timer.return_value = 2 assert hset.get_user(AuthsourceID('as'), Token('t3')) == \ (User(AuthsourceID('as'), Username('u3')), False) # should only need a handler call for user 1 at this point handler.get_user.return_value = (User(AuthsourceID('as'), Username('u1')), True, None, None) timer.return_value = 3 # get the 3 users. Get user 1 last otherwise it'll evict user 2 from the cache assert hset.get_user(AuthsourceID('as'), Token('t2')) == \ (User(AuthsourceID('as'), Username('u2')), True) assert hset.get_user(AuthsourceID('as'), Token('t3')) == \ (User(AuthsourceID('as'), Username('u3')), False) assert hset.get_user(AuthsourceID('as'), Token('t1')) == \ (User(AuthsourceID('as'), Username('u1')), True) # check that the calls to get_user are as expected: assert handler.get_user.call_args_list == [((Token('t1'), ), {}), ((Token('t2'), ), {}), ((Token('t3'), ), {}), ((Token('t1'), ), {})]
def test_remove_mapping_fail_unauthed_for_admin_namespace(): storage = create_autospec(IDMappingStorage, spec_set=True, instance=True) handlers = create_autospec(UserLookupSet, spec_set=True, instance=True) idm = IDMapper(handlers, set(), storage) handlers.get_user.return_value = (User(AuthsourceID('a'), Username('n')), False) storage.get_namespace.return_value = Namespace(NamespaceID('n1'), True, set([ User(AuthsourceID('a'), Username('n1')), User(AuthsourceID('a'), Username('n2'))])) fail_remove_mapping(idm, AuthsourceID('a'), Token('t'), ObjectID(NamespaceID('n1'), 'o1'), ObjectID(NamespaceID('n2'), 'o2'), UnauthorizedError('User a/n may not administrate namespace n1'))
def test_set_namespace_publicly_mappable_fail_unauthed(): storage = create_autospec(IDMappingStorage, spec_set=True, instance=True) handlers = create_autospec(UserLookupSet, spec_set=True, instance=True) idm = IDMapper(handlers, set([AuthsourceID('asone')]), storage) handlers.get_user.return_value = (User(AuthsourceID('asone'), Username('u')), False) storage.get_namespace.return_value = Namespace(NamespaceID('n'), False, set([ User(AuthsourceID('asone'), Username('u2')), User(AuthsourceID('asthree'), Username('u'))])) fail_set_namespace_publicly_mappable( idm, AuthsourceID('asone'), Token('t'), NamespaceID('n'), UnauthorizedError('User asone/u may not administrate namespace n'))
def test_set_public_and_list_namespaces(service_port, mongo): storage = get_storage_instance(mongo) lut = Token('foobar') u = Username('lu') storage.create_local_user(u, lut.get_hashed_token()) priv = NamespaceID('priv') storage.create_namespace(priv) storage.add_user_to_namespace(priv, User(AuthsourceID('local'), u)) storage.set_namespace_publicly_mappable(priv, True) pub = NamespaceID('pub') storage.create_namespace(pub) storage.add_user_to_namespace(pub, User(AuthsourceID('local'), u)) r = requests.put('http://localhost:' + service_port + '/api/v1/namespace/priv/set?publicly_mappable=false', headers={'Authorization': 'local ' + lut.token}) assert r.status_code == 204 r = requests.put('http://localhost:' + service_port + '/api/v1/namespace/pub/set?publicly_mappable=true', headers={'Authorization': 'local ' + lut.token}) assert r.status_code == 204 r = requests.get('http://localhost:' + service_port + '/api/v1/namespace') assert r.json() == { 'publicly_mappable': ['pub'], 'privately_mappable': ['priv'] } r = requests.put('http://localhost:' + service_port + '/api/v1/namespace/missing/set?publicly_mappable=false', headers={'Authorization': 'local ' + lut.token}) assert_json_error_correct( r.json(), { 'error': { 'httpcode': 404, 'httpstatus': 'Not Found', 'appcode': 50010, 'apperror': 'No such namespace', 'message': '50010 No such namespace: missing' } }) assert r.status_code == 404
def test_remove_user_from_namespace_fail_inputs_None(idstorage): u = User(AuthsourceID('as'), 'u') n = NamespaceID('n') fail_remove_namespace_user(idstorage, None, u, TypeError('namespace_id cannot be None')) fail_remove_namespace_user(idstorage, n, None, TypeError('admin_user cannot be None'))
def test_set_is_valid_user_no_authsource(): handler = create_autospec(UserLookup, spec_set=True, instance=True) handler.get_authsource_id.return_value = AuthsourceID('as') fail_set_is_valid_user(UserLookupSet(set([handler])), User(AuthsourceID('bs'), Username('n')), NoSuchAuthsourceError('bs'))
def add_user_to_namespace(namespace, authsource, user): """ Add a user to a namespace. """ admin_authsource, token = _get_auth(request) app.config[_APP].add_user_to_namespace( admin_authsource, token, NamespaceID(namespace), User(AuthsourceID(authsource), Username(user))) return ('', 204)
def test_add_and_remove_namespace_users(idstorage): nsid = NamespaceID('foo') idstorage.create_namespace(nsid) assert idstorage.get_namespace(NamespaceID('foo')) == Namespace( NamespaceID('foo'), False) idstorage.add_user_to_namespace( nsid, User(AuthsourceID('asone'), Username('u1'))) users = set([User(AuthsourceID('asone'), Username('u1'))]) assert idstorage.get_namespace(nsid) == Namespace(NamespaceID('foo'), False, users) idstorage.add_user_to_namespace( nsid, User(AuthsourceID('astwo'), Username('u2'))) users.add(User(AuthsourceID('astwo'), Username('u2'))) assert idstorage.get_namespace(nsid) == Namespace(NamespaceID('foo'), False, users) idstorage.remove_user_from_namespace( NamespaceID('foo'), User(AuthsourceID('asone'), Username('u1'))) users = set([User(AuthsourceID('astwo'), Username('u2'))]) assert idstorage.get_namespace(nsid) == Namespace(NamespaceID('foo'), False, users) idstorage.remove_user_from_namespace( NamespaceID('foo'), User(AuthsourceID('astwo'), Username('u2'))) assert idstorage.get_namespace(nsid) == Namespace(NamespaceID('foo'), False)
def remove_user_from_namespace(namespace, authsource, user): """ Remove a user from a namespace. Removing a non-existant user throws an error. """ admin_authsource, token = _get_auth(request) app.config[_APP].remove_user_from_namespace( admin_authsource, token, NamespaceID(namespace), User(AuthsourceID(authsource), Username(user))) return ('', 204)
def check_local_get_user_admin(isadmin): storage = create_autospec(IDMappingStorage, spec_set=True, instance=True) storage.get_user.return_value = (Username('bar'), isadmin) assert LocalUserLookup(storage).get_user(Token('foo')) == \ (User(AuthsourceID('local'), Username('bar')), isadmin, None, 300) thash = '2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae' assert storage.get_user.call_args_list == [((HashedToken(thash), ), {})]
def test_user_hash(): # string hashes will change from instance to instance of the python interpreter, and therefore # tests can't be written that directly test the hash value. See # https://docs.python.org/3/reference/datamodel.html#object.__hash__ assert hash(User(AuthsourceID('foo'), Username('bar'))) == hash( User(AuthsourceID('foo'), Username('bar'))) assert hash(User(AuthsourceID('bar'), Username('foo'))) == hash( User(AuthsourceID('bar'), Username('foo'))) assert hash(User(AuthsourceID('baz'), Username('foo'))) != hash( User(AuthsourceID('bar'), Username('foo'))) assert hash(User(AuthsourceID('bar'), Username('fob'))) != hash( User(AuthsourceID('bar'), Username('foo')))
def test_remove_user_from_namespace_fail_no_admin_authsource_provider(): storage = create_autospec(IDMappingStorage, spec_set=True, instance=True) handlers = create_autospec(UserLookupSet, spec_set=True, instance=True) idm = IDMapper(handlers, set([AuthsourceID('bs')]), storage) fail_remove_user_from_namespace(idm, AuthsourceID('as'), Token('t'), NamespaceID('n'), User(AuthsourceID('as'), Username('u')), UnauthorizedError( 'Auth source as is not configured as a provider of system administration status'))
def test_remove_user_from_namespace(log_collector): storage = create_autospec(IDMappingStorage, spec_set=True, instance=True) handlers = create_autospec(UserLookupSet, spec_set=True, instance=True) idm = IDMapper(handlers, set([AuthsourceID('astwo')]), storage) handlers.get_user.return_value = (User(AuthsourceID('astwo'), Username('foo')), True) idm.remove_user_from_namespace( AuthsourceID('astwo'), Token('t'), NamespaceID('ns1'), User(AuthsourceID('asone'), Username('u1'))) assert handlers.get_user.call_args_list == [((AuthsourceID('astwo'), Token('t'),), {})] assert storage.remove_user_from_namespace.call_args_list == \ [((NamespaceID('ns1'), User(AuthsourceID('asone'), Username('u1'))), {})] assert_logs_correct(log_collector, 'Admin astwo/foo removed user asone/u1 from namespace ns1')
def test_remove_mapping_fail_no_such_other_namespace(): # since the return value of the 2nd get namespace call isn't used, and the reason for the # call is to check the namespace exists, we explicitly test the call is made by throwing # an exception. storage = create_autospec(IDMappingStorage, spec_set=True, instance=True) handlers = create_autospec(UserLookupSet, spec_set=True, instance=True) idm = IDMapper(handlers, set(), storage) handlers.get_user.return_value = (User(AuthsourceID('a'), Username('n')), False) storage.get_namespace.side_effect = [ Namespace(NamespaceID('n1'), False, set([ User(AuthsourceID('a'), Username('n')), User(AuthsourceID('a'), Username('n2'))])), NoSuchNamespaceError('n2')] fail_remove_mapping(idm, AuthsourceID('a'), Token('t'), ObjectID(NamespaceID('n1'), 'o1'), ObjectID(NamespaceID('n2'), 'o2'), NoSuchNamespaceError('n2'))
def test_namespace_init_pass(): ns = Namespace(NamespaceID('foo'), True) assert ns.namespace_id == NamespaceID('foo') assert ns.is_publicly_mappable is True assert ns.authed_users == set() ns = Namespace(NamespaceID('whee'), False, None) assert ns.namespace_id == NamespaceID('whee') assert ns.is_publicly_mappable is False assert ns.authed_users == set() ns = Namespace(NamespaceID('baz'), True, set()) assert ns.namespace_id == NamespaceID('baz') assert ns.is_publicly_mappable is True assert ns.authed_users == set() ns = Namespace(NamespaceID('foo'), False, set([User(AuthsourceID('bar'), Username('baz'))])) assert ns.namespace_id == NamespaceID('foo') assert ns.is_publicly_mappable is False assert ns.authed_users == set([User(AuthsourceID('bar'), Username('baz'))])
def test_namespace_equals(): asid = AuthsourceID('as') assert Namespace(NamespaceID('foo'), True, None) == Namespace(NamespaceID('foo'), True, set()) assert Namespace(NamespaceID('foo'), False, set([User(asid, 'foo'), User(asid, 'baz')])) == \ Namespace(NamespaceID('foo'), False, set([User(asid, 'baz'), User(asid, 'foo')])) assert Namespace(NamespaceID('bar'), True, set()) != Namespace( NamespaceID('foo'), True, set()) assert Namespace(NamespaceID('foo'), False, set()) != \ Namespace(NamespaceID('foo'), True, set()) assert Namespace(NamespaceID('foo'), False, set([User(asid, 'foo'), User(asid, 'baz')])) != \ Namespace(NamespaceID('foo'), False, set([User(asid, 'baz'), User(asid, 'fob')])) assert Namespace(NamespaceID('foo'), False, set()) != NamespaceID('foo')
def set_up_data_for_get_namespaces(idstorage): idstorage.create_namespace(NamespaceID('ns1')) idstorage.set_namespace_publicly_mappable(NamespaceID('ns1'), True) idstorage.add_user_to_namespace(NamespaceID('ns1'), User(AuthsourceID('as'), Username('u'))) idstorage.create_namespace(NamespaceID('ns2')) idstorage.create_namespace(NamespaceID('ns3')) idstorage.add_user_to_namespace(NamespaceID('ns3'), User(AuthsourceID('as'), Username('u'))) idstorage.add_user_to_namespace( NamespaceID('ns3'), User(AuthsourceID('astwo'), Username('u3'))) expected = [ Namespace(NamespaceID('ns1'), True, set([User(AuthsourceID('as'), Username('u'))])), Namespace(NamespaceID('ns2'), False), Namespace( NamespaceID('ns3'), False, set([ User(AuthsourceID('as'), Username('u')), User(AuthsourceID('astwo'), Username('u3')) ])) ] return expected
def test_set_is_valid_user_invalid_user(): # invalid users shouldn't get cached. handler = create_autospec(UserLookup, spec_set=True, instance=True) timer = create_autospec(time.time, spec_set=True) handler.get_authsource_id.return_value = AuthsourceID('as') hset = UserLookupSet(set([handler]), timer) handler.is_valid_user.return_value = (False, None, None) timer.return_value = 0 # user will not be in cache assert hset.is_valid_user(User(AuthsourceID('as'), Username('u'))) is False # would normally expect a cache time of 3600s, but should not be cached here. timer.return_value = 10 assert hset.is_valid_user(User(AuthsourceID('as'), Username('u'))) is False assert handler.is_valid_user.call_args_list == [((Username('u'), ), {}), ((Username('u'), ), {})]
def test_create_namespace(log_collector): storage = create_autospec(IDMappingStorage, spec_set=True, instance=True) handlers = create_autospec(UserLookupSet, spec_set=True, instance=True) idm = IDMapper(handlers, set([AuthsourceID('as')]), storage) handlers.get_user.return_value = (User(AuthsourceID('as'), Username('foo')), True) idm.create_namespace(AuthsourceID('as'), Token('bar'), NamespaceID('baz')) assert handlers.get_user.call_args_list == [((AuthsourceID('as'), Token('bar'),), {})] assert storage.create_namespace.call_args_list == [((NamespaceID('baz'),), {})] assert_logs_correct(log_collector, 'Admin as/foo created namespace baz')
def check_get_user(isadmin, customroles): with requests_mock.Mocker() as m: m.get('http://my1stauthservice.com/api/api/V2/token', request_headers={'Authorization': 'bar'}, json={'user': '******', 'expires': 4800, 'cachefor': 5600}) m.get('http://my1stauthservice.com/api/api/V2/me', request_headers={'Authorization': 'bar'}, json={'customroles': customroles}) kbuh = get_user_handler('http://my1stauthservice.com/api', Token('foo'), 'mapping_admin') assert kbuh.get_user(Token('bar')) == \ (User(AuthsourceID('kbase'), Username('u1')), isadmin, 4, 5)