Wiki source code of Registration

Last modified by Vincent Massol on 2014/09/10

Show last authors
1 {{velocity}}
2 ## The registration is enabled:
3 ## - on the main wiki
4 ## - on a subwiki if there is no service "$services.wiki.user"
5 ## - on a subwiki where the user scope allows local users
6 #if($xcontext.isMainWiki() || "$!services.wiki.user" == '' || $services.wiki.user.getUserScope() != "GLOBAL_ONLY")
7 ## These are defined in other places around XWiki, changing them here will result in undefined behavior.
8 #set($redirectParam = 'xredirect')
9 #set($userSpace = 'XWiki.')
10 #set($loginPage = 'XWiki.XWikiLogin')
11 #set($loginAction = 'loginsubmit')
12 ##
13 #set($documentName = 'XWiki.Registration')
14 ##
15 ## Security measure:
16 ## If this document is changed such that it must have programming permission in order to run, change this to false.
17 #set($sandbox = true)
18 ##
19 ## Load the configuration from a seperate document.
20 #loadConfig('XWiki.RegistrationConfig')
21 ##
22 ## Defines what server generated error messages should look like
23 ## The error message when a field is entered incorrectly
24 #set($failureMessageParams = { 'class' : 'LV_validation_message LV_invalid'})
25 ## 'LV_validation_message LV_invalid' depends on this:
26 $xwiki.get('ssfx').use('uicomponents/widgets/validation/livevalidation.css', true)
27 ##
28 ## The * next to the fields to denote they are mandatory.
29 #set($fieldMandatoryStar = { 'class' : 'xRequired'})
30 ##
31 #*
32 * You may include this document in other documents using {{include document="XWiki.Registration"/}}
33 * To specify that the user is invited and should be allowed to register even if Guest does not have permission to
34 * register, set $invited to true. NOTE: The including script must have programming permission to do this.
35 *
36 * To specify some code which should run after registration is successfully completed, set
37 * $doAfterRegistration to a define block of velocity code like so:
38 * #define($doAfterRegistration)
39 * some code
40 * #end
41 * Output from running this code will not be printed.
42 *
43 * The fields which will be seen on the registration page are defined here.
44 * $fields is an array and each field is a Map. The names shown below are Map keys.
45 *
46 * Each field must have:
47 * name - this is the name of the field, it will be the value for "name" and "id"
48 *
49 * Each field may have:
50 * label - this String will be written above the field.
51 *
52 * tag - the HTML tag which will be created, default is <input>, may also be a non form tag such as <img>
53 *
54 * params - a Map, each key value pair will be in the html tag. eg: {"size" : "30"} becomes <input size=30...
55 *
56 * validate a Map describing how to validate the field, validation is done in javascript then redone in velocity
57 * | for security and because not everyone has javascript.
58 * |
59 * +-mandatory (Optional) - Will fail if the field is not filled in.
60 * | +-failureMessage (Required) - The message to display if the field is not filled in.
61 * | +-noscript (Optional) - will not be checked by javascript
62 * |
63 * +-regex (Optional) - Will validate the field using a regular expression.
64 * | | because of character escaping, you must provide a different expression for the
65 * | | javascript validation and the server side validation. Both javascript and server side
66 * | | validation are optional, but if you provide neither, then your field will not be validated.
67 * | |
68 * | +-failureMessage (Optional) - The message to display if the regex evaluation returns false.
69 * | +-jsFailureMessage (Optional) - The message for Javascript to display if regex fails.
70 * | | If jsFailureMessage is not defined Javascript uses failureMessage.
71 * | | NOTE: Javascript injects the failure message using createTextNode so &lt; will
72 * | | be displayed as &lt;
73 * | |
74 * | +-pattern (Optional) - The regular expression to test the input at the server side, it's important to use
75 * | | this if you need to validate the field for security reasons, also it is good because not
76 * | | all browsers use javascript or have it enabled.
77 * | |
78 * | +-jsPattern (Optional) - The regular expression to use for client side, you can use escaped characters to avoid
79 * | | them being parsed as HTML or javascript. To get javascript to unescape characters use:
80 * | | {"jsPattern" : "'+unescape('%5E%5B%24')+'"}
81 * | | NOTE: If no jsPattern is specified, the jsValidator will try to validate
82 * | | using the server pattern.
83 * | |
84 * | +-noscript (Optional) - will not be checked by javascript
85 * |
86 * +-mustMatch (Optional) - Will fail if the entry into the field is not the same as the entry in another field.
87 * | | Good for password confirmation.
88 * | |
89 * | +-failureMessage (Required) - The message to display if the field doesn't match the named field.
90 * | +-name (Required) - The name of the field which this field must match.
91 * | +-noscript (Optional) - will not be checked by javascript
92 * |
93 * +-programmaticValidation (Optional) - This form of validation executes a piece of code which you give it and
94 * | | if the code returns the word "failed" then it gives the error message.
95 * | | Remember to put the code in singel quotes ('') because you want the value
96 * | | of 'code' to equal the literal code, not the output from running it.
97 * | |
98 * | +-code (Required) - The code which will be executed to test whether the field is filled in correctly.
99 * | +-failureMessage (Required) - The message which will be displayed if evaluating the code returns "false"
100 * |
101 * +-fieldOkayMessage (Optional) - The message which is displayed by LiveValidation when a field is validated as okay.
102 * If not specified, will be $defaultFieldOkayMessage
103 *
104 * noReturn - If this is specified, the field will not be filled in if there is an error and the user has to fix their
105 * registration information. If you don't want a password to be passed back in html then set this true
106 * for the password fields. Used for the captcha because it makes no sense to pass back a captcha answer.
107 *
108 * doAfterRegistration - Some Velocity code which will be executed after a successfull registration.
109 * This is used in the favorite color example.
110 * Remember to put the code in singel quotes ('') because you want the 'code' entry to equal the literal
111 * code, not the output from running it.
112 *
113 * Each field may not have: (reserved names)
114 * error - This is used to pass back any error message from the server side code.
115 *
116 * NOTE: This template uses a registration method which requires:
117 * * register_first_name
118 * * register_last_name
119 * * xwikiname
120 * * register_password
121 * * register2_password
122 * * register_email
123 * * template
124 * Removing or renaming any of these fields will result in undefined behavior.
125 *
126 *###
127 #set($fields = [])
128 ##
129 ## The first name field, no checking.
130 #set($field =
131 {'name' : 'register_first_name',
132 'label' : $services.localization.render('core.register.firstName'),
133 'params' : {
134 'type' : 'text',
135 'size' : '60'
136 }
137 })
138 #set($discard = $fields.add($field))
139 ##
140 ## The last name field, no checking.
141 #set($field =
142 {'name' : 'register_last_name',
143 'label' : $services.localization.render('core.register.lastName'),
144 'params' : {
145 'type' : 'text',
146 'size' : '60'
147 }
148 })
149 #set($discard = $fields.add($field))
150 ##
151 ## The user name field, mandatory and programmatically checked to make sure the username doesn't exist.
152 #set($field =
153 {'name' : 'xwikiname',
154 'label' : $services.localization.render('core.register.username'),
155 'params' : {
156 'type' : 'text',
157 'onfocus' : 'prepareName(document.forms.register);',
158 'size' : '60'
159 },
160 'validate' : {
161 'mandatory' : {
162 'failureMessage' : $services.localization.render('core.validation.required.message')
163 },
164 'programmaticValidation' : {
165 'code' : '#nameAvailable($request.get("xwikiname"))',
166 'failureMessage' : $services.localization.render('core.register.userAlreadyExists')
167 }
168 }
169 })
170 #set($discard = $fields.add($field))
171 ## Make sure the chosen user name is not already taken
172 ## This macro is called by programmaticValidation for xwikiname (above)
173 #macro(nameAvailable, $name)
174 #if($xwiki.exists("$userSpace$name"))
175 failed
176 #end
177 #end
178 ##
179 ##The password field, mandatory and must be at least 6 characters long.
180 #set($field =
181 {'name' : 'register_password',
182 'label' : $services.localization.render('core.register.password'),
183 'params' : {
184 'type' : 'password',
185 'autocomplete' : 'off',
186 'size' : '60'
187 },
188 'validate' : {
189 'mandatory' : {
190 'failureMessage' : $services.localization.render('core.validation.required.message')
191 },
192 'regex' : {
193 'pattern' : '/.{6,}/',
194 'failureMessage' : $services.localization.render('xe.admin.registration.passwordTooShort')
195 }
196 }
197 })
198 #set($discard = $fields.add($field))
199 ##
200 ##The confirm password field, mandatory, must match password field, and must also be 6+ characters long.
201 #set($field =
202 {'name' : 'register2_password',
203 'label' : $services.localization.render('core.register.passwordRepeat'),
204 'params' : {
205 'type' : 'password',
206 'autocomplete' : 'off',
207 'size' : '60'
208 },
209 'validate' : {
210 'mandatory' : {
211 'failureMessage' : $services.localization.render('core.validation.required.message')
212 },
213 'mustMatch' : {
214 'name' : 'register_password',
215 'failureMessage' : $services.localization.render('xe.admin.registration.passwordMismatch')
216 },
217 'regex' : {
218 'pattern' : '/.{6,}/',
219 'failureMessage' : $services.localization.render('xe.admin.registration.passwordTooShort')
220 }
221 }
222 })
223 #set($discard = $fields.add($field))
224 ##
225 ## The email address field, regex checked with an email pattern. Mandatory if registration uses email verification
226 #set($field =
227 {'name' : 'register_email',
228 'label' : $services.localization.render('core.register.email'),
229 'params' : {
230 'type' : 'text',
231 'size' : '60'
232 },
233 'validate' : {
234 'regex' : {
235 'pattern' : '/^([^@\s]+)@((?:[-a-zA-Z0-9]+\.)+[a-zA-Z]{2,})$/',
236 'failureMessage' : $services.localization.render('xe.admin.registration.invalidEmail')
237 }
238 }
239 })
240 #if($xwiki.getXWikiPreferenceAsInt('use_email_verification', 0) == 1)
241 #set($field.validate.mandatory = {'failureMessage' : $services.localization.render('core.validation.required.message')})
242 #end
243 #set($discard = $fields.add($field))
244 ##
245 #*********
246 ## Uncomment this code to see an example of how you can easily add a field to the registration page
247 ## NOTE: In order to save the favorite color in the "doAfterRegistration" hook, this page must be
248 ## saved by an administrator and can not self sandboxing.
249 #set($sandbox = false)
250 #set($field =
251 {'name' : 'favorite_color',
252 'label' : 'What is your favorite color',
253 'params' : {
254 'type' : 'text',
255 'size' : '60'
256 },
257 'validate' : {
258 'mandatory' : {
259 'failureMessage' : $services.localization.render('core.validation.required.message')
260 },
261 'regex' : {
262 'pattern' : '/^green$/',
263 'failureMessage' : 'You are not cool enough to register here.'
264 },
265 'fieldOkayMessage' : 'You are awesome.'
266 },
267 'doAfterRegistration' : '#saveFavoriteColor()'
268 })
269 #set($discard = $fields.add($field))
270 ## Save the user's favorite color on their user page.
271 #macro(saveFavoriteColor)
272 #set($xwikiname = $request.get('xwikiname'))
273 #set($userDoc = $xwiki.getDocument("$userSpace$xwikiname"))
274 $userDoc.setContent("$userDoc.getContent() ${xwikiname}'s favorite color is $request.get('favorite_color')!")
275 ## The user (who is not yet logged in) can't save documents so saveWithProgrammingRights
276 ## will save the document as long as the user who last saved this registration page has programming rights.
277 $userDoc.saveWithProgrammingRights("Saved favorite color from registration form.")
278 #end
279 *********###
280 ##
281 ## To disable the captcha on this page, comment out the next two entries.
282 ## The captcha image, not an input field but still defined the same way.
283 #if($captchaservice
284 && !$invited
285 && $xcontext.getUser() == "XWiki.XWikiGuest"
286 && $requireCaptcha)
287 ## Empty label field used for padding.
288 ## Empty 'name' field overriddes name="captcha_image" with "" so name is not specified at all.
289 #set($field =
290 {'name' : 'captcha_image',
291 'label' : "<span class='hidden'>$services.localization.render('core.captcha.image.label')</span>",
292 'tag' : 'img',
293 'params' : {
294 'src' : $doc.getURL('imagecaptcha'),
295 'alt' : $services.localization.render('core.captcha.image.alternateText', [$services.localization.render('core.register.submit')]),
296 'name' : ''
297 }
298 })
299 #set($discard = $fields.add($field))
300 ## The captcha field, mandatory, programmatically checked to make sure the captcha is right
301 ## Not checked by javascript because javascript can't check the captcha and the Ok message because it passes the
302 ## mandatory test is misleading.
303 ## and not filled back in if there is an error ('noReturn')
304 #set($field =
305 {'name' : 'captcha_answer',
306 'label' : $services.localization.render('core.captcha.image.instruction'),
307 'params' : {
308 'type' : 'text',
309 'size' : '60'
310 },
311 'validate' : {
312 'mandatory' : {
313 'failureMessage' : $services.localization.render('core.captcha.captchaAnswerIsWrong'),
314 'noscript' : true
315 },
316 'programmaticValidation' : {
317 'code' : '#checkCaptcha($request, $request.get("captcha_answer"))',
318 'failureMessage' : $services.localization.render('core.captcha.captchaAnswerIsWrong')
319 }
320 },
321 'noReturn' : true
322 })
323 #set($discard = $fields.add($field))
324 #end
325 ##
326 ## Checks the captcha answer; used by programmaticValidation above.
327 #macro(checkCaptcha, $request, $answer)
328 #set($cv = $captchaservice.getCaptchaVerifier('image'))
329 #if(!$cv.isAnswerCorrect($cv.getUserId($request), $answer))
330 failed
331 #end
332 #end
333 ##
334 ## Pass the name of the template to $xwiki.createUser so any contained information will be passed in.
335 #set($field =
336 {'name' : 'template',
337 'params' : {
338 'type' : 'hidden',
339 'value' : 'XWiki.XWikiUserTemplate'
340 }
341 })
342 #set($discard = $fields.add($field))
343 ##
344 ## Pass the redirect parameter on so that the login page may redirect to the right place.
345 ## Not necessary in Firefox 3.0.10 or Opera 9.64, I don't know about IE or Safari.
346 #set($field =
347 {'name' : $redirectParam,
348 'params' : {
349 'type' : 'hidden'
350 }
351 })
352 #set($discard = $fields.add($field))
353 ##
354 #######################################################################
355 ## The Code.
356 #######################################################################
357 ##
358 #if($useLiveValidation)
359 $xwiki.get('jsfx').use('uicomponents/widgets/validation/livevalidation_prototype.js')
360 $xwiki.get('ssfx').use('uicomponents/widgets/validation/livevalidation.css', true)
361 #end
362 ## This application's HTML is dynamically generated and editing in WYSIWYG would not work
363 #if($xcontext.getAction() == 'edit')
364 $response.sendRedirect("$xwiki.getURL($doc.getFullName(), 'edit')?editor=wiki")
365 #end
366 ##
367 ## If this document has PR and is not included from another document then it's author should be set to Guest
368 ## for the duration of it's execution in order to improve security.
369 ## Note we compare document ids because
370 #if($sandbox
371 && $xcontext.hasProgrammingRights()
372 && $xcontext.getDoc().getDocumentReference().equals($xwiki.getDocument($documentName).getDocumentReference()))
373 ##
374 $xcontext.dropPermissions()##
375 #end
376 ##
377 ## Access level to register must be explicitly checked because it is only checked in XWiki.prepareDocuments
378 ## and this page is accessible through view action.
379 #if(!$xcontext.hasAccessLevel('register', 'XWiki.XWikiPreferences'))
380 ## Make an exception if another document with programming permission (Invitation app) has included this
381 ## document and set $invited to true.
382 #if(!$invited || !$xcontext.hasProgrammingRights())
383 $response.sendRedirect("$xwiki.getURL($doc.getFullName(), 'login')")
384 #end
385 #end
386 ## If this is true, then assume the registration page is being viewed inside of a lightbox
387 #if($request.get('xpage'))
388 #set($assumeLightbox = true)
389 #end
390 ##
391 ## Display the heading
392 $heading
393 ## If the submit button has been pressed, then we test the input and maybe create the user.
394 #if($request.getParameter('xwikiname'))
395 ## Do server side validation of input fields.
396 ## This must not be in a #set directive as it will output messages if something goes wrong.
397 #validateFields($fields, $request)
398 ## If server side validation was successfull, create the user
399 #if(!$registrationFailed)
400 #createUser($fields, $request, $response, $doAfterRegistration)
401 #end
402 #end
403 ## If the registration was not successful or if the user hasn't submitted the info yet
404 ## Then we display the registration form.
405 #if(!$registrationDone)
406 $welcomeMessage
407
408 {{html clean=false wiki=false}}
409 <form id="register" action="" method="post" class="xform half">
410 <div>
411 <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" />
412 #set ($userDirectoryReference = $services.model.createDocumentReference('', 'Main', 'UserDirectory'))
413 #if ($xwiki.exists($userDirectoryReference))
414 <input type="hidden" name="parent" value="$!{services.model.serialize($userDirectoryReference, 'default')}" />
415 #end
416 #generateHtml($fields, $fieldMandatoryStar, $failureMessageParams)
417 <div class="wikimodel-emptyline"></div>
418 <span class="buttonwrapper">
419 #if($assumeLightbox)
420 ## LightBox detected...
421 <script type="text/javascript">
422 ## Make the X button not reload the page. (overriding LbClose)
423 window.lb.lbClose = function() {
424 this.lbHide();
425 this.lbClearData();
426 ##return false;
427 }
428 ## Post the form entry to the page and load the result. (we override lbSaveForm)
429 window.lb.lbSaveForm = function() {
430 var formParams = Form.serialize(this.form);
431 Form.disable(this.form);
432 var ajaxRequest = new Ajax.Request(this.saveUrl, {
433 parameters: formParams,
434 asynchronous: false
435 });
436 window.lb.lbFormDataLoaded(ajaxRequest.transport);
437 }
438 </script>
439 ## It doesn't really matter where these are, the scripts will be relocated to the head.
440 <!-- com.xpn.xwiki.plugin.skinx.CssSkinFileExtensionPlugin -->
441 <!-- com.xpn.xwiki.plugin.skinx.JsSkinFileExtensionPlugin -->
442 ##
443 <input class="button" type="submit" value="$services.localization.render('save')" onclick="window.lb.lbSaveForm();"/>
444 </span>#* End ButtonWrapper then start another...*#<span class="buttonwrapper">
445 <input class="button secondary" type="submit" value="$services.localization.render("cancel")" onclick="Form.disable(window.lb.form); window.lb.lbClose();"/>
446 #else
447 ## Not using the LightBox
448 <input type="submit" value="$services.localization.render('core.register.submit')" class="button"/>
449 #end
450 </span>## ButtonWrapper
451 </div>
452 </form>
453 #if($useLiveValidation)
454 #generateJavascript($fields)
455 #end
456 {{/html}}
457
458 ##
459 ## Allow permitted users to configure this application.
460 #if($xcontext.getUser() != 'XWiki.XWikiGuest' && $xcontext.hasAccessLevel("edit", $documentName))
461 [[{{translation key="xe.admin.registration.youCanConfigureRegistrationHere"/}}>>XWiki.XWikiPreferences?section=Registration&editor=globaladmin#HCustomizeXWikiRegistration]]
462 {{html}}<a href="$xwiki.getURL($documentName, 'edit', 'editor=wiki')">$services.localization.render('xe.admin.registration.youCanConfigureRegistrationFieldsHere')</a>{{/html}}
463 #end
464 ## If the registration is done (successful) and we detect the Lightbox simply send the user back to the original page.
465 #elseif($assumeLightbox)
466 {{html clean=false wiki=false}}
467 <script type="text/javascript">
468 var url = window.lb.redirectUrl;
469 window.lb.lbClose;
470 if (url != undefined) {
471 if(window.location.pathname + window.location.search == url) {
472 ## Under certain circumstances (bug) Opera will not load a page if the location is the same as the current page.
473 ## In these cases, location.reload() doesn't work either, the only solution (I could find) was to change the URL.
474 window.location.href = url + "&";
475 } else {
476 window.location.href = url;
477 }
478 }
479 </script>
480 {{/html}}
481 #end
482 #else
483 ## The registration is not allowed on the subwiki
484 ## Redirecting to main wiki's registration page since local user registration is not allowed.
485 #set($mainWikiRegisterPageReference = $services.model.createDocumentReference($services.wiki.mainWikiId, 'XWiki', 'Register'))
486 #set($temp = $response.sendRedirect($xwiki.getURL($mainWikiRegisterPageReference, 'register', $request.queryString)))
487 #end
488 ##
489 ####### The Macros (nothing below this point is run directly) #########
490 #*
491 * Server side validation, this is necessary for security and because not everyone has Javascript
492 *
493 * @param $fields The array of fields to validate.
494 * @param $request An XWikiRequest object which made the register request, used to get parameters.
495 *###
496 #macro(validateFields, $fields, $request)
497 #foreach($field in $fields)
498 #if($field.get('validate') && $field.get('name'))
499 #set($fieldName = $field.get('name'))
500 #set($validate = $field.get('validate'))
501 #set($error = '')
502 #set($value = $request.get($fieldName))
503 #if($value && $value != '')
504 ##
505 ## mustMatch validation
506 #if($error == '' && $validate.get('mustMatch'))
507 #set($mustMatch = $validate.get('mustMatch'))
508 #if($mustMatch.get('name') && $mustMatch.get('failureMessage'))
509 #if($request.get($fieldName) != $request.get($mustMatch.get('name')))
510 #set($error = $mustMatch.get('failureMessage'))
511 #end
512 #else
513 ERROR: In field: ${fieldName}: mustMatch validation required both name
514 (of field which this field must match) and failureMessage.
515 #end
516 #end
517 ##
518 ## Regex validation
519 ## We won't bother with regex validation if there is no entry, that would defeat the purpose of 'mandatory'
520 #if($error == '' && $validate.get('regex') && $value && $value != '')
521 #set($regex = $validate.get('regex'))
522 #if($regex.get('pattern') && $regex.get('failureMessage'))
523 ## Make Java regexes more compatible with Perl/js style regexes by removing leading and trailing /
524 #if($regex.get('pattern').length() > 1)
525 #set($pattern = $regex.get('pattern'))
526 #if($pattern.lastIndexOf('/') < $pattern.length() - 1)
527 ERROR: In field: ${fieldName}: regex validation does not allow flags after the /, please fix [${pattern}].
528 #end
529 #set($pattern = $pattern.substring($mathtool.add(1, $pattern.indexOf('/')), $pattern.lastIndexOf('/')))
530 #else
531 ## I don't expect this but want to maintain compatibility.
532 #set($pattern = $regex.get('pattern'))
533 #end
534 #if($regextool.find($value, $pattern).isEmpty())
535 #set($error = $regex.get('failureMessage'))
536 #end
537 #elseif($regex.get('pattern'))
538 ERROR: In field: ${fieldName}: regex validation must include failureMessage.
539 #end
540 #end
541 ##
542 ## If regex and mustMatch validation passed, try programmatic validation
543 #if($error == '' && $validate.get('programmaticValidation'))
544 #set($pv = $validate.get('programmaticValidation'))
545 #if($pv.get('code') && $pv.get('failureMessage'))
546 #set($pvReturn = "#evaluate($pv.get('code'))")
547 #if($pvReturn.indexOf('failed') != -1)
548 #set($error = $pv.get('failureMessage'))
549 #end
550 #else
551 ERROR: In field: ${fieldName}: programmaticValidation requires code and failureMessage
552 #end
553 #end
554 #else
555 ##
556 ## If no content, check if content is mandatory
557 #if($validate.get('mandatory'))
558 #set($mandatory = $validate.get('mandatory'))
559 #if($mandatory.get('failureMessage'))
560 #set($error = $mandatory.get('failureMessage'))
561 #else
562 ERROR: In field: ${fieldName}: mandatory validation requires a failureMessage
563 #end
564 #end
565 #end
566 #if($error != '')
567 #set($discard = $field.put('error', $error))
568 #set($registrationFailed = true)
569 #end
570 #elseif(!$field.get('name'))
571 ERROR: Field with no name.
572 #end##if(validate)
573 #end##loop
574 #end##macro
575 #*
576 * Create the user.
577 * Calls $xwiki.createUser to create a new user.
578 *
579 * @param $request An XWikiRequest object which made the register request.
580 * @param $response The XWikiResponse object to send any redirects to.
581 * @param $doAfterRegistration code block to run after registration completes successfully.
582 *###
583 #macro(createUser, $fields, $request, $response, $doAfterRegistration)
584 ## CSRF check
585 #if(${services.csrf.isTokenValid("$!{request.getParameter('form_token')}")})
586 ## See if email verification is required and register the user.
587 #if($xwiki.getXWikiPreferenceAsInt('use_email_verification', 0) == 1)
588 #set($reg = $xwiki.createUser(true))
589 #else
590 #set($reg = $xwiki.createUser(false))
591 #end
592 #else
593 $response.sendRedirect("$!{services.csrf.getResubmissionURL()}")
594 #end
595 ##
596 ## Handle output from the registration.
597 #if($reg && $reg <= 0)
598 {{error}}
599 #if($reg == -2)
600 {{translation key="core.register.passwordMismatch"/}}
601 ## -3 means username taken, -8 means username is superadmin name
602 #elseif($reg == -3 || $reg == -8)
603 {{translation key="core.register.userAlreadyExists"/}}
604 #elseif($reg == -4)
605 {{translation key="core.register.invalidUsername"/}}
606 #else
607 {{translation key="core.register.registerFailed" parameters="$reg"/}}
608 #end
609 {{/error}}
610 #elseif($reg)
611 ## Registration was successful
612 #set($registrationDone = true)
613 ##
614 ## If there is any thing to "doAfterRegistration" then do it.
615 #foreach($field in $fields)
616 #if($field.get('doAfterRegistration'))
617 #evaluate($field.get('doAfterRegistration'))
618 #end
619 #end
620 ## If there is a "global" doAfterRegistration, do that as well.
621 ## Calling toString() on a #define block will execute it and we discard the result.
622 #set($discard = $doAfterRegistration.toString())
623 ##
624 ## Define some strings which may be used by autoLogin or loginButton
625 #set($userName = $!request.get('xwikiname'))
626 #set($password = $!request.get('register_password'))
627 #set($loginURL = $xwiki.getURL($loginPage, $loginAction))
628 #if("$!request.getParameter($redirectParam)" != '')
629 #set($redirect = $request.getParameter($redirectParam))
630 #else
631 #set($redirect = $defaultRedirect)
632 #end
633 ## Display a "registration successful" message
634
635 #evaluate($registrationSuccessMessage)
636
637 ## Empty line prevents message from being forced into a <p> block.
638
639 ## Give the user a login button which posts their username and password to loginsubmit
640 #if($loginButton)
641
642 {{html clean=false wiki=false}}
643 <form id="loginForm" action="$loginURL" method="post">
644 <div class="centered">
645 <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" />
646 <input id="j_username" name="j_username" type="hidden" value="$escapetool.xml($!userName)" />
647 <input id="j_password" name="j_password" type="hidden" value="$escapetool.xml($!password)" />
648 <input id="$redirectParam" name="$redirectParam" type="hidden" value="$escapetool.xml($redirect)" />
649 <span class="buttonwrapper">
650 <input type="submit" value="$services.localization.render('login')" class="button"/>
651 </span>
652 </div>
653 </form>
654 ## We don't want autoLogin if we are administrators adding users...
655 #if($autoLogin && !$assumeLightbox)
656 <script type='text/javascript'>
657 document.observe('xwiki:dom:loaded', function() {
658 document.forms['loginForm'].submit();
659 });
660 </script>
661 #end
662 {{/html}}
663
664 #end
665 #end
666 ##
667 #end## createUser Macro
668 #*
669 * Generate HTML form, this is the only place where HTML is written.
670 *
671 * @param $fields The array of fields to use for generating html code.
672 * @param $fieldMandatoryStar The tag parameters for a * indicating a mandatory field.
673 * @param $failureMessageParams The tag parameters for a failure message.
674 *###
675 #macro(generateHtml, $fields, $fieldMandatoryStar, $failureMessageParams)
676 ## Put the same values back into the fields.
677 #getParams($fields)
678 ##
679 <dl>
680 #foreach($field in $fields)
681 #if($field.get('name'))
682 #set($fieldName = $field.get('name'))
683 #if($field.get('label'))
684 #set($label = $field.get('label'))
685 <dt><label for="$fieldName">$label
686 #if($field.get('validate').get('mandatory'))
687 <span ##
688 #foreach($entry in $fieldMandatoryStar.entrySet())
689 $entry.getKey()="$entry.getValue()" ##
690 #end
691 >$services.localization.render('core.validation.required')</span>
692 #end
693 </label>
694 </dt>
695 #end
696 ## If no tag then default tag is <input>
697 #if($field.get('tag'))
698 #set($tag = $field.get('tag'))
699 #else
700 #set($tag = 'input')
701 #end
702 <dd><$tag id="$fieldName" ##
703 #set($params = $field.get('params'))
704 ## If no name parameter is spacified, then we use the field name
705 #if(!$params.get('name'))
706 #set($discard = $params.put('name', $fieldName))
707 #end
708 #foreach($entry in $params.entrySet())
709 ## If a parameter is specified as '' then we don't include it.
710 #if($entry.getValue() != '')
711 $entry.getKey()="$escapetool.xml($entry.getValue())" ##
712 #end
713 #end
714 ></$tag>
715 #if($field.get('error'))
716 <span ##
717 #foreach($entry in $failureMessageParams.entrySet())
718 $entry.getKey()="$entry.getValue()" ##
719 #end
720 >$field.get('error')</span>
721 #end
722 </dd>
723 #else
724 ERROR: Field with no name.
725 #end##if fieldName exists
726 #end
727 </dl>
728 #end
729 #*
730 * Generate the Javascript for interacting with LiveValidation.
731 *
732 * @param $fields The array of fields which to validate.
733 *###
734 #macro(generateJavascript, $fields)
735 <script type='text/javascript'>
736 /* <![CDATA[ */
737 document.observe('xwiki:dom:loaded', function() {
738 ##
739 #foreach($field in $fields)
740 #if($field.get('validate') && $field.get('name'))
741 #set($validate = $field.get('validate'))
742 #if(($validate.get('mandatory') && !$validate.get('mandatory').get('noscript'))
743 || ($validate.get('regex') && !$validate.get('regex').get('noscript'))
744 || ($validate.get('mustMatch') && !$validate.get('mustMatch').get('noscript')))
745 #set($fieldName = $field.get('name'))
746 #if($validate.get('fieldOkayMessage'))
747 #set($okayMessage = $validate.get('fieldOkayMessage'))
748 #else
749 #set($okayMessage = $defaultFieldOkayMessage)
750 #end
751 var ${fieldName}Validator = new LiveValidation("$fieldName", { validMessage: "$okayMessage", wait: 500} );
752 ##
753 #if($validate.get('mandatory'))
754 #set($mandatory = $validate.get('mandatory'))
755 #if($mandatory.get('failureMessage') && !$mandatory.get('noscript'))
756 ${fieldName}Validator.add( Validate.Presence, { failureMessage: "$!mandatory.get('failureMessage')"} );
757 #end
758 #end
759 ##
760 #if($validate.get('mustMatch'))
761 #set($mustMatch = $validate.get('mustMatch'))
762 #if($mustMatch.get('name') && $mustMatch.get('failureMessage') && !$mustMatch.get('noscript'))
763 ${fieldName}Validator.add( Validate.Confirmation, { match: $$("input[name=$!mustMatch.get('name')]")[0], failureMessage: "$!mustMatch.get('failureMessage')"} );
764 #end
765 #end
766 ##
767 #if($validate.get('regex'))
768 #set($regex = $validate.get('regex'))
769 #set($pattern = "")
770 #if($regex.get('jsPattern'))
771 #set($pattern = $regex.get('jsPattern'))
772 #elseif($regex.get('pattern'))
773 #set($pattern = $regex.get('pattern'))
774 #end
775 #set($failMessage = "")
776 #if($regex.get('jsFailureMessage'))
777 #set($failMessage = $regex.get('jsFailureMessage'))
778 #elseif($regex.get('failureMessage'))
779 #set($failMessage = $regex.get('failureMessage'))
780 #end
781 #if($pattern != '' && $failMessage != '' && !$regex.get('noscript'))
782 ${fieldName}Validator.add( Validate.Format, { pattern: $pattern, failureMessage: "$failMessage"} );
783 #end
784 #end##if regex
785 #end##if contains js validateable fields.
786 #end##if validate
787 #end##loop
788 });// ]]>
789 </script>
790 #end##macro
791 #*
792 * Get parameters from request so that values will be filled in if there is a mistake
793 * in one of the entries. Entries will be returned to fields[n].params.value
794 * Fields will not be returned if they have either noReturn or error specified.
795 *
796 * @param $fields The array of fields to get parameters for.
797 *###
798 #macro(getParams $fields)
799 #foreach($field in $fields)
800 #if($field.get('name') && $request.get($field.get('name')))
801 #if(!$field.get('noReturn') && !$field.get('error'))
802 #if(!$field.get('params'))
803 #set($params = {})
804 #set($discard = $field.put('params', $params))
805 #else
806 #set($params = $field.get('params'))
807 #end
808 #set($discard = $params.put('value', $request.get($field.get('name'))))
809 #end
810 #end
811 #end
812 #end
813 #*
814 * Get the configuration from the configuration object.
815 *
816 * @param $configDocumentName The name of the document to get the configuration from.
817 *###
818 #macro(loadConfig, $configDocumentName)
819 #set($configDocument = $xwiki.getDocument($configDocumentName))
820 #if(!$configDocument || !$configDocument.getObject($documentName))
821 ## No config document, load defaults.
822 #set($heading = "$services.localization.render('core.register.title')")
823 #set($welcomeMessage = "$services.localization.render('core.register.welcome')")
824 #set($useLiveValidation = true)
825 #set($defaultFieldOkayMessage = "$services.localization.render('core.validation.valid.message')")
826 #set($loginButton = true)
827 #set($defaultRedirect = "$xwiki.getURL($services.model.resolveDocument('', 'default', $doc.documentReference.extractReference('WIKI')))")
828 #set($userFullName = "$request.get('register_first_name') $request.get('register_last_name')")
829 #set($registrationSuccessMessage = '{{info}}$services.localization.render("core.register.successful", ["[[${userFullName}>>${userSpace}${userName}]]", ${userName}]){{/info}}')
830 #else
831 #set($configObject = $configDocument.getObject($documentName))
832 #if ($xcontext.action == 'register')
833 #set ($heading = "(% id='document-title'%)((( = #evaluate($configObject.getProperty('heading').getValue()) = )))(%%)")
834 #else
835 #set ($heading = "= #evaluate($configObject.getProperty('heading').getValue()) =")
836 #end
837 #set($welcomeMessage = "#evaluate($configObject.getProperty('welcomeMessage').getValue())")
838 #if($configObject.getProperty('liveValidation_enabled').getValue() == 1)
839 #set($useLiveValidation = true)
840 #end
841 #set($defaultFieldOkayMessage = "#evaluate($configObject.getProperty('liveValidation_defaultFieldOkMessage').getValue())")
842 #if($configObject.getProperty('loginButton_enabled').getValue() == 1)
843 #set($loginButton = true)
844 #end
845 #if($configObject.getProperty('loginButton_autoLogin_enabled').getValue() == 1)
846 #set($autoLogin = true)
847 #end
848 #set($defaultRedirect = "#evaluate($configObject.getProperty('defaultRedirect').getValue())")
849 #set($registrationSuccessMessage = "$configObject.getProperty('registrationSuccessMessage').getValue()")
850 #if($configObject.getProperty('requireCaptcha').getValue() == 1)
851 #set($requireCaptcha = true)
852 #end
853 #end
854 #end
855 {{/velocity}}

Get Connected