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
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')
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')
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)
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 == [])
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()
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()
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()
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
def tween(request): web_registry = PyramidWebRegistry(request) with WebYosai.context(yosai, web_registry): response = handler(request) return response
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)
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
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()
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()
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')
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
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)
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
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')
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)
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'])
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
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])