I am new to grails, and I am having a problem on how to write the proper constraints of one of the properties of my class. I want to check if the input contains a space (' '). Here is my code..
static constraints = {
username nullable: false, blank: false, minSize: 6, matches: /[A-za-z0-9_]{6,}/, validator: {
Account.countByUsername(it) < 1
}
Please help me.
Thanks!
You would want to use a custom validator like:
username validator: { val -> if (val.contains(' ')) return 'value.hasASpace' }
Edit: As R. Valbuena pointed out, you would need to change your countByUsername() validator to a unique: true.
In addition to a custom validator, you can also use the matches validator to ensure that only valid characters are used.
It looks like you're using this in your original question and the regex you're using doesn't allow a space, so a username with a space should fail that validator.
If you want to give a special message to someone if they have a space in it (instead of some other invalid character), then doelleri's answer is the right way to do that.
Related
I have a Grails command object that I'm using for updating passwords. It looks like this:
class UpdatePasswordCommand {
String password
static constraints = {
password blank: false,
nullable: false,
size: 8..64,
matches: someLongRegex
validator: { String password, command ->
if (someService.isPasswordSameAsUsername(password)) {
return 'password.invalid.sameasuser'
}
}
I left out everything that doesn't pertain to the question I'm asking.
The problem I'm running into is that, whenever this validation triggers, it will trigger ALL the validations, and the command.errors collection will have an error message for each validation failure. This means that, for example, if the user tried to use test for the password, they will get the following error messages:
* Password length must be between 8 and 64 characters.
* Password must not be the same as the user name.
* Password must contain at least one special character, uppercase letter, and digit.
In this case, if the password length is wrong, I want the validation to stop at that point. Likewise, if it's the same as the username, I don't want it to check against the regex. Is there any way I can get the Grails validation to only return the first validation failure for a particular property? Note that it's important that I only want it to stop per property, because if the user doesn't type in his confirm password, for example, I still want to display two error messages:
* Password length must be between 8 and 64 characters.
* You must enter a confirm password.
Shouldn't that be a practice to provide all the validation messages preemptively to the user so that User can rectify or take care of them in one go, instead of rectifying it one by one?
But anyways you can programmatically force to return back only one message at a time something like below:
static constraints = {
password validator: { String password, command ->
def errorMsgs = []
if (!password){
errorMsgs << 'password.invalid.blank' //'password.invalid.null'
return errorMsgs
} else if (!(password.size() in (8..64))){
if (someService.isPasswordSameAsUsername(password)){
errorMsgs << 'password.invalid.sameasuser'
}
errorMsgs << 'password.invalid.length'
return errorMsgs
} else if (/*password not matching YourRegex*/){
errorMsgs << 'password.invalid.specialCharacters'
return errorMsgs
} else if (someService.isPasswordSameAsUsername(password)){
errorMsgs << 'password.invalid.sameasuser'
return errorMsgs
}
}
}
I think we have to take care of the special cases where more than one message is sent back by adding control logic as done above for password length and its match with user name.
Take a look at grails validate, the interesting thing is that you can pass property names to validate(). The second thing is errors property that implements spring Errors interface. You can use it to clean up messages to show only one for property. Write a custom validator as dmahapatro suggested is a good approach.
Im using Spring form validation to validate the input fields entered by the user. I need help to include space in a particular field. Below is the validation annotation that Im using. But it does not seem to allow space.
#RegExp(value="([0-9|a-z|A-Z|_|$|.])*",message="value can contain only digits,alphabets or _ or . or $")
private String cName ;
I would like to know what value I need to include in the validation annotation to include space in the name
I tried to include '\s' in the exp value to include blank space. But it doesn't seem to work
Any help on this is much appreciated.
Your regex String is not valid for your requirement.
Use the following regex instead:
//([0-9|a-z|A-Z|\\_|\\$|\\.|\\s])+
#Test
public void testRegex() {
String r = "([0-9|a-z|A-Z|\\_|\\$|\\.|\\s])+";
assertTrue("Allows space", Pattern.matches(r, "test test"));
assertTrue("Allows .", Pattern.matches(r, "12My.test"));
assertTrue("Allows _", Pattern.matches(r, "My_123"));
assertTrue("Allows $", Pattern.matches(r, "$ 1.0"));
}
I have the same problem as the people below, but the solutions offered for them does not work for me.
CodeIgniter - disallowed key characters
CodeIgniter Disallowed Key Characters
Disallowed key characters error message in Codeigniter (v2)
I get "Disallowed Key Characters" when I submit a form.
I have CSRF protection enabled, and I am using arrays in my form field names (i.e., search[] as the name as there are multiple selection dropdown options). I have a feeling it is the "[]" in the form name that bothers this form.
I have followed all advice I could see in the posts above.
I disabled CSRF temporarily,
I disabled XSS temporarily,
I edited $config['permitted_uri_chars'] and
I edited Input.php where this message is generated.
Anybody has any additional ideas of what could cause this problem on form submission?
Thanks!
Like my answer here — you just need to update the regex in MY_Input->_clean_input_keys() to allow more characters (eg escaped JSON, or escaped HTML/XML)
Allow just 'English': !preg_match("/^[a-z0-9\:\;\.\,\?\!\#\#\$%\^\*\"\~\'+=\\\ &_\/\.\[\]-\}\{]+$/iu", $str)
Allow Chinese Characters: !preg_match("/^[a-z0-9\x{4e00}-\x{9fa5}\:\;\.\,\?\!\#\#\$%\^\*\"\~\'+=\\\ &_\/\.\[\]-\}\{]+$/iu", $str)
My full working function looks like this:
public function _clean_input_keys($str) {
// NOTE: \x{4e00}-\x{9fa5} = allow chinese characters
// NOTE: 'i' — case insensitive
// NOTE: 'u' — UTF-8 mode
if (!preg_match("/^[a-z0-9\x{4e00}-\x{9fa5}\:\;\.\,\?\!\#\#\$%\^\*\"\~\'+=\\\ &_\/\.\[\]-\}\{]+$/iu", $str)) {
/**
* Check for Development enviroment - Non-descriptive
* error so show me the string that caused the problem
*/
if (is_env_dev()) {
var_dump($str);
}
exit('Disallowed Key Characters.');
}
// Clean UTF-8 if supported
if (UTF8_ENABLED === TRUE) {
return $this->uni->clean_string($str);
}
return $str;
}
my_helper.php
if (!function_exists('is_env_dev')) {
function is_env_dev() {
return (
defined('ENVIRONMENT') && strtolower(ENVIRONMENT) == 'development' ||
defined('ENVIRONMENT') && strtolower(ENVIRONMENT) == 'testing'
);
}
}
Thanks, but I found a comment hidden way below (right at the bottom at the time of this writing) on another post here: CodeIgniter Disallowed Key Characters
The comment suggested that I add $str to the exit() comment to test. This indicated that I had a missing double quote in my form fields. It is a very complex form built up dynamically, with 300 lines of code, so easy to miss.
Hope this answer (and the comment that inspired it) helps someone else.
Validating the source of the output could prevent problems such as this one :-)
Regards
I have 'urlFormat'=>'path' and 'showScriptName'=>false in the urlManager.
I have proxies/read as controller/action and article=>some_name as parameters.
Whenever I create a link such as:
$this->createUrl('proxies/read', array('article'=>$name));
The result is an URL of the type:
proxies/read?article=socks5_proxy_list
I would like to dump the query parameter and reformat the URL to look like this:
controller/action/param_name/param_value
In this case that would be:
proxies/read/article/socks5_proxy_list
My current 'rules' look like this:
'rules'=>array(
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>/article/<article:\w+>'=>'<controller>/<action>/article/<article>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
),
But they don't seem to be working.
Shortcut to make this work:
$this->createUrl('proxies/read/article/'.$name);
And leave the urlManager rules without your custom rule.
Another way:
// urlManager
'rules'=>array(// order of rules is also important
'<controller:\w+>/<action:\w+>/article/<article:\w+>'=>'<controller>/<action>',
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
),
In the above array, i just put the new rule in the beginning, to make sure that, that rule is applied whenever such a pattern is encountered. If you have other rules, then just make sure that this rule appears before a more general rule, that can match the pattern. Rule of thumb: more specific rule should appear before general rule.
create url in view:
$this->createUrl('proxies/read', array('article'=>$name));
Incase you don't need any of the default "user-friendly url" rules, but only need path format urls, then you only need to specify 'urlFormat'=>'path' and leave the 'rules' array empty or omitted all together.
Read the URL Management guide in the definitive guide, if you haven't already.
no need for rules..
http://yourhost.com/mycontroller/dosomething/param1/value/param2/value
class MyController extends Controller {
public function actionDosomething($param1, $param2) {
}
}
as for createUrl(). hand it a key=>value array of parameters as a second parameter
http://www.yiiframework.com/doc/api/1.1/CController#createUrl-detail
try these set of rules
'rules'=>array(
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>/*'=>'<controller>/<action>',
),
How do you set an error message for max_length and min_length rules. For instance, if I set a rule max_length[6], I'd like the error message to display
Max characters allowed: 5
I got the same problem and even though this post is old, there's no correct answer.. You just have to use the string placeholder %s in second place of your message. In the documentation (http://codeigniter.com/user_guide/libraries/form_validation.html#settingerrors) there is an example for a field not being empty:
$this->form_validation->set_message('username_check', 'The %s field can not be the word "test"');
There, it uses the %s placeholder for the name of the field, but if you modify the 'max_length' message putting the field name first and the length second like this:
$this->form_validation->set_message('max_length', 'The field %s max length is %s');
it will work. Is not the best solution, but that one works for me. Hope it helps
application/language/en/en_lang.php I have this:
$lang['name'] = "Name";
$lang['form_required'] = "is required.";
application/language/es/es_lang.php I have this:
$lang['name'] = "Nombre";
$lang['form_required'] = "es requiero.";
application/controllers/yourController.php I have this:
$this->form_validation->set_rules('name', $this->lang->line('name'), 'required|alpha|xss_clean');
$this->form_validation->set_message('required', '%s ' . $this->lang->line('form_required'));
I hope this help!
#Daniel is correct. Per CodeIgniter's documentation, you can override the default error message for any validation rule (such as "min_length", "max_length", etc.) like this:
$this->form_validation->set_message('validation_rule', 'Your message here');
So, in your example you could do:
$this->form_validation->set_message('max_length', 'Max characters allowed: 5');
Simply include that where your validation rules exist.
gAMBOOKa,
create a 'new' rule that also checks for max_length
$this->form_validation->set_rules('username', 'Username', 'required|_max_length[12]');
and for the method..
function _max_length($val)
{
if (strlen($this->input->post('username')) > $val)
{
$this->form_validation->set_message('_max_length', 'Max characters allowed: 5')
return FALSE;
}
return TRUE;
}
add this to your controller as a new rule and set the message like so ---^
CodeIgniter has one of the better documentations out of all the frameworks. Read the userguide on their site or the one in your CI directory.
http://codeigniter.com/user_guide/libraries/form_validation.html#settingerrors
Take a look in system/language/english/form_validation_lang.php and you'll find
$lang['max_length'] = "The %s field can not exceed %s characters in length.";
Which is easily overridden by copying it to
application/language/english/form_validation_lang.php
And changing it to the string you'd like. Do not edit the file in system/ directly, then it'll be overwritten if you upgrade CodeIgniter.
There is no need to add a new method. You may set a custom message to a form validation error by accessing the "max_length" rule as shown below.
$this->form_validation->set_rules('username', 'Username', 'required|min_length[5]', array('required' => 'Username is required.','max_length' => 'Max characters allowed: 5')
);
Note: This is also applicable for "min_length" rule.