# # # # password_util.cfv (Contains password validation utilities) # # # # check_is_expired_password() # check_is_previous_used_password_error() # get_password_validation_rules_dat() # create_password_rules_info_text() # # include "templates.util.encoding"; # # # # check_is_expired_password() # # # subroutine(check_is_expired_password( string user_node_name), ( # # Checks if the passowrd is expired. This subroutine should only be invoked # if "preferences.password.password_expires" is set to true. # # Note, the user_node_name may be empty in case of command_line_authentication via a script, # so check for user existence before cheking for an expired password bool is_expired_password = false; if (user_node_name ne "" and ?("users." . user_node_name)) then ( node user = "users." . user_node_name; int password_creation_time = if (user?{"password_creation_time"}) then (@user{"password_creation_time"}) else (0); if (password_creation_time > 0) then ( int days_until_password_expiration = @("preferences.password.days_until_password_expiration"); int seconds_until_expiration = 24 * 60 * 60 * days_until_password_expiration; int current_time = now(); debug_message("#### check_is_expired_password() - password_creation_time: " . password_creation_time . "\n"); debug_message("#### check_is_expired_password() - current_time: " . current_time . "\n"); debug_message("#### check_is_expired_password() - seconds_until_expiration: " . seconds_until_expiration . "\n"); if ((current_time - password_creation_time) > seconds_until_expiration) then ( is_expired_password = true; ); ) else ( # The password_creation_time does not exist, for this case we set is_expired_password to true is_expired_password = true; ); ); is_expired_password; )); # # # # check_is_previous_used_password_error() # # # subroutine(check_is_previous_used_password_error( string user_node_name, string new_password_checksum), ( # Checks the use of the new password if the option prevent_use_of_previous_passwords is set to true. bool is_previous_used_password_error = false; if (@("preferences.password.prevent_use_of_previous_passwords")) then ( node user = "users." . user_node_name; # Note, if no password_checksum_history node exists then create it now # with one entry of the existing passowrd_checksum if (!user?{"password_checksum_history"}) then ( string existing_password_checksum = @user{"password_checksum"}; user . ".password_checksum_history." . existing_password_checksum = ""; save_node("users"); ); node password_checksum_history = user{"password_checksum_history"}; int number_of_previous_passwords_to_check = @("preferences.password.number_of_previous_passwords_to_check"); # Get the number of the node which we check first, starting with the last node int item_index = num_subnodes(password_checksum_history) - 1; int number_of_items_checked = 0; string previous_password_checksum; while (!is_previous_used_password_error and (item_index >= 0) and (number_of_items_checked < number_of_previous_passwords_to_check)) ( previous_password_checksum = node_name(subnode_by_number(password_checksum_history, item_index)); if (previous_password_checksum eq new_password_checksum) then ( is_previous_used_password_error = true; ); item_index--; number_of_items_checked++; ); ); is_previous_used_password_error; )); # # # # get_password_validation_rules_dat() # # # # subroutine(get_password_validation_rules_dat, ( # Returns a js object which contains password validation paramters. # The prevent_use_of_previous_password and number_of_previous_passwords_to_check # is handled by a single parameter. If prevent_use_of_previous_password is true # we create a password_checksum_history array with the number of previous password # checksums. So we simply check the array length, if it is greater 0 then we know # that we have to check. node psw = "preferences.password"; # prevent_use_of_previous_password is CURRENTLY NOT USED, WE CHECK THAT ON THE SERVER SIDE ONLY! # bool prevent_use_of_previous_password = @psw{"prevent_use_of_previous_password"}; # int number_of_previous_passwords_to_check = @psw{"number_of_previous_passwords_to_check"}; # string previous_password_checksums_to_check_dat = "[]"; string dat = "{"; dat .= add_json("minimumLength", @psw{"minimum_length"}, "int"); dat .= add_json("requiresLetter", @psw{"requires_letter"}, "bool"); dat .= add_json("requiresMixedCase", @psw{"requires_mixed_case"}, "bool"); dat .= add_json("requiresDigit", @psw{"requires_digit"}, "bool"); dat .= add_json("requiresSymbol", @psw{"requires_symbol"}, "bool"); dat = close_json(dat); dat; )); # # # # create_password_rules_info_text() # # # subroutine(create_password_rules_info_text, ( # Creates a password rules info text according the paramters in preferences.password, i.e.: # "Password rules: minimum 8 characters, contains letters, uppercase and lowercase, ..." # KHP-RC, we may add this feature later or not at all because it doesn't look to be easy # to create the text automatically. #* node password = "preferences.password"; string info_text; delete_node("v.temp_text"); v.temp_text = ""; node temp_text = "v.temp_text"; *# ));