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_local_get_users():
    storage = create_autospec(IDMappingStorage, spec_set=True, instance=True)
    storage.get_users.return_value = {
        Username('foo'): False,
        Username('bar'): True
    }

    assert LocalUserLookup(storage).get_users() == {
        Username('foo'): False,
        Username('bar'): True
    }

    assert storage.get_users.call_args_list == [((), {})]
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_get_namespace_not_admin():
    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'))]))
    handlers.get_user.return_value = (User(AuthsourceID('b'), Username('u2')), False)

    assert idm.get_namespace(NamespaceID('n'), AuthsourceID('b'), Token('t')) == Namespace(
        NamespaceID('n'), True, None)
    assert storage.get_namespace.call_args_list == [((NamespaceID('n'), ), {})]
    assert handlers.get_user.call_args_list == [((AuthsourceID('b'), Token('t')), {})]
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_local_is_valid_user():
    storage = create_autospec(IDMappingStorage, spec_set=True, instance=True)
    storage.user_exists.return_value = True

    luh = LocalUserLookup(storage)

    assert luh.is_valid_user(Username('foo')) == (True, None, 3600)

    storage.user_exists.return_value = False

    assert luh.is_valid_user(Username('bar')) == (False, None, 3600)

    assert storage.user_exists.call_args_list == [((Username('foo'), ), {}),
                                                  ((Username('bar'), ), {})]
Example #7
0
 def get_users(self) -> Dict[Username, bool]:
     try:
         userdocs = self._db[_COL_USERS].find({}, {_FLD_TOKEN: 0})
         return {Username(u[_FLD_USER]): u[_FLD_ADMIN] for u in userdocs}
     except PyMongoError as e:
         raise IDMappingStorageError('Connection to database failed: ' +
                                     str(e)) from e
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_update_user_token_fail_input_None(idstorage):
    t = HashedToken('t')
    u = Username('u')
    fail_update_user_token(idstorage, None, t,
                           TypeError('username cannot be None'))
    fail_update_user_token(idstorage, u, None,
                           TypeError('token cannot be None'))
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_is_valid_user(json, result):
    with requests_mock.Mocker() as m:
        m.get('http://my1stauthservice.com/api/api/V2/users/?list=imauser',
              request_headers={'Authorization': 'foo'},
              json=json)

        kbuh = get_user_handler('http://my1stauthservice.com/api/', Token('foo'), 'admin')

        assert kbuh.is_valid_user(Username('imauser')) == (result, None, 3600)
Example #14
0
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')
Example #15
0
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'))
Example #16
0
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'))
Example #17
0
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_get_users(idstorage):
    assert idstorage.get_users() == {}

    idstorage.create_local_user(Username('foo'), HashedToken('t1'))

    assert idstorage.get_users() == {Username('foo'): False}

    idstorage.create_local_user(Username('mrsentity'), HashedToken('t2'))
    idstorage.create_local_user(Username('mrsenigma'), HashedToken('t3'))
    idstorage.update_local_user_token(Username('mrsenigma'), HashedToken('t4'))

    idstorage.set_local_user_as_admin(Username('foo'), True)
    idstorage.set_local_user_as_admin(Username('mrsenigma'), True)

    assert idstorage.get_users() == {
        Username('foo'): True,
        Username('mrsenigma'): True,
        Username('mrsentity'): False
    }
Example #19
0
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_set_is_valid_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.is_valid_user.return_value = (True, None, None)
    timer.return_value = 0

    assert hset.is_valid_user(User(AuthsourceID('as'), Username('u1'))) is True

    # add user 2. Don't need another return value for is_valid_user, has to be True to cache
    timer.return_value = 1

    assert hset.is_valid_user(User(AuthsourceID('as'), Username('u2'))) is True

    # add user 3, user 1 should now be evicted from the cache
    timer.return_value = 2

    assert hset.is_valid_user(User(AuthsourceID('as'), Username('u3'))) is True

    # force an assert fail if is_valid_user is called early:
    handler.is_valid_user.return_value = (False, 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.is_valid_user(User(AuthsourceID('as'), Username('u2'))) is True

    assert hset.is_valid_user(User(AuthsourceID('as'), Username('u3'))) is True

    # get user 1
    handler.is_valid_user.return_value = (True, None, None)
    assert hset.is_valid_user(User(AuthsourceID('as'), Username('u1'))) is True

    # check that the calls to is_valid_user are as expected:
    assert handler.is_valid_user.call_args_list == [((Username('u1'), ), {}),
                                                    ((Username('u2'), ), {}),
                                                    ((Username('u3'), ), {}),
                                                    ((Username('u1'), ), {})]
def test_is_valid_user_fail_invalid_token():
    with requests_mock.Mocker() as m:
        m.get('http://my1stauthservice.com/api/api/V2/users/?list=supausah3',
              request_headers={'Authorization': 'foo'},
              status_code=401,
              json={'error': {'apperror': 'Invalid token', 'message': '10020 Invalid token'}})

        kbuh = get_user_handler('http://my1stauthservice.com/api', Token('foo'), 'admin')

        fail_is_valid_user(kbuh, Username('supausah3'), InvalidTokenError(
            'KBase auth server reported token is invalid.'))
def test_is_valid_user_fail_auth_returned_other_error():
    with requests_mock.Mocker() as m:
        m.get('http://my1stauthservice.com/api/api/V2/users/?list=supausah2',
              request_headers={'Authorization': 'baz'},
              status_code=400,
              json={'error': {'apperror': 'Authentication failed',
                              'message': '10000 Authentication failed: crap'}})

        kbuh = get_user_handler('http://my1stauthservice.com/api', Token('baz'), 'admin')

        fail_is_valid_user(kbuh, Username('supausah2'), IOError(
            'Error from KBase auth server: 10000 Authentication failed: crap'))
Example #23
0
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'))])
Example #24
0
    def get_user(self, token: HashedToken) -> Tuple[Username, bool]:
        not_none(token, 'token')
        try:
            userdoc = self._db[_COL_USERS].find_one(
                {_FLD_TOKEN: token.token_hash}, {_FLD_TOKEN: 0})
        except PyMongoError as e:
            raise IDMappingStorageError('Connection to database failed: ' +
                                        str(e)) from e

        if not userdoc:
            raise InvalidTokenError()
        return (Username(userdoc[_FLD_USER]), userdoc[_FLD_ADMIN])
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 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_update_and_get_user(idstorage):
    # create
    idstorage.create_local_user(Username('foo'), HashedToken('bar'))
    assert idstorage.get_user(HashedToken('bar')) == (Username('foo'), False)

    # update
    idstorage.update_local_user_token(Username('foo'), HashedToken('bat'))
    assert idstorage.get_user(HashedToken('bat')) == (Username('foo'), False)

    idstorage.update_local_user_token(Username('foo'), HashedToken('boo'))
    assert idstorage.get_user(HashedToken('boo')) == (Username('foo'), False)

    # test different user
    idstorage.create_local_user(Username('foo1'), HashedToken('baz'))
    assert idstorage.get_user(HashedToken('baz')) == (Username('foo1'), False)
Example #29
0
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)