Wiki source code of Reset password (step 2)
Last modified by JeromeVelociter on 2008/08/26 02:35
Show last authors
| author | version | line-number | content |
|---|---|---|---|
| 1 | #** | ||
| 2 | This page completes the password reset procedure. It works according to the next algorithm: | ||
| 3 | 1. Verify that the correct verification URL is entered, by checking the 'u' and 'v' request parameters against the existing ResetPasswordRequest objects | ||
| 4 | 2. Display a form requesting the new password | ||
| 5 | 3. When receiving the new password via form submission, update the user object with the new password, and remove the ResetPasswordRequest object | ||
| 6 | |||
| 7 | URL parameters: | ||
| 8 | |||
| 9 | u = user account in the verification URL | ||
| 10 | v = random verification string | ||
| 11 | p = the new password | ||
| 12 | p2 = the new password (for misspelling check) | ||
| 13 | |||
| 14 | !!!!! IMPORTANT !!!!! | ||
| 15 | |||
| 16 | This document requires programming rights, so always make sure | ||
| 17 | it is saved by a user with programming rights, and that | ||
| 18 | it is secured against unprivileged editing. | ||
| 19 | |||
| 20 | *# | ||
| 21 | ## | ||
| 22 | ## | ||
| 23 | ## First, check if the page has programming rights, as nothing works otherwise | ||
| 24 | #if($xwiki.hasProgrammingRights()) | ||
| 25 | ## | ||
| 26 | ## | ||
| 27 | ## The name of the class used for storing password reset verification data. | ||
| 28 | #set($verifClass = "XWiki.ResetPasswordRequestClass") | ||
| 29 | ## | ||
| 30 | ## START MACROS | ||
| 31 | ## | ||
| 32 | #** | ||
| 33 | * Encrypt a string to get the value that would be stored inside a PasswordProperty field. | ||
| 34 | * It is used to check if the unencrypted parameter from the URL is the value stored in the | ||
| 35 | * ResetPasswordRequest object. | ||
| 36 | * @param value The plaintext value to encrypt. | ||
| 37 | * @param result The encrypted output. | ||
| 38 | *# | ||
| 39 | #macro(encrypt $value $result) | ||
| 40 | #set($result = $xwiki.getDocument($verifClass).getxWikiClass().getXWikiClass().get("verification").getPasswordHash($value)) | ||
| 41 | #end | ||
| 42 | ## | ||
| 43 | ## | ||
| 44 | #** | ||
| 45 | * Verify that the request parameters are valid. | ||
| 46 | * @param userName The user name (full document name) received in the URL. | ||
| 47 | * @param validationString The unencrypted key that is stored in the ResetPasswordRequestClass object. | ||
| 48 | * @param result A boolean where the validation result is returned. True if the request is valid, false otherwise. | ||
| 49 | *# | ||
| 50 | #macro(verifyRequest $userName $validationString $result) | ||
| 51 | #set($result = false) | ||
| 52 | #if($validationString != "" && $userName != "") | ||
| 53 | #encrypt($validationString $encryptedValidationString) | ||
| 54 | #if("$!xwiki.getDocument($userName).getObject($verifClass).getProperty('verification').getValue()" == $encryptedValidationString) | ||
| 55 | #set($result = true) | ||
| 56 | #end | ||
| 57 | #end | ||
| 58 | #end | ||
| 59 | ## | ||
| 60 | ## | ||
| 61 | #** | ||
| 62 | * Displays the password reset form. | ||
| 63 | * @param message An optional message to display, for example if the sent password is empty. | ||
| 64 | * @param u The user account (full document name), which needs to be preserved. | ||
| 65 | * @param v The validation string, which will be checked again upon receiving the form. | ||
| 66 | *# | ||
| 67 | #macro(displayForm $message $userName $validationString) | ||
| 68 | 1 Reset password for ~~${xwiki.getUserName($userName)}~~ | ||
| 69 | #if($message != "") | ||
| 70 | #warning($message) | ||
| 71 | #end | ||
| 72 | <form action="$doc.getURL()" method="post" onsubmit="if($('password').value == '') {alert('The password cannot be an empty string.'); return false;} else if($('password').value != $('password2').value) {alert('The two passwords do not match.'); return false; }"> | ||
| 73 | <div class="hidden"> | ||
| 74 | <input type="hidden" name="u" value="$userName"/> | ||
| 75 | <input type="hidden" name="v" value="$validationString"/> | ||
| 76 | </div> | ||
| 77 | <dl> | ||
| 78 | <dt><label for="p">New password:</label></dt> | ||
| 79 | <dd><input id="p" type="password" name="p" value="" size="20"/></dd> | ||
| 80 | <dt><label for="p2">Re-enter new password:</label></dt> | ||
| 81 | <dd><input id="p2" type="password" value="" name="p2" size="20"/></dd> | ||
| 82 | </dl> | ||
| 83 | <div> | ||
| 84 | <input type="submit" value="Save" class="button"/> | ||
| 85 | </div> | ||
| 86 | </form> | ||
| 87 | #end | ||
| 88 | ## | ||
| 89 | ## END MACROS | ||
| 90 | ## | ||
| 91 | ## | ||
| 92 | #set($userName = "$!request.u") | ||
| 93 | #set($validationString = "$!request.v") | ||
| 94 | #set($password = "$!request.p") | ||
| 95 | #set($password2 = "$!request.p2") | ||
| 96 | #verifyRequest($userName $validationString $result) | ||
| 97 | #if($result) | ||
| 98 | #set($vuserDoc = $xwiki.getDocument($userName)) | ||
| 99 | #if($request.getParameterMap().containsKey("p")) ## Second step, set the user password | ||
| 100 | #if($password == "") | ||
| 101 | #displayForm("The password cannot be empty." $userName $validationString) | ||
| 102 | #elseif($password != $password2) | ||
| 103 | #displayForm("The two passwords do not match." $userName $validationString) | ||
| 104 | #else | ||
| 105 | $vuserDoc.getObject("XWiki.XWikiUsers").set("password", $password) | ||
| 106 | #set($discard = $vuserDoc.removeObjects($verifClass)) | ||
| 107 | $vuserDoc.saveWithProgrammingRights() | ||
| 108 | #info("The password has been successfully set. Please <a href='$xwiki.getURL('XWiki.XWikiLogin', 'login')'>login</a> to continue.") | ||
| 109 | #end | ||
| 110 | #else ## First step, request the user password | ||
| 111 | ## The user might not complete this step, and leave the URL in the (public) browser's | ||
| 112 | ## history. Prevent reusing the URL by invalidating the initial verification URL and only | ||
| 113 | ## post the new string in the hidden form data. | ||
| 114 | #set($validationString = $util.generateRandomString(30)) | ||
| 115 | $vuserDoc.getObject($verifClass).set("verification", $validationString) | ||
| 116 | $vuserDoc.saveWithProgrammingRights() | ||
| 117 | #displayForm("" $userName $validationString) | ||
| 118 | #end | ||
| 119 | #else | ||
| 120 | #error("Wrong parameters. [Back to the password reset page »>ResetPassword]") | ||
| 121 | #end | ||
| 122 | ## | ||
| 123 | ## Clear private variables, so that they cannot be accessed from the rest of the page (comments, panels...) | ||
| 124 | #set($validationString = "") | ||
| 125 | #set($password = "") | ||
| 126 | #set($password2 = "") | ||
| 127 | ## | ||
| 128 | ## | ||
| 129 | #else ## No programming rights, warn and exit | ||
| 130 | #error("This page requires programming rights to work, which currently isn't true. Please notify an administrator of this problem and try again later.") | ||
| 131 | #end |