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 check_set_get_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.get_user.return_value = (User(AuthsourceID('as'),
                                          Username('u1')), False, epoch, rel)
    timer.return_value = timervals[0]

    # cache user for X secs
    assert hset.get_user(AuthsourceID('as'), Token('t')) == \
        (User(AuthsourceID('as'), Username('u1')), False)

    # force an error if the handler is called
    handler.get_user.return_value = None
    timer.return_value = timervals[1]

    assert hset.get_user(AuthsourceID('as'), Token('t')) == \
        (User(AuthsourceID('as'), Username('u1')), False)

    # expect handler call at Y sec
    handler.get_user.return_value = (User(AuthsourceID('as'),
                                          Username('u1')), True, epoch, rel)
    timer.return_value = timervals[2]

    assert hset.get_user(AuthsourceID('as'), Token('t')) == \
        (User(AuthsourceID('as'), Username('u1')), True)

    # check correct number of calls to get_user
    assert handler.get_user.call_args_list == [((Token('t'), ), {}),
                                               ((Token('t'), ), {})]
Beispiel #3
0
def test_create_and_get_namespace(service_port, mongo):
    storage = get_storage_instance(mongo)
    t = Token('foobar')

    # fail to create a namespace
    r = requests.put('http://localhost:' + service_port +
                     '/api/v1/namespace/myns',
                     headers={'Authorization': 'local ' + t.token})

    assert_json_error_correct(
        r.json(), {
            'error': {
                'httpcode': 401,
                'httpstatus': 'Unauthorized',
                'appcode': 10020,
                'apperror': 'Invalid token',
                'message': '10020 Invalid token'
            }
        })
    assert r.status_code == 401

    # succeed at creating a namespace
    storage.create_local_user(Username('user1'), t.get_hashed_token())
    storage.set_local_user_as_admin(Username('user1'), True)

    r = requests.put('http://localhost:' + service_port +
                     '/api/v1/namespace/myns',
                     headers={'Authorization': 'local ' + t.token})

    assert r.status_code == 204

    # get the namespace with a populated user list
    r = requests.get('http://localhost:' + service_port +
                     '/api/v1/namespace/myns',
                     headers={'Authorization': 'local ' + t.token})

    assert r.json() == {
        'namespace': 'myns',
        'publicly_mappable': False,
        'users': []
    }

    assert r.status_code == 200

    # fail getting a namespace
    r = requests.get('http://localhost:' + service_port +
                     '/api/v1/namespace/myns1')

    assert_json_error_correct(
        r.json(), {
            'error': {
                'httpcode': 404,
                'httpstatus': 'Not Found',
                'appcode': 50010,
                'apperror': 'No such namespace',
                'message': '50010 No such namespace: myns1'
            }
        })
    assert r.status_code == 404
def test_get_user_fail_invalid_token_token():
    with requests_mock.Mocker() as m:
        m.get('http://my1stauthservice.com/api/api/V2/token',
              request_headers={'Authorization': 'bar'},
              status_code=401,
              json={'error': {'apperror': 'Invalid token', 'message': '10020 Invalid token'}})

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

        fail_get_user(kbuh, Token('bar'), InvalidTokenError(
            'KBase auth server reported token is invalid.'))
def test_get_user_fail_auth_returned_other_error_token():
    with requests_mock.Mocker() as m:
        m.get('http://my1stauthservice.com/api/api/V2/token',
              request_headers={'Authorization': 'bar'},
              status_code=401,
              json={'error': {'apperror': 'Authentication failed',
                              'message': '10000 Authentication failed: crap'}})

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

        fail_get_user(kbuh, Token('bar'),
                      IOError('Error from KBase auth server: 10000 Authentication failed: crap'))
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_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)
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')), {})]
Beispiel #10
0
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_init():
    with requests_mock.Mocker() as m:
        m.get('http://whee.com/',
              request_headers={'Accept': 'application/json'},
              json={'version': '0.1.2', 'gitcommithash': 'hashyhash', 'servertime': 3})
        kbuh = KBaseUserLookup('http://whee.com', Token('foo'), 'admin')
        assert kbuh.auth_url == 'http://whee.com/'
def test_get_user_fail_invalid_token_me():
    # this should basically be impossible, but it doesn't hurt to test it
    with requests_mock.Mocker() as m:
        m.get('http://my1stauthservice.com/api/api/V2/token',
              request_headers={'Authorization': 'bar'},
              json={'user': '******', 'expires': 2000, 'cachefor': 3000})

        m.get('http://my1stauthservice.com/api/api/V2/me',
              request_headers={'Authorization': 'bar'},
              status_code=401,
              json={'error': {'apperror': 'Invalid token', 'message': '10020 Invalid token'}})

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

        fail_get_user(kbuh, Token('bar'), InvalidTokenError(
            'KBase auth server reported token is invalid.'))
def test_get_user_fail_not_json_token(log_collector):
    html = '<html><body>Sorry gopsasquatchpron.com has been shut down</body></html>'
    with requests_mock.Mocker() as m:
        m.get('http://my1stauthservice.com/api/api/V2/token',
              request_headers={'Authorization': 'bar'},
              status_code=404,
              text=html)

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

        fail_get_user(kbuh, Token('bar'),
                      IOError('Non-JSON response from KBase auth server, status code: 404'))

    assert_logs_correct(
        log_collector, 'Non-JSON response from KBase auth server, status code: 404, response:\n' +
        html)
def test_get_user_fail_auth_returned_other_error_me():
    # this should basically be impossible, but it doesn't hurt to test it
    with requests_mock.Mocker() as m:
        m.get('http://my1stauthservice.com/api/api/V2/token',
              request_headers={'Authorization': 'bar'},
              json={'user': '******', 'expires': 2000, 'cachefor': 3000})

        m.get('http://my1stauthservice.com/api/api/V2/me',
              request_headers={'Authorization': 'bar'},
              status_code=401,
              json={'error': {'apperror': 'Authentication failed',
                              'message': '10000 Authentication failed: crap'}})

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

        fail_get_user(kbuh, Token('bar'),
                      IOError('Error from KBase auth server: 10000 Authentication failed: crap'))
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 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)
def check_missing_keys(json, missing_keys):
    with requests_mock.Mocker() as m:
        m.get('http://my1stauthservice.com/',
              request_headers={'Accept': 'application/json'},
              json=json)

        fail_init('http://my1stauthservice.com', Token('foo'), 'admin', IOError(
            'http://my1stauthservice.com/ does not appear to be the KBase auth server. ' +
            'The root JSON response does not contain the expected keys ' + missing_keys))
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_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_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_get_user_fail_not_json_me(log_collector):
    html = '<html><body>Sorry notthensa.com has been shut down</body></html>'
    with requests_mock.Mocker() as m:
        m.get('http://my1stauthservice.com/api/api/V2/token',
              request_headers={'Authorization': 'bar'},
              json={'user': '******', 'expires': 2000, 'cachefor': 3000})

        m.get('http://my1stauthservice.com/api/api/V2/me',
              request_headers={'Authorization': 'bar'},
              status_code=404,
              text=html)

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

        fail_get_user(kbuh, Token('bar'),
                      IOError('Non-JSON response from KBase auth server, status code: 404'))

    assert_logs_correct(
        log_collector, 'Non-JSON response from KBase auth server, status code: 404, response:\n' +
        html)
def test_init_with_builder():
    with requests_mock.Mocker() as m:
        m.get('http://whee.com/',
              request_headers={'Accept': 'application/json'},
              json={'version': '0.1.2', 'gitcommithash': 'hashyhash', 'servertime': 3})
        kbuh = build_lookup({'url': 'http://whee.com', 'token': 'foo', 'admin-role': 'admin'})
        assert kbuh.auth_url == 'http://whee.com/'
        # reach into the implementation here to avoid running all tests twice, one for constructor,
        # one for builder. Outweights the bad practice here
        assert kbuh._token == Token('foo')
        assert kbuh._kbase_system_admin == 'admin'
def test_create_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('foo')
    t = Token('t')
    n = NamespaceID('n')

    # authsource id is checked by the handler set
    fail_create_namespace(idm, as_, None, n, TypeError('token cannot be None'))
    fail_create_namespace(idm, as_, t, None, TypeError('namespace_id cannot be None'))
def test_init_fail_auth_returned_error():
    # there isn't really a believable error the auth service could generate at the root, so
    # we just use any old error
    with requests_mock.Mocker() as m:
        m.get('http://my1stauthservice.com/',
              request_headers={'Accept': 'application/json'},
              status_code=401,
              json={'error': {'apperror': 'Authentication failed',
                              'message': '10000 Authentication failed: crap'}})

        fail_init('http://my1stauthservice.com', Token('foo'), 'admin',
                  IOError('Error from KBase auth server: 10000 Authentication failed: crap'))
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'))
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 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_token_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(Token('foo')) == hash(Token('foo'))
    assert hash(Token('bar')) == hash(Token('bar'))
    assert hash(Token('foo')) != hash(Token('bar'))
def test_set_namespace_publicly_mappable_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)

    aid = AuthsourceID('asone')
    t = Token('t')
    n = NamespaceID('id')
    e = ' cannot be None'

    # handler set checks the authsource id
    fail_set_namespace_publicly_mappable(idm, aid, None, n, TypeError('token' + e))
    fail_set_namespace_publicly_mappable(idm, aid, t, None, TypeError('namespace_id' + e))
def test_init_fail_not_json(log_collector):
    html = '<html><body>Sorry mylittleponypron.com has been shut down</body></html>'
    with requests_mock.Mocker() as m:
        m.get('http://my1stauthservice.com/',
              request_headers={'Accept': 'application/json'},
              status_code=404,
              text=html)

        fail_init('http://my1stauthservice.com/', Token('foo'), 'admin',
                  IOError('Non-JSON response from KBase auth server, status code: 404'))

    assert_logs_correct(
        log_collector, 'Non-JSON response from KBase auth server, status code: 404, response:\n' +
        html)