def test_01_timelimit(self): c, tdelta = parse_timelimit("1/5s") self.assertEqual(c, 1) self.assertEqual(tdelta, timedelta(seconds=5)) c, tdelta = parse_timelimit("5/10M") self.assertEqual(c, 5) self.assertEqual(tdelta, timedelta(minutes=10)) c, tdelta = parse_timelimit(" 5 / 10M ") self.assertEqual(c, 5) self.assertEqual(tdelta, timedelta(minutes=10)) c, tdelta = parse_timelimit("7/120h") self.assertEqual(c, 7) self.assertEqual(tdelta, timedelta(hours=120)) self.assertEqual(tdelta, timedelta(days=5)) # A missing time specifier raises an Exception self.assertRaises(Exception, parse_timelimit, "7/12") # A non number raises an Exception self.assertRaises(Exception, parse_timelimit, "seven/12m")
def auth_user_timelimit(wrapped_function, user_object, passw, options=None): """ This decorator checks the policy settings of ACTION.AUTHMAXSUCCESS, ACTION.AUTHMAXFAIL If the authentication was successful, it checks, if the number of allowed successful authentications is exceeded (AUTHMAXSUCCESS). If the AUTHMAXFAIL is exceed it denies even a successful authentication. The wrapped function is usually token.check_user_pass, which takes the arguments (user, passw, options={}) :param wrapped_function: :param user_object: :param passw: :param options: Dict containing values for "g" and "clientip" :return: Tuple of True/False and reply-dictionary """ # First we call the wrapped function res, reply_dict = wrapped_function(user_object, passw, options) options = options or {} g = options.get("g") if g: clientip = options.get("clientip") policy_object = g.policy_object max_success = policy_object.get_action_values(action=ACTION.AUTHMAXSUCCESS, scope=SCOPE.AUTHZ, realm=user_object.realm, user=user_object.login, client=clientip) max_fail = policy_object.get_action_values( action=ACTION.AUTHMAXFAIL, scope=SCOPE.AUTHZ, realm=user_object.realm, user=user_object.login, client=clientip) # Check for maximum failed authentications # Always - also in case of unsuccessful authentication if len(max_fail) > 1: raise PolicyError("Contradicting policies for %s" % ACTION.AUTHMAXFAIL) if len(max_fail) == 1: policy_count, tdelta = parse_timelimit(max_fail[0]) fail_c = g.audit_object.get_count({"user": user_object.login, "realm": user_object.realm, "action": "%/validate/check"}, success=False, timedelta=tdelta) log.debug("Checking users timelimit %s: %s " "failed authentications" % (max_fail[0], fail_c)) if fail_c >= policy_count: res = False reply_dict["message"] = ("Only %s failed authentications " "per %s" % (policy_count, tdelta)) if res: # Check for maximum successful authentications # Only in case of a successful authentication if len(max_success) > 1: raise PolicyError("Contradicting policies for %s" % ACTION.AUTHMAXSUCCESS) if len(max_success) == 1: policy_count, tdelta = parse_timelimit(max_success[0]) # check the successful authentications for this user succ_c = g.audit_object.get_count({"user": user_object.login, "realm": user_object.realm, "action": "%/validate/check"}, success=True, timedelta=tdelta) log.debug("Checking users timelimit %s: %s " "succesful authentications" % (max_success[0], succ_c)) if succ_c >= policy_count: res = False reply_dict["message"] = ("Only %s successfull " "authentications per %s" % (policy_count, tdelta)) return res, reply_dict
def auth_user_timelimit(wrapped_function, user_object, passw, options=None): """ This decorator checks the policy settings of ACTION.AUTHMAXSUCCESS, ACTION.AUTHMAXFAIL If the authentication was successful, it checks, if the number of allowed successful authentications is exceeded (AUTHMAXSUCCESS). If the AUTHMAXFAIL is exceed it denies even a successful authentication. The wrapped function is usually token.check_user_pass, which takes the arguments (user, passw, options={}) :param wrapped_function: :param user_object: :param passw: :param options: Dict containing values for "g" and "clientip" :return: Tuple of True/False and reply-dictionary """ # First we call the wrapped function res, reply_dict = wrapped_function(user_object, passw, options) options = options or {} g = options.get("g") if g: clientip = options.get("clientip") policy_object = g.policy_object max_success_dict = policy_object.get_action_values( action=ACTION.AUTHMAXSUCCESS, scope=SCOPE.AUTHZ, realm=user_object.realm, resolver=user_object.resolver, user=user_object.login, client=clientip, unique=True) max_fail_dict = policy_object.get_action_values( action=ACTION.AUTHMAXFAIL, scope=SCOPE.AUTHZ, realm=user_object.realm, resolver=user_object.resolver, user=user_object.login, client=clientip, unique=True) # Check for maximum failed authentications # Always - also in case of unsuccessful authentication if len(max_fail_dict) == 1: policy_count, tdelta = parse_timelimit(list(max_fail_dict)[0]) fail_c = g.audit_object.get_count({"user": user_object.login, "realm": user_object.realm, "action": "%/validate/check"}, success=False, timedelta=tdelta) log.debug("Checking users timelimit %s: %s " "failed authentications" % (list(max_fail_dict)[0], fail_c)) if fail_c >= policy_count: res = False reply_dict["message"] = ("Only %s failed authentications " "per %s" % (policy_count, tdelta)) g.audit_object.add_policy(next(iter(max_fail_dict.values()))) if res: # Check for maximum successful authentications # Only in case of a successful authentication if len(max_success_dict) == 1: policy_count, tdelta = parse_timelimit(list(max_success_dict)[0]) # check the successful authentications for this user succ_c = g.audit_object.get_count({"user": user_object.login, "realm": user_object.realm, "action": "%/validate/check"}, success=True, timedelta=tdelta) log.debug("Checking users timelimit %s: %s " "succesful authentications" % (list(max_success_dict)[0], succ_c)) if succ_c >= policy_count: res = False reply_dict["message"] = ("Only %s successfull " "authentications per %s" % (policy_count, tdelta)) return res, reply_dict