# License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. from __future__ import absolute_import import time from flask import session from flask.ext.login import current_user from nose.tools import assert_raises from nose.tools import eq_ from nose.tools import with_setup from relengapi.lib import auth from relengapi.lib.permissions import p from relengapi.lib.testing.context import TestContext test_context = TestContext() p.test_lib_auth.a.doc("test perm a") p.test_lib_auth.b.doc("test perm b") def clear_loaders(): auth._request_loaders = [] def test_AnonymousUser(): u = auth.AnonymousUser() eq_(u.type, 'anonymous') eq_(str(u), 'anonymous:') eq_(u.is_authenticated, False) eq_(u.is_active, False) eq_(u.is_anonymous, True) eq_(u.permissions, set()) @test_context def test_HumanUser(app): u = auth.HumanUser("florence@nightingale.com") eq_(u.type, 'human') eq_(u.authenticated_email, 'florence@nightingale.com') eq_(str(u), 'human:florence@nightingale.com') eq_(u.is_authenticated, True) eq_(u.is_active, True) eq_(u.is_anonymous, False) with app.test_request_context('/'): eq_(u.permissions, set()) @test_context def test_HumanUser_perms_in_session(app): u = auth.HumanUser("florence@nightingale.com") with app.test_request_context('/'): session['perms'] = ['test_lib_auth.a'] session['perms_exp'] = time.time() + 10000 eq_(u.permissions, set([p.test_lib_auth.a])) del session['perms'] # .. and still cached eq_(u.permissions, set([p.test_lib_auth.a])) @test_context def test_HumanUser_perms_session_expired(app): @auth.permissions_stale.connect_via(app) def set_perms(app, user, permissions): permissions.add(p.test_lib_auth.a) permissions.add(p.test_lib_auth.b) u = auth.HumanUser("florence@nightingale.com") with app.test_request_context('/'): session['perms'] = ['test_lib_auth.a'] session['perms_exp'] = time.time() - 10000 eq_(u.permissions, set([p.test_lib_auth.a, p.test_lib_auth.b])) eq_(sorted(session['perms']), ['test_lib_auth.a', 'test_lib_auth.b']) assert session['perms_exp'] > time.time() @with_setup(clear_loaders, clear_loaders) @test_context def test_request_loader(app, client): @auth.request_loader def rl(req): if 'user' in req.headers: return auth.HumanUser(req.headers['user']) @app.route("/test") def test(): return str(current_user) eq_(client.get('/test').data, 'anonymous:') eq_(client.get('/test', headers=[('user', 'f@n.com')]).data, 'human:f@n.com') @with_setup(clear_loaders, clear_loaders) def test_request_loader_not_set(): bad_user = auth.HumanUser('me@me.com') bad_user._permissions = 'not-a-set' auth._request_loaders = [lambda req: bad_user] assert_raises(TypeError, lambda: auth._request_loader(None)) @test_context def test_login_request(client): assert 'A valid login is required' in client.get('/login_request').data @test_context.specialize(user=auth.HumanUser('jeanne')) def test_login_request_logged_in(client): resp = client.get('/login_request') eq_((resp.status_code, resp.headers[ 'location']), (302, 'http://localhost/')) @test_context.specialize(user=auth.HumanUser('jeanne')) def test_login_request_logged_in_next(client): resp = client.get('/login_request?next=/foo') eq_((resp.status_code, resp.headers[ 'location']), (302, 'http://localhost/foo')) @test_context def test_clear_perms_cache(app): with app.test_request_context('/'): session['perms'] = ['test_lib_auth.a'] session['perms_exp'] = time.time() + 10000 auth._clear_perms_cache() assert 'perms' not in session assert 'perms_exp' not in session @test_context def test_config_invalid_auth_type(app): app.config['RELENGAPI_AUTHENTICATION'] = {'type': 'no-such'} assert_raises(RuntimeError, lambda: auth.init_app(app)) @test_context def test_config_invalid_perm_type(app): app.config['RELENGAPI_PERMISSIONS'] = {'type': 'no-such'} assert_raises(RuntimeError, lambda: auth.init_app(app))