Wiki source code of Reset password (step 2)

Last modified by JeromeVelociter on 2008/08/26 02:35

Show last authors
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 &#187;>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