Kohana 3.2 ORM-based user auth error: “ORM_Validation_Exception [ 0 ]: Failed to validate array”

After being interested in it for a while, I’ve started experimenting with Kohana (v 3.2). When I started working with the ORM-based user authentication it ships with, I immediately ran into some trouble. Searches turned up scant information, so I’m posting this to help people who run into the same problem.

The first problem is that the Kohana documentation leaves a lot to be desired. In this case, it says very little about using the ORM-based user authentication. There’s almost nothing in the User Guide part of the documentation, and I found the API documentation related to this functionality to be incomplete and misleading.

I enabled the auth and ORM modules in my bootstrap, and configured it (with some help from Mixu’s tech blog: Step-by-step guide to Kohana 3 auth).

Then I tried programatically creating a user, as follows, and ran into a brick wall:



$user = array(

  'username' => 'abcdebug',

  'password' => 'pass',

  'email' => 'test@example.com'

);


ORM::factory( 'user' )->create_user(

  $user,

  array_keys( $user )

);



That was based on the API documentation for Model_Auth_User::create_user(), which lead me to believe that I could just pass an array containing ‘username’, ‘password’, and ’email’ elements.

However, all that got me was the extremely unhelpful error message: “ORM_Validation_Exception [ 0 ]: Failed to validate array”

I later discovered that the default validation requires a password with min length 8, but that was not the whole problem.

I dug deeper and discovered (with some hints [1]) that the default validation also requires a password_confirm element (that must match the value of password, naturally) to be included in the first argument to create_user(). E.g.:



$user = array(

  'username' => 'abcdebug',

  'password' => 'password',

  'email' => 'test@example.com'

);


$post = $user;

$post[ 'password_confirm' ] = $user[ 'password' ];


ORM::factory( 'user' )->create_user(

  $post,

  array_keys( $user )

);


That’s very counterintutive to me. I expected to easily be able to create a user programatically with the default setup, and when doing that I don’t expect to have to confirm the values I’m passing to the create method. I’d also expect that to be mentioned in the create_user() documentation, especially since there’s nothing (that I’ve found) in the User Guide about this.

Update:

Now that I’ve dug deeper into Kohana, including its ORM and validation, I see that Model_Auth_User::create_user() is a kludge to bundle validation into the model that doesn’t really belong there. If you want to create a new user using the included model without the password_confirm validation, then you can call the following:



ORM::factory( 'user' )

  ->values( $user, array_keys( $user ) )

  ->create();


create() is part of the core ORM module and will invoke the validation configured in Model_Auth_User::rules(). On the other hand, create_user() is not part of the core ORM, it’s just an addition to Model_Auth_User to add extra validation, e.g. for password_confirm.

Oddly, it only failed on not providing the password confirmation value, when I’d consider the email address more important to confirm, since that’s probably the only recourse you have to “authenticate” the user’s identity if they forget their password.

In this case the error message could also have been a lot more helpful. It turns out if you copy modules/orm/classes/model/auth/user.php to application/classes/model/auth/user.php and catch ORM_Validation_Exception in create_user() call ORM::factory( 'user' )->create_user() in a try block and catch ORM_Validation_Exception (say as $e), calling $e->errors( 'model' ) returns data that includes the message “password confirm must be the same as password confirm”. I don’t know why that error message is not displayed by the default exception handling. As an aside, that error message itself is a bit off. Should probably say “password confirm must be the same as password”. The error message is incorrect due to a bug in the included Model_Auth_User class. Where the validation rule for password_confirm is configured, the order of the parameters doesn’t match the built-in error message for the matches validation method.

I don’t know enough about Kohana to know if there’s a way to set this up that I would consider better. I guess it would be nice if out of the box you could easily programmatically create users as I was trying to do, and also easily create users based on registration form submissions, where confirming certain values might be desirable.

I’m not sure yet how I feel about the way they’ve bundled the extra validation, e.g. for password_confirm, into the user model. But in any case, out of the box, you can either bypass that extra validation by calling ORM::factory( 'user' )->create(), or include it by calling ORM::factory( 'user' )->create_user(), as described above, respectively.

References

  • [1] I got hints from some forum posts, such as this one (by MasterGberry). This post (by Isaiah) alerted me that the included user model is perhaps only meant to be a reference implementation: “It’s expected that you override the included user model, and customize it to fit you needs.”

2 thoughts on “Kohana 3.2 ORM-based user auth error: “ORM_Validation_Exception [ 0 ]: Failed to validate array”

  1. “I’m not sure yet how I feel about the way they’ve bundled the extra validation, e.g. for password_confirm, into the user model.”

    Sure, “password_confirm” doesn’t belong in the method rules() as it’s not a field in the database, but does belong in the model as it’s completely dependant on the “password” field. I think of create_user() as a useful method for validating “create user” forms. If you aren’t using the create_user() method, and you need a password_confirm field, then you will need to do external validation which is not that elegant. This create_user() just makes life easier, whether you use it or not is up to you. As you’ve demonstrated, there’s nothing stopping you from creating a user in the typical ORM fashion, by either using create() or save().

    “Oddly, it only failed on not providing the password confirmation value, when I’d consider the email address more important to confirm”

    It validates the following rules: http://kohanaframework.org/3.2/guide/api/Model_Auth_User#rules
    http://kohanaframework.org/3.2/guide/api/Model_Auth_User#get_password_validation

    “I don’t know why that error message is not displayed by the default exception handling.”

    It’s handled by ORM validation exception, not sure what you were expecting, that’s how Kohana manages ORM validation.

  2. Sure, “password_confirm” doesn’t belong in the method rules() as it’s not a field in the database, but does belong in the model as it’s completely dependant on the “password” field.

    At this point, I’m just not so sure that it’s a proper separation of concerns, that it makes sense for the model to perform that kind of validation.

    There doesn’t appear to be much of a consensus about this kind of thing even among Kohana users, e.g.:

    http://forum.kohanaframework.org/discussion/7962/validation-in-model-controller-or-both/p1

    http://forum.kohanaframework.org/discussion/4956/the-definitive-validation-discussion/p1

    It validates the following rules…

    Yes, thanks for the links, I figured all of that out by the time I updated the post. I didn’t find the API docs for `create_user()` particularly helpful though when I was just getting started figuring out Kohana’s ORM, validation, and exception handling. Different description and / or example usage and / or parameters documentation could have made it clear to me sooner what was going on with the `password_confirm` issue. E.g.:

    Create a new user [based on registration form input]. See create() for programatically creating a new user.

    Example usage:

    // $_POST must contain password_confirm in addition to elements of $expected

    Also, it might be possible to better organize the Kohana User Guide documentation items about this and make them more cohesive, with each other and with the model that Kohana ships with. For example

    * User Guide > ORM > Validation shows `password_confirm` validation being added in a controller, and doesn’t show an example registration form.

    * User Guide > ORM > Examples > Validation also shows `password_confirm` validation being added in a controller, this time with a ‘member’ model (and, on the plus side, a sample form).

    * User Guide > Kohana > Security > Validation again uses an example of a user registration form, this time with all of the validation being done in the controller (except for doing unique username validation in the model), a `confirm` field (not `password_confirm`), and a `Model_User::register()` method.

    Also, if Kohana is going to include a user model, especially one that bundles in validation for password confirmation, why not include a sample controller and view(s) too that provide a cohesive working example of a user registration process?

    I think of create_user() as a useful method for validating “create user” forms. If you aren’t using the create_user() method, and you need a password_confirm field, then you will need to do external validation which is not that elegant.

    Maybe I’ll end up agreeing, but I’m not convinced yet that the `create_user()` (“model helper method”) approach is the best solution.

    `password_confirm` is one issue, but the way the included model deals with password length validation is just compensation for how it handles password hashing. For what it’s worth, after I wrote the post I started experimenting with a way to deal with that kind of issue within the ORM validation mechanism.

    This create_user() just makes life easier, whether you use it or not is up to you. As you’ve demonstrated, there’s nothing stopping you from creating a user in the typical ORM fashion, by either using create() or save().

    Yes, I was just confused by `create_user()` when I was getting started figuring out Kohana. It’s fine if it’s a smart way to do it and it makes life easier in a legitmate way, but there are a lot of ill-advised things that people think are easier in the short term and that cause problems down the road.

    It’s handled by ORM validation exception, not sure what you were expecting, that’s how Kohana manages ORM validation.

    Yes, since I didn’t know yet how Kohana manages ORM validation, I was befuddled by the cryptic error message. A number of visitors that arrive here have searched for that error message or seem to be in search of help understanding Kohana’s user model, ORM, validation, etc. I created the post to help people who ran into the same difficulty as me, and I updated it once I figured out how to work with the ORM validation. And if it’s misleading or inaccurate, I’m willing to revise it further.

Leave a Reply

Your email address will not be published. Required fields are marked *

Note: Comments are moderated. Spam comments will never be published.

Is this comment spam?