{{html clean="false"}} {{/html}} {{velocity}} ## ## ####################################################################### ## The Constants ####################################################################### ## ## Output #set($youUsedDisallowedChars = "You can't use the characters ") #set($fieldMandatory = "Field is mandatory.") #set($passwordMismatch = "Passwords do not match.") #set($invalidEmail = "Must be a valid email address.") #set($fieldOkay = "OK.") ## ## #set($redirectParam = "xredirect") #set($coreSpace = "XWiki.") ## ## Defines what server generated error messages should look like ## We will just reference the liveValidation style. ## The error message when a field is entered incorrectly #set($failureMessageParams = {'class' : 'LV_validation_message LV_invalid'}) ## The * next to the fields to denote they are mandatory. #set($fieldMandatoryStar = $failureMessageParams) ## ## Client side javascript regex name validation. ## escaped version of: ^[^<>\'\"\\x5C]*$ ## blocks < > ' " \ #set($jsNameRegex = "'+unescape('%5E%5B%5E%3C%3E%27%22%5Cx5C%5D*%24')+'") #set($serverSideNameRegex = "^[^<>\'\"\x5C]*$") ## tells the user that they can't use the characters < > ' " \ #set($nameYouUsedDisallowedChars = "$youUsedDisallowedChars "+unescape('%27%20%20%22%20%3C%20%3E%20')+"") ## #* * The fields which will be seen on the registration page are defined here. * $fields is an array and each field is a Map. The names shown below are Map keys. * * Each field must have: * name - this is the name of the field, it will be the value for "name" and "id" * * Each field may have: * prompt - this String will be written above the field. * tag - the HTML tag which will be created, default is , may also be a non form tag such as * params - a Map, each key value pair will be in the html tag. eg: {"size" : "30"} becomes ' \" \\ " } } }) #set($discard = $fields.add($field)) ## ## The last name field, mandatory and checked for disallowed characters. #set($field = {"name" : "register_last_name", "prompt" : $msg.get('core.register.lastName'), "params" : { "type" : "text", "size" : "30" }, "validate" : { "mandatory" : { "failureMessage" : $fieldMandatory }, "regex" : { "jsPattern" : $jsNameRegex, "pattern" : $serverSideNameRegex, "failureMessage" : $nameYouUsedDisallowedChars } } }) #set($discard = $fields.add($field)) ## ## The user name field, mandatory and programmatically checked to make sure the username doesn't exist. #set($field = {"name" : "xwikiname", "prompt" : $msg.get('core.register.username'), "params" : { "type" : "text", "onfocus" : "prepareName(document.forms.register);", "size" : "20" }, "validate" : { "mandatory" : { "failureMessage" : $fieldMandatory }, "programmaticValidation" : { "code" : "#nameAvailable($request.get('xwikiname'))", "failureMessage" : $msg.get('core.register.userAlreadyExists') } } }) #set($discard = $fields.add($field)) ## Make sure the chosen user name is not already taken ## This macro is called by programmaticValidation for xwikiname (above) #macro(nameAvailable, $name) #if($xwiki.exists("$coreSpace$name")) false #end #end ## ##The password field, mandatory. #set($field = {"name" : "register_password", "prompt" : $msg.get('core.register.password'), "params" : { "type" : "password", "size" : "10" }, "validate" : { "mandatory" : { "failureMessage" : $fieldMandatory } } }) #set($discard = $fields.add($field)) ## ##The confirm password field, mandatory and must match password field. #set($field = {"name" : "register2_password", "prompt" : $msg.get('core.register.passwordRepeat'), "params" : { "type" : "password", "size" : "10" }, "validate" : { "mandatory" : { "failureMessage" : $fieldMandatory }, "mustMatch" : { "name" : "register_password", "failureMessage" : $passwordMismatch } } }) #set($discard = $fields.add($field)) ## ## The email address field, mandatory and regex checked with an email pattern. #set($field = {"name" : "register_email", "prompt" : $msg.get('core.register.email'), "params" : { "type" : "text", "size" : "30" }, "validate" : { "mandatory" : { "failureMessage" : $fieldMandatory }, "regex" : { "jsPattern" : '^([^@\\s]+)@((?:[-a-zA-Z0-9]+\\.)+[a-zA-Z]{2,})$', "pattern" : '^([^@\s]+)@((?:[-a-zA-Z0-9]+\.)+[a-zA-Z]{2,})$', "failureMessage" : $invalidEmail } } }) #set($discard = $fields.add($field)) #* ## Uncomment this code to see an example of how you can easily add a field to the registration page ## ## #set($field = {"name" : "fav_color", "prompt" : "What is your favorite color", "params" : { "type" : "text", "size" : "30" }, "validate" : { "mandatory" : { "failureMessage" : $fieldMandatory }, "regex" : { "jsPattern" : "green", "failureMessage" : "You are not cool enough to register here." } } }) #set($discard = $fields.add($field)) ## *# ## ## To disable the captcha, comment out the next two entries. ## The captcha image, not an input field but still defined the same way. ## Empty prompt used for padding. #set($field = {"name" : "captcha_image", "prompt" : "", "tag" : "img", "params" : { "src" : "$doc.getURL('jcaptcha')", "alt" : "$msg.get('altText', [$msg.get('core.register.submit')])" } }) #set($discard = $fields.add($field)) ## The captcha field #set($field = {"name" : "captcha_answer", "prompt" : $msg.get('instruction'), "params" : { "type" : "text", "size" : "30" }, "validate" : { "mandatory" : { "failureMessage" : $fieldMandatory }, "programmaticValidation" : { "code" : "#checkCaptcha($request, $request.get('captcha_answer'))", "failureMessage" : "The captcha answer was wrong" } } }) ##TODO: $msg.get('org.xwiki.captcha.wrongAnswer') #set($discard = $fields.add($field)) ## ## Checks the captcha answer for the programmaticValidation above. #macro(checkCaptcha, $request, $answer) #set($cv = $captchaservice.getCaptchaVerifier("defaultImageCaptcha")) #if(!$cv.isAnswerCorrect($cv.getUserId($request), $answer)) false #end #end ## ## ####################################################################### ## The Code. ####################################################################### ## ## ## If the submit button has been pressed, then we create the user. #if($request.getParameter("xwikiname")) ## #* If captcha is required then we need to check it. #if($captchaRequired) #set($cv = $captchaservice.getCaptchaVerifier($captchaType)) #if(!$cv.isAnswerCorrect($cv.getUserId($request), $request.getParameter("captchaAnswer"))) #set($captchaAnswerIncorrect = true) #set($registrationFailed = true) #end #end *# ## ## Server side validation, this is necessary for security and because not everyone has Javascript #foreach($field in $fields) #if($field.get("validate") && $field.get("name")) #set($fieldName = $field.get("name")) #set($validate = $field.get("validate")) #set($error = "") #if($request.get($fieldName) && $request.get($fieldName) != "") #set($value = $request.get($fieldName)) ## ## Regex validation #if($validate.get("regex")) #set($regex = $validate.get("regex")) #if($regex.get("pattern") && $regex.get("failureMessage")) #if(!$xwiki.getUtil().match($regex.get("pattern"), $value)) #set($error = $regex.get("failureMessage")) #end #elseif($regex.get("pattern")) ERROR: In field: ${fieldName}: regex validation must include failureMessage. #end #end ## ## If regex validation passed, check "mustMatch" validation #if($error == "" && $validate.get("mustMatch")) #set($mustMatch = $validate.get("mustMatch")) #if($mustMatch.get("name") && $mustMatch.get("failureMessage")) #if($request.get($fieldName) != $request.get($mustMatch.get("name"))) #set($error = $mustMatch.get("failureMessage")) #end #else ERROR: In field: ${fieldName}: mustMatch validation required both name (of field which this field must match) and failureMessage. #end #end ## ## If regex and mustMatch validation passed, try programmatic validation #if($error == "" && $validate.get("programmaticValidation")) #set($pv = $validate.get("programmaticValidation")) #if($pv.get("code") && $pv.get("failureMessage")) #set($pvReturn = "#evaluate($pv.get('code'))") #if($pvReturn != "" && $pvReturn != "true") #set($error = $pv.get("failureMessage")) #end #else ERROR: In field: ${fieldName}: programmaticValidation requires code and failureMessage #end #end ## ## If no content, check if content is mandatory #elseif($validate.get("mandatory")) #set($mandatory = $validate.get("mandatory")) #if($mandatory.get("failureMessage")) #set($error = $mandatory.get("failureMessage")) #else ERROR: In field: ${fieldName}: mandatory validation requires a failureMessage #end #end #if($error != "") #set($discard = $field.put("error", $error)) #set($registrationFailed = true) #end #elseif(!$field.get("name")) ERROR: Field with no name. #end##if(validate) #end##loop ## ## ## Now we register. #if(!$registrationFailed) ## See if email verification is required and register the user. #if($xwiki.getXWikiPreferenceAsInt("use_email_verification", 0) == 1) #set($reg = $xwiki.createUser(true)) #else #set($reg = $xwiki.createUser(false)) #end ## ## Handle output from the registration. #if($reg && $reg <= 0) {{error}} #if($reg == -2) $msg.get('core.register.passwordMismatch') ## -3 means username taken, -8 means username is superadmin name #elseif($reg == -3 || $reg == -8) $msg.get('core.register.userAlreadyExists') #elseif($reg == -4) $msg.get('core.register.invalidUsername') #else $msg.get('core.register.registerFailed', [$reg]) #end {{/error}} #elseif($reg) ## Registration was successful #set($registrationDone = true) #set($xwname = "$coreSpace${request.xwikiname}") #info($msg.get('core.register.successful', [$xwiki.getUserName($xwname), $request.xwikiname])) ## ## Send a redirect if one was sent to us. #set($redirect = $request.getParameter($redirectParam)) #if($redirect) $response.sendRedirect($redirect); #end #end ## #end## If captcha is right or not active #end## If info was returned. ## ## ## If the registration was not successful or if the user hasn't submitted the info yet ## Then we display the registration form. #if(!$registrationDone) ## Put the same values back into the fields. #getParams() ## ## Blank line to put html macro in it's own paragraph {{html}}
## ## Validate the input using javascript, this is not for security but it improves user experience. ##$xwiki.get("jsfx").use("resources/js/yui/livevalidation/livevalidation_prototype.compressed.js") ## TODO: port to local files. ##$xwiki.get("ssx").use("XWiki.LiveValidationExtension") ##$xwiki.get("jsx").use("XWiki.LiveValidationExtension") {{/html}} ## ## Blank line to put html macro in own paragraph #end ## ## #** * Get parameters from request so that values will be filled in if there is a mistake * in one of the entries. *# #macro(getParams) #blockXSS() #foreach($field in $fields) #if($field.get("name") && $request.get($field.get("name"))) #set($discard = $field.put("value", $request.get($field.get("name")))) #end #end #end ## ## #* * Block XSS * * We must prevent non-persistent XSS by not getting parameters if the request is not a post * or if the referer header is not this page. * Imagine a link such as .../XWiki/Register?register_first_name= *# #macro(blockXSS) #if($request.getParameterMap().size() > 0) #if($request.getHeader("referer") != $xwiki.getRequestURL() || $request.getMethod() != "POST") ## If there is a redirect to send after registration is over, preserve it. #set($redirect = $request.getParameter($redirectParam)) #if($redirect) ## There is a redirect parameter, if that is not the only parameter, then send a redirect with that as the only param #if($request.getParameterMap().size() > 1) $response.sendRedirect("$request.getRequestURI()?$!redirectParam=$!redirect") #end #else ## There is no redirect parameter, no parameters are acceptable. $response.sendRedirect($request.getRequestURI()) #end #end #end #end {{/velocity}}