Wiki source code of Forgot your password?

Last modified by Ecaterina Valica on 2019/03/27 14:31

Hide last authors
Administrator 3.1 1 {{velocity}}
Administrator 1.1 2 #**
3 This page starts the password reset procedure. It works according to the next algorithm:
4 1. Display a form requesting the username
5 2. When receiving the username via form submission, generate a random verification string which is stored (as a hash) inside a ResetPasswordRequestClass object attached to the user's profile page. If no such object exists, it is created, but an existing object will be reused, meaning that at most one password reset request can be active at a moment.
6 3. Send an email to the address configured in the user's profile, containing a link to the second step of the password reset procedure.
7
8 URL parameters:
9
10 u = user account sent in the form
Administrator 3.1 11 *###
Administrator 1.1 12 ##
13 ##
14 ## The name of the class used for storing password reset verification data.
JeromeVelociter 4.1 15 #set ($verifClass = 'XWiki.ResetPasswordRequestClass')
16 #set ($userName = "$!request.get('u')")
17 #if ($userName == '')## First step, display the form requesting the username
Ecaterina Valica 7.1 18 {{translation key="xe.admin.passwordReset.instructions"/}}
Administrator 1.1 19
Administrator 3.1 20 {{html}}
Ecaterina Valica 9.1 21 <form method="post" action="$doc.getURL()" class="xformInline">
Administrator 3.1 22 <div>
23 <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" />
Ecaterina Valica 7.1 24 <label for="u">$services.localization.render('xe.admin.passwordReset.username.label')</label> <input type="text" id="u" name="u"/> <span class="buttonwrapper"><input type="submit" value="$services.localization.render('xe.admin.passwordReset.submit')" class="button"/></span>
Administrator 3.1 25 </div>
Administrator 1.1 26 </form>
Administrator 3.1 27 {{/html}}
28 #else## Second step, generate the verification string, store it, and send the email
Administrator 1.1 29 ## TODO: Once the usernames are not bound to the XWiki space, revisit this code
JeromeVelociter 4.1 30 #if ($userName.indexOf('.') != -1)
31 #set ($userDoc = $xwiki.getDocumentAsAuthor(${userName}))
Administrator 1.1 32 #else
JeromeVelociter 4.1 33 #set ($userDoc = $xwiki.getDocumentAsAuthor("XWiki.${userName}"))
Administrator 1.1 34 #end
35 ## Check if the user exists and has a valid email address configured in his profile
JeromeVelociter 4.1 36 #set ($userObj = '')
37 #set ($userObj = $userDoc.getObject('XWiki.XWikiUsers'))
Ecaterina Valica 11.1 38 ## If local user does not exist check global user
39 #if (!$userObj && ${xcontext.database} != ${xcontext.mainWikiName})
40 #if ($userName.indexOf('.') != -1)
41 #set ($userDoc = $xwiki.getDocumentAsAuthor("${xcontext.mainWikiName}:${userName}"))
42 #else
43 #set ($userDoc = $xwiki.getDocumentAsAuthor("${xcontext.mainWikiName}:XWiki.${userName}"))
44 #end
45 #set ($userObj = $userDoc.getObject('XWiki.XWikiUsers'))
46 #end
JeromeVelociter 4.1 47 #if (!$userObj)
Administrator 3.1 48
Ecaterina Valica 7.1 49 {{warning}}$services.localization.render('xe.admin.passwordReset.error.noUser', ["//${escapetool.xml($userName)}//"]){{/warning}}
Administrator 3.1 50
Administrator 1.1 51 #elseif ($userDoc.getObject('XWiki.LDAPProfileClass'))
Administrator 3.1 52
Ecaterina Valica 7.1 53 {{warning}}$services.localization.render('xe.admin.passwordReset.error.ldapUser', ["//${escapetool.xml($userName)}//"]){{/warning}}
Administrator 3.1 54
Administrator 1.1 55 #else
JeromeVelociter 4.1 56 #set ($userEmail = $userObj.getProperty('email').value)
57 #if ("$!userEmail" == '')
Administrator 3.1 58
Ecaterina Valica 7.1 59 {{error}}{{translation key="xe.admin.passwordReset.error.noEmail"/}}{{/error}}
Administrator 3.1 60
Administrator 1.1 61 #else
62 ## Find the object that will hold the verification string
JeromeVelociter 4.1 63 #set ($verifObj = '')
64 #set ($verifObj = $userDoc.getObject($verifClass, true))
Administrator 1.1 65 ## Generate a random string
Admin 5.1 66 #set ($verifStr = $util.generateRandomString(30))
Administrator 1.1 67 ## If the class is correctly configured, the string should automatically be stored as a hash
JeromeVelociter 4.1 68 #set ($discard = $verifObj.set('verification', $verifStr))
Ecaterina Valica 7.1 69 #set ($discard = $userDoc.saveAsAuthor($services.localization.render('xe.admin.passwordReset.versionComment'), true))
Administrator 1.1 70 ## Compose the verification URL
Ecaterina Valica 11.1 71 #set ($userDocRef = $escapetool.url($services.model.serialize($userDoc.documentReference, 'default')))
72 #set ($passwordResetURL = $xwiki.getDocument("XWiki.ResetPasswordComplete").getExternalURL('view', "u=${userDocRef}&v=${verifStr}"))
Ecaterina Valica 9.1 73 ## Send the email
74 #set ($from = $services.mailsender.configuration.fromAddress)
75 #if ("$!from" == '')
76 #set ($from = "no-reply@${request.serverName}")
77 #end
78 #set ($mailTemplateReference = $services.model.createDocumentReference('', 'XWiki', 'ResetPasswordMailContent'))
79 #set ($mailParameters = {'from' : $from, 'to' : $userEmail, 'language' : $xcontext.locale})
80 #set ($message = $services.mailsender.createMessage('template', $mailTemplateReference, $mailParameters))
81 #set ($discard = $message.setType('Reset Password'))
82 #macro (displayError $text)
Administrator 3.1 83
Ecaterina Valica 9.1 84 {{html}}
85 <div class="xwikirenderingerror" title="Click to get more details about the error" style="cursor: pointer;">
86 $services.localization.render('xe.admin.passwordReset.error.emailFailed')
87 </div>
88 <div class="xwikirenderingerrordescription hidden">
89 <pre>${text}</pre>
90 </div>
91 {{/html}}
Administrator 3.1 92
Ecaterina Valica 9.1 93 #end
94 ## Check for an error constructing the message!
95 #if ($services.mailsender.lastError)
96 #displayError($exceptiontool.getStackTrace($services.mailsender.lastError))
Ecaterina Valica 10.1 97 #else
Ecaterina Valica 9.1 98 ## Send the message and wait for it to be sent or for any error to be raised.
99 #set ($mailResult = $services.mailsender.send([$message], 'database'))
100 ## Check for errors during the send
101 #if ($services.mailsender.lastError)
102 #displayError($exceptiontool.getStackTrace($services.mailsender.lastError))
103 #else
104 #set ($failedMailStatuses = $mailResult.statusResult.getAllErrors())
105 #if ($failedMailStatuses.hasNext())
106 #set ($mailStatus = $failedMailStatuses.next())
107 #displayError($mailStatus.errorDescription)
108 #else
Administrator 3.1 109
Ecaterina Valica 9.1 110 {{info}}$services.localization.render('xe.admin.passwordReset.emailSent', ["$userDoc.display('email', $userObj)"]){{/info}}
Administrator 3.1 111
Ecaterina Valica 9.1 112 #end
113 #end
Administrator 1.1 114 #end
115 #end
116 #end
Ecaterina Valica 7.1 117 [[{{translation key="xe.admin.passwordReset.error.retry"/}}>>$doc.fullName]] | [[{{translation key="xe.admin.passwordReset.error.recoverUsername"/}}>>ForgotUsername]] | [[{{translation key="xe.admin.passwordReset.login"/}}>>path:$xwiki.getURL('XWiki.XWikiLogin', 'login')]]
Administrator 1.1 118 #end
119 ## Clear private variables, so that they cannot be accessed from the rest of the page (comments, panels...)
JeromeVelociter 4.1 120 #set ($verifStr = '')
121 #set ($passwordResetURL = '')
Administrator 3.1 122 {{/velocity}}