Example #1
0
def test_handle_auth_error(mocker):
    flash = mocker.patch("flask_multipass.core.flash")
    app = Flask("test")
    app.config["SECRET_KEY"] = "testing"
    multipass = Multipass(app)
    with app.test_request_context():
        multipass.handle_auth_error(AuthenticationFailed())
        assert flash.called
        assert session["_multipass_auth_failed"]
Example #2
0
def test_handle_auth_error(mocker):
    flash = mocker.patch('flask_multipass.core.flash')
    app = Flask('test')
    app.config['SECRET_KEY'] = 'testing'
    multipass = Multipass(app)
    with app.test_request_context():
        multipass.handle_auth_error(AuthenticationFailed())
        assert flash.called
        assert session['_multipass_auth_failed']
Example #3
0
def test_multiple_apps():
    apps = Flask('test'), Flask('test')
    multipass = Multipass()
    for app in apps:
        multipass.init_app(app)
    # The separate loop here is on purpose as the extension needs to
    # be present on all apps after initializing them
    for app in apps:
        assert app.extensions['multipass'].multipass is multipass
Example #4
0
def test_handle_auth_error(mocker):
    flash = mocker.patch('flask_multipass.core.flash')
    app = Flask('test')
    app.config['SECRET_KEY'] = 'testing'
    multipass = Multipass(app)
    with app.test_request_context():
        multipass.handle_auth_error(AuthenticationFailed())
        assert flash.called
        assert session['_multipass_auth_failed']
Example #5
0
def test_multiple_apps():
    apps = Flask("test"), Flask("test")
    multipass = Multipass()
    for app in apps:
        multipass.init_app(app)
    # The separate loop here is on purpose as the extension needs to
    # be present on all apps after initializing them
    for app in apps:
        assert app.extensions["multipass"].multipass is multipass
Example #6
0
def test_handle_auth_error_with_redirect(mocker):
    flash = mocker.patch('flask_multipass.core.flash')
    redirect = mocker.patch('flask_multipass.core.redirect')
    app = Flask('test')
    app.config['SECRET_KEY'] = 'testing'
    multipass = Multipass(app)
    with app.test_request_context():
        multipass.handle_auth_error(AuthenticationFailed(), redirect_to_login=True)
        assert flash.called
        redirect.assert_called_with(app.config['MULTIPASS_LOGIN_URLS'][0])
Example #7
0
def test_handle_auth_error_with_redirect(mocker):
    flash = mocker.patch("flask_multipass.core.flash")
    redirect = mocker.patch("flask_multipass.core.redirect")
    app = Flask("test")
    app.config["SECRET_KEY"] = "testing"
    multipass = Multipass(app)
    with app.test_request_context():
        multipass.handle_auth_error(AuthenticationFailed(), redirect_to_login=True)
        assert flash.called
        redirect.assert_called_with(app.config["MULTIPASS_LOGIN_URLS"][0])
Example #8
0
def test_next_url_invalid():
    app = Flask('test')
    app.add_url_rule('/success', 'success')
    app.config['SECRET_KEY'] = 'testing'
    app.config['MULTIPASS_SUCCESS_ENDPOINT'] = 'success'
    multipass = Multipass(app)
    with app.test_request_context():
        request.args = {'next': '//evil.com'}
        multipass.set_next_url()
        assert multipass._get_next_url() == '/success'
Example #9
0
def test_handle_auth_error_with_redirect(mocker):
    flash = mocker.patch('flask_multipass.core.flash')
    redirect = mocker.patch('flask_multipass.core.redirect')
    app = Flask('test')
    app.config['SECRET_KEY'] = 'testing'
    multipass = Multipass(app)
    with app.test_request_context():
        multipass.handle_auth_error(AuthenticationFailed(), redirect_to_login=True)
        assert flash.called
        redirect.assert_called_with(app.config['MULTIPASS_LOGIN_URLS'][0])
Example #10
0
def test_render_template(mocker):
    render_template = mocker.patch('flask_multipass.core.render_template')
    app = Flask('test')
    app.config['MULTIPASS_FOO_TEMPLATE'] = None
    app.config['MULTIPASS_BAR_TEMPLATE'] = 'bar.html'
    multipass = Multipass(app)
    with app.app_context():
        with pytest.raises(RuntimeError):
            multipass.render_template('FOO', foo='bar')
        multipass.render_template('BAR', foo='bar')
        render_template.assert_called_with('bar.html', foo='bar')
Example #11
0
def test_render_template(mocker):
    render_template = mocker.patch("flask_multipass.core.render_template")
    app = Flask("test")
    app.config["MULTIPASS_FOO_TEMPLATE"] = None
    app.config["MULTIPASS_BAR_TEMPLATE"] = "bar.html"
    multipass = Multipass(app)
    with app.app_context():
        with pytest.raises(RuntimeError):
            multipass.render_template("FOO", foo="bar")
        multipass.render_template("BAR", foo="bar")
        render_template.assert_called_with("bar.html", foo="bar")
Example #12
0
def test_get_state_explicit():
    app = Flask('test')
    app2 = Flask('test2')
    multipass = Multipass()
    multipass.init_app(app)
    multipass.init_app(app2)
    # outside app ctx
    with pytest.raises(RuntimeError):
        assert get_state().app
    # explicit app
    assert get_state(app2).app is app2
    # explicit app inside other app context (unlikely)
    with app.app_context():
        assert get_state(app2).app is app2
Example #13
0
def test_login_finished():
    multipass = Multipass()
    with pytest.raises(AssertionError):
        multipass.login_finished(None)
    callback = Mock()
    multipass.identity_handler(callback)
    multipass.login_finished('foo')
    callback.assert_called_with('foo')
Example #14
0
def test_get_members(mocker, settings, group_dn, mock_data, expected):
    mocker.patch('flask_multipass.providers.ldap.util.ReconnectLDAPObject')
    mocker.patch(
        'flask_multipass.providers.ldap.providers.build_group_search_filter',
        side_effect=MagicMock(side_effect=mock_data['groups']))
    mocker.patch(
        'flask_multipass.providers.ldap.providers.build_user_search_filter',
        side_effect=MagicMock(side_effect=mock_data['groups']))
    app = Flask('test')
    multipass = Multipass(app)
    with app.app_context():
        idp = LDAPIdentityProvider(multipass, 'LDAP test idp', settings)

    idp._search_groups = MagicMock(
        side_effect=lambda x: mock_data['subgroups'].get(x, []))
    idp._search_users = MagicMock(
        side_effect=lambda x: mock_data['users'].get(x, []))
    group = LDAPGroup(idp, 'LDAP test group', group_dn)

    with pytest.raises(StopIteration):
        members = group.get_members()
        while True:
            member = next(members)
            assert member.provider.name == idp.name
            assert member.identifier == expected.pop(0)
Example #15
0
def test_map_search_criteria(criteria, mapping, result):
    app = Flask('test')
    Multipass(app)
    with app.app_context():
        settings = {'mapping': mapping}
        provider = IdentityProvider(None, 'foo', settings)
        assert provider.map_search_criteria(criteria) == result
Example #16
0
def test_login_view(mocker):
    handle_auth_error = mocker.patch.object(Multipass, 'handle_auth_error')
    app = Flask('test')
    e = AuthenticationFailed()

    @app.route('/ok')
    @login_view
    def ok():
        return ''

    @app.route('/err')
    @login_view
    def err():
        raise Exception

    @app.route('/fail')
    @login_view
    def fail():
        raise e

    Multipass(app)
    with app.test_client() as c:
        c.get('/ok')
        assert not handle_auth_error.called
        c.get('/err')
        assert not handle_auth_error.called
        c.get('/fail')
        handle_auth_error.assert_called_with(e, True)
Example #17
0
def test_create_login_rule(mocker):
    process_login = mocker.patch.object(Multipass, 'process_login')
    app = Flask('test')
    Multipass(app)
    with app.test_client() as c:
        for url in app.config['MULTIPASS_LOGIN_URLS']:
            c.get(url)
    assert process_login.call_count == 2
Example #18
0
def test_get_state():
    app = Flask('test')
    multipass = Multipass(app)
    with app.app_context():
        state = get_state(app)
        assert state.multipass is multipass
        assert state.app is app
        assert get_state(app) is state
Example #19
0
def test_settings_copied():
    app = Flask('test')
    Multipass(app)
    with app.app_context():
        settings = {'foo': 'bar'}
        provider = IdentityProvider(None, None, settings)
        provider.settings['foo'] = 'foobar'
        assert settings['foo'] == 'bar'
Example #20
0
def test_create_login_rule_disabled(mocker):
    process_login = mocker.patch.object(Multipass, 'process_login')
    app = Flask('test')
    app.config['MULTIPASS_LOGIN_URLS'] = None
    Multipass(app)
    with app.test_client() as c:
        for url in ('/login/', '/login/<provider>'):
            assert c.get(url).status_code == 404
    assert not process_login.called
Example #21
0
def test_default_idp_settings(mocker, required_settings, expected_settings):
    certifi = mocker.patch('flask_multipass.providers.ldap.providers.certifi')
    certifi.where.return_value = '/default/ca-certs-file'
    app = Flask('test')
    multipass = Multipass(app)
    with app.app_context():
        idp = LDAPIdentityProvider(multipass, 'LDAP test idp',
                                   {'ldap': required_settings})
    assert idp.ldap_settings == expected_settings
Example #22
0
def test_initialize_providers_unique():
    app = Flask('test')
    app.config['MULTIPASS_AUTH_PROVIDERS'] = {
        'test': {'type': 'unique', 'foo': 'bar'},
        'test2': {'type': 'unique', 'hello': 'world'},
    }
    multipass = Multipass()
    multipass.register_provider(FooProvider, 'foo')
    multipass.register_provider(UniqueProvider, 'unique')
    with pytest.raises(RuntimeError):
        multipass.init_app(app)
Example #23
0
def test_login_finished():
    multipass = Multipass()
    with pytest.raises(AssertionError):
        multipass.login_finished(None)
    callback = Mock()
    multipass.identity_handler(callback)
    multipass.login_finished("foo")
    callback.assert_called_with("foo")
Example #24
0
def test_has_member_bad_identifier(mocker, settings):
    mocker.patch('flask_multipass.providers.ldap.util.ReconnectLDAPObject')
    app = Flask('test')
    multipass = Multipass(app)
    with app.app_context():
        idp = LDAPIdentityProvider(multipass, 'LDAP test idp', settings)
    group = LDAPGroup(idp, 'LDAP test group', 'group_dn')

    with pytest.raises(IdentityRetrievalFailed):
        group.has_member(None)
Example #25
0
def test_next_url():
    app = Flask('test')
    app.add_url_rule('/success', 'success')
    app.config['SECRET_KEY'] = 'testing'
    app.config['MULTIPASS_SUCCESS_ENDPOINT'] = 'success'
    multipass = Multipass(app)
    with app.test_request_context():
        # default url - not in session
        assert multipass._get_next_url() == '/success'
        multipass.set_next_url()
        # default url - in session
        assert multipass._get_next_url() == '/success'
        request.args = {'next': '/private'}
        # next url specified, but not in session yet
        assert multipass._get_next_url() == '/success'
        multipass.set_next_url()
        # removed from session after retrieving it once
        assert multipass._get_next_url() == '/private'
        assert multipass._get_next_url() == '/success'
Example #26
0
def test_has_member_slapd(mocker, settings, group_dn, user_mock, expected):
    mocker.patch('flask_multipass.providers.ldap.util.ReconnectLDAPObject')
    mocker.patch('flask_multipass.providers.ldap.providers.get_user_by_id',
                 return_value=(user_mock['dn'], user_mock['data']))

    app = Flask('test')
    multipass = Multipass(app)
    with app.app_context():
        idp = LDAPIdentityProvider(multipass, 'LDAP test idp', settings)
    group = LDAPGroup(idp, 'LDAP test group', group_dn)
    assert group.has_member(user_mock['data']['uid'][0]) == expected
Example #27
0
def test_initialize_providers_unique():
    app = Flask('test')
    app.config['MULTIPASS_AUTH_PROVIDERS'] = {
        'test': {'type': 'unique', 'foo': 'bar'},
        'test2': {'type': 'unique', 'hello': 'world'},
    }
    multipass = Multipass()
    multipass.register_provider(FooProvider, 'foo')
    multipass.register_provider(UniqueProvider, 'unique')
    with pytest.raises(RuntimeError):
        multipass.init_app(app)
Example #28
0
def test_has_member_unknown_user(mocker, settings):
    mocker.patch('flask_multipass.providers.ldap.util.ReconnectLDAPObject')
    mocker.patch('flask_multipass.providers.ldap.providers.get_user_by_id',
                 return_value=(None, {
                     'cn': ['Configuration']
                 }))
    app = Flask('test')
    multipass = Multipass(app)
    with app.app_context():
        idp = LDAPIdentityProvider(multipass, 'LDAP test idp', settings)
    group = LDAPGroup(idp, 'LDAP test group', 'group_dn')

    assert not group.has_member('unknown_user')
Example #29
0
def test_initialize_providers_unique():
    app = Flask("test")
    app.config["MULTIPASS_AUTH_PROVIDERS"] = {
        "test": {"type": "unique", "foo": "bar"},
        "test2": {"type": "unique", "hello": "world"},
    }
    multipass = Multipass()
    multipass.register_provider(FooProvider, "foo")
    multipass.register_provider(UniqueProvider, "unique")
    with pytest.raises(RuntimeError):
        multipass.init_app(app)
Example #30
0
def test_next_url():
    app = Flask('test')
    app.add_url_rule('/success', 'success')
    app.config['SECRET_KEY'] = 'testing'
    app.config['MULTIPASS_SUCCESS_ENDPOINT'] = 'success'
    multipass = Multipass(app)
    with app.test_request_context():
        # default url - not in session
        assert multipass._get_next_url() == '/success'
        multipass._set_next_url()
        # default url - in session
        assert multipass._get_next_url() == '/success'
        request.args = {'next': '/private'}
        # next url specified, but not in session yet
        assert multipass._get_next_url() == '/success'
        multipass._set_next_url()
        # removed from session after retrieving it once
        assert multipass._get_next_url() == '/private'
        assert multipass._get_next_url() == '/success'
Example #31
0
def test_next_url():
    app = Flask("test")
    app.add_url_rule("/success", "success")
    app.config["SECRET_KEY"] = "testing"
    app.config["MULTIPASS_SUCCESS_ENDPOINT"] = "success"
    multipass = Multipass(app)
    with app.test_request_context():
        # default url - not in session
        assert multipass._get_next_url() == "/success"
        multipass.set_next_url()
        # default url - in session
        assert multipass._get_next_url() == "/success"
        request.args = {"next": "/private"}
        # next url specified, but not in session yet
        assert multipass._get_next_url() == "/success"
        multipass.set_next_url()
        # removed from session after retrieving it once
        assert multipass._get_next_url() == "/private"
        assert multipass._get_next_url() == "/success"
Example #32
0
def test_initialize_providers():
    app = Flask('test')
    app.config['MULTIPASS_AUTH_PROVIDERS'] = {
        'test': {'type': 'foo', 'foo': 'bar'},
        'test2': {'type': 'unique', 'hello': 'world'},
    }
    multipass = Multipass()
    multipass.register_provider(FooProvider, 'foo')
    multipass.register_provider(UniqueProvider, 'unique')
    with app.app_context():
        auth_providers = multipass._create_providers('AUTH', AuthProvider)
        assert auth_providers['test'].settings == {'foo': 'bar'}
        assert auth_providers['test2'].settings == {'hello': 'world'}
Example #33
0
def test_render_template(mocker):
    render_template = mocker.patch('flask_multipass.core.render_template')
    app = Flask('test')
    app.config['MULTIPASS_FOO_TEMPLATE'] = None
    app.config['MULTIPASS_BAR_TEMPLATE'] = 'bar.html'
    multipass = Multipass(app)
    with app.app_context():
        with pytest.raises(RuntimeError):
            multipass.render_template('FOO', foo='bar')
        multipass.render_template('BAR', foo='bar')
        render_template.assert_called_with('bar.html', foo='bar')
Example #34
0
def test_iter_group(mocker, settings, group_dn, subgroups, expected):
    app = Flask('test')
    multipass = Multipass(app)
    with app.app_context():
        idp = LDAPIdentityProvider(multipass, 'LDAP test idp', settings)
    group = LDAPGroup(idp, 'LDAP test group', group_dn)
    visited_groups = []
    iter_group = group._iter_group()
    # should not throw StopIteration as the initial group dn must be returned first
    current_dn = next(iter_group)
    with pytest.raises(StopIteration):
        while current_dn:
            visited_groups.append(current_dn)
            current_dn = iter_group.send(subgroups.get(current_dn, []))

    assert len(visited_groups) == len(expected)
    assert set(visited_groups) == expected
Example #35
0
def test_initialize_providers():
    app = Flask('test')
    app.config['MULTIPASS_AUTH_PROVIDERS'] = {
        'test': {'type': 'foo', 'foo': 'bar'},
        'test2': {'type': 'unique', 'hello': 'world'},
    }
    multipass = Multipass()
    multipass.register_provider(FooProvider, 'foo')
    multipass.register_provider(UniqueProvider, 'unique')
    with app.app_context():
        auth_providers = multipass._create_providers('AUTH', AuthProvider)
        assert auth_providers['test'].settings == {'foo': 'bar'}
        assert auth_providers['test2'].settings == {'hello': 'world'}
Example #36
0
def test_initialize_providers():
    app = Flask("test")
    app.config["MULTIPASS_AUTH_PROVIDERS"] = {
        "test": {"type": "foo", "foo": "bar"},
        "test2": {"type": "unique", "hello": "world"},
    }
    multipass = Multipass()
    multipass.register_provider(FooProvider, "foo")
    multipass.register_provider(UniqueProvider, "unique")
    with app.app_context():
        auth_providers = multipass._create_providers("AUTH", AuthProvider)
        assert auth_providers["test"].settings == {"foo": "bar"}
        assert auth_providers["test2"].settings == {"hello": "world"}
Example #37
0
def test_get_state_explicit():
    app = Flask('test')
    app2 = Flask('test2')
    multipass = Multipass()
    multipass.init_app(app)
    multipass.init_app(app2)
    # outside app ctx
    with pytest.raises(RuntimeError):
        assert get_state().app
    # explicit app
    assert get_state(app2).app is app2
    # explicit app inside other app context (unlikely)
    with app.app_context():
        assert get_state(app2).app is app2
Example #38
0
def test_has_member_ad(mocker, settings, group_mock, user_mock, expected):
    def get_token_groups(user_dn):
        if user_mock['dn'] != user_dn:
            pytest.fail('expected {0}, got {1}'.format(user_mock['dn'],
                                                       user_dn))
        return user_mock['token_groups']

    mocker.patch('flask_multipass.providers.ldap.util.ReconnectLDAPObject')
    mocker.patch('flask_multipass.providers.ldap.providers.get_user_by_id',
                 return_value=(user_mock['dn'], user_mock['data']))
    mocker.patch('flask_multipass.providers.ldap.providers.get_group_by_id',
                 return_value=(group_mock['dn'], group_mock['data']))
    mocker.patch(
        'flask_multipass.providers.ldap.providers.get_token_groups_from_user_dn',
        side_effect=get_token_groups)

    app = Flask('test')
    multipass = Multipass(app)
    with app.app_context():
        idp = LDAPIdentityProvider(multipass, 'LDAP test idp', settings)
    group = LDAPGroup(idp, 'LDAP test group', group_mock['dn'])
    assert group.has_member(user_mock['data']['uid'][0]) == expected
Example #39
0
def test_login_finished_returns():
    multipass = Multipass()
    multipass.identity_handler(Mock(return_value='bar'))
    assert multipass.login_finished('foo') == 'bar'
Example #40
0
def test_login_finished_returns():
    multipass = Multipass()
    multipass.identity_handler(Mock(return_value='bar'))
    assert multipass.login_finished('foo') == 'bar'
Example #41
0
def test_login_check():
    multipass = Multipass()
    callback = Mock()
    assert multipass.login_check(callback) is callback
Example #42
0
def test_identity_handler():
    multipass = Multipass()
    callback = Mock()
    assert multipass.identity_handler(callback) is callback
Example #43
0
def test_init_app_twice():
    multipass = Multipass()
    app = Flask("test")
    multipass.init_app(app)
    with pytest.raises(RuntimeError):
        multipass.init_app(app)
Example #44
0
def test_validate_next_url(url, valid):
    app = Flask('test')
    multipass = Multipass(app)
    with app.test_request_context():
        assert multipass.validate_next_url(url) == valid
Example #45
0
def test_login_check():
    multipass = Multipass()
    callback = Mock()
    assert multipass.login_check(callback) is callback
Example #46
0
from __future__ import unicode_literals

import json

from flask import Flask, render_template, flash, session, url_for, redirect, request, g
from flask_sqlalchemy import SQLAlchemy

from flask_multipass import Multipass
from flask_multipass.providers.sqlalchemy import SQLAlchemyAuthProviderBase, SQLAlchemyIdentityProviderBase


application = app = Flask(__name__)
app.debug = True
app.secret_key = 'fma-example'
db = SQLAlchemy()
multipass = Multipass()


class User(db.Model):
    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    email = db.Column(db.String)
    affiliation = db.Column(db.String)


class Identity(db.Model):
    __tablename__ = 'identities'

    id = db.Column(db.Integer, primary_key=True)
Example #47
0
def test_init_app_twice():
    multipass = Multipass()
    app = Flask('test')
    multipass.init_app(app)
    with pytest.raises(RuntimeError):
        multipass.init_app(app)
Example #48
0
def test_init_app_late():
    app = Flask('text')
    multipass = Multipass()
    multipass.init_app(app)
    assert app.extensions['multipass'].multipass is multipass
Example #49
0
def test_init_app_late():
    app = Flask("text")
    multipass = Multipass()
    multipass.init_app(app)
    assert app.extensions["multipass"].multipass is multipass
Example #50
0
def test_init_app_late():
    app = Flask('text')
    multipass = Multipass()
    multipass.init_app(app)
    assert app.extensions['multipass'].multipass is multipass
Example #51
0
def test_login_finished_returns():
    multipass = Multipass()
    multipass.identity_handler(Mock(return_value="bar"))
    assert multipass.login_finished("foo") == "bar"
Example #52
0
def test_identity_handler():
    multipass = Multipass()
    callback = Mock()
    assert multipass.identity_handler(callback) is callback
Example #53
0
def test_init_app_immediately():
    app = Flask('test')
    multipass = Multipass(app)
    assert app.extensions['multipass'].multipass is multipass