def test_kb_config_maximal_config(): p = mock_path_to_file('path', [ '[idmapping]', 'mongo-host=foo', 'mongo-db=bar', 'mongo-user=u', 'mongo-pwd=p', 'dont-trust-x-ip-headers=true', 'authentication-enabled= authone, auththree, \t authtwo , local ', 'authentication-admin-enabled= authone, autha, \t authbcd ', 'auth-source-authone-factory-module= some.module \t ', 'auth-source-authtwo-factory-module= some.other.module \t ', 'auth-source-authtwo-init-key= val \t ', 'auth-source-authtwo-init-whee= whoo \t ', 'auth-source-auththree-factory-module= some.other.other.module \t ', 'auth-source-auththree-init-x=Y']) c = KBaseConfig(p) assert c.mongo_host == 'foo' assert c.mongo_db == 'bar' assert c.mongo_user == 'u' assert c.mongo_pwd == 'p' assert c.auth_enabled == set([AuthsourceID('authone'), AuthsourceID('authtwo'), AuthsourceID('auththree'), AuthsourceID('local')]) assert c.auth_admin_enabled == set([AuthsourceID('authone'), AuthsourceID('authbcd'), AuthsourceID('autha')]) assert c.lookup_configs == {AuthsourceID('authone'): ('some.module', {}), AuthsourceID('authtwo'): ('some.other.module', {'key': 'val', 'whee': 'whoo'}), AuthsourceID('auththree'): ('some.other.other.module', {'x': 'Y'})} assert c.ignore_ip_headers is True
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 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 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 check_set_get_user_default_cache_ttl(hset, handler, timer, timervals): handler.get_user.return_value = (User(AuthsourceID('as'), Username('u')), False, None, None) timer.return_value = timervals[0] # user will not be in cache assert hset.get_user(AuthsourceID('as'), Token('t')) == \ (User(AuthsourceID('as'), Username('u')), False) # user is now cached handler.get_user.return_value = None # should cause error if called from now on timer.return_value = timervals[1] # just below default cache time assert hset.get_user(AuthsourceID('as'), Token('t')) == \ (User(AuthsourceID('as'), Username('u')), False) # now expire the user handler.get_user.return_value = (User(AuthsourceID('as'), Username('u')), True, None, None) timer.return_value = timervals[2] assert hset.get_user(AuthsourceID('as'), Token('t')) == \ (User(AuthsourceID('as'), Username('u')), True) # get the user again, should be cached. handler.get_user.return_value = None # should cause error if called from now on timer.return_value = timervals[3] assert hset.get_user(AuthsourceID('as'), Token('t')) == \ (User(AuthsourceID('as'), Username('u')), True) assert handler.get_user.call_args_list == [((Token('t'), ), {}), ((Token('t'), ), {})]
def test_create_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_create_namespace(idm, AuthsourceID('as'), Token('t'), NamespaceID('n'), UnauthorizedError( 'Auth source as is not configured as a provider of system administration status'))
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_create_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_create_namespace(idm, AuthsourceID('as'), Token('t'), NamespaceID('n'), UnauthorizedError('User as/foo is not a system administrator'))
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_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_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_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 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_None_input(): storage = create_autospec(IDMappingStorage, spec_set=True, instance=True) handlers = create_autospec(UserLookupSet, spec_set=True, instance=True) idm = IDMapper(handlers, set(), storage) as_ = AuthsourceID('a') t = Token('t') n = NamespaceID('n') u = User(AuthsourceID('b'), Username('u')) # authsource id is checked by the handler set fail_remove_user_from_namespace(idm, as_, None, n, u, TypeError('token cannot be None')) fail_remove_user_from_namespace(idm, as_, t, None, u, TypeError('namespace_id cannot be None')) fail_remove_user_from_namespace(idm, as_, t, n, None, TypeError('user cannot be None'))
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_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 check_set_get_user_default_cache_ttl_set_ttl(ttl, 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, cache_user_expiration=ttl) check_set_get_user_default_cache_ttl(hset, handler, timer, timervals)
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 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_set_get_user_default_cache_ttl(): 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) check_set_get_user_default_cache_ttl(hset, handler, timer, [0, 299, 300, 301])
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_init_fail(): storage = create_autospec(IDMappingStorage, spec_set=True, instance=True) handlers = create_autospec(UserLookupSet, spec_set=True, instance=True) a = AuthsourceID('a') fail_init(None, set(), storage, TypeError('user_lookup cannot be None')) fail_init(handlers, None, storage, TypeError('admin_authsources cannot be None')) fail_init(handlers, set([a, None]), storage, TypeError('None item in admin_authsources')) fail_init(handlers, set(), None, TypeError('storage cannot be None'))
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 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