Laboratoire pédagogique du Greta du Velay

Laboratoire pédagogique du Greta du Velay

Authake: user management, authentication and ACL for CakePHP

Authake is (another) solution to manage users and groups and their rights in a CakePHP platform, as well as their registration, email confirmation and password changing requests. It's composed by a component, a plugin, and a helper. The ACL model was presented by Marco Sbragi in the tutorial YACCA Yet Another Cake Component for Auth, that I used as an exercice to start learning Cake. So, thanks Marco for your article. UPDATE: This software is not developped anymore by its original author. Nik Chankov made some changes to support Cake 1.3. I advice to use its version: http://github.com/nchankov/authake WARNING : This software is in beta stage of development, and is closely related to the security of your applications. Please, contribute here to make it better before using in production! And of course, no warranty at all if you install this software... Contact: post comment below or mail to jakecake-dev and you add the domain name velay.greta.fr

Demonstration

The demo site is offline now, as I don't maintain anymore this software. You will find some screenshots here : admin page, rules list, group view.

State of art

Authake is ready for debug, and many aspects need to be improved.

  • CSS made for Firefox and not tested elsewhere (I am not CSS designer). You will find everything in /app/webroot/css
    • authake.css for the whole GUI and flashhelper.css for alert flashes.
    • Related HTML files are in the views folder (/app/plugins/authake/views). Don't modify inside any <?php statements ?> if you don't know what you do!
  • Translations are coming, but before need sanitizing all the __('messages');
  • Stability. For hackers... HABTM relations saving should be inspected.
  • Authake provide a simple profile for users (login, email, password). You should create your own profile table if you need to save more information for users, and then link your profile table to the user_id of authake_users.
  • And more!

Requirements

  • Before anything, read Marco's tutorial on the Bakery (or here on its blog), it's 10 min.
  • Authake is intended to work on the last 1.2 version of CakePHP. I use the last SVN, but sometimes apply patches from Trac. Maybe some coding styles could improve the stability...
  • I suggest you to have a working installation of Cake, then replace the /app folder with Authake app folder. No support provided here regarding CakePHP installation problems.

Install

  • Download the last Authake version.
  • Extract it. You will have a authake-app folder. Rename it to app and move it in your cake installation.
  • Make /app/tmp/* writeable by the web server.
  • Create a database, and fill it with the /app/authake.sql SQL statements. You might rename the tables later if needed.
  • Modify /app/config/database.php to configure your database.
  • Look for the Authake options at the bottom of /app/config/core.php . You might change it later.
  • It should be a full working application (hope!).

How does it work

User and groups

The user and group model is quite simple. There are users, registered in the authake_users table. There are groups, in authake_groups table. A user can belongs to one or more groups. The relation is made in the authake_groups_users table. The user with id 1 is a special user: it's not possible to delete it and is not editable by others (even with proper administrator rights). The group with id 0 is the "Everybody" group. All users and anonymous guests belong to this group by default. This group cannot be deleted.

Rules

Then there are rules for the ACL (authake_rules table). A rule is a Perl regular expression that says if an action is allowed or not. One rule belongs to one group only. All the rules of groups that the user belongs to are tested for each URL checked. Ex. If user in groups TheGroup and TheOtherGroup accesses the URL /page/index, all the rules that belongs to groups Everybody, TheGroup and TheOtherGroup are tested to match ^(/page/index)$. The last rule that matches in the list tells if the URL is allowed or not. For this reason, by default the first rule tells that all users are denied to access anything, then rules allow some actions (but you can reverse: allow anything then deny). The last rule tells that administrators are allowed to access anything. The rule order is specified in the field order, and can be changed through the Authake GUI. If the rule fails the check:

  • If the user is not logged, we propose to login then forward to previous failed action.
  • If the user is logged, forward to the default denied page (/user/denied, see core config file to change it) or forward to the action specified by the last failed rule.

^( )$ is automatically added around each rule to ensure that the full URL is checked. You can use * as wildcard (replaced by .*). Slash / is automaticaly backslashed \/. You can check several actions in one rule with an ' or ' (replaced by | in the regex). Look at the examples in the default database.

Authake component and AppController::beforeFilter() callback

The main works is done in the Authake component (/app/controllers/components/authake.php). This component is the heart of the system. It manages the user login and checks the URL according to groups and rules. The job is done in the AppController::beforeFilter() callback (/app/app_controller.php). Options for the component are in the core config file (/app/config/core.php) under the key Authake.*.

The Plugin

Found in /app/plugins/authake. It contains controllers, models, views and helpers. AuthakeAppController and AuthakeAppModel provide some methods for internal use.

Plugin models

The data model (users, groups, rules in the database) is stored in the plugin models folder (/app/plugins/authake/model/). Nothing particular.

Plugin controllers

There are in /app/plugins/authake/controllers

  • AuthakeController controls the main Authake management page. It should be only allowed to specific users.
  • Users, Groups, Rules controllers control the pages to list, view, edit and add related elements. It should be only allowed to specific users.
  • UserController regroups all actions and views that all users can access (register, confirm registration, login, retrieve password, etc).

Plugin views and CSS

Views (in /app/plugins/authake/views) are the HTML outputs for each controller. Related CSS are in the webroot folder (/app/webroot/css). The file authake.css contains everything concerning Authake. Each view encapsulate its content in a <div id="authake">. In addition Authake provide a CSS to format the Session::Flash messages (flashhelper.css).

Helpers

Authake plugin implements two helpers (in /app/plugins/authake/views/helpers):

  • HtmlbisHelper is a small addons to HtmlHelper.
  • Authak3 enables views to get some information regarding the authentication system (user logged, its groups, isAllowed, etc). The name Authak3 is strange: it seems Cake forbids to have a helper called like an installed plugin.

Others elements

Some other files are more or less part of Authake. The home page is in /app/views/pages/home.ctp but should be overridden by your application. Some graphics elements are in /app/views/pages/layouts: templates for flash message, email layouts (for text and html, but EmailComponent in HTML mode fails to work properly on my installation...). The icons are in /app/webroot/img/icons. I used the nice SILK ICONS of Mark James, thanks to him.

Changelog

v1.13 (feb 26, 2008)

  • The default database ids were buggy, as I forgot to include the auto_increment values when exporting to sql (thanks to Eric)

v1.12 (feb 25, 2008)

  • Bug (partialy solved) when password changing in user_controller.php (thanks to Kiang, http://twpug.net/)

v1.11 (feb 19, 2008)

  • Accounts have an expiry date

v1.10 (feb 14, 2008)

THE DATABASE CHANGED SO YOU SHOULD REINSTALL ALL THE TABLES

  • Only administrators can modify or make an administrator. Avoid to gain administrator level.
  • Accounts can be disabled (Marco Sbragi's suggestion)
  • Cometic changes in app_controller.php (everything moved to authake component).
  • Possible to set a specific flash message for the rule that denies the access.
  • New session timeout feature. Allow to have an illimited cake session, and then choose the application session timeout.

First release (feb 12, 2008)

Commentaires

Hi Jej thanks very much for the credits (not very common tasks todays).
I have downloaded the plugin and it seems working well.
I still use cake 1.1 and were thinking to port my system to 1.2, now that it is on beta, you have saved me a lot of work.
In the meantime on my old version I have added 1 field to the users structure: Disabled. To disable login without delete the account. I have seen that you have enhanced the rule logic. It is more sophisticated but a little more complex for end users without knowledge of regex. What do you think of a wizard for helping users to build rules?
Forms layout is little broken in IE I will work on css to adjust and let you know.
Thank you for the good work.
Ciao Marco

Hi Marco,

Thanks for the CSS on IE. I don't work with Windows so difficult for me to test that.

For the rule logic that's the same as yours. Except that I compacted different builtin rules in one, with a regex |, to avoid multiple lines (you can do the same in your component). As it was not readable I provided a way to replace the | with ' or ', so that it's still possible to use it in the sub-regex.

For the wizard, it's a good idea, and of course you can start to do it :)) I don't know how to design that for best ergonomy, so feel free!

To disable logins I was thinking to add a date of expiry for the account, like in the unix accounting model. And a max delay to change the password. But it could be nice as well to have a disable option like you suggest. I put it in my TODO!

Read you,
Jerome

Hello, thanks for the great work. :)

Maybe it would be better to add one option for guest to drop down list of group when adding or editing the rule. :)

Well, I found bugs...

In user_controller.php
1. Remove line 55
$this->redirect('index');
2. Line 63
$this->User->save($user['User']);
Replace with
$this->User->save($user);

@kiang (06:02): I don't know what you mean. There is a 'Everybody' group, that is the guest users. Is it your question?
@kiang (10:02): thanks, but their is still a bug here. The groups are erased when saving the user. Even with your modification it appends. Maybe a bug in cake. To test try to change admin password in its profile page (not by editing the user). The admin become a guest without any group after changin password and saving.

There is a problem with the SQL adding data for the group

INSERT INTO `authake_groups` VALUES (1,'Administrators'),(3,'Other test group'),(2,'User & group managers'),(4,'Everybody');

As you can see "Everybody" gets inserted with an ID of 4. However, according to the doc above, and the code, the "Everybody" group must have an ID of 0.

For those who already have it installed, just open the database and manually make the change and you should be good to go.

Corrected, thanks. See changelog.
Jerome

@Jérôme Combaz ( 11:02 ):
The ‘Everybody’ group didn't work for guests. I must set the group_id to 0 to allow guests( user who not login ) visit my website. So I add an option 0 => Guest to the form when editing rules. :)

@kiang:
Sorry Kiang! In fact it was a problem during the export of my working database. I used phpMyAdmin to copy my DB and during that operation, phpMA rewritted the ID in a wrong order. Then the dump included in the archive was buggy.

So now it should be ok. Try to re-import the authake.sql in your db then retry.

Maybe that choice (to impose a ID for everybody group) is not a good solution. It avoids to have a relation between each user and group "Everybody". Feel free to hack that of course!

Jerome

Hi our congratulations due to you nice work!

Our PHP server starts php tags for <?php and in line 2 of authake/views/rules/index.ctp the line starts for <?

We will use your component, Are you interested to receive a CSS who works under Explorer? What about the spanish translate?

@david: thanks for your comment, I will update. Ok for the IE CSS, don't hesitate to share it here. For the spanish, I did not implement the i18n related files. So if you have to translate, maybe that's better to start now with the i18n, to share it later.

Jerome

Same error in plugins/authake/views/groups/index.ctp (2) renderElement('gotoadminpage'); } ?>

Now we only translate the default.pot we are fighting with I18N translator, if we have time don't worry we translate using I18N

Hello,
I get the following error after configuring authake in WAMP environment. My default CakePHP setup works fine.
Can you please suggest?

Fatal error: Class 'Configure' not found in D:\wamp\www\cake\app\config\core.php on line 43

Thanks

@DSKR: No idea at all... I left cakephp since a while for ruby/rails...

Jerome

@DSKR: I had the same problem. You need version 1.2 of cakePHP. It won't work with version 1.1

I have successfully installed Authake in my project and fully understand how to control access to certain controller actions. For example, I have a "view" controller for a table called "articles" that can be accessed by both administrators and unauthenticated users.

But let's say I want to do the following: I want administrators to see all articles when they browse to the "view" controller, but I want unauthenticated users to only see articles that are marked in my table as "published." The pseudocode follows:

If user is unauthenticated, paginate the articles table with $scope1 and send the results to the view. If user is authenticated and is an administrator, paginate the articles table with $scope2 and send the results to the view.

An explanation and/or code would be helpful. Thank you in advance.

I liked this project, till now, but I really think that some stuff needs to be changed.
Like, I love the Idea that the project is a plugin. I didn't know how to use that before, and now
it makes a lot of sence, I think its because I didn't try cake's 1.2 version.

First sugestion. I think that you should be using another connection and having that info in the
AuthakeAppModel, like:
var $useDbConfig = 'authake';

and with that we can config the prefix of the db connection like:

var $authake = array(
'driver' => 'mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'root',
'password' => 'pass',
'database' => 'database',
'prefix' => 'authake_'
);

doing that the models dont need to specify the useTable var.

Second, Is ther a CVS or SVN that you all had being uploading updates, like, why not use
CakeForge?

Hi Marcio,

Thanks for your comments.

In fact I left CakePhp. I thinks that's not really mature for development nor tests, the code is really crap, have erratic bugs, and the community looks a bit strange! I see today that the beta is still dated of "2nd of january", maybe I was true to left few months ago :)

Cheers,
Jerome

ps: the code is GPL, so feel free, and don't forget credits ;)

That's a shame that you left, the project seemed pretty promising.

Just as curiosity, If you left cake php, witch way did you go? Are using another framework??

Saludos.
Marcio Granado

I spent some days to learn ruby, now I'm waiting to have a need to learn rails. Ruby can drive cocoa apps as well, interesting to learn xcode.

Read you,
Jerome

Too bad you left Cake :/

RC1 was released earlier this month, you can check out whats new in the release @ the bakery. Nonetheless, thanks for this contribution.

Thanks for this information, Steve. I will restart some watch on this topic, so!

Cheers, Jerome

Jerome,

Thanks for your work on Authake. I was uncertain of whether to implement this as you say you have moved out of the CakePHP orbit, but, after some encouragement from Marco, I have installed it in a new 1.2 application. Since am using 1.2 RC1 for development, one question I have is whether I can simply replace verything *but* /app when 1.2 is finally released. I am new to CakePHP, so don't have a good sense of whether /app and /app subdirectories and files stay the same. I need to come up with some sort of diff script!

I looked at a number of MVC-oriented tools, mostly PHP (with which I am familiar), and was initially concerned about development progress (and maybe some developer strife) in CakePHP, but it seems like they have started the engine on the bus again. I am not a competent judge of code quality, but I was attracted by the CLI/bake tools and the availability of alternate auth modules like Authake (a much better fit for my requirements than the built-in ACL system).

Thanks again for producing this.

Jim

Hi Jim,

Thanks for using Authake and sorry to leave you in the middle of the river! I think you can use Authake and hack it quite easily according to your needs. I made it to learn and evaluate CakePHP, you can do as well.

To answer your question, note that it's not mandatory to replace your /app. I just mention it so that people can test it quickly without asking to much questions regarding the integration in an existing application. Once you understand Authake and Cake you can of course integrate it in your existing application (and not the opposite).

To finish, and to give you another taste, have a look to the goldberg project (http://goldberg.240gl.org/). It's a ruby generator that produces a framework for your application in order to manage content and security in a very beautyful way. You just have to plug your own pages (through controller and views) and to set the good rights on these pages, and voila, goldberg does the rest! That's an Authake power 3...

Read you,
Jérôme

A side note....I posed this question on CakePHP Google group but would like to add it here in case anyone has considered it....

We use university "Pubcookie" serviice that provides traustable HTTPD Auth (provides REMOTE_USER) so I am looking to use that for authentication and have Authake perform only authorization. Our PubCookie ID maps to Authake "login" in table User.

I am looking at the user_controller and login forms to see where I would change to substitute $login = $_SERVER['REMOTE_USER']; and other code, but it anyone more familiar with CakePHP can suggest a general approach to this type of modification (less ugly, less likely to break things!), I am "all ears".

(and I should say that I am looking at AuthComponent, but not sure how to meld that with Authake)

Thanks!

Jim

Well, in case anyone ever wants to do the same thing and stumbles across this earlier REMOTE_USER posting, I might as well answer my own query since I now have this working (PubCookie authentication and Authake authorization).

For starters, I made my own Authake account administrator; as has happened with other applications, once automatic PubCookie login works, the original login+password may no longer work.

Most of the changes were in plugins/authake/controllers/user_controller.php. What I did was to clone the login() function to a new function called pclogin() and modified that. The new pclogin function does not test for form data with "if (!empty($this->data) )", but instead sets "$login = $_SERVER['REMOTE_USER']; " . Local passwords are no longer used, so I simply set all passwords to a single arbitrary value and supply that as well in pclogin(). Not very elegant, but allowed me to avoid making too many changes to other Authake functions.

I changed the add function in users_controlller so that it sets new user passwords to the single value and it also creates the user email from $login (since we are all in same mail domain). I disabled the password/email fields in user/add.ctp.

I modified the first line of getLoginData() in plugins/authake/models/user.php to eliminate password check.

I changed the default path in /config.core.php from "login" to my new "pclogin"

So, it took me a while to figure this out, but in the end it looks like it is working wing very few changes to Authake functions.

Jim

Thanks for your hack and feedback, Jim.

Jerome

How can I send you a Spanish traduction of Authake ???

Hi,

I have just installed Authake on CakePHP using PostgreSQL and it works (I had to manually create the tables and add the data, but it works)!
The only error I have is when I try to edit or create a rule. I get an error on:
AuthakeAppModel::getEnumValues() - APP\plugins\authake\authake_app_model.php, line 43

The code on that line is:
//Get the values for the specified column (database and version specific, needs testing)
$result = $this->query("SHOW COLUMNS FROM {$tableName} LIKE '{$columnName}'");

Any ideas on how to get this to work for PostgreSQL?

Any help is appreciated!!!

Furthermore, I love your plugin, saves me a lot of time :D :D

GrandiJoos

Hi, me again ;)

First of all, ignore the post above, I noticed that this code was not yours so I'll solve it myself :)

I do have a couple of other questions:
1) can I ask for the userId in a model too or only in controllers (by $this->Authake->getUserId())?
2) what would be the best way to allow certain parts of my website only for logged in users? Should I automatically add each user to a 'user' group? Or should I add methods to each view/controller to check if the user is logged in or not? (the latest sounds not good to me because it does not use the access rules)

Thanks again in advance ;)

GrandiJoos :D

Thanks, is the best option for manage ACLs in CakePHP !!

I found a bug:

In /authake/user/index, when an user edit profile, no groups are saved.
Can you help me with this ?

Thanks

Thanks Rodrigo. Cannot help anymore, sorry... It's far from me now! But happy to see that it's still in use :)

Cheers,
Jerome

Jérôme,

thank you for your effort, I am using Authake (with few changes) in my projects succesfully. I have translated it into Portuguese(Brazilian). Also, to whom it may concern, the bugs 5. and 31. are solved by including the id primary key (id int unsigned not null auto_increment primary key) in the HABTM table authake_groups_users.

Thanks
Filippo Pardini

Hi,

thanks for your great tool. Right now I'm working on integrating it into our cake app. But there is one problem I just found:
If you import your authake.sql file the "Everybody" group in table "authake_groups" gets ID 4. Which has to be ID 0. Think this is a MySQL problem, i.e. autoincrement value has to be >0.

Cheers
Jens

I need to solve a problem. In our company, we have a problem with a user group that always that we need change of admin to other group like a common user, all users that belong to the admin group are changed to a common user too (what don't happen with the other groups). We think that this doubt is unknown. Can you help us?

you mention the function isAllowed in the Helper. This is what I need to determine whether to show menu links, but this is not in the Authak3 helper. Do you know how to create it? thanks

dont worry I figure it out... I moved the isAllowed and getRules functions from controllers\components\authake.php to plugins\authake\views\helpers\authak3.php and it worked ok

Thanks for the feedback!

Jerome

During install also needed to create directory 'sessions' in app\tmp

Ola Jerome,
I know that you have moved to Ruby, but now that I'm using CakePhp 1.2 use authake for all my projects. I have done some modification and as i have seen in this blog many other users have tweked up the plugin. Why don't you open a project at cakeforge, as the original developer of the applications, where we can try to merge all the patches and enhancements and have a repository for authake? If you don't have time can you authorize me or any other of the contributors presents in this blog to do this? I think it is very important that the project is at your name.
What think all other in this blog of this idea?
Give us a feedback.
Thanks.

Ciao
Marco

I received a warning from the users controller when trying to edit a user. When the modification of the headers is attempted, it generates a second warning which causes the page load to fail. Here are the warnings:

Warning (2): in_array() [function.in-array]: Wrong datatype for second argument [APP/plugins/authake/controllers/users_controller.php, line 109]
Warning (2): Cannot modify header information - headers already sent by (output started at /home/jsierra/cake/cake/basics.php:111) [CORE/cake/libs/controller/controller.php, line 615]

If you suppress the warnings on the in_array calls in the users controller, it fixes the problem. The new line 109 in users_controller.php looks like this:

if (isset($this->data['Group']['Group']) and @in_array(1, $this->data['Group']['Group']) and !@in_array(1, $this->Authake->getGroupIds())) {

After adding the warning suppression, it appears to work properly.

Marco,

I corresponded with you last year via the YACCA page and was pleased to receive your thoughts on Authake. I continue to use it with the crude HTTPD Auth hacks noted above. Right now I am thinking about a database-driven menu system that will pre-check Authake rights and only display menu links to which a person has access. Anyhow, I really appreciate your suggestion here.

Jerome, what you have created is great. I hope you will entertain Marco's suggestion.

Thanks!

Jim

Hi Marco, Jim and all,

Sorry to answer so late. As you know I am a bit far away of authake and cake, and maybe more now.

I think this software has just to live as the GPL licence allows it, that's the less.

Marco, I guess you are the obvious person to open a repository in your name, as my code is based on you model. Just respect the terms of the GPL 3 of course, and put some greetings somewhere if you wish!

Thanks Jim for all your contributions (Marco, give him a password ;) )

I hope you will make authake survive in the big cloud :o)

Good luck, read you.

Jérôme

Ola Jerome thanks for your replay.
You don't have to excuse for anything. Anyone of us, i think, have to work hard and time is always short.
I want to thank you for your words. As soon as possible I will try to open a project at cakeforge, with the current version of authake i own with little modification i have made. As I have said above unfortunately i have no much time and for sure I would have pleasure to have jim as a contributor to the project.
@Jim I have seen your e-mail. I will replay to you as soon as possible to define the details.
Thanks to all.
Marco

I, i give you a little update of components/authake.php.

I find a problem, if i delete a default rule are generated a lot of redirection to authake/user/login, to resolve this problem i put, in function

function isAllowed($url = "", $group_ids = null)

before

foreach( $rules as $data )

this code

if ($url="/authake/user/login") return true;

Thank very much for your big and important work for open source community.

By

Stefano Somaglia

Hi Jerome,
before some weeks I have downloaded the linked package for Authake. Under 1.2.x you have a lot of errors which primary are induced because changes in the flash method of cake.
Also there are some bugs in the update method. I.e. if u update an user u will be redirected to user no. 1 - independent which user you have updated. It can happen that you fire the admin from Administration group (this should be cached).
The encoding method for the password (only md5) isn't state of the art.
I have seen that you have opened a project at CakePHP but it's complete empty. So my question is: Did you still push the Authake Plugin or is it fall in desuetude.
Im willing to share my modifications. But I think it's necessary to do this in the project.
Regards Thomas

I tried to change the routes.php /authake/user/register be displayed when the request for /users/register but does not work.

Any idea?

Hi,

Thanks every thing works fine for me!

Nauman

Hi Thomas,

Thanks for your comment.

Sorry but authake and cake are very far from me now! Reuse and improve as you think it's better. If you need access to the cakeforge project I opened, maybe we can manage that with the bakery team.

Cheers,
Jerome

Hi,

i fixed a litte this for me.
Because I ues this very cool migration script:
http://developingwithstyle.com/2008/10/07/cakephp-db-migrations-v40-is-n...
i translated your sql script to an yml file.
Unfortunately the enum type isn´t defined...

So I found
http://grahamweldon.com/blog/ditching-enum-for-something-more-portable-a...

and decided to:
1. change the enum type to a string,
2. added a var var $permissiontypes = array('Allow'=>'Allow', 'Deny' => 'Deny'); to your rule model
3. fixed in the rules_controller the $permissions = $this->Rule->getEnumValues('permission'); to $permissions = $this->Rule->permissiontypes;

... now it works fine for me :)

Thanks!

Matthias

Pages