Exemplo n.º 1
0
def test_webyosai_requires_user(web_yosai, mock_web_registry,
                                valid_thedude_username_password_token,
                                valid_thedude_totp_token):
    """
    confirm user approved and denied
    """
    # yeah, it's a dumb example but I chose the big lebowski cuz I love the movie
    @WebYosai.requires_user
    def transport_ransom(the_ringer, destination):
        return 'transported'

    with WebYosai.context(web_yosai, mock_web_registry):
        subject = WebYosai.get_current_subject()
        try:
            subject.login(valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            subject.login(valid_thedude_totp_token)
        result = transport_ransom('the_ringer', 'the_nihilists')

        assert result == 'transported'

        subject.logout()

        with pytest.raises(mock_web_registry.mock_exception):
            transport_ransom('the_ringer', 'the_nihilists')
Exemplo n.º 2
0
def test_webyosai_requires_role(web_yosai, mock_web_registry,
                                valid_thedude_username_password_token,
                                valid_thedude_totp_token):
    """
    confirm role approved and denied
    """
    # yeah, it's a dumb example but I chose the big lebowski cuz I love the movie
    # the dude is a courier so he can transport the ringer but he's not a thief
    # so he can't access ransom

    @WebYosai.requires_role(['courier'])
    def transport_ransom(the_ringer, destination):
        return 'transported'

    @WebYosai.requires_role(['thief'])
    def access_ransom(the_ringer):
        return 'accessed'

    with WebYosai.context(web_yosai, mock_web_registry):
        subject = WebYosai.get_current_subject()
        try:
            subject.login(valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            subject.login(valid_thedude_totp_token)

        result = transport_ransom('the_ringer', 'the_nihilists')
        assert result == 'transported'

        with pytest.raises(mock_web_registry.mock_exception):
            access_ransom('the_ringer')
Exemplo n.º 3
0
def test_remember_me_with_expired_session(
        web_yosai, mock_web_registry, monkeypatch,
        remembered_valid_thedude_username_password_token,
        remembered_valid_thedude_totp_token):
    """
    Send a request that contains an idle expired session_id and remember_me cookie.
    A new session is created and the user remembered.  Confirm user identity.
    """
    monkeypatch.setattr(web_yosai.security_manager.session_manager,
                        'idle_timeout', 1000)  # milliseconds

    with WebYosai.context(web_yosai, mock_web_registry):
        subject = WebYosai.get_current_subject()

        try:
            subject.login(remembered_valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            subject.login(remembered_valid_thedude_totp_token)

        old_session_id = subject.get_session().session_id
        time.sleep(2)
        subject = WebYosai.get_current_subject()
        new_session_id = subject.get_session().session_id

        assert old_session_id != new_session_id
Exemplo n.º 4
0
def test_run_as_raises(web_yosai, mock_web_registry, walter_identifier):

    with WebYosai.context(web_yosai, mock_web_registry):
        new_web_subject = WebYosai.get_current_subject()
        # a login is required , so this should raise:
        with pytest.raises(ValueError):
            new_web_subject.run_as(walter_identifier)
Exemplo n.º 5
0
def test_run_as_pop(walter_identifier, jackie_identifier, web_yosai,
                    mock_web_registry, jackie_testpermissions,
                    walter_testpermissions,
                    valid_thedude_username_password_token,
                    valid_thedude_totp_token):
    jp = jackie_testpermissions
    wp = walter_testpermissions

    with WebYosai.context(web_yosai, mock_web_registry):
        new_web_subject = WebYosai.get_current_subject()
        try:
            new_web_subject.login(valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            new_web_subject.login(valid_thedude_totp_token)

        new_web_subject.run_as(jackie_identifier)
        jackieresults = new_web_subject.is_permitted(jp['perms'])
        assert jackieresults == jp['expected_results']

        new_web_subject.run_as(walter_identifier)
        walterresults = new_web_subject.is_permitted(wp['perms'])
        assert walterresults == wp['expected_results']

        new_web_subject.pop_identity()
        assert new_web_subject.identifiers == jackie_identifier

        new_web_subject.logout()
Exemplo n.º 6
0
def test_session_idle_expiration_clears_cache(
        thedude_identifier, thedude_testpermissions, caplog, web_yosai, mock_web_registry,
        valid_thedude_username_password_token, valid_thedude_totp_token):
    cache_handler = web_yosai.security_manager.session_manager.session_handler.\
        session_store.cache_handler

    tp = thedude_testpermissions

    with WebYosai.context(web_yosai, mock_web_registry):
        new_web_subject = WebYosai.get_current_subject()
        try:
            new_web_subject.login(valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            new_web_subject.login(valid_thedude_totp_token)

        new_web_subject.is_permitted(tp['perms'])  # caches authz_info

        session = new_web_subject.get_session()
        session = cache_handler.get('session', identifier=session.session_id)

        twenty_ago = (60 * 20 * 1000)
        session.last_access_time = session.last_access_time - twenty_ago
        cache_handler.set('session', session.session_id, session)
        session = cache_handler.get('session', identifier=session.session_id)

        session = new_web_subject.get_session()

        with pytest.raises(ExpiredSessionException):
            session.last_access_time  # this triggers the expiration

            out = caplot.text
            assert ('Clearing cached authc_info for [thedude]' in out and
                    'Clearing cached authz_info for [thedude]' in out)

            new_web_subject.logout()
Exemplo n.º 7
0
def test_has_role(web_yosai, mock_web_registry, thedude_testroles, event_bus,
                  valid_thedude_username_password_token,
                  valid_thedude_totp_token):
    tr = thedude_testroles
    event_detected = None

    def event_listener(identifiers=None,
                       items=None,
                       logical_operator=None,
                       topic=EVENT_TOPIC):
        nonlocal event_detected
        event_detected = items

    event_bus.subscribe(event_listener, 'AUTHORIZATION.RESULTS')

    with WebYosai.context(web_yosai, mock_web_registry):
        new_web_subject = WebYosai.get_current_subject()
        try:
            new_web_subject.login(valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            new_web_subject.login(valid_thedude_totp_token)

        result = new_web_subject.has_role(tr['roles'])

        assert (tr['expected_results'] == result
                and frozenset(event_detected) == result)

        new_web_subject.logout()
Exemplo n.º 8
0
def test_session_attributes(web_yosai, mock_web_registry, monkeypatch,
                            valid_thedude_username_password_token,
                            valid_thedude_totp_token):
    """
    Developer-defined session attribute schema is to serialize correctly
    """

    value1 = {'attribute1': 'value1'}
    values = {'attribute2': 'value2', 'attribute3': 'value3'}

    with WebYosai.context(web_yosai, mock_web_registry):
        subject = WebYosai.get_current_subject()

        old_session = subject.get_session()

        old_session.set_attribute('attribute1', 'value1')
        old_session.set_attributes(values)

        try:
            subject.login(valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            subject.login(valid_thedude_totp_token)

        new_session = subject.get_session()
        values.update(value1)
        assert (new_session.get_attributes(values.keys()) == values.keys())

    class Value4:
        pass

    with pytest.raises(CBOREncodeError):
        new_session.set_attribute('attribute4', Value4())  # not serializable
Exemplo n.º 9
0
def test_subject_invalid_login(web_yosai, invalid_walter_username_password_token,
                               mock_web_registry):

    with pytest.raises(AuthenticationException):

        with WebYosai.context(web_yosai, mock_web_registry):
            subject = WebYosai.get_current_subject()
            subject.login(invalid_walter_username_password_token)
Exemplo n.º 10
0
def test_create_yosai_instance():
    """
    Create a new WebYosai instance from env_var settings and from file_path
    settings.  This subsequently creates a configured WebSecurityManager.
    web_yosai is configured using the file_path approach
    """
    first_yosai = WebYosai(env_var='YOSAI_SETTINGS')

    file_path = os.environ.get('YOSAI_SETTINGS')
    second_yosai = WebYosai(file_path=file_path)

    assert first_yosai.security_manager and second_yosai.security_manager
Exemplo n.º 11
0
def test_new_session_at_login(web_yosai, mock_web_registry,
        valid_thedude_username_password_token, valid_thedude_totp_token):
    """
    At login, an anonymous session is deleted from cache and a new session is created.
    """
    with WebYosai.context(web_yosai, mock_web_registry):
        subject = WebYosai.get_current_subject()
        old_session_id = subject.get_session().session_id
        try:
            subject.login(valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            subject.login(valid_thedude_totp_token)
        new_session_id = subject.get_session().session_id
        assert old_session_id != new_session_id
Exemplo n.º 12
0
def test_login_clears_cache(
        thedude_identifier, caplog, web_yosai, mock_web_registry,
        valid_thedude_username_password_token, valid_thedude_totp_token):
    with WebYosai.context(web_yosai, mock_web_registry):
        new_web_subject = WebYosai.get_current_subject()
        try:
            new_web_subject.login(valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            new_web_subject.login(valid_thedude_totp_token)

        out = caplog.text

        assert 'Clearing cached authz_info for [thedude]' in out
        new_web_subject.logout()
Exemplo n.º 13
0
def test_web_yosai_get_current_webregistry(web_yosai, monkeypatch):
    mock_stack = ['webregistry']
    monkeypatch.setattr(global_webregistry_context, 'stack', mock_stack)

    result = WebYosai.get_current_webregistry()

    assert result == 'webregistry'
Exemplo n.º 14
0
def test_stopped_session(web_yosai, mock_web_registry,
        valid_thedude_username_password_token, valid_thedude_totp_token):
    """
    When a user logs out, the user's session is stopped.
    """
    with WebYosai.context(web_yosai, mock_web_registry):
        subject = WebYosai.get_current_subject()
        try:
            subject.login(valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            subject.login(valid_thedude_totp_token)
        subject.logout()
        assert (mock_web_registry.current_session_id is None and
                mock_web_registry.session_id_history[0][0] == 'SET' and
                mock_web_registry.session_id_history[1][0] == 'SET' and
                mock_web_registry.session_id_history[2][0] == 'DELETE')
Exemplo n.º 15
0
def test_authenticated_subject_has_role_collective(
        web_yosai, mock_web_registry, thedude_testroles,
        valid_thedude_username_password_token, valid_thedude_totp_token):
    tr = thedude_testroles

    with WebYosai.context(web_yosai, mock_web_registry):
        new_web_subject = WebYosai.get_current_subject()
        try:
            new_web_subject.login(valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            new_web_subject.login(valid_thedude_totp_token)

        assert ((new_web_subject.has_role_collective(tr['roles'], all) is False) and
                (new_web_subject.has_role_collective(tr['roles'], any) is True))

        new_web_subject.logout()
Exemplo n.º 16
0
def test_web_context(web_yosai, mock_web_registry):
    """
    When entering a new WebYosai context, a yosai instance is pushed onto a yosai_context
    stack and a web_registry is pushed onto a yosai_webregistry_context stack.
    When closing the context: the pushed yosai instance is popped from the
    yosai_context stack, the pushed web_registry is popped from the
    yosai_webregistry_context, and the current executing subject is popped
    from the global_subject_context stack.

    elements tested include:
        get_current_yosai
        get_current_webregistry
        get_current_subject
    """
    # first ensure that the threadlocal is empty
    assert (global_subject_context.stack == []
            and global_yosai_context.stack == []
            and global_webregistry_context.stack == [])

    with WebYosai.context(web_yosai, mock_web_registry):
        assert (global_subject_context.stack == []
                and global_yosai_context.stack == [web_yosai]
                and global_webregistry_context.stack == [mock_web_registry])

    # this tests context exit
    assert (global_subject_context.stack == []
            and global_yosai_context.stack == []
            and global_webregistry_context.stack == [])
Exemplo n.º 17
0
    def tween(request):

        web_registry = PyramidWebRegistry(request)

        with WebYosai.context(yosai, web_registry):
            response = handler(request)
        return response
Exemplo n.º 18
0
def launchpad(context, request):
    subject = WebYosai.get_current_subject()

    # check_roles looks like:  [('role_name', Boolean), ...]
    check_roles = subject.has_role(['physician', 'patient', 'nurse_practitioner'])
    roles = [role for role, check in filter(lambda x: x[1], check_roles)]

    return {'roles': roles}
Exemplo n.º 19
0
def yosai_from_settings(settings):
    """
    Convenience method to construct a ``Yosai`` instance, referencing paste-deploy
    INI settings to obtain the envvar or filepath to yosai settings.

    :raises: KeyError when neither yosai env_var nor file_path are defined
    :returns: a Yosai instance
    """
    env_var = settings['yosai.settings_filepath_envvar']
    if env_var:
        return WebYosai(env_var=env_var)

    file_path = settings['yosai.settings_filepath']
    if file_path:
        return WebYosai(file_path=file_path)

    raise ValueError('pyramid_yosai must have either an env_var or file_path')
Exemplo n.º 20
0
def test_forget_remembered_identity(
        web_yosai, mock_web_registry, monkeypatch,
        remembered_valid_thedude_username_password_token,
        remembered_valid_thedude_totp_token):
    """
    Logout and ensure that the identity is forgotten through removal of the
    remember_me cookie.
    """
    with WebYosai.context(web_yosai, mock_web_registry):
        subject = WebYosai.get_current_subject()

        try:
            subject.login(remembered_valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            subject.login(remembered_valid_thedude_totp_token)

        assert mock_web_registry.current_remember_me is not None
        subject.logout()
        assert mock_web_registry.current_remember_me is None
Exemplo n.º 21
0
def home(request):

    subject = WebYosai.get_current_subject()

    if subject.authenticated:
        next_url = request.route_url('launchpad')
    else:
        next_url = request.route_url('login')

    return HTTPFound(location=next_url)
Exemplo n.º 22
0
def test_authenticated_subject_is_permitted_collective(
        web_yosai, mock_web_registry, thedude_testpermissions,
        valid_thedude_username_password_token, valid_thedude_totp_token):
    tp = thedude_testpermissions

    with WebYosai.context(web_yosai, mock_web_registry):
        new_web_subject = WebYosai.get_current_subject()
        try:
            new_web_subject.login(valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            new_web_subject.login(valid_thedude_totp_token)

        assert ((new_web_subject.is_permitted_collective(tp['perms'], any) is True) and
                (new_web_subject.is_permitted_collective(tp['perms'], all) is False))

        new_web_subject.logout()

        with pytest.raises(ValueError):
            new_web_subject.is_permitted_collective(tp['perms'], any)
Exemplo n.º 23
0
def test_remember_me_at_login(web_yosai, mock_web_registry,
                              remembered_valid_thedude_username_password_token,
                              remembered_valid_thedude_totp_token):
    """
    Remember a user at login.  The remember_me cookie is to be set at login
    when remember_me setting is True in UsernamePasswordToken.  Confirm
    user identity.
    """

    with WebYosai.context(web_yosai, mock_web_registry):
        new_subject = WebYosai.get_current_subject()
        assert mock_web_registry.current_remember_me is None

        try:
            new_subject.login(remembered_valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            new_subject.login(remembered_valid_thedude_totp_token)

        assert mock_web_registry.current_remember_me is not None
Exemplo n.º 24
0
def test_absolute_timeout(web_yosai, mock_web_registry, monkeypatch,
        valid_thedude_username_password_token, valid_thedude_totp_token):
    """
    A session that absolute timeouts will raise an exception at validation and
    the sessionmanager deletes the expired session from cache.
    """
    monkeypatch.setattr(web_yosai.security_manager.session_manager, 'absolute_timeout', 1000)  # milliseconds

    with WebYosai.context(web_yosai, mock_web_registry):
        subject = WebYosai.get_current_subject()
        try:
            subject.login(valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            subject.login(valid_thedude_totp_token)
        sleep(2)
        try:
            subject = WebYosai.get_current_subject()
        except mock_web_registry.mock_exception:
            assert (mock_web_registry.current_session_id is None and
                    mock_web_registry.session_id_history[0][0] == 'SET')
Exemplo n.º 25
0
def test_logout_clears_cache(
        thedude_identifier, web_yosai, mock_web_registry,thedude_testpermissions,
        caplog, valid_thedude_username_password_token, valid_thedude_totp_token):
    tp = thedude_testpermissions

    with WebYosai.context(web_yosai, mock_web_registry):
        new_web_subject = WebYosai.get_current_subject()
        try:
            new_web_subject.login(valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            new_web_subject.login(valid_thedude_totp_token)

        new_web_subject.is_permitted(tp['perms'])  # caches authz_info

        new_web_subject.logout()

        out = caplog.text

        assert ('Clearing cached authc_info for [thedude]' in out and
                'Clearing cached authz_info for [thedude]' in out)
Exemplo n.º 26
0
def pending_rx(context, request):
    if request.method == "POST":
        approve_rx_requests(request.dbsession, request.POST)
        next_url = request.route_url('pending_rx')
        return HTTPFound(next_url)

    else:
        current_username = WebYosai.get_current_subject().identifiers.primary_identifier
        results = get_pending_physician_requests(request.dbsession,
                                                 current_username).all()

        return {'results': results}
Exemplo n.º 27
0
def test_authenticated_subject_is_permitted(
        web_yosai, mock_web_registry, thedude_testpermissions,
        valid_thedude_username_password_token, valid_thedude_totp_token):

    tp = thedude_testpermissions

    with WebYosai.context(web_yosai, mock_web_registry):
        new_web_subject = WebYosai.get_current_subject()

        try:
            new_web_subject.login(valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            new_web_subject.login(valid_thedude_totp_token)

        results = new_web_subject.is_permitted(tp['perms'])
        assert results == tp['expected_results']

        new_web_subject.logout()

        with pytest.raises(ValueError):
            new_web_subject.is_permitted(tp['perms'])
Exemplo n.º 28
0
def test_csrf_token_management(web_yosai, mock_web_registry, monkeypatch,
        valid_thedude_username_password_token, valid_thedude_totp_token):
    """
    CSRF Token generation and retrieval from session state
    """

    with WebYosai.context(web_yosai, mock_web_registry):
        subject = WebYosai.get_current_subject()

        old_session = subject.get_session()
        old_token = old_session.get_csrf_token()

        try:
            subject.login(valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            subject.login(valid_thedude_totp_token)

        new_session = subject.get_session()
        new_token = new_session.new_csrf_token()

        assert new_token != old_token
Exemplo n.º 29
0
def test_flash_messages_management(web_yosai, mock_web_registry, monkeypatch,
                                   valid_thedude_username_password_token,
                                   valid_thedude_totp_token):
    """
    flash messages saving and retrieval from session state
    """

    with WebYosai.context(web_yosai, mock_web_registry):
        subject = WebYosai.get_current_subject()

        old_session = subject.get_session()

        msg = 'Flash Message One, Default Queue'
        msg2 = 'Flash Message Two, Default Queue'
        old_session.flash(msg)
        old_session.flash(msg2)

        msg3 = 'Flash Message Two'
        old_session.flash(msg3, queue='queue2')

        default_queue_flash_peek = old_session.peek_flash()
        default_queue_flash_pop = old_session.pop_flash()
        try:
            subject.login(valid_thedude_username_password_token)
        except AdditionalAuthenticationRequired:
            subject.login(valid_thedude_totp_token)

        new_session = subject.get_session()
        default_queue_flash_peek_new = new_session.peek_flash()
        default_queue_flash_pop_new = new_session.pop_flash()
        queue2_flash_peek_new = new_session.peek_flash('queue2')
        queue2_flash_pop_new = new_session.pop_flash('queue2')

    assert (default_queue_flash_peek == [msg, msg2]
            and default_queue_flash_pop == [msg, msg2]
            and default_queue_flash_peek_new == []
            and default_queue_flash_pop_new is None
            and queue2_flash_peek_new == [msg3]
            and queue2_flash_pop_new == [msg3])
Exemplo n.º 30
0
def request_rx(context, request):

    rx_request_form = RxRequestForm(request.POST)

    if request.method == "POST" and rx_request_form.validate():
        add_rx_request(request.dbsession, rx_request_form.data['prescription'])

        # request.session.flash('RX Request Submitted.')
        next_url = request.route_url('request_rx')
        return HTTPFound(next_url)
    else:
        current_username = WebYosai.get_current_subject().identifiers.primary_identifier
        results = get_pending_patient_requests(request.dbsession,
                                               current_username).all()

        return {'rx_request_form': rx_request_form,
                'results': results,
                'user': current_username}
Exemplo n.º 31
0
def write_rx(context, request):

    write_rx_form = WriteRXForm(request.POST)

    if request.method == 'POST' and write_rx_form.validate():

        medicine = write_rx_form.data['medicine'].id
        perm = 'prescription:write:{0}'.format(medicine)

        current_user = WebYosai.get_current_subject()
        try:
            current_user.check_permission([perm])

        except IdentifiersNotSetException:
            msg = ("Attempting to perform a user-only operation.  The "
                   "current Subject is NOT a user (they haven't been "
                   "authenticated or remembered from a previous login). "
                   "ACCESS DENIED.")
            raise HTTPUnauthorized(msg)

        except AuthorizationException:
            status_msg = "Access Denied.  Insufficient Permission."
            return {'status_msg': status_msg}

        current_username = current_user.identifiers.primary_identifier

        create_rx(request.dbsession,
                  current_username,
                  write_rx_form.data['medicine'],
                  write_rx_form.data['patient'],
                  write_rx_form.data['title'],
                  write_rx_form.data['fill_qty'],
                  write_rx_form.data['num_fills'])

        # When a prescription gets created, a new resource-level permission could be
        # created in the yosai database, allowing resource-level authorization
        # for that new rx. However, time has not yet allowed support for adding new
        # resource to the yosai db.  Adding this to TO-DO.
        #resource = ResourceModel(name=prescription.id)

        return {'status_msg': 'Successfully Wrote Rx'}
Exemplo n.º 32
0
def login(request):

    login_form = LoginForm(request.POST)

    if request.method == "POST" and login_form.validate():

        authc_token = UsernamePasswordToken(username=login_form.username.data,
                                            password=login_form.password.data,
                                            remember_me=login_form.remember_me.data)

        try:
            subject = WebYosai.get_current_subject()
            subject.login(authc_token)

            next_url = request.route_url('launchpad')
            return HTTPFound(location=next_url)

        except AuthenticationException:
            # request.session.flash('Invalid Login Credentials.')
            return {'login_form': login_form}

    else:
        return {'login_form': login_form}
Exemplo n.º 33
0
 def generate_csrf_token(self, context=None):
     # the context param isn't needed with yosai
     subject = WebYosai.get_current_subject()
     session = subject.get_session()
     return session.get_csrf_token()
Exemplo n.º 34
0
def web_yosai(session_attributes):
    return WebYosai(env_var='YOSAI_WEB_SETTINGS',
                    session_attributes=session_attributes)
Exemplo n.º 35
0
 def generate_csrf_token(self, context=None):
     # the context param isn't needed with yosai
     subject = WebYosai.get_current_subject()
     session = subject.get_session()
     return session.get_csrf_token()
Exemplo n.º 36
0
def test_web_yosai_get_current_webregistry_raises(web_yosai, monkeypatch):
    mock_stack = []
    monkeypatch.setattr(global_webregistry_context, 'stack', mock_stack)

    with pytest.raises(YosaiContextException):
        WebYosai.get_current_webregistry()