├── Test ├── Fixture │ ├── empty │ └── UserFixture.php └── Case │ ├── View │ └── Helper │ │ └── empty │ ├── Model │ ├── Behavior │ │ └── empty │ └── UserTest.php │ └── Controller │ └── Component │ └── empty ├── View ├── Layouts │ ├── js │ │ └── empty │ ├── rss │ │ └── empty │ ├── xml │ │ └── empty │ ├── Emails │ │ ├── text │ │ │ └── default.ctp │ │ └── html │ │ │ └── default.ctp │ └── authake.ctp ├── User │ ├── message.ctp │ ├── denied.ctp │ ├── pass.ctp │ ├── profile.ctp │ ├── lost_password.ctp │ ├── verify.ctp │ ├── register.ctp │ ├── login.ctp │ └── index.ctp ├── Elements │ ├── error.ctp │ ├── info.ctp │ ├── success.ctp │ ├── warning.ctp │ ├── gotohomepage.ctp │ └── gotoadminpage.ctp ├── Emails │ └── html │ │ ├── register.ctp │ │ ├── verify.ctp │ │ └── lost_password.ctp ├── Helper │ ├── GravatarHelper.php │ ├── HtmlbisHelper.php │ ├── htmlbis.php │ ├── authake.php │ └── AuthakeHelper.php ├── Groups │ ├── add.ctp │ ├── index.ctp │ ├── edit.ctp │ └── view.ctp ├── Users │ ├── add.ctp │ ├── edit.ctp │ ├── index.ctp │ └── view.ctp ├── Authake │ ├── index.ctp │ ├── settings.ctp │ └── help.ctp └── Rules │ ├── add.ctp │ ├── view.ctp │ ├── edit.ctp │ └── index.ctp ├── VERSION.md ├── webroot ├── js │ ├── custom.js │ ├── vendors.php │ └── html5shiv.js ├── favicon.ico ├── img │ ├── adminBack.jpg │ ├── cake.icon.gif │ ├── cake.power.gif │ ├── icons │ │ ├── add.png │ │ ├── door.png │ │ ├── key.png │ │ ├── lock.png │ │ ├── time.png │ │ ├── user.png │ │ ├── accept.png │ │ ├── cross.png │ │ ├── delete.png │ │ ├── door_in.png │ │ ├── empty.png │ │ ├── error.png │ │ ├── group.png │ │ ├── house.png │ │ ├── lock_go.png │ │ ├── pencil.png │ │ ├── arrow_up.png │ │ ├── clock_go.png │ │ ├── door_open.png │ │ ├── door_out.png │ │ ├── group_add.png │ │ ├── lock_add.png │ │ ├── lock_edit.png │ │ ├── lock_open.png │ │ ├── user_add.png │ │ ├── user_edit.png │ │ ├── arrow_down.png │ │ ├── clock_delete.png │ │ ├── group_delete.png │ │ ├── group_edit.png │ │ ├── information.png │ │ ├── lock_break.png │ │ ├── lock_delete.png │ │ └── user_delete.png │ ├── glyphicons-halflings.png │ ├── no-photo-placeholder.png │ ├── glyphicons-halflings-gray.png │ └── glyphicons-halflings-white.png ├── .htaccess ├── index.php ├── css.php ├── css │ └── custom.css └── test.php ├── Config └── authake_config.php ├── Controller ├── AuthakeAppController.php ├── Component │ ├── FilterComponent.php │ └── AuthakeComponent.php ├── AuthakeController.php ├── GroupsController.php ├── RulesController.php └── UsersController.php ├── Model ├── Group.php ├── Rule.php ├── AuthakeAppModel.php └── User.php ├── CHANGELOG.md ├── db └── authake_clean.sql └── README.md /Test/Fixture/empty: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /View/Layouts/js/empty: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /View/Layouts/rss/empty: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /View/Layouts/xml/empty: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Test/Case/View/Helper/empty: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Test/Case/Model/Behavior/empty: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Test/Case/Controller/Component/empty: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /VERSION.md: -------------------------------------------------------------------------------- 1 | Authake plugin version 2.2.3 2 | -------------------------------------------------------------------------------- /webroot/js/custom.js: -------------------------------------------------------------------------------- 1 | //alert($("body").text()); -------------------------------------------------------------------------------- /View/Layouts/Emails/text/default.ctp: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /webroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/favicon.ico -------------------------------------------------------------------------------- /webroot/img/adminBack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/adminBack.jpg -------------------------------------------------------------------------------- /webroot/img/cake.icon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/cake.icon.gif -------------------------------------------------------------------------------- /webroot/img/cake.power.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/cake.power.gif -------------------------------------------------------------------------------- /webroot/img/icons/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/add.png -------------------------------------------------------------------------------- /webroot/img/icons/door.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/door.png -------------------------------------------------------------------------------- /webroot/img/icons/key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/key.png -------------------------------------------------------------------------------- /webroot/img/icons/lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/lock.png -------------------------------------------------------------------------------- /webroot/img/icons/time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/time.png -------------------------------------------------------------------------------- /webroot/img/icons/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/user.png -------------------------------------------------------------------------------- /webroot/img/icons/accept.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/accept.png -------------------------------------------------------------------------------- /webroot/img/icons/cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/cross.png -------------------------------------------------------------------------------- /webroot/img/icons/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/delete.png -------------------------------------------------------------------------------- /webroot/img/icons/door_in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/door_in.png -------------------------------------------------------------------------------- /webroot/img/icons/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/empty.png -------------------------------------------------------------------------------- /webroot/img/icons/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/error.png -------------------------------------------------------------------------------- /webroot/img/icons/group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/group.png -------------------------------------------------------------------------------- /webroot/img/icons/house.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/house.png -------------------------------------------------------------------------------- /webroot/img/icons/lock_go.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/lock_go.png -------------------------------------------------------------------------------- /webroot/img/icons/pencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/pencil.png -------------------------------------------------------------------------------- /webroot/img/icons/arrow_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/arrow_up.png -------------------------------------------------------------------------------- /webroot/img/icons/clock_go.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/clock_go.png -------------------------------------------------------------------------------- /webroot/img/icons/door_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/door_open.png -------------------------------------------------------------------------------- /webroot/img/icons/door_out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/door_out.png -------------------------------------------------------------------------------- /webroot/img/icons/group_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/group_add.png -------------------------------------------------------------------------------- /webroot/img/icons/lock_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/lock_add.png -------------------------------------------------------------------------------- /webroot/img/icons/lock_edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/lock_edit.png -------------------------------------------------------------------------------- /webroot/img/icons/lock_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/lock_open.png -------------------------------------------------------------------------------- /webroot/img/icons/user_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/user_add.png -------------------------------------------------------------------------------- /webroot/img/icons/user_edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/user_edit.png -------------------------------------------------------------------------------- /webroot/img/icons/arrow_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/arrow_down.png -------------------------------------------------------------------------------- /webroot/img/icons/clock_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/clock_delete.png -------------------------------------------------------------------------------- /webroot/img/icons/group_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/group_delete.png -------------------------------------------------------------------------------- /webroot/img/icons/group_edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/group_edit.png -------------------------------------------------------------------------------- /webroot/img/icons/information.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/information.png -------------------------------------------------------------------------------- /webroot/img/icons/lock_break.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/lock_break.png -------------------------------------------------------------------------------- /webroot/img/icons/lock_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/lock_delete.png -------------------------------------------------------------------------------- /webroot/img/icons/user_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/icons/user_delete.png -------------------------------------------------------------------------------- /webroot/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /webroot/img/no-photo-placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/no-photo-placeholder.png -------------------------------------------------------------------------------- /webroot/img/glyphicons-halflings-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/glyphicons-halflings-gray.png -------------------------------------------------------------------------------- /webroot/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midorikocak/authake/HEAD/webroot/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /Test/Fixture/UserFixture.php: -------------------------------------------------------------------------------- 1 | 'User', 'records' => true); 4 | } 5 | ?> -------------------------------------------------------------------------------- /View/User/message.ctp: -------------------------------------------------------------------------------- 1 |
2 |

 

3 |

4 | Html->link(__("Go to homepage"), "/")."
"; 6 | ?> 7 |

8 |
-------------------------------------------------------------------------------- /View/Elements/error.ctp: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 | -------------------------------------------------------------------------------- /View/Elements/info.ctp: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 | -------------------------------------------------------------------------------- /View/Elements/success.ctp: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 | -------------------------------------------------------------------------------- /View/Elements/warning.ctp: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 | -------------------------------------------------------------------------------- /View/Layouts/Emails/html/default.ctp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /View/Elements/gotohomepage.ctp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /webroot/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | RewriteEngine On 3 | RewriteCond %{REQUEST_FILENAME} !-d 4 | RewriteCond %{REQUEST_FILENAME} !-f 5 | RewriteRule ^(.*)$ index.php?url=$1 [QSA,L] 6 | -------------------------------------------------------------------------------- /View/User/denied.ctp: -------------------------------------------------------------------------------- 1 |
2 |

3 |

 

4 |

5 | Html->link(__("Go to homepage"), "/")."
"; 7 | ?> 8 |

9 |
-------------------------------------------------------------------------------- /View/Elements/gotoadminpage.ctp: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /View/Emails/html/register.ctp: -------------------------------------------------------------------------------- 1 |

2 |

3 |

Html->url(array('plugin'=>'authake', 'controller'=>'user', 'action'=>'verify', $code), true); 5 | echo $this->Html->link(__('Click here to verify'), $url);?> 6 |

7 |

8 |


-------------------------------------------------------------------------------- /View/Emails/html/verify.ctp: -------------------------------------------------------------------------------- 1 |

2 |

3 |

Html->url(array('plugin'=>'authake', 'controller'=>'user', 'action'=>'verify', $code), true); 5 | echo $this->Html->link(__('Click here to verify'), $url);?> 6 |

7 |

8 |


-------------------------------------------------------------------------------- /View/User/pass.ctp: -------------------------------------------------------------------------------- 1 |
2 | element('gotohomepage'); ?> 3 |
4 | Form->create(null, array('url' => array('controller' => 'user', 'action'=>'pass')));?> 5 |
6 | 7 | Form->input('passwordchangecode', array('label'=>__('Code'), 'size'=>'40')); 9 | echo $this->Form->input('password1', array('size'=>'40', 'type'=>'password')); 10 | echo $this->Form->input('password2', array('size'=>'40', 'type'=>'password')); 11 | ?> 12 |
13 | Form->end(__('Confirm'));?> 14 |
15 |
-------------------------------------------------------------------------------- /View/Emails/html/lost_password.ctp: -------------------------------------------------------------------------------- 1 |

2 |

3 |

Html->url(array('plugin'=>'authake', 'controller'=>'user', 'action'=>'pass', $code), true); 5 | echo $this->Html->link(__('Click here to change your password'), $url);?> 6 |

7 |

8 |

9 |


-------------------------------------------------------------------------------- /View/User/profile.ctp: -------------------------------------------------------------------------------- 1 |
2 | element('gotohomepage'); ?> 3 |
4 | Form->create(null, array('url' => array('controller' => 'user', 'action'=>'changemypassword')));?> 5 |
6 | Form->input('email', array('label'=>'Email', 'size'=>'40'));?> 7 | Form->input('code', array('label'=>'Code', 'size'=>'40'));?> 8 | Form->input('password1', array('label'=>'New password', 'type'=>'password', 'value' => '', 'size'=>'12'));?> 9 | Form->input('password2', array('label'=>'Please re-enter password', 'type'=>'password', 'value' => '', 'size'=>'12'));?> 10 |
11 | Form->end(__('Change my password now')) ?> 12 |
13 |
14 | 15 | 16 | -------------------------------------------------------------------------------- /View/User/lost_password.ctp: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | Form->create(null, array('url' => array('controller' => 'user', 'action'=>'lost_password')));?> 6 |
7 |

8 |
9 |
10 | Form->input('loginoremail', array('label'=>__('Login or email'), 'size'=>'40'));?> 11 |
12 | 19 |
20 |
21 |
22 |
-------------------------------------------------------------------------------- /View/User/verify.ctp: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | Form->create(null, array('url' => array('controller' => 'user', 'action'=>'verify')));?> 6 |
7 |

8 |
9 |
10 | Form->input('code', array('size'=>'40', 'title'=>__('Please insert the code which you received in your e-mail.'))); 12 | ?> 13 |
14 | 21 |
22 |
23 |
24 |
-------------------------------------------------------------------------------- /Config/authake_config.php: -------------------------------------------------------------------------------- 1 | 4 | array ( 5 | 'useDefaultLayout' => '1', 6 | 'baseUrl' => '/', 7 | 'service' => 'Authake', 8 | 'loginAction' => 9 | array ( 10 | 'plugin' => 'authake', 11 | 'controller' => 'user', 12 | 'action' => 'login', 13 | 'named' => 14 | array ( 15 | ), 16 | 'pass' => 17 | array ( 18 | ), 19 | ), 20 | 'loggedAction' => '/', 21 | 'sessionTimeout' => '604800', 22 | 'defaultDeniedAction' => 23 | array ( 24 | 'plugin' => 'authake', 25 | 'controller' => 'user', 26 | 'action' => 'denied', 27 | 'named' => 28 | array ( 29 | ), 30 | 'pass' => 31 | array ( 32 | ), 33 | ), 34 | 'rulesCacheTimeout' => '300', 35 | 'systemEmail' => 'noreply@example.com', 36 | 'systemReplyTo' => 'noreply@example.com', 37 | 'passwordVerify' => '1', 38 | 'registration' => '1', 39 | 'defaultGroup' => '2', 40 | 'useEmailAsUsername' => '0', 41 | ), 42 | ); 43 | -------------------------------------------------------------------------------- /View/Helper/GravatarHelper.php: -------------------------------------------------------------------------------- 1 | $val ) 26 | $url .= ' ' . $key . '="' . $val . '"'; 27 | $url .= ' />'; 28 | } 29 | return $url; 30 | } 31 | } 32 | ?> -------------------------------------------------------------------------------- /View/User/register.ctp: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | Form->create(null, array('url' => array('controller' => 'user', 'action'=>'register')));?> 6 |
7 |

8 |
9 |
10 | Form->input('login', array('label'=>__('Login'), 'size'=>'12')); 12 | // do not show if we're using emails as usernames 13 | echo $this->Form->input('email', array('label'=>__('Email'), 'size'=>'40')); 14 | echo $this->Form->input('password1', array('type'=>'password', 'label'=>__('Password'), 'value' => '', 'size'=>'12')); 15 | echo $this->Form->input('password2', array('type'=>'password', 'label'=>__('Please, re-enter password'), 'value' => '', 'size'=>'12')); 16 | ?> 17 |
18 | 25 |
26 |
27 |
28 |
-------------------------------------------------------------------------------- /View/User/login.ctp: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | Form->create(null, array('url' => array('controller' => 'user', 'action'=>'login')));?> 6 |
7 |

8 |
9 | 10 | Html->link(__("I forgot my password..."), array('action'=>'lost_password'),array('class'=>'btn btn-mini')); ?> 11 | Html->link(__("Sign In"), array('action'=>'register'), array('class'=>'btn btn-success btn-mini'))?> 12 | 13 |
14 |
15 |
16 | Form->input('login', array('label'=>'Login', 'size'=>'14')); 18 | echo $this->Form->input('password', array('label'=>'Password', 'value' => '', 'size'=>'14')); 19 | ?> 20 |
21 | 28 |
29 |
30 |
31 |
-------------------------------------------------------------------------------- /Controller/AuthakeAppController.php: -------------------------------------------------------------------------------- 1 | . 20 | */ 21 | App::uses('AppController', 'Controller'); 22 | //App::uses('PagesController', 'Controller'); 23 | class AuthakeAppController extends AppController { 24 | var $helpers = array('Time', 'Authake.Htmlbis'); 25 | function __makePassword($password1, $password2) { 26 | 27 | if ($password1 != $password2) 28 | { 29 | $this->Session->setFlash(__('The two passwords do not match!'), 'error'); 30 | return false; 31 | } 32 | 33 | return md5($password1); 34 | } 35 | 36 | function beforeFilter(){ 37 | parent::beforeFilter(); 38 | $this->layout = 'authake'; 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /Model/Group.php: -------------------------------------------------------------------------------- 1 | . 20 | */ 21 | App::uses('AuthakeAppModel', 'Authake.Model'); 22 | class Group extends AuthakeAppModel { 23 | var $name = 'Group'; 24 | var $useTable = 'authake_groups'; 25 | var $recursive = 1; 26 | var $hasMany = array('Rule' => array('className' => 'Authake.Rule', 'exclusive' => false, 'dependent' => false, 'foreignKey' => 'group_id', 'order' => 'Rule.order ASC' ) ); 27 | var $useDbConfig = 'authake'; 28 | var $hasAndBelongsToMany = array('User' => array('className' => 'Authake.User', 'joinTable' => 'authake_groups_users', 'foreignKey' => 'group_id', 'associationForeignKey'=> 'user_id', 'order' => 'User.id', 'displayField' => 'login' ) ); 29 | } 30 | ?> -------------------------------------------------------------------------------- /Test/Case/Model/UserTest.php: -------------------------------------------------------------------------------- 1 | . 20 | */ 21 | 22 | App::uses('User','Authake.Model'); 23 | 24 | class UserTestCase extends CakeTestCase { 25 | 26 | public $fixtures = array('plugin.authake.user'); 27 | public $User; 28 | 29 | public function setUp() 30 | { 31 | parent::setUp(); 32 | $this->User = ClassRegistry::init('Authake.User'); 33 | } 34 | 35 | public function testObject() 36 | { 37 | $this->assertTrue(is_object($this->User)); 38 | } 39 | 40 | public function testLoginData() 41 | { 42 | $login='admin'; 43 | $password='admin'; 44 | $result = $this->User->getLoginData($login, $password); 45 | $expected = $this->User->getLoginData($login, $password); 46 | $this->assertEquals($expected, $result); 47 | } 48 | } 49 | ?> -------------------------------------------------------------------------------- /webroot/js/vendors.php: -------------------------------------------------------------------------------- 1 | 12 | * Copyright 2005-2008, Cake Software Foundation, Inc. 13 | * 1785 E. Sahara Avenue, Suite 490-204 14 | * Las Vegas, Nevada 89104 15 | * 16 | * Licensed under The MIT License 17 | * Redistributions of files must retain the above copyright notice. 18 | * 19 | * @filesource 20 | * @copyright Copyright 2005-2008, Cake Software Foundation, Inc. 21 | * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project 22 | * @package cake 23 | * @subpackage cake.app.webroot.js 24 | * @since CakePHP(tm) v 0.2.9 25 | * @version $Revision: 6311 $ 26 | * @modifiedby $LastChangedBy: phpnut $ 27 | * @lastmodified $Date: 2008-01-02 00:33:52 -0600 (Wed, 02 Jan 2008) $ 28 | * @license http://www.opensource.org/licenses/mit-license.php The MIT License 29 | */ 30 | /** 31 | * Enter description here... 32 | */ 33 | $file = $_GET['file']; 34 | $pos = strpos($file, '..'); 35 | if ($pos === false) { 36 | if (is_file('../../vendors/javascript/'.$file) && (preg_match('/(\/.+)\\.js/', $file))) 37 | { 38 | readfile('../../vendors/javascript/'.$file); 39 | } 40 | } else { 41 | header('HTTP/1.1 404 Not Found'); 42 | } 43 | ?> -------------------------------------------------------------------------------- /View/Helper/HtmlbisHelper.php: -------------------------------------------------------------------------------- 1 | . 20 | */ 21 | 22 | 23 | App::import('Helper', 'Html'); 24 | 25 | class HtmlbisHelper extends HtmlHelper { 26 | 27 | function iconlink($icon, $title, $url = null, $htmlAttributes = array(), $confirmMessage = false) { 28 | $img = parent::image("/authake/img/icons/{$icon}.png", array('title' => $title)); 29 | return parent::link($img, $url, am($htmlAttributes, array('escape'=>false)), $confirmMessage, false); 30 | } 31 | 32 | function iconallowdeny($what) { 33 | if ($what == true) 34 | echo "".__('Allow').""; 35 | else 36 | echo "".__('Deny').""; 37 | } 38 | } 39 | ?> -------------------------------------------------------------------------------- /View/Helper/htmlbis.php: -------------------------------------------------------------------------------- 1 | . 20 | */ 21 | 22 | 23 | App::import('Helper', 'Html'); 24 | 25 | class HtmlbisHelper extends HtmlHelper { 26 | 27 | function iconlink($icon, $title, $url = null, $htmlAttributes = array(), $confirmMessage = false) { 28 | $img = parent::image("/authake/img/icons/{$icon}.png", array('title' => $title)); 29 | return parent::link($img, $url, am($htmlAttributes, array('escape'=>false)), $confirmMessage, false); 30 | } 31 | 32 | function iconallowdeny($what) { 33 | if ($what == true) 34 | echo $this->image("/authake/img/icons/accept.png", array('title' => __('Allow'))); 35 | else 36 | echo $this->image("/authake/img/icons/delete.png", array('title' => __('Deny'))); 37 | } 38 | } 39 | ?> -------------------------------------------------------------------------------- /View/Helper/authake.php: -------------------------------------------------------------------------------- 1 | . 20 | */ 21 | 22 | 23 | class AuthakeHelper extends AppHelper { 24 | 25 | var $helpers = array('Session'); 26 | 27 | function getUserId() { 28 | return $this->Session->read('Authake.id'); 29 | } 30 | 31 | function isLogged() { 32 | return ($this->getUserId() !== null); 33 | } 34 | 35 | function getLogin() { 36 | return $this->Session->read('Authake.login'); 37 | } 38 | 39 | function getGroupIds() { 40 | $gid = $this->Session->read('Authake.group_ids'); 41 | return (empty($gid) ? array(0) : $gid); 42 | } 43 | 44 | function getGroupNames() { 45 | $gn = $this->Session->read('Authake.group_names'); 46 | return (is_array($gn) ? $gn : array(__('Guest'))); 47 | } 48 | 49 | function isMemberOf($gid) { 50 | return in_array($gid, $this->getGroupIds()); 51 | } 52 | 53 | } 54 | 55 | ?> -------------------------------------------------------------------------------- /View/Groups/add.ctp: -------------------------------------------------------------------------------- 1 | Html->addCrumb('New Group', $this->Html->url( null, true )); ?> 2 |
3 |
4 |
5 |
6 |

Crate a New Group

7 |
8 | Cancel 9 |
10 |
11 |
12 | Form->create('Group');?> 13 |
14 |
15 | Group Information 16 |
17 | 18 |
19 | Form->input('name', array('label'=>false,'after'=>'
'));?> 20 |
21 |
22 | 23 |
24 | Form->input('User', array('style'=>'width: 15em;', 'label'=>false, 'after'=>'Select users if you want to add them to this group.
')); 26 | ?> 27 |
28 |
29 |
30 | Form->end(array('div'=>false,'label'=>'Submit','class'=>'action input-action btn btn-primary'));?> 31 | Cancel 32 |
33 |
34 |
35 |
36 |
37 |
38 | -------------------------------------------------------------------------------- /Model/Rule.php: -------------------------------------------------------------------------------- 1 | . 20 | */ 21 | App::uses('AuthakeAppModel', 'Authake.Model'); 22 | class Rule extends AuthakeAppModel { 23 | var $name = 'Rule'; 24 | var $useTable = 'authake_rules'; 25 | var $belongsTo = array('Group' => array('className' => 'Authake.Group', 'foreignKey' => 'group_id', 'order' => 'Rule.order ASC' ) ); 26 | var $useDbConfig = 'authake'; 27 | function getRules($group_ids, $cleanRegex = false) { 28 | 29 | if (is_array($group_ids)) 30 | { 31 | //if no group get rules for the all users (with group_id is null) 32 | $groups = implode(',', $group_ids); 33 | $conditions = "Rule.group_id IN ({$groups}) OR Rule.group_id is NULL"; 34 | } 35 | else 36 | { 37 | $conditions = 'Rule.group_id is NULL'; 38 | } 39 | 40 | $fields = ''; 41 | $order = 'Rule.order ASC, Rule.group_id ASC'; 42 | $data = $this->find('all', array('conditions'=>$conditions, 'fields'=>$fields, 'order'=>$order, 'contain'=>array())); 43 | 44 | if ($cleanRegex) 45 | { 46 | $nb = count($data); 47 | 48 | for ($i=0; $i<$nb; $i++) 49 | { 50 | $data[$i]['Rule']['action'] = str_replace(array('/','*', ' or '), array('\/', '.*', '|'), $data[$i]['Rule']['action']); 51 | } 52 | } 53 | 54 | return $data; 55 | } 56 | } 57 | ?> -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | v2.3.1 (Mar 25, 2012) Mutlu Tevfik Kocak 2 | * Settings are working 3 | * Schema is deleted due to faults 4 | 5 | v2.2.3 (Nov 6, 2012) Mutlu Tevfik Kocak 6 | * Gravatar support 7 | * All new look & feel 8 | * Continuous login failure issue solved 9 | * New markdowns added 10 | * Enum type of rule permissions are removed 11 | * Schema file generated 12 | * New markdown files added 13 | 14 | v2.1 (Jan, 31 2012) 15 | * fixed: this->rquest->data issues 16 | * login using email 17 | * views thanks to Lonardo Pedretti 18 | * fixed: getcontrollers 19 | 20 | v2.0 (Oct 27, 2011) Mutlu Tevfik Kocak 21 | 22 | THIS VERSION RUNS ONLY WITH CAKEPHP 2.0 23 | 24 | * All changes made to run with CakePHP 2.0 25 | * __() translations without true thing 26 | * $components are now $this->Component 27 | * All folder and file names are compatible with CakePHP 2.0 28 | * And many other great things to run with CakePHP 2.0 29 | 30 | v1.3 (Apr 25, 2010) Nik Chankov 31 | 32 | * Repacked the plugin into a single directory. Working with CakePHP 1.3. Adding many settings which could be overwriten within a project. 33 | 34 | v1.13 (feb 26, 2008) 35 | 36 | * The default database ids were buggy, as I forgot to include the auto_increment values when exporting to sql (thanks to Eric) 37 | 38 | v1.12 (feb 25, 2008) 39 | 40 | * Bug (partialy solved) when password changing in user_controller.php (thanks to Kiang, http://twpug.net/) 41 | 42 | v1.11 (feb 19, 2008) 43 | 44 | * Accounts have an expiry date 45 | 46 | v1.10 (feb 14, 2008) 47 | 48 | THE DATABASE CHANGED SO YOU SHOULD REINSTALL ALL THE TABLES 49 | 50 | * Only administrators can modify or make an administrator. Avoid to gain administrator level. 51 | * Accounts can be disabled (Marco Sbragi's suggestion) 52 | * Cometic changes in app_controller.php (everything moved to authake component). 53 | * Possible to set a specific flash message for the rule that denies the access. 54 | * New session timeout feature. Allow to have an illimited cake session, and then choose the application session timeout. 55 | 56 | First release (feb 12, 2008) 57 | -------------------------------------------------------------------------------- /webroot/js/html5shiv.js: -------------------------------------------------------------------------------- 1 | /* 2 | HTML5 Shiv v3.6.2pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | (function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag(); 5 | a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/\w+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x"; 6 | c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode|| 7 | "undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",version:"3.6.2pre",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);if(g)return a.createDocumentFragment(); 8 | for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;dHtml->addCrumb('New User', $this->Html->url( null, true )); ?> 2 |
3 |
4 |
5 |
6 |

Add a New User

7 |
8 | Cancel 9 |
10 |
11 |
12 | Form->create('User');?> 13 |
14 |
15 | User Information 16 |
17 | Form->input('login', array('label'=>array('text'=>__('Login'),'class'=>'control-label'),'between'=>'
', 'after'=>'Username used when login. If configured, can be email.
'));?> 18 |
19 |
20 | Form->input('password', array('label'=>array('text'=>__('Password'),'class'=>'control-label'),'size'=>'12' ,'between'=>'
', 'after'=>'User\'s password. Choose a strong one.
'));?> 21 |
22 |
23 | Form->input('email', array('label'=>array('text'=>__('Email'),'class'=>'control-label'),'size'=>'40', 'between'=>'
', 'after'=>'User\'s email address. Choose a real one. Confirmation goes to this email.
'));?> 24 |
25 |
26 | Form->input('Group', array('label'=>array('text'=>__('In groups Press \'Control\' for multi-selection'),'class'=>'control-label'),'style'=>'width: 15em;', 'between'=>'
', 'after'=>'
'));?> 27 |
28 |
29 |
30 | 35 |
36 |
37 |
38 |
39 | Form->end(array('div'=>false,'label'=>'Create','class'=>'action input-action btn btn-primary'));?> 40 | Cancel 41 |
42 |
43 |
44 |
45 |
46 |
-------------------------------------------------------------------------------- /View/Authake/index.ctp: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 |
7 |
Users
8 |
9 |
10 |
11 |
12 |
13 |

14 |
Admins
15 |
16 |
17 |
18 |
19 |

20 |
Total Users
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
Groups & Rules
31 |
32 |
33 |
34 |
35 |
36 |

37 |
Groups
38 |
39 |
40 |
41 |
42 |

43 |
Rules
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
News from the Author
56 |
57 |
58 |
59 | 90 | 91 |
92 |
93 |
94 |
95 |
-------------------------------------------------------------------------------- /Model/AuthakeAppModel.php: -------------------------------------------------------------------------------- 1 | . 20 | */ 21 | App::uses('AppModel', 'Model'); 22 | class AuthakeAppModel extends AppModel { 23 | /** 24 | * Get Enum Values 25 | * Snippet v0.1.3 26 | * http://cakeforge.org/snippet/detail.php?type=snippet&id=112 27 | * 28 | * Gets the enum values for MySQL 4 and 5 to use in selectTag() 29 | */ 30 | function getEnumValues($columnName=null, $respectDefault=false) { 31 | if ($columnName==null) 32 | { 33 | return array(); 34 | } 35 | 36 | //no field specified 37 | //Get the name of the table 38 | $db =& ConnectionManager::getDataSource($this->useDbConfig); 39 | $tableName = $db->fullTableName($this, false);//Get the values for the specified column (database and version specific, needs testing) 40 | $result = $this->query("SHOW COLUMNS FROM {$tableName} LIKE '{$columnName}'");//figure out where in the result our Types are (this varies between mysql versions) 41 | $types = null; 42 | 43 | if (isset($result[0]['COLUMNS']['Type'] ) ) 44 | { 45 | $types = $result[0]['COLUMNS']['Type']; 46 | $default = $result[0]['COLUMNS']['Default']; 47 | } 48 | 49 | //MySQL 5 50 | elseif (isset($result[0][0]['Type'] ) ) 51 | { 52 | $types = $result[0][0]['Type']; 53 | $default = $result[0][0]['Default']; 54 | } 55 | 56 | //MySQL 4 57 | else { 58 | return array(); 59 | } 60 | 61 | //types return not accounted for 62 | //Get the values 63 | $values = explode('\',\'', preg_replace('/(enum)\(\'(.+?)\'\)/', '\\2', $types) ); 64 | 65 | if ($respectDefault) 66 | { 67 | $assoc_values = array("$default"=>Inflector::humanize($default)); 68 | 69 | foreach ($values as $value ) 70 | { 71 | if ($value==$default) 72 | { 73 | continue; 74 | } 75 | 76 | $assoc_values[$value] = Inflector::humanize($value); 77 | } 78 | } 79 | else 80 | { 81 | $assoc_values = array(); 82 | 83 | foreach ($values as $value ) 84 | { 85 | $assoc_values[$value] = Inflector::humanize($value); 86 | } 87 | } 88 | 89 | return $assoc_values; 90 | } 91 | 92 | //end getEnumValues 93 | } 94 | ?> -------------------------------------------------------------------------------- /View/User/index.ctp: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

6 |
7 |
8 |
9 |
10 | Authake->Gravatar->get_gravatar($this->Authake->getUserMail(),130,'','',true); 14 | } 15 | ?> 16 |
17 |
18 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 48 | 49 | 50 | 51 | 52 | 53 | 54 |
(ID {$user['User']['id']})"; ?>
Groups 30 | 34 |
35 | 43 |
44 | 47 |
Time->format('d/m/Y H:i', $this->Time->fromString($user['User']['created'])); ?>
55 |
56 | Form->create('User', array('url' => array('controller' => 'user', 'action'=>'index')));?> 57 |
58 | 59 | Form->input('email', array('value'=>$user['User']['email'], 'size'=>'40', 'after'=>'

'.__('(If modified, you will have to confirm it before the next login)').'

')); 61 | echo $this->Form->input('password1', array('type'=>'password', 'label'=> __('New Password') , 'value' => '', 'size'=>'12')); 62 | echo $this->Form->input('password2', array('type'=>'password', 'label'=> __('Enter Your New Password Again'), 'value' => '', 'size'=>'12')); 63 | ?> 64 |
65 | Form->end(array('div'=>false,'label'=>'Save','class'=>'action input-action btn btn-success'));?> 66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | -------------------------------------------------------------------------------- /View/Groups/index.ctp: -------------------------------------------------------------------------------- 1 | Html->addCrumb('Groups', $this->Html->url( null, true )); 2 | $up = null; 3 | //echo $this->Html->image($this->Gravatar->get_gravatar('mtkocak@gmail.com')); 4 | ?> 5 |
6 |
7 |
8 |
9 |

10 | 11 | Paginator->counter(array( 13 | 'format' => __('There are %current% groups on this system.') 14 | )); 15 | ?> 16 | 17 |

18 |
19 | 24 |
25 |
26 |
27 | 28 | 29 | 32 | 33 | 36 | 70 | 71 | 72 | 73 |
34 | Html->link($group['Group']['name'], array('action'=>'view', $group['Group']['id'])); ?> 35 | 37 | 69 |
74 | 79 |
80 |
81 |
82 |
-------------------------------------------------------------------------------- /webroot/index.php: -------------------------------------------------------------------------------- 1 | dispatch(); 84 | } 85 | if (Configure::read() > 0) { 86 | echo ""; 87 | } 88 | ?> -------------------------------------------------------------------------------- /View/Helper/AuthakeHelper.php: -------------------------------------------------------------------------------- 1 | . 20 | */ 21 | 22 | class AuthakeHelper extends AppHelper { 23 | 24 | var $helpers = array('Session','Authake.Gravatar','Html'); 25 | 26 | function getUserId() { 27 | return $this->Session->read('Authake.id'); 28 | } 29 | 30 | function getUserEmail() { 31 | return $this->Session->read('Authake.email'); 32 | } 33 | 34 | function getUserMenu() { 35 | if ( ! Configure::read('Authake.useEmailAsUsername') ) 36 | { 37 | $loginName = $this->getLogin(); 38 | } 39 | else 40 | { 41 | $loginName = $this->getUserEmail(); 42 | } 43 | if($loginName){ 44 | $output = ''; 54 | } 55 | else 56 | { 57 | $output = '
  • '.$this->Html->link(__('Sign Up'), array('plugin'=>'authake','controller'=> 'user', 'action'=>'register')).'
  • '; 58 | $output .= '
  • '.$this->Html->link(__('Login'), array('plugin'=>'authake','controller'=> 'user', 'action'=>'login')).'
  • '; 59 | } 60 | return $output; 61 | } 62 | 63 | function isLogged() { 64 | return ($this->getUserId() !== null); 65 | } 66 | 67 | function getLogin() { 68 | return $this->Session->read('Authake.login'); 69 | } 70 | 71 | function getGroupIds() { 72 | $gid = $this->Session->read('Authake.group_ids'); 73 | return (empty($gid) ? array(0) : $gid); 74 | } 75 | 76 | function getGroupNames() { 77 | $gn = $this->Session->read('Authake.group_names'); 78 | return (is_array($gn) ? $gn : array(__('Guest'))); 79 | } 80 | 81 | function isMemberOf($gid) { 82 | return in_array($gid, $this->getGroupIds()); 83 | } 84 | 85 | } 86 | 87 | ?> -------------------------------------------------------------------------------- /db/authake_clean.sql: -------------------------------------------------------------------------------- 1 | SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; 2 | 3 | CREATE TABLE IF NOT EXISTS `authake_groups` ( 4 | `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 5 | `name` varchar(64) COLLATE utf8_unicode_ci NOT NULL, 6 | PRIMARY KEY (`id`) 7 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ; 8 | 9 | INSERT INTO `authake_groups` (`id`, `name`) VALUES 10 | (1, 'Administrators'), 11 | (2, 'Registered users'); 12 | 13 | CREATE TABLE IF NOT EXISTS `authake_groups_users` ( 14 | `user_id` int(10) unsigned NOT NULL DEFAULT '0', 15 | `group_id` int(10) unsigned NOT NULL DEFAULT '0' 16 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 17 | 18 | 19 | INSERT INTO `authake_groups_users` (`user_id`, `group_id`) VALUES 20 | (1, 1); 21 | 22 | CREATE TABLE IF NOT EXISTS `authake_rules` ( 23 | `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 24 | `name` varchar(256) COLLATE utf8_unicode_ci NOT NULL COMMENT 'Rule description', 25 | `group_id` int(10) unsigned DEFAULT NULL, 26 | `order` int(10) unsigned DEFAULT NULL, 27 | `action` varchar(512) COLLATE utf8_unicode_ci DEFAULT NULL, 28 | `permission` tinyint(1) NOT NULL DEFAULT '0', 29 | `forward` varchar(64) COLLATE utf8_unicode_ci NOT NULL, 30 | `message` varchar(512) COLLATE utf8_unicode_ci NOT NULL, 31 | PRIMARY KEY (`id`) 32 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=7 ; 33 | 34 | INSERT INTO `authake_rules` (`id`, `name`, `group_id`, `order`, `action`, `permission`, `forward`, `message`) VALUES 35 | (1, 'Allow everything for Administrators', 1, 999999, '*', 1, '', ''), 36 | (2, 'Allow anybody to see the home page, the error page, to register, to log in, see profile and log out', null, 200, '/ or /authake/user/* or /register or /login or /logout or /lost-password or /verify(/)?* or /pass(/)?* or /profile or /denied or /pages(/)?* or //pages/*', 1, '', ''), 37 | (4, 'Deny everything for everybody by default (allow to have allow by default then deny)', null, 0, '*', 0, '', 'Access denied!'), 38 | (6, 'Display a message for denied admin page', null, 100, '/authake(/index)? or /authake/users* or /authake/groups* or /authake/rules*', 0, '', 'You are not allowed to access the administration page!'); 39 | 40 | CREATE TABLE IF NOT EXISTS `authake_users` ( 41 | `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 42 | `login` varchar(32) COLLATE utf8_unicode_ci NOT NULL, 43 | `password` varchar(50) COLLATE utf8_unicode_ci NOT NULL, 44 | `email` varchar(128) COLLATE utf8_unicode_ci NOT NULL, 45 | `emailcheckcode` varchar(128) COLLATE utf8_unicode_ci NOT NULL, 46 | `passwordchangecode` varchar(128) COLLATE utf8_unicode_ci NOT NULL, 47 | `disable` tinyint(1) NOT NULL COMMENT 'Disable/enable account', 48 | `expire_account` date DEFAULT NULL, 49 | `created` datetime DEFAULT NULL, 50 | `updated` datetime DEFAULT NULL, 51 | PRIMARY KEY (`id`) 52 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=2 ; 53 | 54 | INSERT INTO `authake_users` (`id`, `login`, `password`, `email`, `emailcheckcode`, `passwordchangecode`, `disable`, `expire_account`, `created`, `updated`) VALUES 55 | (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 'root', '', '', 0, NULL, '2008-02-12 12:19:31', '2008-02-12 12:19:31'); 56 | 57 | -------------------------------------------------------------------------------- /webroot/css.php: -------------------------------------------------------------------------------- 1 | 11 | * Copyright 2005-2008, Cake Software Foundation, Inc. 12 | * 1785 E. Sahara Avenue, Suite 490-204 13 | * Las Vegas, Nevada 89104 14 | * 15 | * Licensed under The MIT License 16 | * Redistributions of files must retain the above copyright notice. 17 | * 18 | * @filesource 19 | * @copyright Copyright 2005-2008, Cake Software Foundation, Inc. 20 | * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project 21 | * @package cake 22 | * @subpackage cake.app.webroot 23 | * @since CakePHP(tm) v 0.2.9 24 | * @version $Revision: 6311 $ 25 | * @modifiedby $LastChangedBy: phpnut $ 26 | * @lastmodified $Date: 2008-01-02 00:33:52 -0600 (Wed, 02 Jan 2008) $ 27 | * @license http://www.opensource.org/licenses/mit-license.php The MIT License 28 | */ 29 | if (!defined('CAKE_CORE_INCLUDE_PATH')) { 30 | header('HTTP/1.1 404 Not Found'); 31 | exit('File Not Found'); 32 | } 33 | /** 34 | * Enter description here... 35 | */ 36 | uses('file'); 37 | /** 38 | * Enter description here... 39 | * 40 | * @param unknown_type $path 41 | * @param unknown_type $name 42 | * @return unknown 43 | */ 44 | function make_clean_css($path, $name) { 45 | require(VENDORS . 'csspp' . DS . 'csspp.php'); 46 | $data = file_get_contents($path); 47 | $csspp = new csspp(); 48 | $output = $csspp->compress($data); 49 | $ratio = 100 - (round(strlen($output) / strlen($data), 3) * 100); 50 | $output = " /* file: $name, ratio: $ratio% */ " . $output; 51 | return $output; 52 | } 53 | /** 54 | * Enter description here... 55 | * 56 | * @param unknown_type $path 57 | * @param unknown_type $content 58 | * @return unknown 59 | */ 60 | function write_css_cache($path, $content) { 61 | if (!is_dir(dirname($path))) { 62 | mkdir(dirname($path)); 63 | } 64 | $cache = new File($path); 65 | return $cache->write($content); 66 | } 67 | 68 | if (preg_match('|\.\.|', $url) || !preg_match('|^ccss/(.+)$|i', $url, $regs)) { 69 | die('Wrong file name.'); 70 | } 71 | 72 | $filename = 'css/' . $regs[1]; 73 | $filepath = CSS . $regs[1]; 74 | $cachepath = CACHE . 'css' . DS . str_replace(array('/','\\'), '-', $regs[1]); 75 | 76 | if (!file_exists($filepath)) { 77 | die('Wrong file name.'); 78 | } 79 | 80 | if (file_exists($cachepath)) { 81 | $templateModified = filemtime($filepath); 82 | $cacheModified = filemtime($cachepath); 83 | 84 | if ($templateModified > $cacheModified) { 85 | $output = make_clean_css($filepath, $filename); 86 | write_css_cache($cachepath, $output); 87 | } else { 88 | $output = file_get_contents($cachepath); 89 | } 90 | } else { 91 | $output = make_clean_css($filepath, $filename); 92 | write_css_cache($cachepath, $output); 93 | $templateModified = time(); 94 | } 95 | 96 | header("Date: " . date("D, j M Y G:i:s ", $templateModified) . 'GMT'); 97 | header("Content-Type: text/css"); 98 | header("Expires: " . gmdate("D, j M Y H:i:s", time() + DAY) . " GMT"); 99 | header("Cache-Control: cache"); // HTTP/1.1 100 | header("Pragma: cache"); // HTTP/1.0 101 | print $output; 102 | ?> -------------------------------------------------------------------------------- /View/Layouts/authake.ctp: -------------------------------------------------------------------------------- 1 | Html->docType('html5'); ?> 2 | 3 | 4 | <?php echo $title_for_layout ?> 5 | 6 | Html->charset(); 8 | echo $this->Html->meta('icon'); 9 | $this->Html->css('/authake/css/bootstrap.min', null, array('inline' => false)); 10 | $this->Html->css('/authake/css/custom', null, array('inline' => false)); 11 | $this->Html->script('Authake.jquery-latest', array('block' => 'script')); 12 | $this->Html->script('Authake.custom', array('block' => 'script')); 13 | $this->Html->script('Authake.bootstrap.min', array('block' => 'script')); 14 | $this->Html->script('Authake.html5shiv', array('block' => 'script')); 15 | 16 | echo $this->fetch('meta'); 17 | echo $this->fetch('css'); 18 | echo $this->fetch('script'); 19 | ?> 20 | 21 | 22 |
    23 | 62 |
    63 |
    64 | Session->check('Message.flash')): 66 | echo $this->Session->flash(); 67 | endif; 68 | ?> 69 | ".$this->Html->getCrumbs(' » ', array( 71 | 'text' => 'Dashboard', 72 | 'url' => array('controller' => 'authake', 'action' => 'index', 'home'), 73 | 'escape' => false 74 | ))."

    "; 75 | echo $this->fetch('content'); 76 | ?> 77 |
    78 | 80 | 81 | -------------------------------------------------------------------------------- /Controller/Component/FilterComponent.php: -------------------------------------------------------------------------------- 1 | array("%1\$s LIKE", "%2\$s%%"), 24 | "text"=>array("%1\$s LIKE", "%2\$s%%"), 25 | "date"=>array("DATE_FORMAT(%1\$s, '%%d-%%m-%%Y')", "%2\$s"), 26 | "datetime"=>array("DATE_FORMAT(%1\$s, '%%d-%%m-%%Y')", "%2\$s") 27 | ); 28 | /** 29 | * Function which will change controller->data array 30 | * 31 | * @param object $controller the class of the controller which call this component 32 | * @access public 33 | */ 34 | function initialize(Controller $controller) { } 35 | function __construct(ComponentCollection $collection, $settings = array()) { 36 | parent::__construct($collection, $settings); 37 | } 38 | function process($controller){ 39 | $this->_prepareFilter($controller); 40 | $ret = array(); 41 | if(isset($controller->request->data)){ 42 | //Loop for models 43 | foreach($controller->request->data as $key=>$value){ 44 | if(isset($controller->{$key})){ 45 | $columns = $controller->{$key}->getColumnTypes(); 46 | foreach($value as $k=>$v){ 47 | if($v != ''){ 48 | //Trim the value 49 | $v=trim($v); 50 | //Check if there are some fieldFormatting set 51 | if(isset($this->fieldFormatting[$columns[$k]])){ 52 | $ret[sprintf($this->fieldFormatting[$columns[$k]][0], $key.'.'.$k, $v)] = sprintf($this->fieldFormatting[$columns[$k]][1], $key.'.'.$k, $v); 53 | } else { 54 | $ret[$key.'.'.$k] = $v; 55 | } 56 | } 57 | } 58 | //unsetting the empty forms 59 | if(count($value) == 0){ 60 | unset($controller->data[$key]); 61 | } 62 | } 63 | } 64 | } 65 | return $ret; 66 | } 67 | 68 | /** 69 | * function which will take care of the storing the filter data and loading after this from the Session 70 | */ 71 | function _prepareFilter(Controller $controller){ 72 | if(isset($controller->data)){ 73 | foreach($controller->data as $model=>$fields){ 74 | foreach($fields as $key=>$field){ 75 | if($field == ''){ 76 | unset($controller->request->data[$model][$key]); 77 | } 78 | } 79 | } 80 | $controller->Session->write($controller->name.'.'.$controller->params['action'], $controller->data); 81 | } 82 | $filter = $controller->Session->read($controller->name.'.'.$controller->params['action']); 83 | $controller->data = $filter; 84 | } 85 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Authake 2 | ============ 3 | 4 | Authake is finally arrived to CakePHP 2.2.3 and 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. 5 | 6 | Newest features are: 7 | 8 | 1. Totally new look & feel. New interface using twitter bootstrap library 9 | 2. Generated schema file to use cache schema create 10 | 3. Total adaptation to CakePHP 2.2.3 11 | 4. Totally new Dashboard 12 | 5. Gravatar Support 13 | 6. Better alerts 14 | 7. Beautiful navigation and breadcrumbs 15 | 8. html5shiv support for older browsers 16 | 9. Dropdown lists for commands 17 | 10. Help file with regex information 18 | 11. Settings page (needs some effort) 19 | 12. Better readme files with markdowns 20 | 21 | Further changes are here for your contribution: 22 | 23 | - sha1 security 24 | - long id's 25 | - For questions and issues: Mutlu Tevfik Kocak mtkocak(at) gmail.com 26 | 27 | Downlad 28 | -------------- 29 | 30 | https://github.com/mtkocak/authake 31 | 32 | For install instructions and feedback, please go to Authake home page: http://www.mtkocak.net/?p=333 33 | 34 | Install 35 | ---------- 36 | 37 | 1. Unzip the plugin to your app/Plugin folder with the name Authake. Case is important, lowercase folder name does not work. 38 | 39 | 2. You have to have in your bootstrap.php 40 | 41 | CakePlugin::loadAll(); 42 | //or 43 | CakePlugin::load('Authake'); 44 | 45 | 3. You can create schema from plugin using command to console terminal when you are in your app folder: 46 | 47 | Do not use any schema to generate SQL. Causes redirection loop instead of it add the Authake/db/authake_clean.sql to your database. 48 | 49 | 4. Add this to your config/database.php to make authake work. 50 | 51 | The idea behind this is that it would be possible to have 1 Authake instalation which handle multiple apps. 52 | 53 | var $authake = array( 54 | 'datasource' => 'Database/Mysql', 55 | 'persistent' => false, 56 | 'host' => 'localhost', 57 | 'login' => ", //username for the db 58 | 'password' => ", //password for the db 59 | 'database' => 'authake', //or any other where you have imported the authake.sql file 60 | 'prefix' => ", 61 | ); 62 | 63 | 5. Create AppController.php in you'r app's Controller folder first. 64 | 65 | Change it's contents like this: UPDATED: No need debug_kit anymore 66 | 67 | auth(); 75 | } 76 | private function auth(){ 77 | Configure::write('Authake.useDefaultLayout', true); 78 | $this->Authake->beforeFilter($this); 79 | } 80 | 81 | } 82 | ?> 83 | 84 | 6. Use username: **admin** password: **admin** to login 85 | 86 | For any question mtkocak@gmail.com 87 | 88 | 7. Change the permissions of Config folder to 777 and recurse into enclosed items 89 | Chmod 777 90 | 91 | 8. Your login page is located at http://localhost/auth/authake/user/login if you want to login from http://localhost/auth/login you have to create a route at app/config/routes.php like this: 92 | 93 | Router::connect('/login', array('plugin'=>'authake','controller' => 'user', 'action' => 'login')); 94 | 95 | Before the line that contains: 96 | 97 | require CAKE . 'Config' . DS . 'routes.php'; 98 | -------------------------------------------------------------------------------- /View/Rules/add.ctp: -------------------------------------------------------------------------------- 1 | Html->addCrumb('New Rule', $this->Html->url( null, true )); ?> 2 |
    3 |
    4 |
    5 |
    6 |

    Add a New Rule

    7 |
    8 | Cancel 9 |
    10 |
    11 |
    12 | Form->create('Rule');?> 13 |
    14 |
    15 | Rule Information 16 |
    17 | 18 |
    19 | Form->input('name', array('label'=>false, 'type'=>'textarea', 'cols'=>'50', 'rows'=>'2', 'after'=>'Description of the Rule
    '));?> 20 |
    21 |
    22 | 23 |
    24 | Form->input('group_id', array('label'=>false, 'empty'=>true, 'after'=>'Groups that this Rule is applied
    '));?> 25 |
    26 |
    27 | 28 |
    29 | Form->input('order', array('label'=>false, 'after'=>'The order of importance.
    '));?> 30 |
    31 |
    32 | 33 |
    34 | Form->input('action', array('label'=>false, 'type'=>'textarea', 'cols'=>'50', 'rows'=>'3', 'after'=>'Action that defines Rule. You can use Regular Expressions.'));?> 35 |
    36 |
    37 |
    38 | 39 |
    40 | Form->select('permission', array('1' => 'Allow', '0' => 'Deny'), array('label'=>false, 'empty'=>false, 'style'=>'width: 5em;','escape' => false,'between'=>'
    '));?> 41 | Permission Type. Allow / Deny 42 |
    43 |
    44 |
    45 | Form->input('forward', array('label'=>array('text'=>__('Forward action on error'),'class'=>'control-label'),'between'=>'
    ', 'after'=>'The route to be forwarded after allowed rule.
    '));?> 46 |
    47 |
    48 | Form->input('message', array('label'=>array('text'=>__('Flash message on deny'),'class'=>'control-label'), 'type'=>'textarea', 'cols'=>'50', 'rows'=>'2','between'=>'
    ', 'after'=>'Deny message on failed entry.
    '));?> 49 |
    50 |
    51 |
    52 | Form->end(array('div'=>false,'label'=>'Submit','class'=>'action input-action btn btn-primary'));?> 53 | Cancel 54 |
    55 |
    56 |
    57 |
    58 |
    59 |
    -------------------------------------------------------------------------------- /Controller/AuthakeController.php: -------------------------------------------------------------------------------- 1 | . 20 | */ 21 | class AuthakeController extends AuthakeAppController { 22 | var $uses = array('Authake.User','Authake.Rule','Authake.Group');// needed as we don't have any model 23 | //var $layout = 'authake'; 24 | 25 | function index() { 26 | $this->set('title_for_layout', 'Authake User & Group Management'); 27 | $admins = $this->Group->find('all', array('conditions'=>array('name'=>'Administrators'))); 28 | $adminCount = sizeof($admins[0]['User']); 29 | $userCount = $this->User->find('count'); 30 | $groupCount = $this->Group->find('count'); 31 | $ruleCount = $this->Rule->find('count'); 32 | $this->set(compact('adminCount','userCount','groupCount','ruleCount')); 33 | } 34 | 35 | function help() { 36 | $this->set('title_for_layout', 'Help for Authake'); 37 | } 38 | 39 | function settings(){ 40 | if (!empty($this->request->data['Settings'])) 41 | { 42 | $this->request->data['Settings']['loginAction'] = Router::parse($this->request->data['Settings']['loginAction']); 43 | $this->request->data['Settings']['defaultDeniedAction'] = Router::parse($this->request->data['Settings']['defaultDeniedAction']); 44 | Configure::write('Authake',$this->request->data['Settings']); 45 | } 46 | $configs = Configure::read('Authake'); 47 | Configure::dump('authake_config.php', 'Authake', array('Authake')); 48 | $this->set(compact('configs'));// fix permissions dropdown menu 49 | } 50 | 51 | function reset(){ 52 | Configure::write('Authake.baseUrl', Router::url('/', true)); // set the full application url 53 | Configure::write('Authake.service', 'Authake'); //Name of the service i.e. "Super Authake" 54 | Configure::write('Authake.loginAction', array('plugin' => 'authake', 'controller' => 'user', 'action' => 'login', 'admin' => 0)); 55 | Configure::write('Authake.loggedAction', Configure::read('Authake.baseUrl')); 56 | Configure::write('Authake.sessionTimeout', 3600 * 24 * 7); 57 | Configure::write('Authake.defaultDeniedAction', array('plugin' => 'authake', 'controller' => 'user', 'action' => 'denied', 'admin' => 0)); 58 | Configure::write('Authake.rulesCacheTimeout', 300); 59 | Configure::write('Authake.systemEmail', 'noreply@example.com'); 60 | Configure::write('Authake.systemReplyTo', 'noreply@example.com'); 61 | Configure::write('Authake.passwordVerify', true); 62 | Configure::write('Authake.registration', true); //or false 63 | Configure::write('Authake.defaultGroup', 2); //could be array or single number 64 | Configure::write('Authake.useDefaultLayout', false); //could be true or false 65 | Configure::write('Authake.useEmailAsUsername', false); //could be true or false 66 | Configure::dump('authake_config.php', 'Authake', array('Authake')); 67 | $this->Session->setFlash(__('Authake Reset'), 'success'); 68 | $this->redirect(array('action'=>'index')); 69 | } 70 | } 71 | ?> -------------------------------------------------------------------------------- /View/Groups/edit.ctp: -------------------------------------------------------------------------------- 1 | Html->addCrumb('New Group', $this->Html->url( null, true )); ?> 2 |
    3 |
    4 |
    5 |
    6 |

    Crate a New Group

    7 |
    8 |

    Modify Rule

    9 |
    10 | Html->link(__('View group'), array('action'=>'view', $this->Form->value('Group.id')), array('class'=>'btn btn-primary'));?> 11 | Cancel 12 | Html->link(__('Delete'), array('action'=>'delete', $this->Form->value('Group.id')), array('class'=>'btn btn-danger'), sprintf(__('Are you sure you want to delete @%s?'), $this->Form->value('Group.name'))); ?> 13 |
    14 |
    15 |
    16 |
    17 | Form->create('Group');?> 18 |
    19 |
    20 | Group Information 21 |
    22 | 23 |
    24 | Form->input('id'); 26 | echo $this->Form->input('name', array('label'=>false,'after'=>'
    '));?> 27 |
    28 |
    29 | 30 |
    31 | Form->input('User', array('style'=>'width: 15em;', 'label'=>false, 'after'=>'Select users if you want to add them to this group.
    ')); 33 | ?> 34 |
    35 |
    36 |
    37 | Form->end(array('div'=>false,'label'=>'Edit','class'=>'action input-action btn btn-success'));?> 38 | Html->link(__('View Rule'), array('action'=>'view', $this->Form->value('Group.id')), array('class'=>'btn btn-primary'));?> 39 | Cancel 40 | Html->link(__('Delete'), array('action'=>'delete', $this->Form->value('Group.id')), array('class'=>'btn btn-danger'), sprintf(__('Are you sure you want to delete @%s?'), $this->Form->value('Group.name'))); ?> 41 |
    42 |
    43 |
    44 |
    45 |
    46 |
    47 | 48 |
    49 | 54 |
    55 | Form->create('Group');?> 56 |
    57 | request->data['Group']['name']; ?> 58 | Form->input('id'); 60 | echo $this->Form->input('name', array('label'=>__('Name'))); 61 | echo $this->Form->input('User', array('label'=>__('Users in this group
    Press \'Control\' for multi-selection'), 'style'=>'width: 15em;')); 62 | ?> 63 |
    64 | Form->end(__('Modify'));?> 65 |
    66 |
    67 |
      68 |
    • Html->link(__('View group'), array('action'=>'view', $this->Form->value('Group.id')));?>
    • 69 |
    • Html->link(__('Delete'), array('action'=>'delete', $this->Form->value('Group.id')), null, sprintf(__('Are you sure you want to delete # %s?'), $this->Form->value('Group.id'))); ?>
    • 70 |
    71 |
    72 |
    73 | -------------------------------------------------------------------------------- /View/Rules/view.ctp: -------------------------------------------------------------------------------- 1 | Html->addCrumb('View Rule', $this->Html->url( null, true )); 2 | $up = null; 3 | //echo $this->Html->image($this->Gravatar->get_gravatar('mtkocak@gmail.com')); 4 | ?> 5 |
    6 |
    7 |
    8 |
    9 |

    10 |

    11 |
    12 |
    13 | Html->link(__('Edit Rule'), array('action'=>'edit', $rule['Rule']['id']),array('class'=>'btn btn-primary')); ?> 14 | 17 | 28 |
    29 |
    30 |
    31 |
    32 | 35 | 36 | 37 | 38 | 39 | 42 | 43 | 44 | 45 | 51 | 52 | 53 | 54 | 57 | 58 | 59 | 60 | 63 | 64 | 65 | 66 | 69 | 70 | 71 | 72 | 81 | 82 | 83 | 84 | 93 | 94 | 95 |
    40 | 41 |
    46 | ".__("Everybody, including not logged users").""; 48 | else 49 | echo $this->Html->link($rule['Group']['name'], array('controller'=> 'groups', 'action'=>'view', $rule['Group']['id']),array('class'=>'label')); ?> 50 |
    55 | 56 |
    61 | ', $rule['Rule']['action']); ?> 62 |
    67 | Htmlbis->iconallowdeny($rule['Rule']['permission']);?> 68 |
    73 | 80 |
    85 | 92 |
    96 |
    97 |
    98 |
    99 | Html->link(__('Edit Rule'), array('action'=>'edit', $rule['Rule']['id']),array('class'=>'btn')); ?> 100 | 101 | New rule 102 | 103 |
    104 |
    105 |
    106 |
    107 |
    108 |
    109 |
    -------------------------------------------------------------------------------- /View/Users/edit.ctp: -------------------------------------------------------------------------------- 1 | Html->addCrumb('Edit User', $this->Html->url( null, true )); ?> 2 |
    3 |
    4 |
    5 |
    6 |

    Modify User data['User']['login']; ?>

    7 |
    8 | Html->link(__('View user'), array('action'=>'view', $this->Form->value('User.id')), array('class'=>'btn btn-primary'));?> 9 | Cancel 10 | Html->link(__('Delete'), array('action'=>'delete', $this->Form->value('User.id')), array('class'=>'btn btn-danger'), sprintf(__('Are you sure you want to delete @%s?'), $this->Form->value('User.login'))); ?> 11 |
    12 |
    13 |
    14 | Form->create('User');?> 15 |
    16 |
    17 | User Information 18 | Form->input('id');?> 19 |
    20 | Form->input('Group', array('label'=>array('text'=>__('In groups Press \'Control\' for multi-selection'),'class'=>'control-label'),'style'=>'width: 15em;', 'between'=>'
    ', 'after'=>'
    '));?> 21 |
    22 |
    23 | Form->input('email', array('label'=>array('text'=>__('Email'),'class'=>'control-label'),'size'=>'40', 'between'=>'
    ', 'after'=>'User\'s email address. Choose a real one. Confirmation goes to this email.
    '));?> 24 |
    25 |
    26 | Form->input('password', array('label'=>array('text'=>__('Password (visible!)'),'class'=>'control-label'),'type'=>'text','value'=>'','size'=>'12' ,'between'=>'
    ', 'after'=>'
    '));?> 27 |
    28 |
    29 | Form->input('passwordchangecode', array('label'=>array('text'=>__('Password Change Code'),'class'=>'control-label'), 'between'=>'
    ', 'after'=>'This is the code sent to User\'s email address at any password change
    '));?> 30 |
    31 |
    32 | Form->input('emailchangecode', array('label'=>array('text'=>__('Email Check Code'),'class'=>'control-label'), 'between'=>'
    ', 'after'=>'This is the code sent to User\'s email address at to validate account
    '));?> 33 |
    34 |
    35 | Form->input('expire_account', array('label'=>array('text'=>__('Account Expiry Date'),'class'=>'control-label'), 'between'=>'
    ', 'after'=>'
    '));?> 36 |
    37 |
    38 |
    39 | 44 |
    45 |
    46 |
    47 |
    48 | Form->end(array('div'=>false,'label'=>'Edit','class'=>'action input-action btn btn-success'));?> 49 | Html->link(__('View user'), array('action'=>'view', $this->Form->value('User.id')), array('class'=>'btn btn-primary'));?> 50 | Cancel 51 | Html->link(__('Delete'), array('action'=>'delete', $this->Form->value('User.id')), array('class'=>'btn btn-danger'), sprintf(__('Are you sure you want to delete @%s?'), $this->Form->value('User.login'))); ?> 52 |
    53 |
    54 |
    55 |
    56 |
    57 |
    -------------------------------------------------------------------------------- /Controller/GroupsController.php: -------------------------------------------------------------------------------- 1 | . 20 | */ 21 | 22 | 23 | class GroupsController extends AuthakeAppController { 24 | 25 | 26 | var $paginate = array( 27 | 'limit' => 100000, 28 | 'order' => array( 29 | 'Group.id' => 'asc' 30 | ) 31 | ); 32 | //var $layout = 'authake'; 33 | 34 | var $uses = array('Authake.Group', 'Authake.Rule'); 35 | 36 | function index($tableonly = false) { 37 | $this->Group->recursive = 0; 38 | $this->set('groups', $this->paginate()); 39 | $this->set('tableonly', $tableonly); 40 | } 41 | 42 | function view($id = null, $viewactions = null) { 43 | if (!$id) { 44 | $this->Session->setFlash(__('Invalid group.'), 'warning'); 45 | $this->redirect(array('action'=>'index')); 46 | } 47 | 48 | $this->set('group', $this->Group->read(null, $id)); 49 | $this->set('rules', $this->Rule->getRules(array($id))); 50 | 51 | if ($viewactions === 'actions') 52 | $this->set('actions', $this->Authake->getActionsPermissions(array($id))); 53 | } 54 | 55 | function add() { 56 | if (!empty($this->request->data)) { 57 | $this->Group->create(); 58 | if ($this->Group->save($this->request->data)) { 59 | $this->Session->setFlash(__('The group has been saved'), 'success'); 60 | $this->redirect(array('action'=>'index')); 61 | } else { 62 | $this->Session->setFlash(__('The group could not be saved. Please, try again'), 'error'); 63 | } 64 | } 65 | ($users = $this->Group->User->find('list', array("fields"=>array("User.id", "User.login")))); 66 | $this->set(compact('users')); 67 | } 68 | 69 | function edit($id = null) { 70 | if (!$id && empty($this->request->data)) { 71 | $this->Session->setFlash(__('Invalid group'), 'warning'); 72 | $this->redirect(array('action'=>'index')); 73 | } 74 | 75 | if ($id == 1 and !in_array(1, $this->Authake->getGroupIds())) { 76 | $this->Session->setFlash(__('You cannot edit the group administrators'), 'warning'); 77 | $this->redirect(array('action'=>'index')); 78 | } 79 | 80 | if (!empty($this->request->data)) { 81 | if ($this->Group->save($this->request->data)) { 82 | $this->Session->setFlash(__('The group has been saved'), 'success'); 83 | } else { 84 | $this->Session->setFlash(__('The group could not be saved. Please, try again.'), 'error'); 85 | } 86 | $this->redirect(array('action'=>'index')); 87 | } 88 | if (empty($this->request->data)) { 89 | $this->request->data = $this->Group->read(null, $id); 90 | } 91 | 92 | 93 | // !!! CAKE BUG !!! should return array(array('id'=>'login), ...) 94 | // resolved in https://trac.cakephp.org/changeset/6360 95 | $users = $this->Group->User->find('list', array("fields"=>array("User.id", "User.login"))); 96 | 97 | /* 98 | $users = $this->Group->User->find('all'); 99 | $users = Set::combine($users, '{n}.User.id', '{n}.User.login'); 100 | */ 101 | $this->set(compact('users')); 102 | } 103 | 104 | function delete($id = null) { 105 | if (!$id || $id == 1) { 106 | $this->Session->setFlash(__('Impossible to delete this group'), 'error'); 107 | $this->redirect(array('action'=>'index')); 108 | } 109 | if ($this->Group->delete($id)) { 110 | $this->Session->setFlash(__('Group deleted'), 'success'); 111 | $this->redirect(array('action'=>'index')); 112 | } 113 | } 114 | 115 | } 116 | 117 | ?> -------------------------------------------------------------------------------- /Controller/RulesController.php: -------------------------------------------------------------------------------- 1 | . 20 | */ 21 | class RulesController extends AuthakeAppController { 22 | var $uses = array('Authake.Rule');//var $scaffold; 23 | // var $layout = 'authake'; 24 | function index($tableonly = false) { 25 | $this->Rule->recursive = 0; 26 | $this->set('rules', $this->Rule->find('all')); 27 | $this->set('tableonly', $tableonly); 28 | } 29 | 30 | function view($id = null) { 31 | 32 | if (!$id) 33 | { 34 | $this->Session->setFlash(__('Invalid Rule.'), 'error'); 35 | $this->redirect(array('action'=>'index')); 36 | } 37 | 38 | $this->set('rule', $this->Rule->read(null, $id)); 39 | } 40 | 41 | function add() { 42 | 43 | if (!empty($this->request->data)) 44 | { 45 | $this->Rule->create(); 46 | 47 | if ($this->Rule->save($this->request->data)) 48 | { 49 | $this->Session->setFlash(__('The Rule has been saved'), 'success'); 50 | $this->redirect(array('action'=>'index')); 51 | } 52 | else 53 | { 54 | $this->Session->setFlash(__('The Rule could not be saved. Please, try again.'), 'warning'); 55 | } 56 | } 57 | 58 | $groups = $this->Rule->Group->find('list'); 59 | $this->set(compact('groups'));// fix permissions dropdown menu 60 | $permissions = $this->Rule->getEnumValues('permission'); 61 | $this->set(compact('permissions')); 62 | } 63 | 64 | function edit($id = null) {//$this->Rule->getEnumValues('permission')); 65 | 66 | if (!$id && empty($this->request->data)) 67 | { 68 | $this->Session->setFlash(__('Invalid Rule'), 'error'); 69 | $this->redirect(array('action'=>'index')); 70 | } 71 | 72 | 73 | if ($id == '1') 74 | {// do not touch to the admin rule 75 | $this->Session->setFlash(__('Impossible to edit this rule!'), 'warning'); 76 | $this->redirect(array('action'=>'index')); 77 | } 78 | 79 | 80 | if (!empty($this->request->data)) 81 | { 82 | 83 | if ($this->Rule->save($this->request->data)) 84 | { 85 | $this->Session->setFlash(__('The Rule has been saved'), 'success'); 86 | $this->redirect(array('action'=>'index')); 87 | } 88 | else 89 | { 90 | $this->Session->setFlash(__('The Rule could not be saved. Please, try again.'), 'warning'); 91 | } 92 | } 93 | 94 | 95 | if (empty($this->request->data)) 96 | { 97 | $this->request->data = $this->Rule->read(null, $id); 98 | } 99 | 100 | // fix groups dropdown menu 101 | $groups = $this->Rule->Group->find('list'); 102 | $this->set(compact('groups'));// fix permissions dropdown menu 103 | $permissions = $this->Rule->getEnumValues('permission'); 104 | $this->set(compact('permissions')); 105 | } 106 | 107 | function delete($id = null) { 108 | 109 | if (!$id) 110 | { 111 | $this->Session->setFlash(__('Invalid id for Rule'), 'error'); 112 | } 113 | elseif ($id == '1') 114 | {// do not touch to the admin rule 115 | $this->Session->setFlash(__('Impossible to delete this rule!'), 'warning'); 116 | } 117 | elseif ($this->Rule->delete($id)) 118 | { 119 | $this->Session->setFlash(__('Rule deleted'), 'success'); 120 | } 121 | 122 | $this->redirect(array('action'=>'index')); 123 | } 124 | 125 | function up($id1, $id2) {// swap order of two rules 126 | 127 | if ($id1 != 1 && $id2 != 1) 128 | { 129 | $r1 = $this->Rule->findById($id1); 130 | $r2 = $this->Rule->findById($id2);// pr(array($r1,$r2)); 131 | $order = $r1['Rule']['order']; 132 | $r1['Rule']['order'] = $r2['Rule']['order']; 133 | $r2['Rule']['order'] = $order;// pr(array($r1,$r2)); 134 | $this->Rule->save($r1); 135 | $this->Rule->save($r2); 136 | } 137 | 138 | $this->redirect(array('action'=>'index')); 139 | } 140 | } 141 | ?> -------------------------------------------------------------------------------- /View/Rules/edit.ctp: -------------------------------------------------------------------------------- 1 | Html->addCrumb('New Rule', $this->Html->url( null, true )); ?> 2 |
    3 |
    4 |
    5 |
    6 |

    Modify Rule

    7 |
    8 | Html->link(__('View rule'), array('action'=>'view', $this->Form->value('Rule.id')), array('class'=>'btn btn-primary'));?> 9 | Cancel 10 | Html->link(__('Delete'), array('action'=>'delete', $this->Form->value('Rule.id')), array('class'=>'btn btn-danger'), sprintf(__('Are you sure you want to delete @%s?'), $this->Form->value('Rule.name'))); ?> 11 |
    12 |
    13 |
    14 | Form->create('Rule');?> 15 |
    16 |
    17 | Rule Information 18 |
    19 | 20 |
    21 | Form->input('id'); 23 | echo $this->Form->input('name', array('label'=>false, 'type'=>'textarea', 'cols'=>'50', 'rows'=>'2', 'after'=>'Description of the Rule
    '));?> 24 |
    25 |
    26 | 27 |
    28 | Form->input('group_id', array('label'=>false, 'empty'=>true, 'after'=>'Groups that this Rule is applied
    '));?> 29 |
    30 |
    31 | 32 |
    33 | Form->input('order', array('label'=>false, 'after'=>'The order of importance.
    '));?> 34 |
    35 |
    36 | 37 |
    38 | Form->input('action', array('label'=>false, 'type'=>'textarea', 'cols'=>'50', 'rows'=>'3', 'after'=>'Action that defines Rule. You can use Regular Expressions.'));?> 39 |
    40 |
    41 |
    42 | 43 |
    44 | Form->select('permission', array('1' => 'Allow', '0' => 'Deny'), array('label'=>false, 'empty'=>false, 'style'=>'width: 5em;','escape' => false,'between'=>'
    '));?> 45 | Permission Type. Allow / Deny 46 |
    47 |
    48 |
    49 | Form->input('forward', array('label'=>array('text'=>__('Forward action on error'),'class'=>'control-label'),'between'=>'
    ', 'after'=>'The route to be forwarded after allowed rule.
    '));?> 50 |
    51 |
    52 | Form->input('message', array('label'=>array('text'=>__('Flash message on deny'),'class'=>'control-label'), 'type'=>'textarea', 'cols'=>'50', 'rows'=>'2','between'=>'
    ', 'after'=>'Deny message on failed entry.
    '));?> 53 |
    54 |
    55 |
    56 | Form->end(array('div'=>false,'label'=>'Edit','class'=>'action input-action btn btn-success'));?> 57 | Html->link(__('View Rule'), array('action'=>'view', $this->Form->value('Rule.id')), array('class'=>'btn btn-primary'));?> 58 | Cancel 59 | Html->link(__('Delete'), array('action'=>'delete', $this->Form->value('Rule.id')), array('class'=>'btn btn-danger'), sprintf(__('Are you sure you want to delete @%s?'), $this->Form->value('Rule.name'))); ?> 60 |
    61 |
    62 |
    63 |
    64 |
    65 |
    -------------------------------------------------------------------------------- /Model/User.php: -------------------------------------------------------------------------------- 1 | . 20 | */ 21 | App::uses('AuthakeAppModel', 'Authake.Model'); 22 | class User extends AuthakeAppModel { 23 | var $name = 'User'; 24 | var $useTable = 'authake_users'; 25 | var $useDbConfig = 'authake'; 26 | var $recursive = 1; 27 | var $hasAndBelongsToMany = array('Group' => array('className' => 'Authake.Group', 'joinTable' => 'authake_groups_users', 'foreignKey' => 'user_id', 'associationForeignKey' => 'group_id', 'conditions' => '', 'fields' => '', 'order' => '', 'limit' => '', 'offset' => '', 'finderQuery' => '', 'deleteQuery' => '', 'insertQuery' => '')); 28 | function beforeValidate($options = array()){ 29 | $validateOptions = array(); 30 | if(!Configure::read('Authake.useEmailAsUsername')) 31 | { 32 | $loginOptions = array('login' => array( 33 | 'alphanumeric' => array( 34 | 'rule' => 'alphaNumeric', 35 | 'message' => 'Only alphabets and numbers allowed' 36 | ), 37 | 'minlength' => array( 38 | 'rule' => array('minLength', ( Configure::read('Authake.useEmailAsUsername') ? '0' : '3' )), 39 | /* set min length to 0 if we do not want usernames but only emails*/ 40 | 'message' => 'Minimum length of 3 characters' 41 | ), 42 | 'maxlength' => array( 43 | 'rule' => array('maxLength', '32'), 44 | 'message' => 'Maximum length of 32 characters' 45 | ), 46 | )); 47 | $validateOptions = $loginOptions; 48 | } 49 | $otherOptions = array( 50 | 'email' => array( 51 | 'notEmpty' => array( 52 | 'rule' => 'notEmpty', 53 | 'message'=>__('Username can not be blank') 54 | ), 55 | 'unique' => array( 56 | 'rule' => 'isUnique', 57 | 'message'=>__('This e-mail has already been used'), 58 | 'on'=>'create' 59 | ), 60 | /*'emailAddress' => array('rule' => array('email', true),'message' => __('Please supply a valid email address'))*/ 61 | ), 62 | 'password1' => array( 63 | 'checkEmpty' => array( 64 | 'rule' => array('notEmpty'), 65 | 'message' => __('Passwords must be equal and not empty'), 66 | 'on' => 'create' 67 | ) 68 | ), 69 | 'password2' => array( 70 | 'checkInsertPass' => array( 71 | 'rule' => array('notEmpty'), 72 | 'message' => __('Passwords must be equal and not empty'), 73 | 'on' => 'create' 74 | ) 75 | ) 76 | ); 77 | $validateOptions += $otherOptions; 78 | $this->validate = $validateOptions; 79 | } 80 | 81 | function checkPasswords() 82 | { 83 | if (($this->request->data['User']['password1'] != $this->request->data['User']['password2'])) 84 | { 85 | return false; 86 | } 87 | 88 | return true; 89 | } 90 | 91 | function getLoginData($login='', $password='') 92 | { 93 | $hashed = md5($password); 94 | 95 | if (Configure::read('Authake.useEmailAsUsername') == false) 96 | { 97 | $data = $this->find('first', array('conditions'=>array('login'=>$login, 'password'=>$hashed), 'recursive' => 1)); 98 | } 99 | else 100 | { 101 | $data = $this->find('first', array('conditions'=>array('email'=>$login, 'password'=>$hashed), 'recursive' => 1)); 102 | } 103 | 104 | if (!empty($data)) 105 | { 106 | /* 107 | $data['User']['group_ids'][] = 0; // everybody is at least a guest 108 | $data['User']['group_names'][] = __('Guest'); 109 | */ 110 | 111 | if (!empty($data['Group'])) 112 | { 113 | foreach ($data['Group'] as $group) 114 | { 115 | $data['User']['group_ids'][] = $group['id']; 116 | $data['User']['group_names'][] = $group['name']; 117 | } 118 | } 119 | 120 | unset($data['User']['password']);// not useful to save the encrypted password in session 121 | return $data; 122 | } 123 | else 124 | { 125 | return false; 126 | } 127 | } 128 | 129 | function getGroups($id) 130 | { 131 | $groups = $this->findById($id);//SORUN TAM DA BURADA OLABİLİR 132 | $list = array(0); 133 | 134 | foreach ($groups['Group'] as $group) 135 | { 136 | $list[] = $group['id']; 137 | } 138 | 139 | return $list;//var_dump($list); 140 | } 141 | } 142 | ?> -------------------------------------------------------------------------------- /View/Rules/index.ctp: -------------------------------------------------------------------------------- 1 | Html->addCrumb('New Rule', $this->Html->url( null, true )); 2 | $up = null; 3 | //echo $this->Html->image($this->Gravatar->get_gravatar('mtkocak@gmail.com')); 4 | ?> 5 |
    6 |
    7 |
    8 |
    9 |

    10 | 11 | List of all rules applied in your system. 12 | 13 |

    14 |
    15 | 20 |
    21 |
    22 |
    23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | $rule): 37 | ?> 38 | 39 | 43 | 55 | 56 | 57 | 58 | 61 | 114 | 117 | 118 | 119 | 120 |
     
    40 | 41 | Htmlbis->link($rule['Rule']['name'], array('action'=>'view', $rule['Rule']['id'])); ?> 42 | 44 | Html->url(array('controller'=> 'groups', 'action'=>'view', $rule['Group']['id'])).'" class="label">'.$groupname.''; 50 | else 51 | echo $groupname; 52 | 53 | ?> 54 | Htmlbis->iconallowdeny($rule['Rule']['permission']); ?>', $rule['Rule']['action']); 60 | ?> 62 |
    63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 112 |
    113 |
    115 | 116 |
    121 |
    122 |
    123 |
    124 |
    -------------------------------------------------------------------------------- /webroot/css/custom.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: transparent url(../img/adminBack.jpg) 0 0 repeat; 3 | padding-top: 51px; 4 | min-height: 402px; 5 | } 6 | 7 | footer .navbar 8 | { 9 | position: relative; 10 | bottom:0px; 11 | left: 0 !important; 12 | right: 0 !important; 13 | width: 101%; 14 | display: block; 15 | } 16 | 17 | .navbar-static-bottom { 18 | position: static; 19 | width: 100%; 20 | margin-bottom: 0; 21 | bottom:0px; 22 | margin: -1px -1px 0; 23 | } 24 | 25 | /* FL UI */ 26 | 27 | .section { 28 | background-color: #fff; 29 | border: 1px solid #ccc; 30 | -webkit-border-radius: 4px; 31 | -moz-border-radius: 4px; 32 | -ms-border-radius: 4px; 33 | -o-border-radius: 4px; 34 | border-radius: 4px; 35 | margin-bottom: 18px; 36 | } 37 | 38 | .section-header { 39 | background-color: #f6f6f6; 40 | background-image: -moz-linear-gradient(top, #fafafa, #f2f2f2); 41 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fafafa), to(#f2f2f2)); 42 | background-image: -webkit-linear-gradient(top, #fafafa, #f2f2f2); 43 | background-image: -o-linear-gradient(top, #fafafa, #f2f2f2); 44 | background-image: linear-gradient(to bottom, #fafafa,#f2f2f2); 45 | background-repeat: repeat-x; 46 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFAFAFA', endColorstr='#FFF2F2F2', GradientType=0); 47 | border-top: 1px solid #fff; 48 | border-bottom: 1px solid #ccc; 49 | -moz-border-radius-topleft: 4px; 50 | -webkit-border-top-left-radius: 4px; 51 | border-top-left-radius: 4px; 52 | -moz-border-radius-topright: 4px; 53 | -webkit-border-top-right-radius: 4px; 54 | border-top-right-radius: 4px; 55 | height: 46px; 56 | padding: 0 15px 0; 57 | } 58 | 59 | .section-actions { 60 | float: right; 61 | margin-top: 9px; 62 | margin-bottom: 0; 63 | } 64 | 65 | .btn-toolbar /* Düzelt Alt Class Ekle */ 66 | { 67 | margin: 0; 68 | } 69 | .section-body { 70 | min-height: 18px; 71 | padding: 9px 15px 0; 72 | } 73 | 74 | .form-actions { 75 | padding: 17px 20px 18px; 76 | margin-top: 18px; 77 | margin-bottom: 18px; 78 | background-color: #f5f5f5; 79 | border-top: 1px solid #e5e5e5; 80 | } 81 | 82 | 83 | 84 | .section-header h3 { 85 | line-height: 28px; 86 | } 87 | 88 | .section-header h3, .section-header h5 { 89 | color: #555; 90 | float: left; 91 | text-transform: uppercase; 92 | text-shadow: 1px 1px 0 #fff; 93 | } 94 | 95 | .section-small .section-header { 96 | height: 37px !important; 97 | line-height: 37px; 98 | padding: 0 11px 0; 99 | } 100 | 101 | .section-small .section-header h5 { 102 | font-size: 12px; 103 | line-height: 20px; 104 | } 105 | 106 | .section-small .section-header .section-actions { 107 | margin-top: 4px; 108 | } 109 | 110 | .ac { 111 | text-align: center; 112 | } 113 | 114 | .stat-block { 115 | color: #454545; 116 | margin-bottom: 18px; 117 | } 118 | 119 | h3 { 120 | font-size: 18px; 121 | line-height: 20px; 122 | } 123 | 124 | h6 { 125 | color: #999; 126 | text-transform: uppercase; 127 | } 128 | 129 | h6 { 130 | font-size: 12px; 131 | line-height: 20px; 132 | } 133 | 134 | h5 { 135 | color: #555; 136 | float: left; 137 | text-transform: uppercase; 138 | text-shadow: 1px 1px 0 #fff; 139 | } 140 | 141 | .success { 142 | color: #508600; 143 | } 144 | 145 | .stat-block h1, .stat-block h2, .stat-block h3, .stat-block h4, .stat-block h5, .stat-block h6 { 146 | margin: 0; 147 | } 148 | 149 | #assets-table { 150 | font-size: 11px; 151 | } 152 | 153 | .ar { 154 | text-align: right !important; 155 | } 156 | 157 | 158 | 159 | .well-small { 160 | padding: 9px; 161 | -webkit-border-radius: 3px; 162 | -moz-border-radius: 3px; 163 | border-radius: 3px; 164 | } 165 | 166 | outer-bordered td { 167 | border-left: 0; 168 | } 169 | 170 | .table-bordered, .table-outer-bordered { 171 | border: 1px solid #ddd; 172 | border-collapse: separate; 173 | border-left: 0; 174 | -webkit-border-radius: 4px; 175 | -moz-border-radius: 4px; 176 | border-radius: 4px; 177 | } 178 | 179 | .table-outer-bordered { 180 | border-left: 1px solid #ddd !important; 181 | } 182 | 183 | .table-outer-bordered td { 184 | border-left: 1px solid #ddd; 185 | } 186 | 187 | .table th, .table td { 188 | padding: 8px; 189 | line-height: 18px; 190 | text-align: left; 191 | vertical-align: top; 192 | border-top: 1px solid #ddd; 193 | } 194 | 195 | bordered { 196 | border-collapse: separate; 197 | } 198 | 199 | table { 200 | border-collapse: collapse; 201 | border-spacing: 0; 202 | } 203 | 204 | .table-outer-bordered { 205 | border-left: 1px solid #ddd; 206 | } 207 | 208 | .table-outer-bordered th, .table-outer-bordered td { 209 | border-left: 0; 210 | } 211 | 212 | .table-bordered, .table-outer-bordered { 213 | border: 1px solid #ddd; 214 | border-collapse: separate; 215 | border-left: 0; 216 | -webkit-border-radius: 4px; 217 | -moz-border-radius: 4px; 218 | border-radius: 4px; 219 | } 220 | 221 | .table-bordered caption + thead tr:first-child th, .table-outer-bordered caption + thead tr:first-child th, .table-bordered caption + tbody tr:first-child th, .table-outer-bordered caption + tbody tr:first-child th, .table-bordered caption + tbody tr:first-child td, .table-outer-bordered caption + tbody tr:first-child td, .table-bordered colgroup + thead tr:first-child th, .table-outer-bordered colgroup + thead tr:first-child th, .table-bordered colgroup + tbody tr:first-child th, .table-outer-bordered colgroup + tbody tr:first-child th, .table-bordered colgroup + tbody tr:first-child td, .table-outer-bordered colgroup + tbody tr:first-child td, .table-bordered thead:first-child tr:first-child th, .table-outer-bordered thead:first-child tr:first-child th, .table-bordered tbody:first-child tr:first-child th, .table-outer-bordered tbody:first-child tr:first-child th, .table-bordered tbody:first-child tr:first-child td, .table-outer-bordered tbody:first-child tr:first-child td { 222 | border-top: 0; 223 | } -------------------------------------------------------------------------------- /Controller/UsersController.php: -------------------------------------------------------------------------------- 1 | . 20 | */ 21 | class UsersController extends AuthakeAppController { 22 | var $uses = array('Authake.User', 'Authake.Rule'); 23 | var $components = array('Authake.Filter','Session');// var $layout = 'authake'; 24 | var $paginate = array('limit' => 10, 'order' => array('User.login' => 'asc'));//var $scaffold; 25 | 26 | function index($tableonly = false) { 27 | $this->User->recursive = 1; 28 | $filter = $this->Filter->process($this); 29 | $this->set('users', $this->paginate(null, $filter)); 30 | $this->set('tableonly', $tableonly); 31 | } 32 | 33 | function view($id = null, $viewactions = null) { 34 | $this->User->recursive = 1;// to select user, groups and rules 35 | 36 | if (!$id) 37 | { 38 | $this->Session->setFlash(__('Invalid User')); 39 | $this->redirect(array('action'=>'index')); 40 | } 41 | 42 | $this->set('user', $this->User->read(null, $id)); 43 | $groups = $this->User->getGroups($id); 44 | $this->set('rules', $this->Rule->getRules($groups)); 45 | 46 | if ($viewactions === 'actions') 47 | { 48 | $this->set('actions', $this->Authake->getActionsPermissions($groups)); 49 | } 50 | } 51 | 52 | function add() { 53 | 54 | if (!empty($this->request->data)) 55 | {// only an admin can make an admin 56 | 57 | if (in_array(1, $this->request->data['Group']['Group']) and !in_array(1, $this->Authake->getGroupIds())) 58 | { 59 | $this->Session->setFlash(__('You cannot add a user in administrators group'), 'warning'); 60 | $this->redirect(array('action'=>'index')); 61 | } 62 | 63 | $p = $this->request->data['User']['password']; 64 | $this->request->data['User']['password'] = $this->__makePassword($p, $p); 65 | $this->User->create(); 66 | 67 | if ($this->User->save($this->request->data)) 68 | { 69 | $this->Session->setFlash(__('The User has been saved'), 'success'); 70 | $this->redirect(array('action'=>'index')); 71 | } 72 | else 73 | { 74 | $this->Session->setFlash(__('The User could not be saved. Please, try again.'), 'error'); 75 | } 76 | } 77 | 78 | $this->request->data['User']['password'] = ''; 79 | $groups = $this->User->Group->find('list'); 80 | $this->set(compact('groups')); 81 | } 82 | 83 | function edit($id = null) { 84 | 85 | if (!$id && empty($this->request->data)) 86 | { 87 | $this->Session->setFlash(__('Invalid User')); 88 | $this->redirect(array('action'=>'index')); 89 | } 90 | 91 | $user = $this->User->read(null, $id);// check if user allow to edit (only an admin can edit an admin) 92 | $gr = Set::extract($user, 'Group.{n}.id'); 93 | 94 | if (in_array(1, $gr) and !in_array(1, $this->Authake->getGroupIds())) 95 | { 96 | $this->Session->setFlash(__('You cannot edit a user in administrators group'), 'warning'); 97 | $this->redirect(array('action'=>'index')); 98 | } 99 | 100 | 101 | if (!empty($this->request->data)) 102 | {// only Admin (id 1) can modify its profile (for security reasons) 103 | 104 | if ($id == 1 && $this->Authake->getUserId() != 1) 105 | { 106 | $this->Session->setFlash(__('Only the admin can change its profile!'), 'warning'); 107 | $this->redirect(array('action'=>'index')); 108 | } 109 | 110 | // only an admin can make an admin 111 | 112 | if ($this->request->data['Group']['Group'] == '') 113 | { 114 | $this->request->data['Group']['Group'] = array(); 115 | } 116 | 117 | 118 | if (isset($this->request->data['Group']['Group']) and in_array(1, $this->request->data['Group']['Group']) and !in_array(1, $this->Authake->getGroupIds()) ) 119 | { 120 | $this->Session->setFlash(__('You cannot add a user in administrators group'), 'warning'); 121 | $this->redirect(array('action'=>'index')); 122 | } 123 | 124 | // check if pwd changed 125 | 126 | if ($p = $this->request->data['User']['password']) 127 | { 128 | $this->request->data['User']['password'] = $this->__makePassword($p, $p); 129 | } 130 | else 131 | { 132 | unset($this->request->data['User']['password']); 133 | } 134 | 135 | 136 | if (empty($this->request->data['Group'])) 137 | { 138 | $this->request->data['Group']['Group'] = array(); 139 | } 140 | 141 | // delete user-group relation if selection empty 142 | unset($this->request->data['User']['login']);// never change the login 143 | // save user 144 | 145 | if ($this->User->save($this->request->data)) 146 | { 147 | $this->Session->setFlash(__('The User has been saved'), 'success'); 148 | $this->redirect(array('action'=>'index')); 149 | } 150 | else 151 | { 152 | $this->Session->setFlash(__('The User could not be saved. Please, try again.'), 'error'); 153 | } 154 | } 155 | 156 | // show edit form 157 | $this->request->data = $user; 158 | $this->request->data['User']['password'] = '';// find groups 159 | $groups = $this->User->Group->find('list'); 160 | unset($groups[0]);// remove group 0 (everybody) 161 | $this->set(compact('groups')); 162 | } 163 | 164 | function delete($id = null) {// check if user in admins group 165 | $user = $this->User->read(null, $id); 166 | 167 | if (!$id || $id == 1) 168 | { 169 | $this->Session->setFlash(__('Invalid id for User'), 'error'); 170 | $this->redirect(array('action'=>'index')); 171 | } 172 | 173 | // check if user allow to edit (only an admin can edit an admin) 174 | $gr = Set::extract($user, 'Group.{n}.id'); 175 | 176 | if (in_array(1, $gr) and !in_array(1, $this->Authake->getGroupIds())) 177 | { 178 | $this->Session->setFlash(__('You cannot delete a user in administrators group'), 'warning'); 179 | $this->redirect(array('action'=>'index')); 180 | } 181 | 182 | 183 | if ($this->User->delete($id)) 184 | { 185 | $this->Session->setFlash(__('User deleted'), 'success'); 186 | $this->redirect(array('action'=>'index')); 187 | } 188 | } 189 | } 190 | ?> 191 | -------------------------------------------------------------------------------- /View/Groups/view.ctp: -------------------------------------------------------------------------------- 1 | Html->addCrumb('View Group', $this->Html->url( null, true )); 2 | ?> 3 |
    4 |
    5 |
    6 |
    7 |

    {$group['Group']['name']}"); ?>

    8 |
    9 |
    10 | Html->link(__('Edit group'), array('action'=>'edit', $group['Group']['id']), array('class'=>'btn btn-primary')); ?> 11 | 14 | 31 |
    32 |
    33 |
    34 |
    35 |
    36 | 37 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 52 | 53 | 54 | 55 | 81 | 82 | 83 | 84 |
    LoginEmailActions
    Html->link($user['login'], array('controller'=> 'users', 'action'=>'view', $user['id']));?> 56 | 80 |
    85 |
    86 |
    87 | 92 |
    93 |
    94 | 97 | 98 | 99 | 103 | 104 | 107 | 109 | 110 | 113 | 147 | 148 | 149 | 150 |
    105 | 106 | 108 | Htmlbis->iconallowdeny($rule['permission']); ?>', $rule['action']); 112 | ?> 114 | 146 |
    151 |
    152 | 162 |
    163 |
    164 |
    165 |
    166 |
    167 |
    -------------------------------------------------------------------------------- /View/Users/index.ctp: -------------------------------------------------------------------------------- 1 | Html->addCrumb('Users', $this->Html->url( null, true )); ?> 2 |
    3 |
    4 |
    5 |
    6 |

    7 | Users 8 | 9 | Paginator->counter(array( 11 | 'format' => __('There are %current% users on this system.') 12 | )); 13 | ?> 14 | 15 |

    16 | 21 |
    22 |
    23 |
    24 |
    25 | 32 | Paginator->counter(array( 34 | 'format' => __('
    35 |
    36 |

    37 | %current% 38 |

    39 |
    40 | Total Users 41 |
    42 |
    43 |
    44 |
    45 |
    46 |

    47 | %page% 48 |

    49 |
    50 | Page Number 51 |
    52 |
    53 |
    54 |
    55 |
    56 |

    57 | %pages% 58 |

    59 |
    60 | Total Pages 61 |
    62 |
    63 |
    ') 64 | )); 65 | ?> 66 |
    67 |
    68 |
    69 | 101 |
    102 | 103 |
    104 |
    105 | 106 | 107 | Time->fromString($exp) < time())) 119 | $class = " class=\"{$class} disabled\""; 120 | else 121 | $class = " class=\"{$class}\""; 122 | 123 | ?> 124 | 125 | 130 | 135 | 138 | 141 | 151 | 154 | 161 | 188 | 189 | 190 | 191 |
    126 | 127 | Gravatar->get_gravatar($user['User']['email'],30,'','',true) ?> 128 | 129 | 131 | 132 | 133 | 134 | 136 | Html->link($user['User']['login'], array('action'=>'view', $user['User']['id'])); ?> 137 | 139 | {$email}"; ?> 140 | 142 |
    143 | $group) 146 | $gr[] = $this->Html->link(__($group['name']), array('controller'=>'groups', 'action'=>'view', $group['id']),array('class'=>'label')); 147 | 148 | echo implode(' ', $gr); ?> 149 |
    150 |
    152 | Time->format('d/m/Y', $user['User']['created']); ?>  153 | 155 | Disabled '; 156 | 157 | $exp = $user['User']['expire_account']; 158 | if ($exp != '0000-00-00' and $this->Time->fromString($exp) < time()) echo 'Expired'; 159 | ?> 160 | 162 |
    163 | 164 | 165 | 166 | 167 | 168 | 169 | 186 |
    187 |
    192 | 197 |
    198 |
    199 |
    200 |
    201 | -------------------------------------------------------------------------------- /webroot/test.php: -------------------------------------------------------------------------------- 1 | 11 | * Copyright 2005-2008, Cake Software Foundation, Inc. 12 | * 1785 E. Sahara Avenue, Suite 490-204 13 | * Las Vegas, Nevada 89104 14 | * 15 | * Licensed under The Open Group Test Suite License 16 | * Redistributions of files must retain the above copyright notice. 17 | * 18 | * @filesource 19 | * @copyright Copyright 2005-2008, Cake Software Foundation, Inc. 20 | * @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests 21 | * @package cake 22 | * @subpackage cake.cake.tests.libs 23 | * @since CakePHP(tm) v 1.2.0.4433 24 | * @version $Revision: 6311 $ 25 | * @modifiedby $LastChangedBy: phpnut $ 26 | * @lastmodified $Date: 2008-01-02 00:33:52 -0600 (Wed, 02 Jan 2008) $ 27 | * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License 28 | */ 29 | error_reporting(E_ALL); 30 | set_time_limit(0); 31 | ini_set('memory_limit','128M'); 32 | if (!defined('DS')) { 33 | define('DS', DIRECTORY_SEPARATOR); 34 | } 35 | if (!defined('ROOT')) { 36 | define('ROOT', dirname(dirname(dirname(__FILE__)))); 37 | } 38 | if (!defined('APP_DIR')) { 39 | define('APP_DIR', basename(dirname(dirname(__FILE__)))); 40 | } 41 | if (!defined('CAKE_CORE_INCLUDE_PATH')) { 42 | define('CAKE_CORE_INCLUDE_PATH', ROOT); 43 | } 44 | if (!defined('WEBROOT_DIR')) { 45 | define('WEBROOT_DIR', basename(dirname(__FILE__))); 46 | } 47 | if (!defined('WWW_ROOT')) { 48 | define('WWW_ROOT', dirname(__FILE__) . DS); 49 | } 50 | if (!defined('CORE_PATH')) { 51 | if (function_exists('ini_set')) { 52 | ini_set('include_path', CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS . PATH_SEPARATOR . ini_get('include_path')); 53 | define('APP_PATH', null); 54 | define('CORE_PATH', null); 55 | } else { 56 | define('APP_PATH', ROOT . DS . APP_DIR . DS); 57 | define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS); 58 | } 59 | } 60 | 61 | ini_set('display_errors', 1); 62 | if (!include(CORE_PATH . 'cake' . DS . 'bootstrap.php')) { 63 | trigger_error("Can't find CakePHP core. Check the value of CAKE_CORE_INCLUDE_PATH in app/webroot/test.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR); 64 | } 65 | 66 | $corePath = Configure::corePaths('cake'); 67 | if (isset($corePath[0])) { 68 | define('TEST_CAKE_CORE_INCLUDE_PATH', rtrim($corePath[0], DS) . DS); 69 | } else { 70 | define('TEST_CAKE_CORE_INCLUDE_PATH', CAKE_CORE_INCLUDE_PATH); 71 | } 72 | require_once CAKE . 'tests' . DS . 'lib' . DS . 'test_manager.php'; 73 | 74 | if (Configure::read('debug') < 1) { 75 | die(__('Debug setting does not allow access to this url.')); 76 | } 77 | 78 | if (!isset($_SERVER['SERVER_NAME'])) { 79 | $_SERVER['SERVER_NAME'] = ''; 80 | } 81 | if (empty( $_GET['output'])) { 82 | $_GET['output'] = 'html'; 83 | } 84 | 85 | $dispatch =& new Dispatcher(); 86 | $dispatch->baseUrl(); 87 | define('BASE', $dispatch->webroot); 88 | 89 | /** 90 | * 91 | * Used to determine output to display 92 | */ 93 | define('CAKE_TEST_OUTPUT_HTML',1); 94 | define('CAKE_TEST_OUTPUT_TEXT',2); 95 | 96 | if (isset($_GET['output']) && $_GET['output'] == 'html') { 97 | define('CAKE_TEST_OUTPUT', CAKE_TEST_OUTPUT_HTML); 98 | } else { 99 | define('CAKE_TEST_OUTPUT', CAKE_TEST_OUTPUT_TEXT); 100 | } 101 | 102 | if (!vendor('simpletest' . DS . 'reporter')) { 103 | CakePHPTestHeader(); 104 | include CAKE . 'tests' . DS . 'lib' . DS . 'simpletest.php'; 105 | CakePHPTestSuiteFooter(); 106 | exit(); 107 | } 108 | 109 | function &CakeTestsGetReporter() { 110 | static $Reporter = NULL; 111 | if (!$Reporter) { 112 | switch (CAKE_TEST_OUTPUT) { 113 | case CAKE_TEST_OUTPUT_HTML: 114 | require_once LIB_TESTS . 'cake_reporter.php'; 115 | $Reporter = new CakeHtmlReporter(); 116 | break; 117 | default: 118 | $Reporter = new TextReporter(); 119 | break; 120 | } 121 | } 122 | return $Reporter; 123 | } 124 | 125 | function CakePHPTestRunMore() { 126 | switch (CAKE_TEST_OUTPUT) { 127 | case CAKE_TEST_OUTPUT_HTML: 128 | if (isset($_GET['group'])) { 129 | if (isset($_GET['app'])) { 130 | $show = '?show=groups&app=true'; 131 | } else { 132 | $show = '?show=groups'; 133 | } 134 | } 135 | if (isset($_GET['case'])) { 136 | if (isset($_GET['app'])) { 137 | $show = '??show=cases&app=truee'; 138 | } else { 139 | $show = '?show=cases'; 140 | } 141 | } 142 | echo "

    Run more tests

    \n"; 143 | break; 144 | } 145 | } 146 | 147 | function CakePHPTestCaseList() { 148 | switch (CAKE_TEST_OUTPUT) { 149 | case CAKE_TEST_OUTPUT_HTML: 150 | if (isset($_GET['app'])) { 151 | echo HtmlTestManager::getTestCaseList(APP_TEST_CASES); 152 | } else { 153 | echo HtmlTestManager::getTestCaseList(CORE_TEST_CASES); 154 | } 155 | break; 156 | case CAKE_TEST_OUTPUT_TEXT: 157 | default: 158 | if (isset($_GET['app'])) { 159 | echo TextTestManager::getTestCaseList(APP_TEST_CASES); 160 | } else { 161 | echo TextTestManager::getTestCaseList(CORE_TEST_CASES); 162 | } 163 | break; 164 | } 165 | } 166 | 167 | function CakePHPTestGroupTestList() { 168 | switch (CAKE_TEST_OUTPUT) { 169 | case CAKE_TEST_OUTPUT_HTML: 170 | if (isset($_GET['app'])) { 171 | echo HtmlTestManager::getGroupTestList(APP_TEST_GROUPS); 172 | } else { 173 | echo HtmlTestManager::getGroupTestList(CORE_TEST_GROUPS); 174 | } 175 | break; 176 | case CAKE_TEST_OUTPUT_TEXT: 177 | default: 178 | if (isset($_GET['app'])) { 179 | echo TextTestManager::getGroupTestList(APP_TEST_GROUPS); 180 | } else { 181 | echo TextTestManager::getGroupTestList(CORE_TEST_GROUPS); 182 | } 183 | break; 184 | } 185 | } 186 | 187 | function CakePHPTestHeader() { 188 | switch (CAKE_TEST_OUTPUT) { 189 | case CAKE_TEST_OUTPUT_HTML: 190 | $baseUrl = BASE; 191 | $characterSet = 'charset=utf-8'; 192 | include CAKE . 'tests' . DS . 'lib' . DS . 'header.php'; 193 | break; 194 | case CAKE_TEST_OUTPUT_TEXT: 195 | default: 196 | header(' content-type: text/plain'); 197 | break; 198 | } 199 | } 200 | 201 | function CakePHPTestSuiteHeader() { 202 | switch (CAKE_TEST_OUTPUT) { 203 | case CAKE_TEST_OUTPUT_HTML: 204 | $groups = $_SERVER['PHP_SELF'].'?show=groups'; 205 | $cases = $_SERVER['PHP_SELF'].'?show=cases'; 206 | include CAKE . 'tests' . DS . 'lib' . DS . 'content.php'; 207 | break; 208 | } 209 | } 210 | 211 | function CakePHPTestSuiteFooter() { 212 | switch ( CAKE_TEST_OUTPUT) { 213 | case CAKE_TEST_OUTPUT_HTML: 214 | $baseUrl = BASE; 215 | include CAKE . 'tests' . DS . 'lib' . DS . 'footer.php'; 216 | break; 217 | } 218 | } 219 | 220 | CakePHPTestHeader(); 221 | CakePHPTestSuiteHeader(); 222 | define('RUN_TEST_LINK', $_SERVER['PHP_SELF']); 223 | 224 | if (isset($_GET['group'])) { 225 | if ('all' == $_GET['group']) { 226 | TestManager::runAllTests(CakeTestsGetReporter()); 227 | } else { 228 | if (isset($_GET['app'])) { 229 | TestManager::runGroupTest(ucfirst($_GET['group']), APP_TEST_GROUPS, CakeTestsGetReporter()); 230 | } else { 231 | TestManager::runGroupTest(ucfirst($_GET['group']), CORE_TEST_GROUPS, CakeTestsGetReporter()); 232 | } 233 | } 234 | CakePHPTestRunMore(); 235 | CakePHPTestSuiteFooter(); 236 | exit(); 237 | } 238 | 239 | if (isset($_GET['case'])) { 240 | TestManager::runTestCase($_GET['case'], CakeTestsGetReporter()); 241 | CakePHPTestRunMore(); 242 | CakePHPTestSuiteFooter(); 243 | exit(); 244 | } 245 | 246 | if (isset($_GET['show']) && $_GET['show'] == 'cases') { 247 | CakePHPTestCaseList(); 248 | } else { 249 | CakePHPTestGroupTestList(); 250 | } 251 | CakePHPTestSuiteFooter(); 252 | ?> -------------------------------------------------------------------------------- /View/Users/view.ctp: -------------------------------------------------------------------------------- 1 | Html->addCrumb('View User', $this->Html->url( null, true )); 2 | //echo $this->Html->image($this->Gravatar->get_gravatar('mtkocak@gmail.com')); 3 | ?> 4 |
    5 |
    6 |
    7 | 31 |
    32 |
    33 |
    34 | Gravatar->get_gravatar($user['User']['email'],130,'','',true) ?> 35 |
    36 |
    37 | 40 | ".__('Account disabled')."
    "; 43 | } 44 | ?> 45 | 46 | 47 | 48 | 49 | 51 | 52 | 53 | 54 | 64 | 65 | 66 | 67 | 72 | 73 | 74 | 75 | 80 | 81 | 82 | 83 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 |
    User ID1 50 |
    Groups 55 |
    56 | $group) 59 | $gr[] = $this->Html->link(__($group['name']), array('controller'=>'groups', 'action'=>'view', $group['id']),array('class'=>'label')); 60 | 61 | echo implode('', $gr); ?> 62 |
    63 |
    Password Change Code 68 | 71 |
    Email Check Code 76 | 79 |
    Account Expires On 84 | 91 |
    User CreatedTime->format('d/m/Y H:i', $this->Time->fromString($user['User']['created'])); ?>
    Updated OnTime->format('d/m/Y H:i', $this->Time->fromString($user['User']['updated'])); ?>
    103 | 115 | 116 | 119 | 120 | $ruleslist) { 122 | ?> 123 | 124 | 127 | 142 | 143 | 146 |
    125 | 126 | 128 | $rule) 130 | { 131 | if ($rule['permission'] == true) 132 | { 133 | echo ''.$rule['action'].""; 134 | } 135 | else 136 | { 137 | echo ''.$rule['action'].""; 138 | } 139 | } 140 | ?> 141 |
    147 | 150 | 151 | 152 | 156 | 157 | 160 | 162 | 163 | 166 | 200 | 201 | 202 | 203 |
    158 | 159 | 161 | Htmlbis->iconallowdeny($rule['permission']); ?>', $rule['action']); 165 | ?> 167 | 199 |
    204 |
    205 | 215 |
    216 |
    217 |
    218 |
    219 |
    220 |
    221 | -------------------------------------------------------------------------------- /View/Authake/settings.ctp: -------------------------------------------------------------------------------- 1 | Html->addCrumb('Authake Settings', $this->Html->url( null, true )); ?> 3 |
    4 |
    5 |
    6 |
    7 |

    Authake Settings

    8 |
    9 | Cancel 10 | Html->link(__('Reset Authake'), array('controller'=>'authake','action'=>'reset'), array('class'=>'btn btn-danger'),'Are you sure you want to reset Authake settings?'); ?> 11 |
    12 |
    13 |
    14 | Form->create('Settings');?> 15 |
    16 |
    17 | Authake Settings 18 |
    19 | Form->input('baseUrl', array('value'=>$configs['baseUrl'],'type'=>'text','label'=>array('text'=>__('Base URL'),'class'=>'control-label'),'between'=>'
    ', 'after'=>'Base URL, used to insert the application URL in mails.
    '));?> 20 |
    21 |
    22 | Form->input('service', array('value'=>$configs['service'],'type'=>'text','label'=>array('text'=>__('Service'),'class'=>'control-label'),'between'=>'
    ', 'after'=>'Name of the service i.e. "Super Authake"
    '));?> 23 |
    24 |
    25 | Form->input('loginAction', array('value'=>Router::url($configs['loginAction']+ array("base" => false)),'type'=>'text','label'=>array('text'=>__('Login Action'),'class'=>'control-label'),'between'=>'
    ', 'after'=>'Default login action
    '));?> 26 |
    27 |
    28 | Form->input('loggedAction', array('value'=>$configs['loggedAction'],'type'=>'text','label'=>array('text'=>__('Logged Action'),'class'=>'control-label'),'between'=>'
    ', 'after'=>'Used to redirect the users if the current user is logged out. Basically, this is used in case when The login page is the home page. If this is not set to different location, then it\'s going into recursion.
    '));?> 29 |
    30 |
    31 | Form->input('sessionTimeout', array('value'=>$configs['sessionTimeout'],'type'=>'number','label'=>array('text'=>__('Session Timeout'),'class'=>'control-label'),'between'=>'
    ', 'after'=>'Session timeout in seconds, if managed by Authake (or null to disable)
    '));?> 32 |
    33 |
    34 | Form->input('defaultDeniedAction', array('value'=>Router::url($configs['defaultDeniedAction']+ array("base" => false)),'type'=>'text','label'=>array('text'=>__('Default Denied Action'),'class'=>'control-label'),'between'=>'
    ', 'after'=>'Default page when access is denied (should be allowed by ACLs...)
    '));?> 35 |
    36 |
    37 | Form->input('rulesCacheTimeout', array('value'=>$configs['rulesCacheTimeout'],'type'=>'number','label'=>array('text'=>__('Rules Cache Timeout'),'class'=>'control-label'),'between'=>'
    ', 'after'=>'Reload all rules every x seconds
    '));?> 38 |
    39 |
    40 | Form->input('systemEmail', array('value'=>$configs['systemEmail'],'type'=>'text','label'=>array('text'=>__('System Email'),'class'=>'control-label'),'between'=>'
    ', 'after'=>'Email which sends the system mails
    '));?> 41 |
    42 |
    43 | Form->input('systemReplyTo', array('value'=>$configs['systemReplyTo'],'type'=>'text','label'=>array('text'=>__('System Reply To'),'class'=>'control-label'),'between'=>'
    ', 'after'=>'Email which sends the system mails (Reply To)
    '));?> 44 |
    45 |
    46 |
    47 | 59 | User need to authenticate that he requested the password change (by receiving the confirmation link at his e-mail) 60 |
    61 |
    62 |
    63 |
    64 | 76 |
    77 |
    78 |
    79 | Form->input('defaultGroup', array('value'=>$configs['defaultGroup'],'type'=>'number','label'=>array('text'=>__('Default Group'),'class'=>'control-label'),'between'=>'
    ', 'after'=>'Default group for registered users If set registered user will be inserted into specified group
    '));?> 80 |
    81 |
    82 |
    83 | 95 | Skip using authake layout for User controller. This is used to display default layout of the application to actions like login, register, change password etc. 96 |
    97 |
    98 |
    99 |
    100 | 112 | Use only email instead of user/email (a lot of sites are using this behavior, i.e.: Google, so people is already used to it) Defaults to false so it keeps on the old behavior 113 |
    114 |
    115 |
    116 |
    117 | Form->end(array('div'=>false,'label'=>'Save','class'=>'action input-action btn btn-primary'));?> 118 | Cancel 119 |
    120 |
    121 |
    122 |
    123 |
    124 |
    -------------------------------------------------------------------------------- /Controller/Component/AuthakeComponent.php: -------------------------------------------------------------------------------- 1 | . 21 | */ 22 | 23 | class AuthakeComponent extends Component { 24 | 25 | var $components = array('Session'); 26 | var $_forward = null; 27 | var $_flashmessage = ''; 28 | 29 | function initialize(Controller $controller) { 30 | 31 | } 32 | 33 | function __construct(ComponentCollection $collection, $settings = array()) { 34 | parent::__construct($collection, $settings); 35 | } 36 | 37 | function startup(Controller $controller = null) { 38 | App::uses('PhpReader', 'Configure'); 39 | //Configure::config('Authake', new PhpReader(APP.'/Plugin/Authake/Config/')); 40 | Configure::config('Authake', new PhpReader(App::pluginPath('Authake').'Config/')); 41 | 42 | Configure::load('authake_config.php', 'Authake'); 43 | /** 44 | * AUTHAKE CONFIGURATION 45 | * All these changes can be overrided in AppController->beforeFilter action 46 | */ 47 | /** 48 | * Base URL, used to insert the application URL in mails. 49 | */ 50 | if (Configure::read('Authake.baseUrl') == null) { 51 | Configure::write('Authake.baseUrl', Router::url('/', true)); // set the full application url 52 | } 53 | if (Configure::read('Authake.service') == null) { 54 | Configure::write('Authake.service', 'Authake'); //Name of the service i.e. "Super Authake" 55 | } 56 | /** 57 | * Default login action 58 | */ 59 | if (Configure::read('Authake.loginAction') == null) { 60 | Configure::write('Authake.loginAction', array('plugin' => 'authake', 'controller' => 'user', 'action' => 'login', 'admin' => 0)); 61 | } 62 | /** 63 | * Used to redirect the users if the current user is logged out. Basically, this 64 | * is used in case when The login page is the home page. If this is not set to different location, then it's going into recursion. 65 | */ 66 | if (Configure::read('Authake.loggedAction') == null) { 67 | Configure::write('Authake.loggedAction', Configure::read('Authake.baseUrl')); 68 | } 69 | /** 70 | * Session timeout in seconds, if managed by Authake (or null to disable) 71 | */ 72 | if (Configure::read('Authake.sessionTimeout') == null) { 73 | Configure::write('Authake.sessionTimeout', 3600 * 24 * 7); 74 | } 75 | /** 76 | * Default page when access is denied (should be allowed by ACLs...) 77 | */ 78 | if (Configure::read('Authake.defaultDeniedAction') == null) { 79 | Configure::write('Authake.defaultDeniedAction', array('plugin' => 'authake', 'controller' => 'user', 'action' => 'denied', 'admin' => 0)); 80 | } 81 | /** 82 | * Reload all rules every x seconds 83 | */ 84 | if (Configure::read('Authake.rulesCacheTimeout') == null) { 85 | Configure::write('Authake.rulesCacheTimeout', 300); 86 | } 87 | /** 88 | * Email which sends the system mails 89 | */ 90 | if (Configure::read('Authake.systemEmail') == null) { 91 | Configure::write('Authake.systemEmail', 'noreply@example.com'); 92 | } 93 | if (Configure::read('Authake.systemReplyTo') == null) { 94 | Configure::write('Authake.systemReplyTo', 'noreply@example.com'); 95 | } 96 | /** 97 | * User need to authenticate that he requested the password change 98 | * (by receiving the confirmation link at his e-mail) 99 | */ 100 | if (Configure::read('Authake.passwordVerify') == null) { 101 | Configure::write('Authake.passwordVerify', true); 102 | } 103 | /** 104 | * Users can register 105 | */ 106 | if (Configure::read('Authake.registration') == null) { 107 | Configure::write('Authake.registration', true); //or false 108 | } 109 | /** 110 | * Default group for registered users 111 | * If set registered user will be inserted into specified group 112 | */ 113 | if (Configure::read('Authake.defaultGroup') == null) { 114 | Configure::write('Authake.defaultGroup', 2); //could be array or single number 115 | } 116 | /** 117 | * Skip using authake layout for User controller. 118 | * This is used to display default layout of the application to actions 119 | * like login, register, change password etc. 120 | */ 121 | if (Configure::read('Authake.useDefaultLayout') == null) { 122 | Configure::write('Authake.useDefaultLayout', false); //could be true or false 123 | } 124 | /** 125 | * Use only email instead of user/email (a lot of sites are using this behavior, i.e.: Google, 126 | * so people is already used to it) 127 | * Defaults to false so it keeps on the old behavior 128 | */ 129 | 130 | if (Configure::read('Authake.useEmailAsUsername') == null) { 131 | Configure::write('Authake.useEmailAsUsername', false); //could be true or false 132 | } 133 | //Configure::dump('authake_config.php', 'Authake', array('Authake')); 134 | } 135 | 136 | function beforeFilter(&$controller) { //pr($this); 137 | //Getting vars 138 | $this->startup(); 139 | 140 | // get action path 141 | 142 | $path = $controller->request->params; 143 | 144 | $loginAction = Configure::read('Authake.loginAction'); 145 | 146 | if(!is_array($loginAction)) 147 | { 148 | $loginAction = Router::parse($loginAction); 149 | } 150 | if (Router::url($controller->request->params + array("base" => false)) != Router::url($loginAction + array("base" => false)) ) { 151 | 152 | $this->setPreviousUrl(null); 153 | } 154 | 155 | // check session timeout 156 | $tm = Configure::read('Authake.sessionTimeout'); 157 | if ($tm && $this->isLogged()) { 158 | $ts = $this->Session->read('Authake.timestamp'); 159 | if ((time() - $ts) > $tm) { 160 | $this->setPreviousUrl($path); 161 | $this->logout(); 162 | $this->Session->setFlash(__('Your session expired'), 'warning'); 163 | $controller->redirect($loginAction); 164 | } 165 | $this->setTimestamp(); 166 | } 167 | 168 | if (!$this->isAllowed($path)) { // check for permissions 169 | if ($this->isLogged()) { // if denied & logged, write a message 170 | if ($this->_flashmessage) { // message from the rule (accept path in %s) 171 | $this->Session->setFlash(sprintf(__($this->_flashmessage), $path), 'error'); // Set Flash message 172 | } 173 | 174 | $fw = $this->_forward ? $this->_forward : Configure::read('Authake.defaultDeniedAction'); 175 | $controller->redirect($fw); 176 | } else { // if denied & not loggued, propose to log in 177 | $this->setPreviousUrl($path); 178 | $strpath = Router::url($path + array("base" => false)); 179 | $this->Session->setFlash(sprintf(__('You have to log in to access %s'), $strpath), 'warning'); 180 | $controller->redirect($loginAction); 181 | } 182 | $this->_flashmessage = ''; 183 | } 184 | } 185 | 186 | /** 187 | * API functions 188 | */ 189 | function setPreviousUrl($url) { 190 | $this->Session->write('Authake.previousUrl', $url); 191 | } 192 | 193 | function getPreviousUrl() { 194 | return Router::reverse($this->Session->read('Authake.previousUrl')); 195 | } 196 | 197 | function isLogged() { 198 | return ($this->getUserId() !== null); 199 | } 200 | 201 | function getLogin() { 202 | return $this->Session->read('Authake.login'); 203 | } 204 | 205 | function getUserId() { 206 | return $this->Session->read('Authake.id'); 207 | } 208 | 209 | function getUserEmail() { 210 | return $this->Session->read('Authake.email'); 211 | } 212 | 213 | function getGroupIds() { 214 | $gid = $this->Session->read('Authake.group_ids'); 215 | return (empty($gid) ? null : $gid); //If not logged in (or no groups - return null) 216 | } 217 | 218 | function getGroupNames() { 219 | $gn = $this->Session->read('Authake.group_names'); 220 | return (is_array($gn) ? $gn : array(__('Guest'))); 221 | } 222 | 223 | function isMemberOf($gid) { 224 | return in_array($gid, $this->getGroupIds()); 225 | } 226 | 227 | function setTimestamp() { 228 | $ts = $this->Session->write('Authake.timestamp', time()); 229 | } 230 | 231 | function login($user) { 232 | $previousUrl = $this->Session->read("Authake.previousUrl"); 233 | $this->Session->write('Authake', $user); 234 | $this->Session->write("Authake.previousUrl", $previousUrl); 235 | $this->setTimestamp(); 236 | } 237 | 238 | function logout() { 239 | $this->Session->delete('Authake'); 240 | } 241 | 242 | function getRules($group_ids = null) { 243 | $force_reload = (time() - $this->Session->read('Authake.cacheRulesTime')) > Configure::read('Authake.rulesCacheTimeout'); 244 | 245 | if ($force_reload 246 | || is_array($group_ids) 247 | //|| ($cacheRules = $this->Session->read('Authake.cacheRules')) === null 248 | || $cacheRules = null === null 249 | ) { 250 | App::import("Model", "Authake.Rule"); 251 | $rule = new Rule; 252 | $cacheRules = $rule->getRules(is_array($group_ids) ? $group_ids : $this->getGroupIds(), true); // use groups provided or take groups of the users 253 | 254 | if ($group_ids === null) { // cache only if groups of user used 255 | $this->Session->write('Authake.cacheRules', $cacheRules); 256 | $this->Session->write('Authake.cacheRulesTime', time()); 257 | } 258 | } 259 | 260 | return $cacheRules; 261 | } 262 | 263 | // Function to check the access for the controller / action 264 | function isAllowed($url = "", $group_ids = null) { // $checkStr: "/name/action/" $group_ids: check again thess groups 265 | if (is_array($url)) { $url = $this->cleanUrl($url) ;} 266 | $allow = false; 267 | $rules = $this->getRules($group_ids); 268 | foreach ($rules as $data) { 269 | if (preg_match("/^({$data['Rule']['action']})$/i", $url, $matches)) { 270 | $allow = $data['Rule']['permission']; //echo $allow.'=>'.$url.' ** '.$data['Rule']['action']; 271 | //The Enum database type has to be changed to boolean, False for deny, True for allow 272 | if ($allow == false) { 273 | $allow = false; 274 | $this->_forward = $data['Rule']['forward']; 275 | $this->_flashmessage = $data['Rule']['message']; 276 | } else { 277 | $allow = true; 278 | } 279 | } 280 | } 281 | return $allow; 282 | } 283 | 284 | function getActionsPermissions($group_ids) { 285 | //pr(getcwd()); 286 | 287 | $controllers = $this->_getControllers(); 288 | $rules = $this->getRules($group_ids); 289 | $actionsList = array(); 290 | 291 | foreach ($controllers as $controller => $actions) { 292 | foreach ($actions as $k => $action) { 293 | $con = strtolower($controller); 294 | $permission = $this->_areGroupsAllowed("/{$con}/{$action}/", $rules); 295 | $actionsList[$controller][] = array('controller' => $con, 'action' => $action, 'permission' => $permission); 296 | } 297 | } 298 | 299 | return $actionsList; 300 | } 301 | 302 | function _getControllers($lowercase = false) {//http://www.cleverweb.nl/cakephp/list-all-controllers-in-cakephp-2/ 303 | $aCtrlClasses = App::objects('controller'); 304 | 305 | foreach ($aCtrlClasses as $controller) { 306 | if ($controller != 'AppController') { 307 | // Load the controller 308 | App::import('Controller', str_replace('Controller', '', $controller)); 309 | 310 | 311 | // Load its methods / actions 312 | $aMethods = get_class_methods($controller); 313 | 314 | foreach ($aMethods as $method => $idx) { 315 | 316 | if ($method{0} == '_') { 317 | unset($aMethods[$idx]); 318 | } 319 | } 320 | 321 | // Load the ApplicationController (if there is one) 322 | App::import('Controller', 'AppController'); 323 | $parentActions = get_class_methods('AppController'); 324 | 325 | $controllers[$controller] = array_diff($aMethods, $parentActions); 326 | } 327 | } 328 | return $controllers; 329 | } 330 | 331 | // Function to check the access for the controller / action 332 | function _areGroupsAllowed($url = "", $rules) { // $checkStr: "/name/action/" $group_ids: check again thess groups 333 | $allow = false; 334 | foreach ($rules as $data) { 335 | if (preg_match("/{$data['Rule']['action']}/i", $url, $matches)) { 336 | $allow = $data['Rule']['permission']; 337 | if ($allow == false) 338 | $allow = false; 339 | else 340 | $allow = true; 341 | } 342 | } 343 | return $allow; 344 | } 345 | 346 | private function cleanUrl($url) { 347 | $clurl = array_intersect_key($url, array("controller" => '', "action" => '', "prefix" => '', "admin" => '')); 348 | 349 | return Router::url($clurl + array("base" => false)); 350 | } 351 | 352 | } 353 | 354 | ?> 355 | -------------------------------------------------------------------------------- /View/Authake/help.ctp: -------------------------------------------------------------------------------- 1 | Html->addCrumb('Authake Help', $this->Html->url( null, true )); ?> 3 |
    4 |
    5 |
    6 |
    7 |

    Authake Help

    8 |
    9 |
    10 |

    Created by Mutlu Tevfik Koçak 2012, based on Authake Plugin. Other authors are: Nick Chankov, Jerome Combaz and many others.

    11 | 14 | 15 |

    20 Regular Expressions

    16 | 17 |

    20.1 Introduction

    18 | 19 |

    A regular expression is a domain specific language for matching text. Naively we could write a small program to match text, but this is error-prone, tedious and not very portable or flexible.

    20 | 21 |

    Instead we use regular expressions which describe the match as a string which (in a simple case) consists of the character types to match and quantifiers for how many times we want to have the character type matched.

    22 | 23 |

    For example normal letters and digits match literally. Something like \w will match word characters, where \s will match whitespace characters (space, tab, newline, etc.). The period (.) will match any character (except newline).

    24 | 25 |

    The basic quantifiers are the asterisk (*) to specify that the match should happen zero or more times, plus (+) for one or more times, or a range can be given as {min,max}.

    26 | 27 |

    This alone gives us capabilities like finding words (\w+) or finding an image tag with an alt argument (<img.*alt=".*">).

    28 | 29 |

    Matching longer text sequences is one thing, but often we are interested in the subset of the match. For example, in the above example we may want to replace the alt argument text. If we enclose part of the regular expression with parentheses, we capture that part in a variable that can be used in the replacement string. The format of the replacement string is described at the end of this section, but to refer to the first capture, we use $1, $2 for the second etc.

    30 | 31 |

    So to change the alt argument text we could search for (<img.*alt=").*(">) and replace that with $1Text Intentionally Removed$2.

    32 | 33 |

    Note that in the examples above .* is used. The asterisk operator is however greedy, meaning that it will match as many characters as possible (which still allow a match to occur), so often we want to change it to non-greedy by adding ?, making it .*?.

    34 | 35 |

    20.1.1 External Resources

    36 | 37 | 43 | 44 |

    20.2 Regular Expressions in TextMate

    45 | 46 |

    Here is a list of places where TextMate makes use of regular expressions:

    47 | 48 |
      49 |
    • Filtering which files should be shown in folder references (added to projects) is done by providing regular expressions.
    • 50 |
    • Find and Find in Project both allow regular expression replacements.
    • 51 |
    • Folding markers are found via regular expressions.
    • 52 |
    • Indentation calculations are based on regular expression matches.
    • 53 |
    • Language grammars are basically a tree (with cycles) that have regular expressions in each node.
    • 54 |
    • Snippets allow regular expression replacements to be applied to variables and (in realtime) mirrored placeholders.
    • 55 |
    56 | 57 |

    So needless to say, these play a big role in TextMate. While you can live a happy life without knowing about them, it is strongly recommended that you do pick up a book, tutorial or similar to get better acquainted with these (if you are not already).

    58 | 59 |

    In addition to TextMate, many common shell commands support regular expressions (sed, grep, awk, find) and popular scripting languages like Perl and Ruby have regular expressions ingrained deep into the language.

    60 | 61 |

    20.3 Syntax (Oniguruma)

    62 | 63 |

    TextMate uses the Oniguruma regular expression library by K. Kosako.

    64 | 65 |

    The following is taken from http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt.

    66 | 67 |
    Oniguruma Regular Expressions Version 5.6.0    2007/04/03
     68 | 
     69 | 	syntax: ONIG_SYNTAX_RUBY (default)
     70 | 
     71 | 
     72 | 	1. Syntax elements
     73 | 
     74 | 	  \       escape (enable or disable meta character meaning)
     75 | 	  |       alternation
     76 | 	  (...)   group
     77 | 	  [...]   character class  
     78 | 
     79 | 
     80 | 	2. Characters
     81 | 
     82 | 	  \t           horizontal tab (0x09)
     83 | 	  \v           vertical tab   (0x0B)
     84 | 	  \n           newline        (0x0A)
     85 | 	  \r           return         (0x0D)
     86 | 	  \b           back space     (0x08)
     87 | 	  \f           form feed      (0x0C)
     88 | 	  \a           bell           (0x07)
     89 | 	  \e           escape         (0x1B)
     90 | 	  \nnn         octal char            (encoded byte value)
     91 | 	  \xHH         hexadecimal char      (encoded byte value)
     92 | 	  \x{7HHHHHHH} wide hexadecimal char (character code point value)
     93 | 	  \cx          control char          (character code point value)
     94 | 	  \C-x         control char          (character code point value)
     95 | 	  \M-x         meta  (x|0x80)        (character code point value)
     96 | 	  \M-\C-x      meta control char     (character code point value)
     97 | 
     98 | 	 (* \b is effective in character class [...] only)
     99 | 
    100 | 
    101 | 	3. Character types
    102 | 
    103 | 	  .        any character (except newline)
    104 | 
    105 | 	  \w       word character
    106 | 
    107 | 	           Not Unicode:
    108 | 	             alphanumeric, "_" and multibyte char. 
    109 | 
    110 | 	           Unicode:
    111 | 	             General_Category -- (Letter|Mark|Number|Connector_Punctuation)
    112 | 
    113 | 	  \W       non word char
    114 | 
    115 | 	  \s       whitespace char
    116 | 
    117 | 	           Not Unicode:
    118 | 	             \t, \n, \v, \f, \r, \x20
    119 | 
    120 | 	           Unicode:
    121 | 	             0009, 000A, 000B, 000C, 000D, 0085(NEL), 
    122 | 	             General_Category -- Line_Separator
    123 | 	                              -- Paragraph_Separator
    124 | 	                              -- Space_Separator
    125 | 
    126 | 	  \S       non whitespace char
    127 | 
    128 | 	  \d       decimal digit char
    129 | 
    130 | 	           Unicode: General_Category -- Decimal_Number
    131 | 
    132 | 	  \D       non decimal digit char
    133 | 
    134 | 	  \h       hexadecimal digit char   [0-9a-fA-F]
    135 | 
    136 | 	  \H       non hexadecimal digit char
    137 | 
    138 | 
    139 | 	  Character Property
    140 | 
    141 | 	    * \p{property-name}
    142 | 	    * \p{^property-name}    (negative)
    143 | 	    * \P{property-name}     (negative)
    144 | 
    145 | 	    property-name:
    146 | 
    147 | 	     + works on all encodings
    148 | 	       Alnum, Alpha, Blank, Cntrl, Digit, Graph, Lower,
    149 | 	       Print, Punct, Space, Upper, XDigit, Word, ASCII,
    150 | 
    151 | 	     + works on EUC_JP, Shift_JIS
    152 | 	       Hiragana, Katakana
    153 | 
    154 | 	     + works on UTF8, UTF16, UTF32
    155 | 	       Any, Assigned, C, Cc, Cf, Cn, Co, Cs, L, Ll, Lm, Lo, Lt, Lu,
    156 | 	       M, Mc, Me, Mn, N, Nd, Nl, No, P, Pc, Pd, Pe, Pf, Pi, Po, Ps,
    157 | 	       S, Sc, Sk, Sm, So, Z, Zl, Zp, Zs, 
    158 | 	       Arabic, Armenian, Bengali, Bopomofo, Braille, Buginese,
    159 | 	       Buhid, Canadian_Aboriginal, Cherokee, Common, Coptic,
    160 | 	       Cypriot, Cyrillic, Deseret, Devanagari, Ethiopic, Georgian,
    161 | 	       Glagolitic, Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul,
    162 | 	       Hanunoo, Hebrew, Hiragana, Inherited, Kannada, Katakana,
    163 | 	       Kharoshthi, Khmer, Lao, Latin, Limbu, Linear_B, Malayalam,
    164 | 	       Mongolian, Myanmar, New_Tai_Lue, Ogham, Old_Italic, Old_Persian,
    165 | 	       Oriya, Osmanya, Runic, Shavian, Sinhala, Syloti_Nagri, Syriac,
    166 | 	       Tagalog, Tagbanwa, Tai_Le, Tamil, Telugu, Thaana, Thai, Tibetan,
    167 | 	       Tifinagh, Ugaritic, Yi
    168 | 
    169 | 
    170 | 
    171 | 	4. Quantifier
    172 | 
    173 | 	  greedy
    174 | 
    175 | 	    ?       1 or 0 times
    176 | 	    *       0 or more times
    177 | 	    +       1 or more times
    178 | 	    {n,m}   at least n but not more than m times
    179 | 	    {n,}    at least n times
    180 | 	    {,n}    at least 0 but not more than n times ({0,n})
    181 | 	    {n}     n times
    182 | 
    183 | 	  reluctant
    184 | 
    185 | 	    ??      1 or 0 times
    186 | 	    *?      0 or more times
    187 | 	    +?      1 or more times
    188 | 	    {n,m}?  at least n but not more than m times  
    189 | 	    {n,}?   at least n times
    190 | 	    {,n}?   at least 0 but not more than n times (== {0,n}?)
    191 | 
    192 | 	  possessive (greedy and does not backtrack after repeated)
    193 | 
    194 | 	    ?+      1 or 0 times
    195 | 	    *+      0 or more times
    196 | 	    ++      1 or more times
    197 | 
    198 | 	    ({n,m}+, {n,}+, {n}+ are possessive op. in ONIG_SYNTAX_JAVA only)
    199 | 
    200 | 	    ex. /a*+/ === /(?>a*)/
    201 | 
    202 | 
    203 | 	5. Anchors
    204 | 
    205 | 	  ^       beginning of the line
    206 | 	  $       end of the line
    207 | 	  \b      word boundary
    208 | 	  \B      not word boundary
    209 | 	  \A      beginning of string
    210 | 	  \Z      end of string, or before newline at the end
    211 | 	  \z      end of string
    212 | 	  \G      matching start position 
    213 | 
    214 | 
    215 | 	6. Character class
    216 | 
    217 | 	  ^...    negative class (lowest precedence operator)
    218 | 	  x-y     range from x to y
    219 | 	  [...]   set (character class in character class)
    220 | 	  ..&&..  intersection (low precedence at the next of ^)
    221 | 
    222 | 	    ex. [a-w&&[^c-g]z] ==> ([a-w] AND ([^c-g] OR z)) ==> [abh-w]
    223 | 
    224 | 	  * If you want to use '[', '-', ']' as a normal character
    225 | 	    in a character class, you should escape these characters by '\'.
    226 | 
    227 | 
    228 | 	  POSIX bracket ([:xxxxx:], negate [:^xxxxx:])
    229 | 
    230 | 	    Not Unicode Case:
    231 | 
    232 | 	      alnum    alphabet or digit char
    233 | 	      alpha    alphabet
    234 | 	      ascii    code value: [0 - 127]
    235 | 	      blank    \t, \x20
    236 | 	      cntrl
    237 | 	      digit    0-9
    238 | 	      graph    include all of multibyte encoded characters
    239 | 	      lower
    240 | 	      print    include all of multibyte encoded characters
    241 | 	      punct
    242 | 	      space    \t, \n, \v, \f, \r, \x20
    243 | 	      upper
    244 | 	      xdigit   0-9, a-f, A-F
    245 | 	      word     alphanumeric, "_" and multibyte characters
    246 | 
    247 | 
    248 | 	    Unicode Case:
    249 | 
    250 | 	      alnum    Letter | Mark | Decimal_Number
    251 | 	      alpha    Letter | Mark
    252 | 	      ascii    0000 - 007F
    253 | 	      blank    Space_Separator | 0009
    254 | 	      cntrl    Control | Format | Unassigned | Private_Use | Surrogate
    255 | 	      digit    Decimal_Number
    256 | 	      graph    [[:^space:]] && ^Control && ^Unassigned && ^Surrogate
    257 | 	      lower    Lowercase_Letter
    258 | 	      print    [[:graph:]] | [[:space:]]
    259 | 	      punct    Connector_Punctuation | Dash_Punctuation | Close_Punctuation |
    260 | 	               Final_Punctuation | Initial_Punctuation | Other_Punctuation |
    261 | 	               Open_Punctuation
    262 | 	      space    Space_Separator | Line_Separator | Paragraph_Separator |
    263 | 	               0009 | 000A | 000B | 000C | 000D | 0085
    264 | 	      upper    Uppercase_Letter
    265 | 	      xdigit   0030 - 0039 | 0041 - 0046 | 0061 - 0066
    266 | 	               (0-9, a-f, A-F)
    267 | 	      word     Letter | Mark | Decimal_Number | Connector_Punctuation
    268 | 
    269 | 
    270 | 
    271 | 	7. Extended groups
    272 | 
    273 | 	  (?#...)            comment
    274 | 
    275 | 	  (?imx-imx)         option on/off
    276 | 	                         i: ignore case
    277 | 	                         m: multi-line (dot(.) match newline)
    278 | 	                         x: extended form
    279 | 	  (?imx-imx:subexp)  option on/off for subexp
    280 | 
    281 | 	  (?:subexp)         not captured group
    282 | 	  (subexp)           captured group
    283 | 
    284 | 	  (?=subexp)         look-ahead
    285 | 	  (?!subexp)         negative look-ahead
    286 | 	  (?<=subexp)        look-behind
    287 | 	  (?<!subexp)        negative look-behind
    288 | 
    289 | 	                     Subexp of look-behind must be fixed character length.
    290 | 	                     But different character length is allowed in top level
    291 | 	                     alternatives only.
    292 | 	                     ex. (?<=a|bc) is OK. (?<=aaa(?:b|cd)) is not allowed.
    293 | 
    294 | 	                     In negative-look-behind, captured group isn't allowed, 
    295 | 	                     but shy group(?:) is allowed.
    296 | 
    297 | 	  (?>subexp)         atomic group
    298 | 	                     don't backtrack in subexp.
    299 | 
    300 | 	  (?<name>subexp), (?'name'subexp)
    301 | 	                     define named group
    302 | 	                     (All characters of the name must be a word character.)
    303 | 
    304 | 	                     Not only a name but a number is assigned like a captured
    305 | 	                     group.
    306 | 
    307 | 	                     Assigning the same name as two or more subexps is allowed.
    308 | 	                     In this case, a subexp call can not be performed although
    309 | 	                     the back reference is possible.
    310 | 
    311 | 
    312 | 	8. Back reference
    313 | 
    314 | 	  \n          back reference by group number (n >= 1)
    315 | 	  \k<name>    back reference by group name
    316 | 	  \k'name'    back reference by group name
    317 | 
    318 | 	  In the back reference by the multiplex definition name,
    319 | 	  a subexp with a large number is referred to preferentially.
    320 | 	  (When not matched, a group of the small number is referred to.)
    321 | 
    322 | 	  * Back reference by group number is forbidden if named group is defined 
    323 | 	    in the pattern and ONIG_OPTION_CAPTURE_GROUP is not setted.
    324 | 
    325 | 
    326 | 	  back reference with nest level
    327 | 
    328 | 	    \k<name+n>     n: 0, 1, 2, ...
    329 | 	    \k<name-n>     n: 0, 1, 2, ...
    330 | 	    \k'name+n'     n: 0, 1, 2, ...
    331 | 	    \k'name-n'     n: 0, 1, 2, ...
    332 | 
    333 | 	    Destinate relative nest level from back reference position.    
    334 | 
    335 | 	    ex 1.
    336 | 
    337 | 	      /\A(?<a>|.|(?:(?<b>.)\g<a>\k<b+0>))\z/.match("reer")
    338 | 
    339 | 	    ex 2.
    340 | 
    341 | 	      r = Regexp.compile(<<'__REGEXP__'.strip, Regexp::EXTENDED)
    342 | 	      (?<element> \g<stag> \g<content>* \g<etag> ){0}
    343 | 	      (?<stag> < \g<name> \s* > ){0}
    344 | 	      (?<name> [a-zA-Z_:]+ ){0}
    345 | 	      (?<content> [^<&]+ (\g<element> | [^<&]+)* ){0}
    346 | 	      (?<etag> </ \k<name+1> >){0}
    347 | 	      \g<element>
    348 | 	      __REGEXP__
    349 | 
    350 | 	      p r.match('<foo>f<bar>bbb</bar>f</foo>').captures
    351 | 
    352 | 
    353 | 
    354 | 	9. Subexp call ("Tanaka Akira special")
    355 | 
    356 | 	  \g<name>    call by group name
    357 | 	  \g'name'    call by group name
    358 | 	  \g<n>       call by group number (n >= 1)
    359 | 	  \g'n'       call by group number (n >= 1)
    360 | 
    361 | 	  * left-most recursive call is not allowed.
    362 | 	     ex. (?<name>a|\g<name>b)   => error
    363 | 	         (?<name>a|b\g<name>c)  => OK
    364 | 
    365 | 	  * Call by group number is forbidden if named group is defined in the pattern
    366 | 	    and ONIG_OPTION_CAPTURE_GROUP is not setted.
    367 | 
    368 | 	  * If the option status of called group is different from calling position
    369 | 	    then the group's option is effective.
    370 | 
    371 | 	    ex. (?-i:\g<name>)(?i:(?<name>a)){0}  match to "A"
    372 | 
    373 | 
    374 | 	10. Captured group
    375 | 
    376 | 	  Behavior of the no-named group (...) changes with the following conditions.
    377 | 	  (But named group is not changed.)
    378 | 
    379 | 	  case 1. /.../     (named group is not used, no option)
    380 | 
    381 | 	     (...) is treated as a captured group.
    382 | 
    383 | 	  case 2. /.../g    (named group is not used, 'g' option)
    384 | 
    385 | 	     (...) is treated as a no-captured group (?:...).
    386 | 
    387 | 	  case 3. /..(?<name>..)../   (named group is used, no option)
    388 | 
    389 | 	     (...) is treated as a no-captured group (?:...).
    390 | 	     numbered-backref/call is not allowed.
    391 | 
    392 | 	  case 4. /..(?<name>..)../G  (named group is used, 'G' option)
    393 | 
    394 | 	     (...) is treated as a captured group.
    395 | 	     numbered-backref/call is allowed.
    396 | 
    397 | 	  where
    398 | 	    g: ONIG_OPTION_DONT_CAPTURE_GROUP
    399 | 	    G: ONIG_OPTION_CAPTURE_GROUP
    400 | 
    401 | 	  ('g' and 'G' options are argued in ruby-dev ML)
    402 | 
    403 | 
    404 | 
    405 | 	-----------------------------
    406 | 	A-1. Syntax depend options
    407 | 
    408 | 	   + ONIG_SYNTAX_RUBY
    409 | 	     (?m): dot(.) match newline
    410 | 
    411 | 	   + ONIG_SYNTAX_PERL and ONIG_SYNTAX_JAVA
    412 | 	     (?s): dot(.) match newline
    413 | 	     (?m): ^ match after newline, $ match before newline
    414 | 
    415 | 
    416 | 	A-2. Original extensions
    417 | 
    418 | 	   + hexadecimal digit char type  \h, \H
    419 | 	   + named group                  (?<name>...), (?'name'...)
    420 | 	   + named backref                \k<name>
    421 | 	   + subexp call                  \g<name>, \g<group-num>
    422 | 
    423 | 
    424 | 	A-3. Lacked features compare with perl 5.8.0
    425 | 
    426 | 	   + \N{name}
    427 | 	   + \l,\u,\L,\U, \X, \C
    428 | 	   + (?{code})
    429 | 	   + (??{code})
    430 | 	   + (?(condition)yes-pat|no-pat)
    431 | 
    432 | 	   * \Q...\E
    433 | 	     This is effective on ONIG_SYNTAX_PERL and ONIG_SYNTAX_JAVA.
    434 | 
    435 | 
    436 | 	A-4. Differences with Japanized GNU regex(version 0.12) of Ruby 1.8
    437 | 
    438 | 	   + add character property (\p{property}, \P{property})
    439 | 	   + add hexadecimal digit char type (\h, \H)
    440 | 	   + add look-behind
    441 | 	     (?<=fixed-char-length-pattern), (?<!fixed-char-length-pattern)
    442 | 	   + add possessive quantifier. ?+, *+, ++
    443 | 	   + add operations in character class. [], &&
    444 | 	     ('[' must be escaped as an usual char in character class.)
    445 | 	   + add named group and subexp call.
    446 | 	   + octal or hexadecimal number sequence can be treated as 
    447 | 	     a multibyte code char in character class if multibyte encoding
    448 | 	     is specified.
    449 | 	     (ex. [\xa1\xa2], [\xa1\xa7-\xa4\xa1])
    450 | 	   + allow the range of single byte char and multibyte char in character
    451 | 	     class.
    452 | 	     ex. /[a-<<any EUC-JP character>>]/ in EUC-JP encoding.
    453 | 	   + effect range of isolated option is to next ')'.
    454 | 	     ex. (?:(?i)a|b) is interpreted as (?:(?i:a|b)), not (?:(?i:a)|b).
    455 | 	   + isolated option is not transparent to previous pattern.
    456 | 	     ex. a(?i)* is a syntax error pattern.
    457 | 	   + allowed incompleted left brace as an usual string.
    458 | 	     ex. /{/, /({)/, /a{2,3/ etc...
    459 | 	   + negative POSIX bracket [:^xxxx:] is supported.
    460 | 	   + POSIX bracket [:ascii:] is added.
    461 | 	   + repeat of look-ahead is not allowed.
    462 | 	     ex. /(?=a)*/, /(?!b){5}/
    463 | 	   + Ignore case option is effective to numbered character.
    464 | 	     ex. /\x61/i =~ "A"
    465 | 	   + In the range quantifier, the number of the minimum is omissible.
    466 | 	     /a{,n}/ == /a{0,n}/
    467 | 	     The simultanious abbreviation of the number of times of the minimum
    468 | 	     and the maximum is not allowed. (/a{,}/)
    469 | 	   + /a{n}?/ is not a non-greedy operator.
    470 | 	     /a{n}?/ == /(?:a{n})?/
    471 | 	   + invalid back reference is checked and cause error.
    472 | 	     /\1/, /(a)\2/
    473 | 	   + Zero-length match in infinite repeat stops the repeat,
    474 | 	     then changes of the capture group status are checked as stop condition.
    475 | 	     /(?:()|())*\1\2/ =~ ""
    476 | 	     /(?:\1a|())*/ =~ "a"
    477 | 
    478 | 
    479 | 	A-5. Disabled functions by default syntax
    480 | 
    481 | 	   + capture history
    482 | 
    483 | 	     (?@...) and (?@<name>...)
    484 | 
    485 | 	     ex. /(?@a)*/.match("aaa") ==> [<0-1>, <1-2>, <2-3>]
    486 | 
    487 | 	     see sample/listcap.c file.
    488 | 
    489 | 
    490 | 	A-6. Problems
    491 | 
    492 | 	   + Invalid encoding byte sequence is not checked in UTF-8.
    493 | 
    494 | 	     * Invalid first byte is treated as a character.
    495 | 	       /./u =~ "\xa3"
    496 | 
    497 | 	     * Incomplete byte sequence is not checked.
    498 | 	       /\w+/ =~ "a\xf3\x8ec"
    499 | 
    500 | 	// END
    501 | 	
    502 | 503 |

    20.4 Replacement String Syntax (Format Strings)

    504 | 505 |

    When you perform a regular expression replace, the replace string is interpreted as a format string which can reference captures, perform case foldings, do conditional insertions (based on capture registers) and support a minimal amount of escape sequences.

    506 | 507 |

    20.4.1 Captures

    508 | 509 |

    To reference a capture, use $n where n is the capture register number. Using $0 means the entire match.

    510 | 511 |

    Example:

    512 | 513 |
       Find: <img src="(.*?)">
    514 | 					Replace: <img src="$1" alt="$1">
    515 | 					
    516 | 517 |

    20.4.2 Case Foldings

    518 | 519 |

    It is possible to convert the next character to upper or lowercase by prepending it with \u or \l. This is mainly useful when the next character stems from a capture register. Example:

    520 | 521 |
       Find: (<a.*?>)(.*?)(</a>)
    522 | 					Replace: $1\u$2$3
    523 | 					
    524 | 525 |

    You can also convert a longer sequence to upper or lowercase by using \U or \L and then \E to disable the case folding again. Example:

    526 | 527 |
       Find: (<a.*?>)(.*?)(</a>)
    528 | 					Replace: $1\U$2\E$3
    529 | 					
    530 | 531 |

    20.4.3 Conditional Insertions

    532 | 533 |

    There are times where the replacements depends on whether or not something was matched. This can be done using (?«n»:«insertion») to insert «insertion» if capture «n» was matched. You can also use (?«n»:«insertion»:«otherwise») to have «otherwise» inserted when capture «n» was not matched.

    534 | 535 |

    To make a capture conditional either place it in an alternation, e.g. foo|(bar)|fud or append a question mark to it: (bar)?. Note that (.*) will result in a match, even when zero characters are matched, so use (.+)? instead.

    536 | 537 |

    So for example if we wish to truncate text to eight words and insert ellipsis only if there were more than eight words, we can use:

    538 | 539 |
       Find: (\w+(?:\W+\w+){,7})\W*(.+)?
    540 | 					Replace: $1(?2:…)
    541 | 					
    542 | 543 |

    Here we first match a word (\w+) followed by up to seven words ((?:\W+\w+){,7}) each preceded by non-word characters (spacing). Then optionally put anything following that (separated by non-word characters) into capture register 2 ((.+)?).

    544 | 545 |

    The replacement first inserts the (up to) eight words matched ($1) and then only if capture 2 matched something, ellipsis ((?2:…)).

    546 | 547 |

    20.4.4 Escape Codes

    548 | 549 |

    In addition to the case folding escape codes, you can insert a newline character with \n, a tab character with \t and a dollar sign with \$.

    550 |
    551 | 552 |
    553 |
    554 |
    --------------------------------------------------------------------------------