def test_subject_invalid_login(invalid_thedude_username_password_token, yosai): with Yosai.context(yosai): new_subject = Yosai.get_current_subject() with pytest.raises(AuthenticationException): new_subject.login(invalid_thedude_username_password_token)
def inner_wrapper(*args, **kwargs): try: with Yosai.context(self._yosai): # Context Manager functions try: try: identity = self.authenticate(request_proxy) if not identity.username: raise UnauthenticatedError('Authentication Required') except: raise UnauthenticatedError('Authentication Required') ApiRequestContextProxy.set_identity(identity) permissions_final = [] # Bind all the permissions as needed for perm in permission_s: domain = perm.domain if perm.domain else '*' action = perm.action if perm.action else '*' target = perm.target if perm.target else '*' if hasattr(domain, 'bind'): domain.bind(operation=f, kwargs=kwargs) domain = domain.value if hasattr(action, 'bind'): action.bind(operation=f, kwargs=kwargs) action = action.value if hasattr(target, 'bind'): target.bind(operation=f, kwargs=kwargs) target = target.value #permissions_final.append(':'.join([domain, action, target])) permissions_final.append(Permission(domain, action, target)) # Do the authz on the bound permissions try: self.authorize(ApiRequestContextProxy().identity(), permissions_final) except UnauthorizedError as ex: raise ex except Exception as e: logger.exception('Error doing authz: {}'.format(e)) raise UnauthorizedError(permissions_final) return f(*args, **kwargs) finally: # Teardown the request context ApiRequestContextProxy.set_identity(None) except UnauthorizedError as ex: return make_response_error(str(ex), in_httpcode=403), 403 except UnauthenticatedError as ex: return Response(response='Unauthorized', status=401, headers=[('WWW-Authenticate', 'basic realm="Authentication required"')]) except AnchoreApiError: raise except Exception as ex: logger.exception('Unexpected exception: {}'.format(ex)) return make_response_error('Internal error', in_httpcode=500), 500
def inline_authz(self, permission_s: list, authc_token: AuthenticationToken=None): """ Non-decorator impl of the @requires() decorator for isolated and inline invocation. Returns authenticated user identity on success or raises an exception :param permission_s: list of Permission objects :param authc_token: optional authc token to use for the authc portion, if omitted or None, the flask request context is used :return: IdentityContext object """ try: with Yosai.context(self._yosai): # Context Manager functions try: try: if not authc_token: identity = self.authenticate(request_proxy) else: identity = self.authenticate_token(authc_token) if not identity.username: raise UnauthenticatedError('Authentication Required') except: raise UnauthenticatedError('Authentication Required') ApiRequestContextProxy.set_identity(identity) permissions_final = [] # Bind all the permissions as needed for perm in permission_s: domain = perm.domain if perm.domain else '*' action = perm.action if perm.action else '*' target = perm.target if perm.target else '*' permissions_final.append(Permission(domain, action, target)) # Do the authz on the bound permissions try: self.authorize(ApiRequestContextProxy.identity(), permissions_final) except UnauthorizedError as ex: raise ex except Exception as e: logger.exception('Error doing authz: {}'.format(e)) raise UnauthorizedError(permissions_final) return ApiRequestContextProxy.identity() finally: # Teardown the request context ApiRequestContextProxy.set_identity(None) except UnauthorizedError as ex: return make_response_error(str(ex), in_httpcode=403), 403 except UnauthenticatedError as ex: return Response(response='Unauthorized', status=401, headers=[('WWW-Authenticate', 'basic realm="Authentication required"')]) except AnchoreApiError: raise except Exception as ex: logger.exception('Unexpected exception: {}'.format(ex)) return make_response_error('Internal error', in_httpcode=500), 500
def test_authenticated_subject_session_attribute_logout( valid_walter_username_password_token, yosai): with Yosai.context(yosai): new_subject = Yosai.get_current_subject() new_subject.login(valid_walter_username_password_token) session = new_subject.get_session() session.set_attribute('attribute1', 'attr1') session.set_attribute('attribute2', 'attr2') assert (session.get_attribute('attribute1') == 'attr1' and session.get_attribute('attribute2') == 'attr2') new_subject.logout()
def test_mfa_subject_locks_at_totp(valid_thedude_username_password_token, yosai, invalid_thedude_totp_token, valid_thedude_totp_token, event_bus, monkeypatch): """ - locks an account after N attempts during totp authc - confirms that a locked account will not authenticate totp """ lock_event_detected = None success_event_detected = None def lock_event_listener(identifier=None, topic=EVENT_TOPIC): nonlocal lock_event_detected lock_event_detected = identifier def success_event_listener(identifier=None, topic=EVENT_TOPIC): nonlocal success_event_detected success_event_detected = identifier event_bus.subscribe(lock_event_listener, 'AUTHENTICATION.ACCOUNT_LOCKED') event_bus.subscribe(success_event_listener, 'AUTHENTICATION.SUCCEEDED') with Yosai.context(yosai): new_subject = Yosai.get_current_subject() da = new_subject.security_manager.authenticator monkeypatch.setattr(da.authc_settings, 'account_lock_threshold', 3) da.init_locking() da.locking_realm.unlock_account('thedude') try: new_subject.login(valid_thedude_username_password_token) except AdditionalAuthenticationRequired as exc: try: new_subject.login(invalid_thedude_totp_token) except AuthenticationException: try: new_subject.login(invalid_thedude_totp_token) except AuthenticationException: try: new_subject.login(invalid_thedude_totp_token) except AuthenticationException: try: new_subject.login(invalid_thedude_totp_token) except LockedAccountException: with pytest.raises(LockedAccountException): new_subject.login(valid_thedude_totp_token) assert lock_event_detected == 'thedude' assert success_event_detected is None da.locking_realm.unlock_account('thedude')
def test_authenticated_subject_is_permitted( valid_thedude_username_password_token, valid_thedude_totp_token, thedude_testpermissions, yosai): tp = thedude_testpermissions with Yosai.context(yosai): new_subject = Yosai.get_current_subject() try: new_subject.login(valid_thedude_username_password_token) except AdditionalAuthenticationRequired: new_subject.login(valid_thedude_totp_token) results = new_subject.is_permitted(tp['perms']) assert results == tp['expected_results'] new_subject.logout() with pytest.raises(ValueError): new_subject.is_permitted(tp['perms'])
def test_subject_valid_single_factor_login( valid_walter_username_password_token, event_bus, yosai, monkeypatch): event_detected = None def event_listener(identifier=None, topic=EVENT_TOPIC): nonlocal event_detected event_detected = identifier event_bus.subscribe(event_listener, 'AUTHENTICATION.SUCCEEDED') with Yosai.context(yosai): new_subject = Yosai.get_current_subject() da = new_subject.security_manager.authenticator monkeypatch.setattr(da.authc_settings, 'account_lock_threshold', 3) da.init_locking() da.locking_realm.unlock_account('walter') new_subject.login(valid_walter_username_password_token) assert event_detected == new_subject.identifiers.primary_identifier