示例#1
0
def test_requires_dynamic_permission_fails(
        yosai, valid_thedude_username_password_token,
        valid_thedude_totp_token):
    class BankCheck:
        def __init__(self):
            self.bankcheck_id = 'bankcheck_12345'

    status = None

    @Yosai.requires_dynamic_permission(
        ['money:bounce:{bankcheck.bankcheck_id}'])
    def do_something(bankcheck):
        nonlocal status
        status = True

    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)
        with pytest.raises(UnauthorizedException):
            do_something(bankcheck=BankCheck())
        new_subject.logout()
        assert status is None
示例#2
0
    def authenticate_token(self, authc_token=None):
        if authc_token:
            subject = Yosai.get_current_subject()
            try:
                subject.login(authc_token)
            except:
                logger.debug_exception('Login failed')
                raise

            user = subject.primary_identifier
            logger.debug('Login complete for user: {}'.format(user))
            if isinstance(user, IdentityContext):
                return user
            else:
                # Simple account lookup to ensure the context identity is complete
                try:
                    logger.debug('Loading identity context from username: {}'.format(user))
                    with session_scope() as db_session:
                        idp = self._idp_factory.for_session(db_session)
                        identity, _ = idp.lookup_user(user)

                        logger.debug('Authc complete for user: {}'.format(user))
                        return identity
                except:
                    logger.debug_exception('Error looking up account for authenticated user')
                    return None
        else:
            logger.debug('Anon auth complete')
            return IdentityContext(username=None, user_account=None, user_account_type=None, user_account_state=None)
示例#3
0
def test_is_permitted(modular_realm_authorizer, thedude_testpermissions,
                      event_bus, thedude_identifier, yosai,
                      valid_thedude_totp_token,
                      valid_thedude_username_password_token):
    """
    get a set of tuple(s), containing the Permission and a Boolean
    indicating whether the permission is granted
    """
    mra = modular_realm_authorizer
    tp = thedude_testpermissions
    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 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 = mra.is_permitted(thedude_identifier, tp['perms'])
        assert (tp['expected_results'] == results
                and set(event_detected) == results)
示例#4
0
def test_subject_mfa_invalid_login_sequence(valid_thedude_totp_token, yosai):

    with Yosai.context(yosai):
        new_subject = Yosai.get_current_subject()

        with pytest.raises(InvalidAuthenticationSequenceException):
            new_subject.login(valid_thedude_totp_token)
    def authorize(self, identity: IdentityContext, permission_list):
        logger.debug(
            'Authorizing with native auth handler: {}'.format(permission_list))

        subject = Yosai.get_current_subject()
        if subject.primary_identifier != identity.username:
            raise UnauthorizedError(permission_list)

        # Do account state check here for authz rather than in the authc path since it's a property of an authenticated user
        self._check_calling_user_account_state(identity)

        self._exec_permission_check(subject, permission_list)

        # Check only after the perms check. Match any allowed permissions that use the namespace as the domain for the authz request
        non_enabled_domains = self._disabled_domains(permission_list)

        logger.debug('Found disabled domains in permission set: {}'.format(
            non_enabled_domains))

        # If found domains not enabled and the caller is not a system service or system admin, disallow
        if non_enabled_domains and identity.user_account_type not in [
                AccountTypes.admin, AccountTypes.service
        ]:
            logger.debug(
                'Failing otherwise passing perm check due to domain state')
            raise AccountStateError(non_enabled_domains[0])

        logger.debug('Passed check permission: {}'.format(permission_list))
示例#6
0
def test_session_idle_expiration_clears_cache(
        valid_thedude_username_password_token, thedude_testpermissions,
        valid_thedude_totp_token, caplog, cache_handler, 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)
        new_subject.is_permitted(tp['perms'])  # caches authz_info

        session = new_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_subject.get_session()

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

            out = caplot.text
            assert ('Clearing cached credentials for [thedude]' in out
                    and 'Clearing cached authz_info for [thedude]' in out)
示例#7
0
def test_check_role_raises(thedude_testroles,
                           valid_thedude_username_password_token,
                           valid_thedude_totp_token, yosai, event_bus):

    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.DENIED')

    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)

        with pytest.raises(UnauthorizedException):
            new_subject.check_role(tr['roles'], all)

            assert event_detected == tr['roles']
        new_subject.logout()
示例#8
0
def test_run_as_pop(walter_identifier, jackie_identifier, yosai,
                    jackie_testpermissions, walter_testpermissions,
                    valid_thedude_username_password_token,
                    valid_thedude_totp_token):

    jp = jackie_testpermissions
    wp = walter_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)

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

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

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

        new_subject.logout()
示例#9
0
    def authenticate(self, request):
        logger.debug('Authenticating with native auth handler')
        subject = Yosai.get_current_subject()

        if request.authorization:
            authc_token = UsernamePasswordToken(
                username=request.authorization.username,
                password=request.authorization.password,
                remember_me=False)

            subject.login(authc_token)
            user = subject.primary_identifier

            # Simple account lookup to ensure the context identity is complete
            try:
                with session_scope() as db_session:
                    idp = self._idp_factory.for_session(db_session)
                    identity, _ = idp.lookup_user(user)

                    logger.debug('Authc complete')
                    return identity
            except:
                logger.exception(
                    'Error looking up account for authenticated user')
                return None
        else:
            logger.debug('Anon auth complete')
            return IdentityContext(username=None,
                                   user_account=None,
                                   user_account_type=None,
                                   user_account_active=None)
示例#10
0
        def inner_wrap(*args, **kwargs):

            subject = Yosai.get_current_subject()

            subject.check_role(roleid_s, logical_operator)

            return fn(*args, **kwargs)
示例#11
0
def test_check_role_succeeds(thedude_testroles,
                             valid_thedude_username_password_token,
                             valid_thedude_totp_token, yosai, event_bus):

    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.GRANTED')

    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)

        assert (new_subject.check_role(tr['roles'], any) is None
                and event_detected == list(tr['roles']))

        new_subject.logout()
示例#12
0
def test_has_role(valid_thedude_username_password_token, thedude_testroles,
                  valid_thedude_totp_token, yosai, event_bus):

    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 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)

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

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

        new_subject.logout()
示例#13
0
def test_authenticated_subject_check_permission_succeeds(
        thedude_testpermissions, valid_thedude_username_password_token,
        valid_thedude_totp_token, yosai, event_bus):

    tp = thedude_testpermissions
    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.GRANTED')

    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)

        check = new_subject.check_permission(tp['perms'], any)
        assert (check is None and event_detected == tp['perms'])

        new_subject.logout()

        with pytest.raises(UnauthenticatedException):
            new_subject.check_permission(tp['perms'], any)
示例#14
0
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)
示例#15
0
def test_run_as_raises(walter_identifier, yosai):

    with Yosai.context(yosai):
        new_subject = Yosai.get_current_subject()
        # a login is required , so this should raise:
        new_subject.logout()
        with pytest.raises(ValueError):
            new_subject.run_as(walter_identifier)
示例#16
0
        def inner_wrap(*args, **kwargs):
            newperms = [perm.format(**kwargs) for perm in permission_s]

            subject = Yosai.get_current_subject()

            subject.check_permission(newperms, logical_operator)

            return fn(*args, **kwargs)
示例#17
0
    def wrap(*args, **kwargs):
        subject = Yosai.get_current_subject()

        if not subject.authenticated:
            msg = "The current Subject is not authenticated.  ACCESS DENIED."
            raise UnauthenticatedException(msg)

        return fn(*args, **kwargs)
示例#18
0
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()
示例#19
0
文件: conftest.py 项目: zhill/yosai
def invalid_thedude_username_password_token(yosai, monkeypatch):
    yield UsernamePasswordToken(username='******',
                                password='******',
                                remember_me=False,
                                host='127.0.0.1')
    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')
示例#20
0
def test_singlefactor_subject_locks_at_userpass(
        invalid_walter_username_password_token, yosai, event_bus, monkeypatch,
        valid_walter_username_password_token):
    """
        - locks a single-factor account after N attempts
        - confirms that a locked account will not authenticate userpass
    """
    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('walter')
        try:
            new_subject.login(invalid_walter_username_password_token)
        except AuthenticationException:
            try:
                new_subject.login(invalid_walter_username_password_token)
            except AuthenticationException:
                try:
                    new_subject.login(invalid_walter_username_password_token)
                except AuthenticationException:
                    try:
                        new_subject.login(
                            invalid_walter_username_password_token)
                    except LockedAccountException:
                        try:
                            event_bus.subscribe(
                                lock_event_listener,
                                'AUTHENTICATION.ACCOUNT_LOCKED')
                            event_bus.subscribe(success_event_listener,
                                                'AUTHENTICATION.SUCCEEDED')
                            account_id = da.authenticate_account(
                                None, valid_walter_username_password_token)
                        except LockedAccountException:
                            assert lock_event_detected == 'walter'
                            assert success_event_detected is None

        da.locking_realm.unlock_account('walter')
示例#21
0
    def wrap(*args, **kwargs):

        subject = Yosai.get_current_subject()

        if subject.identifiers is not None:
            msg = ("Attempting to perform a guest-only operation.  The "
                   "current Subject is NOT a guest (they have either been "
                   "authenticated or remembered from a previous login). "
                   "ACCESS DENIED.")
            raise UnauthenticatedException(msg)

        return fn(*args, **kwargs)
示例#22
0
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')
示例#23
0
def test_totp_replay_attack(yosai, valid_thedude_username_password_token,
                            valid_thedude_totp_token):

    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)

        with pytest.raises(IncorrectCredentialsException):
            new_subject.login(valid_thedude_totp_token)
示例#24
0
    def authorize(self, identity: IdentityContext, permission_list):
        logger.debug(
            'Authorizing with native auth handler: {}'.format(permission_list))

        subject = Yosai.get_current_subject()
        if subject.primary_identifier != identity.username:
            raise UnauthorizedError(permission_list)

        logger.debug('Checking permission: {}'.format(permission_list))
        try:
            subject.check_permission(permission_list, logical_operator=all)
        except (ValueError, auth_exceptions.UnauthorizedException) as ex:
            raise UnauthorizedError(required_permissions=permission_list)

        logger.debug('Passed check permission: {}'.format(permission_list))
示例#25
0
def test_login_clears_cache(thedude_identifier,
                            valid_thedude_username_password_token, caplog,
                            valid_thedude_totp_token, yosai):

    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)

        out = caplog.text

        assert 'Clearing cached authz_info for [thedude]' in out
    new_subject.logout()
示例#26
0
文件: conftest.py 项目: zhill/yosai
def invalid_walter_username_password_token(cache_handler, yosai, monkeypatch):
    keys = cache_handler.keys('*authentication*')
    for key in keys:
        cache_handler.cache_region.delete(key)
    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')
    yield UsernamePasswordToken(username='******',
                                password='******',
                                remember_me=False,
                                host='127.0.0.1')

    keys = cache_handler.keys('*authentication*')
    for key in keys:
        cache_handler.cache_region.delete(key)
    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')
示例#27
0
def test_subject_invalid_single_factor_login(
        yosai, invalid_walter_username_password_token, event_bus):

    event_detected = None

    def event_listener(identifier=None, topic=EVENT_TOPIC):
        nonlocal event_detected
        event_detected = identifier

    event_bus.subscribe(event_listener, 'AUTHENTICATION.FAILED')

    with Yosai.context(yosai):
        new_subject = Yosai.get_current_subject()

        with pytest.raises(IncorrectCredentialsException):
            new_subject.login(invalid_walter_username_password_token)

    assert event_detected == invalid_walter_username_password_token.identifier
示例#28
0
    def authorize(self, identity: IdentityContext, permission_list):
        logger.debug('Authorizing with native auth handler: {}'.format(permission_list))

        subject = Yosai.get_current_subject()
        if subject.primary_identifier != identity.username:
            raise UnauthorizedError(permission_list)

        # Do account state check here for authz rather than in the authc path since it's a property of an authenticated user
        if not identity.user_account_state or identity.user_account_state != AccountStates.enabled:
            raise AccountStateError()

        logger.debug('Checking permission: {}'.format(permission_list))
        try:
            subject.check_permission(permission_list, logical_operator=all)
        except (ValueError, auth_exceptions.UnauthorizedException) as ex:
            raise UnauthorizedError(required_permissions=permission_list)

        logger.debug('Passed check permission: {}'.format(permission_list))
示例#29
0
def invalid_thedude_totp_token(cache_handler, yosai, monkeypatch):
    keys = cache_handler.keys('*authentication*')
    for key in keys:
        cache_handler.cache_region.delete(key)

    token = int(TOTP(key='AYAGB3C5RPYX5375L5VY2ULKZXMXWLZF', digits=6).generate().token)
    yield TOTPToken(totp_token=token)

    keys = cache_handler.keys('*authentication*')
    for key in keys:
        cache_handler.cache_region.delete(key)

    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')
示例#30
0
def test_authenticated_subject_has_role_collective(
        thedude_testroles, valid_thedude_username_password_token,
        valid_thedude_totp_token, yosai):

    tr = thedude_testroles

    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)

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

        new_subject.logout()
示例#31
0
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'])
示例#32
0
def test_requires_role_succeeds(yosai, valid_thedude_username_password_token,
                                valid_thedude_totp_token):

    status = None

    @Yosai.requires_role(['courier'])
    def do_something():
        nonlocal status
        status = True

    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)
        do_something()
        assert status
        new_subject.logout()
示例#33
0
def test_requires_permission_succeeds(yosai,
                                      valid_thedude_username_password_token,
                                      valid_thedude_totp_token):

    status = None

    @Yosai.requires_permission(['money:write:bankcheck_19911109069'])
    def do_something():
        nonlocal status
        status = True

    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)
        do_something()
        new_subject.logout()
        assert status
示例#34
0
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
示例#35
0
        def inner_wrap(*args, **kwargs):

            subject = Yosai.get_current_subject()
            subject.check_permission(permission_s, logical_operator)

            return fn(*args, **kwargs)