In this post, I discuss the details of how to use my admin module. Hopefully this covers all the stuff you need to know; if not, let me know in the comments. I’m just one guy, so it may be quicker to ask on the Kohana forums for troubleshooting. Previous writing:
- Setting up the basic Auth in KO3 (part 1)
- An overview of the functionality provided by the Auth module (part 2)
- Kohana 3 auth: sample implementation and documentation (part 3)
- Getting started with Useradmin, my Kohana 3 auth admin module (part 4; this part)
KO3.1 support is DONE, updating this tutorial to match that now. See part 3 above for changelog.
1. Installation
Changes from 3.x version of the module to 3.1.x compatible version
The useradmin module is no longer offered as a “single application” with Kohana bundled in the same repository. Instead, only the content of the /modules/user directory is now in the repository. This makes it easier to work with the repository in Github.
- You should copy the module to your /modules -directory.
- You need to have the kohana-email module for sending forgotten password emails for now, if you want to use that feature.
- Kohana 3.1 no longer bundles the pagination module which is used in the admin interface. You have to get that module and enable it.
Database schema
Import the MySQL schema from /schema.sql. It will create a “useradmin” database. You might want to rename that when you start; in that case you need to change /application/config/database.php.
Watch this space! Right now, the database schema’s passwords do not work out of the box. I’m working on making a script to generate a secure starting SQL file for you… For now, use Auth::instance()->hash(‘password’) and then reset the admin password via your MySQL admin tool.
Module load order
Make sure that Useradmin is loaded before Auth in your bootstrap.php, because otherwise Kohana will not load the correct Model_User (it’ll use the one in Auth, not the one in Useradmin). Example with the minimum required modules:
Kohana
::modules(array(
'user' => MODPATH
.'user', // Useradmin module
'auth' => MODPATH
.'auth', // Basic authentication
'database' => MODPATH
.'database', // Database access
'orm' => MODPATH
.'orm', // Object Relationship Mapping
'pagination' => MODPATH
.'pagination', // Pagination
'oauth' => MODPATH
.'oauth', // Kohana-Oauth for Twitter
'kohana-email' => MODPATH
.'kohana-email', // Kohana-Email for email
));
The required modules are user, auth, database, ORM, Pagination. Optional modules: Oauth (for Twitter) and kohana-email (for email sending support).
Writable directories
Make sure the /application/logs and /application/cache directories exist and are writable by your server (you’ll get an error if they aren’t).
Copying the static files for performance
The useradmin module now includes a simple media serving capability so that you can get started by just including the module.
However, since it is not a good idea for performance to load CSS and image files via Kohana, you should copy the /public folder to wherever you put your webroot. This way Apache will load it directly (since direct file accesses are preferred in the Kohana default htaccess file).
KO3.1 Auth configuration
In Kohana 3.1, the default hash method is now sha256 instead of sha1. This means that there is no salt_pattern; and that old KO 3.x passwords are not compatible with KO 3.1! See the discussion on this bug for more information. TL;DR: the salt pattern is weak, so if someone steals your database but does not know your salt_key, they can deduce it easily and perform a dictionary attack.
Instead, you need to configure your hash_key which gets passed to http://php.net/manual/en/function.hash-hmac.php. You can also use any of the hast_hmac() supported algorithms if you want to.
Use a random hash_key, for example from: https://www.grc.com/passwords.htm
return array
(
'driver' => 'ORM',
'hash_method' => 'sha256',
'hash_key' => NULL, // replace with random string
'lifetime' => 1209600,
'session_key' => 'auth_user',
'users' => array(),
);
Migrating from KO3.x
Watch this space! I’m working on a better migration path than throwing out the old password database…
Important: Note that the password column should be CHAR(64) for sha256.
2. Useradmin configuration
By default, reCaptcha support and Facebook logins are disabled, but password reset via email is enabled.
Facebook login
To enable Facebook login, set the “facebook” option to true in config/useradmin.php. Then you need to copy /modules/user/config/facebook.php as /application/config/facebook.php and set app_id and secret to the values you got from Facebook. You need to register your site/app here to get those values. That’s really all it takes; you can then start accepting Facebook logins.
For more info about how Facebook logins work, see my series on implementing Facebook login. No additional database changes are needed if you are using my schema.sql; otherwise you need to add one extra field to your User table (`facebook_user_id` BIGINT( 20 )).
ReCaptcha on registration
To enable a ReCaptcha check on registration, set the “captcha” option to true in config/useradmin.php. Then you need to copy /modules/user/config/recaptcha.php as /application/config/recaptcha.php and set privatekey and publickey to the values you get from reCaptcha. Register for reCaptcha here.
Disabling password reset via email, Facebook login or ReCaptcha on registration
If you want to disable Facebook logins, or disable the password reset via email functionality, then copy /modules/user/config/useradmin.php to /application/config/ and set either “facebook” or “email” to false. You can also change the address from which the password reset emails are sent in that file.
3. Customization
Creating your own controllers which extend Controller_App
All the controllers in Useradmin inherit from Controller_App in /modules/user/classes/controller/app.php.
You’ll want you own controllers to also inherit from it, since Controller_App defines a before() action which performs the auth checks.
In addition, Controller_App provides support for template rendering: it defaults to using /modules/user/views/template/default.php. If you want to override that template, you’ll want to copy the default.php file to /application/views/template/default.php and modify it.
The Controller classes for Useradmin default to using /modules/user/views/template/useradmin.php. This means that you can have one UI template for Useradmin, and another for the rest of your application. Alternatively you can integrate the two by adding links to your own template.
Naming your controllers
If you are OK with not using Controller_User, Controller_Admin_User and Controller_App as names in your application, then there will be no naming conflicts and you can just add your controller to /application/classes/controller/.
If you want to extend these controllers without copying, this is possible starting with the Jan 2011 release. Just create /application/classes/controller/user.php and in it do this:
<?php
class Controller_User extends Controller_Useradmin_User {
// your code here
}
This will simply extend the base class defined in the useradmin module and is useful because you don’t need to copy all of the contents of the useradmin-defined controller when you just want to add a few methods or add/change/override properties.
Setting up auth rules for your controllers
You will want to set up auth rules for your controllers. To set a default rule for your whole controller, set the controller’s $auth_required to a string which is the role that is needed to access the controller (or an array of roles if multiple roles are required). In Kohana, the “login” role is given to all users who are allowed to log in, so you can check for the “login” role if you want to ensure users have logged in.
To set the roles required for individual actions, use $secure_actions. It is an array, indexed by action name, of strings or arrays of roles required for each particular action. Here is an example (you might want to copy the comments from Controller_App as well so that the properties are documented):
class Controller_Chat
extends Controller_App
{
public $auth_required = 'login'; // FALSE | string | array
public $secure_actions = array('chat' => 'admin'); // array( action => role)
function action_index
() { ... }
function action_chat
() { ... }
}
In the example, the login role is required to access the controller, and the “chat” action requires the admin role.
4. Using the bundled extras
I’ve bundled three helpers within the module. You can find them in /modules/user/classes/. These are:
Message - A simple helper for setting session messages in controllers. Has two static methods:
- Message::add($type, $message). Adds a message to the session. Type specifies what the class attribute will say on the output.
- Message::output(). Returns the messages set in the session as a set of div tags with the message as the content and the type as the class attribute.
Two basic classes are defined in the css file, which are “error” (red div) and “success” (green div). So you can add messages like this: Message::add(‘success’, ‘Saved data.’) and a div (class=”success”) will be displayed on the next load. Multiple simultaneous messages are supported. The included template file echos Message::output() before the content to show the messages.
Appform - An API-compatible stateful extension to the core Form which shows error messages and additional information in context. Appform calls work exactly the same as core Form calls (e.g. Form::select becomes $appform->select). However, it is stateful: you can set $appform->errors to errors, $appform->defaults to default values for fields and $appform->values to values. More details are available on my post discussing Kohana validation with forms. You have to initialize it using $appform = new Appform() in your views.
Helper_Format. Totally nonessential, it just helps format dates in the useradmin views. See the source code for details.
Note that these do not support transparent extension; this is because I think you should re-implement them anyway in your own application.
5. Extending the user model and adding stuff to the user profile
Adding additional fields to Model_User
It’s not mandatory to have a Model_User, since there is a default one in /modules/user/model/user.php.
Thanks to Kohana 3′s HMVC loading, you can start simple and work your way up to a more comprehensive rewrite. If you just need an extra field, you can add that in the database. The code for saving users is flexible enough that it will save new fields if they exist in the database.
For the view, you can just copy /modules/user/views/user/profile_edit.php to /application/views/user/profile_edit.php and add the extra field input(s) there.
Extending Model_User with new or improved functions
The Model_User in Useradmin is empty and extends Model_Useradmin_User. To extend Model_User in you app, you can create your custom Model_User in /application/classes/model/user.php, and make it extend Model_Useradmin_User.
Note: Support for extending via Model_Useradmin_User was added in the Jan 2011 release.
Adding associations to Model_User
If you need to add an association to another model, you’ll need to redefine that property of Model_User; make sure you copy the auth associations ($_has_many) from the most recent version of Model_Useradmin_User, then use extends to extend without copying the rest of the code, for example:
class Model_User
extends Model_Useradmin_User
{
protected
$_has_many = array(
// New association: attachment
'post' => array('model' => 'post),
// Copied from Model_Useradmin_User
'roles
' => array('through
' => 'roles_users
'),
'user_tokens
' => array(),
);
}
Customizing the user profile view and administrative edit view
Again, you can start implementing your custom views by copying the view files from /modules/user/views/* to /application/views/*, then improving them. Kohana HMVC will take care of loading your application view files instead of the module default views.
Appendix: Auth module models
Useradmin is based on the core KO3 Auth. It does not define Model_Role and Model_User_Token. Instead, these are loaded directly from the KO3 core ORM module (they were moved there in KO 3.1). If you want to redefine these models, make sure you extend Model_Auth_Role and Model_Auth_User_Token in your Model_Role/Model_User_Token (see the core Auth module for definitions).