def test_13_parse_time_offset_from_now(self): td = parse_timedelta("+5s") self.assertEqual(td, timedelta(seconds=5)) td = parse_timedelta("-12m") self.assertEqual(td, timedelta(minutes=-12)) td = parse_timedelta("+123h") self.assertEqual(td, timedelta(hours=123)) td = parse_timedelta("+2d") self.assertEqual(td, timedelta(days=2)) # It is allowed to start without a +/- which would mean a + td = parse_timedelta("12d") self.assertEqual(td, timedelta(days=12)) # Does not contains numbers self.assertRaises(Exception, parse_timedelta, "+twod") s, td = parse_time_offset_from_now("Hello {now}+5d with 5 days.") self.assertEqual(s, "Hello {now} with 5 days.") self.assertEqual(td, timedelta(days=5)) s, td = parse_time_offset_from_now("Hello {current_time}+5m!") self.assertEqual(s, "Hello {current_time}!") self.assertEqual(td, timedelta(minutes=5)) s, td = parse_time_offset_from_now("Hello {current_time}-3habc") self.assertEqual(s, "Hello {current_time}abc") self.assertEqual(td, timedelta(hours=-3))
def do(self, action, options=None): """ This method executes the defined action in the given event. :param action: :param options: Contains the flask parameters g, request, response and the handler_def configuration :type options: dict :return: """ ret = True g = options.get("g") request = options.get("request") response = options.get("response") content = self._get_response_content(response) handler_def = options.get("handler_def") handler_options = handler_def.get("options", {}) serial = request.all_data.get("serial") or \ content.get("detail", {}).get("serial") or \ g.audit_object.audit_data.get("serial") if action.lower() in [ACTION_TYPE.SET_TOKENREALM, ACTION_TYPE.SET_DESCRIPTION, ACTION_TYPE.DELETE, ACTION_TYPE.DISABLE, ACTION_TYPE.ENABLE, ACTION_TYPE.UNASSIGN, ACTION_TYPE.SET_VALIDITY, ACTION_TYPE.SET_COUNTWINDOW, ACTION_TYPE.SET_TOKENINFO, ACTION_TYPE.SET_FAILCOUNTER, ACTION_TYPE.CHANGE_FAILCOUNTER, ACTION_TYPE.SET_RANDOM_PIN, ACTION_TYPE.DELETE_TOKENINFO]: if serial: log.info("{0!s} for token {1!s}".format(action, serial)) if action.lower() == ACTION_TYPE.SET_TOKENREALM: realm = handler_options.get("realm") only_realm = is_true(handler_options.get("only_realm")) # Set the realm.. log.info("Setting realm of token {0!s} to {1!s}".format( serial, realm)) # Add the token realm set_realms(serial, [realm], add=not only_realm) elif action.lower() == ACTION_TYPE.SET_RANDOM_PIN: # If for any reason we have no value, we default to 6 length = int(handler_options.get("length") or 6) pin = generate_password(size=length) if set_pin(serial, pin): content.setdefault("detail", {})["pin"] = pin options.get("response").data = json.dumps(content) elif action.lower() == ACTION_TYPE.DELETE: remove_token(serial=serial) elif action.lower() == ACTION_TYPE.DISABLE: enable_token(serial, enable=False) elif action.lower() == ACTION_TYPE.ENABLE: enable_token(serial, enable=True) elif action.lower() == ACTION_TYPE.UNASSIGN: unassign_token(serial) elif action.lower() == ACTION_TYPE.SET_DESCRIPTION: description = handler_options.get("description") or "" description, td = parse_time_offset_from_now(description) s_now = (datetime.datetime.now(tzlocal()) + td).strftime( AUTH_DATE_FORMAT) set_description(serial, description.format( current_time=s_now, now=s_now, client_ip=g.client_ip, ua_browser=request.user_agent.browser, ua_string=request.user_agent.string)) elif action.lower() == ACTION_TYPE.SET_COUNTWINDOW: set_count_window(serial, int(handler_options.get("count window", 50))) elif action.lower() == ACTION_TYPE.SET_TOKENINFO: tokeninfo = handler_options.get("value") or "" tokeninfo, td = parse_time_offset_from_now(tokeninfo) s_now = (datetime.datetime.now(tzlocal()) + td).strftime( AUTH_DATE_FORMAT) try: username = request.User.loginname realm = request.User.realm except Exception: username = "******" realm = "N/A" add_tokeninfo(serial, handler_options.get("key"), tokeninfo.format( current_time=s_now, now=s_now, client_ip=g.client_ip, username=username, realm=realm, ua_browser=request.user_agent.browser, ua_string=request.user_agent.string)) elif action.lower() == ACTION_TYPE.DELETE_TOKENINFO: delete_tokeninfo(serial, handler_options.get("key")) elif action.lower() == ACTION_TYPE.SET_VALIDITY: start_date = handler_options.get(VALIDITY.START) end_date = handler_options.get(VALIDITY.END) if start_date: d = parse_date(start_date) set_validity_period_start(serial, None, d.strftime(DATE_FORMAT)) if end_date: d = parse_date(end_date) set_validity_period_end(serial, None, d.strftime(DATE_FORMAT)) elif action.lower() == ACTION_TYPE.SET_FAILCOUNTER: try: set_failcounter(serial, int(handler_options.get("fail counter"))) except Exception as exx: log.warning("Misconfiguration: Failed to set fail " "counter!") elif action.lower() == ACTION_TYPE.CHANGE_FAILCOUNTER: try: token_obj = get_one_token(serial=serial) token_obj.set_failcount( token_obj.token.failcount + int(handler_options.get("change fail counter"))) except Exception as exx: log.warning("Misconfiguration: Failed to increase or decrease fail " "counter!") else: log.info("Action {0!s} requires serial number. But no serial " "number could be found in request.") if action.lower() == ACTION_TYPE.INIT: log.info("Initializing new token") init_param = {"type": handler_options.get("tokentype"), "genkey": 1, "realm": handler_options.get("realm", "")} user = None if is_true(handler_options.get("user")): user = self._get_tokenowner(request) tokentype = handler_options.get("tokentype") # Some tokentypes need additional parameters if handler_options.get("additional_params"): add_params = yaml.safe_load(handler_options.get("additional_params")) if type(add_params) == dict: init_param.update(add_params) if tokentype == "sms": if handler_options.get("dynamic_phone"): init_param["dynamic_phone"] = 1 else: init_param['phone'] = user.get_user_phone( phone_type='mobile', index=0) if not init_param['phone']: log.warning("Enrolling SMS token. But the user " "{0!r} has no mobile number!".format(user)) if handler_options.get("sms_identifier"): init_param["sms.identifier"] = handler_options.get("sms_identifier") elif tokentype == "email": if handler_options.get("dynamic_email"): init_param["dynamic_email"] = 1 else: init_param['email'] = user.info.get("email", "") if not init_param['email']: log.warning("Enrolling EMail token. But the user {0!s}" "has no email address!".format(user)) if handler_options.get("smtp_identifier"): init_param["email.identifier"] = handler_options.get("smtp_identifier") elif tokentype == "motp": init_param['motppin'] = handler_options.get("motppin") t = init_token(param=init_param, user=user) log.info("New token {0!s} enrolled.".format(t.token.serial)) return ret
def check_condition(self, options): """ Check if all conditions are met and if the action should be executed. The the conditions are met, we return "True" :return: True """ res = True g = options.get("g") request = options.get("request") response = options.get("response") e_handler_def = options.get("handler_def") if not response or not e_handler_def: # options is missing a response and the handler definition # We are probably in test mode. return True # conditions can be correspnding to the property conditions conditions = e_handler_def.get("conditions") content = json.loads(response.data) user = self._get_tokenowner(request) serial = request.all_data.get("serial") or \ content.get("detail", {}).get("serial") tokenrealms = [] tokentype = None token_obj = None if serial: # We have determined the serial number from the request. token_obj_list = get_tokens(serial=serial) else: # We have to determine the token via the user object. But only if # the user has only one token token_obj_list = get_tokens(user=user) if len(token_obj_list) == 1: token_obj = token_obj_list[0] tokenrealms = token_obj.get_realms() tokentype = token_obj.get_tokentype() if "realm" in conditions: res = user.realm == conditions.get("realm") if "logged_in_user" in conditions and res: # Determine the role of the user try: logged_in_user = g.logged_in_user user_role = logged_in_user.get("role") except Exception: # A non-logged-in-user is a User, not an admin user_role = ROLE.USER res = user_role == conditions.get("logged_in_user") # Check result_value only if the check condition is still True if "result_value" in conditions and res: condition_value = conditions.get("result_value") result_value = content.get("result", {}).get("value") res = condition_value == str(result_value) # checking of max-failcounter state of the token if "token_locked" in conditions and res: if token_obj: locked = token_obj.get_failcount() >= \ token_obj.get_max_failcount() res = (conditions.get("token_locked") in ["True", True]) == \ locked else: # check all tokens of the user, if any token is maxfail token_objects = get_tokens(user=user, maxfail=True) if not ','.join([tok.get_serial() for tok in token_objects]): res = False if "tokenrealm" in conditions and res and tokenrealms: res = False for trealm in tokenrealms: if trealm in conditions.get("tokenrealm").split(","): res = True break if "serial" in conditions and res and serial: serial_match = conditions.get("serial") res = bool(re.match(serial_match, serial)) if CONDITION.USER_TOKEN_NUMBER in conditions and res and user: num_tokens = get_tokens(user=user, count=True) res = num_tokens == int(conditions.get( CONDITION.USER_TOKEN_NUMBER)) # Token specific conditions if token_obj: if CONDITION.TOKENTYPE in conditions and res: res = False if tokentype in conditions.get(CONDITION.TOKENTYPE).split(","): res = True if CONDITION.TOKEN_HAS_OWNER in conditions and res: uid = token_obj.get_user_id() check = conditions.get(CONDITION.TOKEN_HAS_OWNER) if uid and check in ["True", True]: res = True elif not uid and check in ["False", False]: res = True else: log.debug("Condition token_has_owner for token {0!r} " "not fulfilled.".format(token_obj)) res = False if CONDITION.TOKEN_IS_ORPHANED in conditions and res: uid = token_obj.get_user_id() orphaned = uid and not user check = conditions.get(CONDITION.TOKEN_IS_ORPHANED) if orphaned and check in ["True", True]: res = True elif not orphaned and check in ["False", False]: res = True else: log.debug( "Condition token_is_orphaned for token {0!r} not " "fulfilled.".format(token_obj)) res = False if CONDITION.TOKEN_VALIDITY_PERIOD in conditions and res: valid = token_obj.check_validity_period() res = (conditions.get(CONDITION.TOKEN_VALIDITY_PERIOD) in ["True", True]) == valid if CONDITION.OTP_COUNTER in conditions and res: res = token_obj.token.count == \ int(conditions.get(CONDITION.OTP_COUNTER)) if CONDITION.LAST_AUTH in conditions and res: res = not token_obj.check_last_auth_newer( conditions.get(CONDITION.LAST_AUTH)) if CONDITION.COUNT_AUTH in conditions and res: count = token_obj.get_count_auth() cond = conditions.get(CONDITION.COUNT_AUTH) res = compare_condition(cond, count) if CONDITION.COUNT_AUTH_SUCCESS in conditions and res: count = token_obj.get_count_auth_success() cond = conditions.get(CONDITION.COUNT_AUTH_SUCCESS) res = compare_condition(cond, count) if CONDITION.COUNT_AUTH_FAIL in conditions and res: count = token_obj.get_count_auth() c_success = token_obj.get_count_auth_success() c_fail = count - c_success cond = conditions.get(CONDITION.COUNT_AUTH_FAIL) res = compare_condition(cond, c_fail) if CONDITION.TOKENINFO in conditions and res: cond = conditions.get(CONDITION.TOKENINFO) # replace {now} in condition cond, td = parse_time_offset_from_now(cond) s_now = (datetime.datetime.now(tzlocal()) + td).strftime(DATE_FORMAT) cond = cond.format(now=s_now) if len(cond.split("==")) == 2: key, value = [x.strip() for x in cond.split("==")] res = compare_value_value(token_obj.get_tokeninfo(key), "==", value) elif len(cond.split(">")) == 2: key, value = [x.strip() for x in cond.split(">")] res = compare_value_value(token_obj.get_tokeninfo(key), ">", value) elif len(cond.split("<")) == 2: key, value = [x.strip() for x in cond.split("<")] res = compare_value_value(token_obj.get_tokeninfo(key), "<", value) else: # There is a condition, but we do not know it! log.warning("Misconfiguration in your tokeninfo " "condition: {0!s}".format(cond)) res = False return res
def check_condition(self, options): """ Check if all conditions are met and if the action should be executed. The the conditions are met, we return "True" :return: True """ g = options.get("g") request = options.get("request") response = options.get("response") e_handler_def = options.get("handler_def") if not e_handler_def: # options is the handler definition return True # conditions can be corresponding to the property conditions conditions = e_handler_def.get("conditions") content = self._get_response_content(response) user = self._get_tokenowner(request) serial = request.all_data.get("serial") or \ content.get("detail", {}).get("serial") tokenrealms = [] tokenresolvers = [] tokentype = None token_obj = None if serial: # We have determined the serial number from the request. token_obj_list = get_tokens(serial=serial) else: # We have to determine the token via the user object. But only if # the user has only one token token_obj_list = get_tokens(user=user) if len(token_obj_list) == 1: # There is a token involved, so we determine it's resolvers and realms token_obj = token_obj_list[0] tokenrealms = token_obj.get_realms() tokentype = token_obj.get_tokentype() all_realms = get_realms() for tokenrealm in tokenrealms: resolvers = all_realms.get(tokenrealm, {}).get("resolver", {}) tokenresolvers.extend([r.get("name") for r in resolvers]) tokenresolvers = list(set(tokenresolvers)) if CONDITION.CLIENT_IP in conditions: if g and g.client_ip: ip_policy = [ ip.strip() for ip in conditions.get(CONDITION.CLIENT_IP).split(",") ] found, excluded = check_ip_in_policy(g.client_ip, ip_policy) if not found or excluded: return False if CONDITION.REALM in conditions: if user.realm != conditions.get(CONDITION.REALM): return False if CONDITION.RESOLVER in conditions: if user.resolver != conditions.get(CONDITION.RESOLVER): return False if "logged_in_user" in conditions: # Determine the role of the user try: logged_in_user = g.logged_in_user user_role = logged_in_user.get("role") except Exception: # A non-logged-in-user is a User, not an admin user_role = ROLE.USER if user_role != conditions.get("logged_in_user"): return False if CONDITION.RESULT_VALUE in conditions: condition_value = conditions.get(CONDITION.RESULT_VALUE) result_value = content.get("result", {}).get("value") if is_true(condition_value) != is_true(result_value): return False if CONDITION.RESULT_STATUS in conditions: condition_value = conditions.get(CONDITION.RESULT_STATUS) result_status = content.get("result", {}).get("status") if is_true(condition_value) != is_true(result_status): return False # checking of max-failcounter state of the token if "token_locked" in conditions: if token_obj: locked = token_obj.get_failcount() >= \ token_obj.get_max_failcount() if (conditions.get("token_locked") in ["True", True]) != \ locked: return False else: # check all tokens of the user, if any token is maxfail token_objects = get_tokens(user=user, maxfail=True) if not ','.join([tok.get_serial() for tok in token_objects]): return False if CONDITION.TOKENREALM in conditions and tokenrealms: res = False for trealm in tokenrealms: if trealm in conditions.get(CONDITION.TOKENREALM).split(","): res = True break if not res: return False if CONDITION.TOKENRESOLVER in conditions and tokenresolvers: res = False for tres in tokenresolvers: if tres in conditions.get(CONDITION.TOKENRESOLVER).split(","): res = True break if not res: return False if "serial" in conditions and serial: serial_match = conditions.get("serial") if not bool(re.match(serial_match, serial)): return False if CONDITION.USER_TOKEN_NUMBER in conditions and user: num_tokens = get_tokens(user=user, count=True) if num_tokens != int(conditions.get(CONDITION.USER_TOKEN_NUMBER)): return False if CONDITION.DETAIL_ERROR_MESSAGE in conditions: message = content.get("detail", {}).get("error", {}).get("message") search_exp = conditions.get(CONDITION.DETAIL_ERROR_MESSAGE) m = re.search(search_exp, message) if not bool(m): return False if CONDITION.DETAIL_MESSAGE in conditions: message = content.get("detail", {}).get("message") search_exp = conditions.get(CONDITION.DETAIL_MESSAGE) m = re.search(search_exp, message) if not bool(m): return False # Token specific conditions if token_obj: if CONDITION.TOKENTYPE in conditions: if tokentype not in conditions.get( CONDITION.TOKENTYPE).split(","): return False if CONDITION.TOKEN_HAS_OWNER in conditions: uid = token_obj.get_user_id() check = conditions.get(CONDITION.TOKEN_HAS_OWNER) if uid and check in ["True", True]: res = True elif not uid and check in ["False", False]: res = True else: log.debug("Condition token_has_owner for token {0!r} " "not fulfilled.".format(token_obj)) return False if CONDITION.TOKEN_IS_ORPHANED in conditions: orphaned = token_obj.is_orphaned() check = conditions.get(CONDITION.TOKEN_IS_ORPHANED) if orphaned and check in ["True", True]: res = True elif not orphaned and check in ["False", False]: res = True else: log.debug( "Condition token_is_orphaned for token {0!r} not " "fulfilled.".format(token_obj)) return False if CONDITION.TOKEN_VALIDITY_PERIOD in conditions: valid = token_obj.check_validity_period() if (conditions.get(CONDITION.TOKEN_VALIDITY_PERIOD) in ["True", True]) != valid: return False if CONDITION.OTP_COUNTER in conditions: cond = conditions.get(CONDITION.OTP_COUNTER) if not compare_condition(cond, token_obj.token.count): return False if CONDITION.LAST_AUTH in conditions: if token_obj.check_last_auth_newer( conditions.get(CONDITION.LAST_AUTH)): return False if CONDITION.COUNT_AUTH in conditions: count = token_obj.get_count_auth() cond = conditions.get(CONDITION.COUNT_AUTH) if not compare_condition(cond, count): return False if CONDITION.COUNT_AUTH_SUCCESS in conditions: count = token_obj.get_count_auth_success() cond = conditions.get(CONDITION.COUNT_AUTH_SUCCESS) if not compare_condition(cond, count): return False if CONDITION.COUNT_AUTH_FAIL in conditions: count = token_obj.get_count_auth() c_success = token_obj.get_count_auth_success() c_fail = count - c_success cond = conditions.get(CONDITION.COUNT_AUTH_FAIL) if not compare_condition(cond, c_fail): return False if CONDITION.TOKENINFO in conditions: cond = conditions.get(CONDITION.TOKENINFO) # replace {now} in condition cond, td = parse_time_offset_from_now(cond) s_now = (datetime.datetime.now(tzlocal()) + td).strftime(DATE_FORMAT) cond = cond.format(now=s_now) if len(cond.split("==")) == 2: key, value = [x.strip() for x in cond.split("==")] if not compare_value_value(token_obj.get_tokeninfo(key), "==", value): return False elif len(cond.split(">")) == 2: key, value = [x.strip() for x in cond.split(">")] if not compare_value_value(token_obj.get_tokeninfo(key), ">", value): return False elif len(cond.split("<")) == 2: key, value = [x.strip() for x in cond.split("<")] if not compare_value_value(token_obj.get_tokeninfo(key), "<", value): return False else: # There is a condition, but we do not know it! log.warning("Misconfiguration in your tokeninfo " "condition: {0!s}".format(cond)) return False return True
def check_condition(self, options): """ Check if all conditions are met and if the action should be executed. The the conditions are met, we return "True" :return: True """ g = options.get("g") request = options.get("request") response = options.get("response") e_handler_def = options.get("handler_def") if not e_handler_def: # options is the handler definition return True # conditions can be corresponding to the property conditions conditions = e_handler_def.get("conditions") content = self._get_response_content(response) user = self._get_tokenowner(request) serial = request.all_data.get("serial") or \ content.get("detail", {}).get("serial") tokenrealms = [] tokentype = None token_obj = None if serial: # We have determined the serial number from the request. token_obj_list = get_tokens(serial=serial) else: # We have to determine the token via the user object. But only if # the user has only one token token_obj_list = get_tokens(user=user) if len(token_obj_list) == 1: token_obj = token_obj_list[0] tokenrealms = token_obj.get_realms() tokentype = token_obj.get_tokentype() if "realm" in conditions: if user.realm != conditions.get("realm"): return False if "logged_in_user" in conditions: # Determine the role of the user try: logged_in_user = g.logged_in_user user_role = logged_in_user.get("role") except Exception: # A non-logged-in-user is a User, not an admin user_role = ROLE.USER if user_role != conditions.get("logged_in_user"): return False if CONDITION.RESULT_VALUE in conditions: condition_value = conditions.get(CONDITION.RESULT_VALUE) result_value = content.get("result", {}).get("value") if is_true(condition_value) != is_true(result_value): return False if CONDITION.RESULT_STATUS in conditions: condition_value = conditions.get(CONDITION.RESULT_STATUS) result_status = content.get("result", {}).get("status") if is_true(condition_value) != is_true(result_status): return False # checking of max-failcounter state of the token if "token_locked" in conditions: if token_obj: locked = token_obj.get_failcount() >= \ token_obj.get_max_failcount() if (conditions.get("token_locked") in ["True", True]) != \ locked: return False else: # check all tokens of the user, if any token is maxfail token_objects = get_tokens(user=user, maxfail=True) if not ','.join([tok.get_serial() for tok in token_objects]): return False if "tokenrealm" in conditions and tokenrealms: res = False for trealm in tokenrealms: if trealm in conditions.get("tokenrealm").split(","): res = True break if not res: return False if "serial" in conditions and serial: serial_match = conditions.get("serial") if not bool(re.match(serial_match, serial)): return False if CONDITION.USER_TOKEN_NUMBER in conditions and user: num_tokens = get_tokens(user=user, count=True) if num_tokens != int(conditions.get( CONDITION.USER_TOKEN_NUMBER)): return False if CONDITION.DETAIL_ERROR_MESSAGE in conditions: message = content.get("detail", {}).get("error", {}).get("message") search_exp = conditions.get(CONDITION.DETAIL_ERROR_MESSAGE) m = re.search(search_exp, message) if not bool(m): return False if CONDITION.DETAIL_MESSAGE in conditions: message = content.get("detail", {}).get("message") search_exp = conditions.get(CONDITION.DETAIL_MESSAGE) m = re.search(search_exp, message) if not bool(m): return False # Token specific conditions if token_obj: if CONDITION.TOKENTYPE in conditions: if tokentype not in conditions.get(CONDITION.TOKENTYPE).split( ","): return False if CONDITION.TOKEN_HAS_OWNER in conditions: uid = token_obj.get_user_id() check = conditions.get(CONDITION.TOKEN_HAS_OWNER) if uid and check in ["True", True]: res = True elif not uid and check in ["False", False]: res = True else: log.debug("Condition token_has_owner for token {0!r} " "not fulfilled.".format(token_obj)) return False if CONDITION.TOKEN_IS_ORPHANED in conditions: uid = token_obj.get_user_id() orphaned = uid and not user check = conditions.get(CONDITION.TOKEN_IS_ORPHANED) if orphaned and check in ["True", True]: res = True elif not orphaned and check in ["False", False]: res = True else: log.debug("Condition token_is_orphaned for token {0!r} not " "fulfilled.".format(token_obj)) return False if CONDITION.TOKEN_VALIDITY_PERIOD in conditions: valid = token_obj.check_validity_period() if (conditions.get(CONDITION.TOKEN_VALIDITY_PERIOD) in ["True", True]) != valid: return False if CONDITION.OTP_COUNTER in conditions: if token_obj.token.count != \ int(conditions.get(CONDITION.OTP_COUNTER)): return False if CONDITION.LAST_AUTH in conditions: if token_obj.check_last_auth_newer(conditions.get( CONDITION.LAST_AUTH)): return False if CONDITION.COUNT_AUTH in conditions: count = token_obj.get_count_auth() cond = conditions.get(CONDITION.COUNT_AUTH) if not compare_condition(cond, count): return False if CONDITION.COUNT_AUTH_SUCCESS in conditions: count = token_obj.get_count_auth_success() cond = conditions.get(CONDITION.COUNT_AUTH_SUCCESS) if not compare_condition(cond, count): return False if CONDITION.COUNT_AUTH_FAIL in conditions: count = token_obj.get_count_auth() c_success = token_obj.get_count_auth_success() c_fail = count - c_success cond = conditions.get(CONDITION.COUNT_AUTH_FAIL) if not compare_condition(cond, c_fail): return False if CONDITION.TOKENINFO in conditions: cond = conditions.get(CONDITION.TOKENINFO) # replace {now} in condition cond, td = parse_time_offset_from_now(cond) s_now = (datetime.datetime.now(tzlocal()) + td).strftime( DATE_FORMAT) cond = cond.format(now=s_now) if len(cond.split("==")) == 2: key, value = [x.strip() for x in cond.split("==")] if not compare_value_value(token_obj.get_tokeninfo(key), "==", value): return False elif len(cond.split(">")) == 2: key, value = [x.strip() for x in cond.split(">")] if not compare_value_value(token_obj.get_tokeninfo(key), ">", value): return False elif len(cond.split("<")) == 2: key, value = [x.strip() for x in cond.split("<")] if not compare_value_value(token_obj.get_tokeninfo(key), "<", value): return False else: # There is a condition, but we do not know it! log.warning("Misconfiguration in your tokeninfo " "condition: {0!s}".format(cond)) return False return True
def do(self, action, options=None): """ This method executes the defined action in the given event. :param action: :param options: Contains the flask parameters g, request, response and the handler_def configuration :type options: dict :return: """ ret = True g = options.get("g") request = options.get("request") response = options.get("response") content = json.loads(response.data) handler_def = options.get("handler_def") handler_options = handler_def.get("options", {}) serial = request.all_data.get("serial") or \ content.get("detail", {}).get("serial") or \ g.audit_object.audit_data.get("serial") if action.lower() in [ACTION_TYPE.SET_TOKENREALM, ACTION_TYPE.SET_DESCRIPTION, ACTION_TYPE.DELETE, ACTION_TYPE.DISABLE, ACTION_TYPE.ENABLE, ACTION_TYPE.UNASSIGN, ACTION_TYPE.SET_VALIDITY, ACTION_TYPE.SET_COUNTWINDOW, ACTION_TYPE.SET_TOKENINFO, ACTION_TYPE.SET_FAILCOUNTER]: if serial: log.info("{0!s} for token {1!s}".format(action, serial)) if action.lower() == ACTION_TYPE.SET_TOKENREALM: realm = handler_options.get("realm") only_realm = is_true(handler_options.get("only_realm")) # Set the realm.. log.info("Setting realm of token {0!s} to {1!s}".format( serial, realm)) # Add the token realm set_realms(serial, [realm], add=not only_realm) elif action.lower() == ACTION_TYPE.DELETE: remove_token(serial=serial) elif action.lower() == ACTION_TYPE.DISABLE: enable_token(serial, enable=False) elif action.lower() == ACTION_TYPE.ENABLE: enable_token(serial, enable=True) elif action.lower() == ACTION_TYPE.UNASSIGN: unassign_token(serial) elif action.lower() == ACTION_TYPE.SET_DESCRIPTION: description = handler_options.get("description") or "" description, td = parse_time_offset_from_now(description) s_now = (datetime.datetime.now(tzlocal()) + td).strftime( AUTH_DATE_FORMAT) set_description(serial, description.format( current_time=s_now, now=s_now, client_ip=g.client_ip, ua_browser=request.user_agent.browser, ua_string=request.user_agent.string)) elif action.lower() == ACTION_TYPE.SET_COUNTWINDOW: set_count_window(serial, int(handler_options.get("count window", 50))) elif action.lower() == ACTION_TYPE.SET_TOKENINFO: tokeninfo = handler_options.get("value") or "" tokeninfo, td = parse_time_offset_from_now(tokeninfo) s_now = (datetime.datetime.now(tzlocal()) + td).strftime( AUTH_DATE_FORMAT) try: username = request.User.loginname realm = request.User.realm except Exception: username = "******" realm = "N/A" add_tokeninfo(serial, handler_options.get("key"), tokeninfo.format( current_time=s_now, now=s_now, client_ip=g.client_ip, username=username, realm=realm, ua_browser=request.user_agent.browser, ua_string=request.user_agent.string)) elif action.lower() == ACTION_TYPE.SET_VALIDITY: start_date = handler_options.get(VALIDITY.START) end_date = handler_options.get(VALIDITY.END) if start_date: d = parse_date(start_date) set_validity_period_start(serial, None, d.strftime(DATE_FORMAT)) if end_date: d = parse_date(end_date) set_validity_period_end(serial, None, d.strftime(DATE_FORMAT)) elif action.lower() == ACTION_TYPE.SET_FAILCOUNTER: try: set_failcounter(serial, int(handler_options.get("fail counter"))) except Exception as exx: log.warning("Misconfiguration: Failed to set fail " "counter!") else: log.info("Action {0!s} requires serial number. But no serial " "number could be found in request.") if action.lower() == ACTION_TYPE.INIT: log.info("Initializing new token") init_param = {"type": handler_options.get("tokentype"), "genkey": 1, "realm": handler_options.get("realm", "")} user = None if is_true(handler_options.get("user")): user = self._get_tokenowner(request) tokentype = handler_options.get("tokentype") # Some tokentypes need additional parameters or otherwise # will fail to enroll. # TODO: Other tokentypes will require additional parameters if tokentype == "sms": if handler_options.get("dynamic_phone"): init_param["dynamic_phone"] = 1 else: init_param['phone'] = user.get_user_phone( phone_type='mobile') if not init_param['phone']: log.warning("Enrolling SMS token. But the user " "{0!r} has no mobile number!".format(user)) elif tokentype == "email": init_param['email'] = user.info.get("email", "") if not init_param['email']: log.warning("Enrolling EMail token. But the user {0!s}" "has no email address!".format(user)) elif tokentype == "motp": init_param['motppin'] = handler_options.get("motppin") t = init_token(param=init_param, user=user) log.info("New token {0!s} enrolled.".format(t.token.serial)) return ret