<?php
namespace Croogo\Acl\Controller\Component;
use Cake\Controller\Component;
use Cake\Controller\Component\AuthComponent;
use Cake\Core\Configure;
use Cake\Event\Event;
use Cake\ORM\TableRegistry;
use Croogo\Core\Croogo;
use Croogo\Core\Utility\StringConverter;
/**
* AclFilter Component
*
* @category Component
* @package Croogo.Acl.Controller.Component
* @version 1.0
* @author Fahad Ibnay Heylaal <contact@fahad19.com>
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
* @link http://www.croogo.org
*/
class FilterComponent extends Component
{
/**
* _controller
*
* @var Controller
*/
protected $_controller = null;
/**
* beforeFilter
*
* @param Event $event instance of event
* @return void
*/
public function beforeFilter(Event $event)
{
$this->_controller = $event->getSubject();
if ($this->_config('multiRole')) {
Croogo::hookAdminTab('Admin/Users/add', 'Roles', 'Croogo/Acl.admin/roles');
Croogo::hookAdminTab('Admin/Users/edit', 'Roles', 'Croogo/Acl.admin/roles');
}
}
/**
* Helper function to retrieve value from `Access Control` settings
*
* @return mixed null when config key is not found
*/
protected function _config($key)
{
static $config = null;
if (empty($config)) {
$config = Configure::read('Access Control');
}
if (array_key_exists($key, (array)$config)) {
return $config[$key];
}
return null;
}
/**
* configure component settings
*
* @return void
*/
protected function _configure()
{
if (!$this->_registry->has('Croogo/Acl.AutoLogin')) {
$this->_registry->load('Croogo/Acl.AutoLogin');
if (!$this->_registry->has('Cookie')) {
$this->_registry->load('Cookie');
}
}
//Configure AuthComponent
$this->_controller->Auth->setConfig('authenticate', [
AuthComponent::ALL => [
'userModel' => 'Croogo/Users.Users',
'fields' => [
'username' => 'username',
'password' => 'password',
],
'passwordHasher' => [
'className' => 'Fallback',
'hashers' => ['Default', 'Weak']
],
'finder' => 'authUser',
],
]);
if ($this->_config('autoLoginDuration')) {
if (!function_exists('mcrypt_encrypt') && !function_exists('openssl_encrypt')) {
$notice = __d('croogo', '"AutoLogin" (Remember Me) disabled since mcrypt_encrypt or openssl_encrypt is not available');
$this->log($notice, LOG_CRIT);
if ($this->_controller->request->getParam('prefix') == 'admin') {
$this->_controller->Flash->error($notice);
}
if (isset($this->_controller->Settings)) {
$Setting = $this->_controller->Settings;
} else {
$Setting = TableRegistry::get('Croogo/Settings.Settings');
}
$Setting->write('Access Control.autoLoginDuration', '');
}
$this->_controller->Auth->setConfig('authenticate', ['Croogo/Acl.Cookie']);
}
if ($this->_config('multiColumn')) {
$this->_controller->Auth->setConfig('authenticate', ['Croogo/Acl.MultiColumn']);
} else {
$this->_controller->Auth->setConfig('authenticate', ['Form']);
}
$this->_controller->Auth->setConfig('authorize', [
AuthComponent::ALL => [
'actionPath' => 'controllers',
'userModel' => 'Croogo/Users.Users',
],
'Croogo/Acl.AclCached' => [
'actionPath' => 'controllers',
]
]);
if ($this->_controller->request->getParam('prefix') == 'admin' &&
!$this->_controller->Auth->user()) {
$this->_controller->Auth->setConfig('authError', false);
}
$this->configureLoginActions();
}
/**
* Load login actions configurations
*
* @return void
*/
public function configureLoginActions()
{
$this->_controller->Auth->setConfig('loginAction', [
'prefix' => false,
'plugin' => 'Croogo/Users',
'controller' => 'Users',
'action' => 'login',
]);
if ($this->request->getParam('prefix') === 'admin') {
$this->_controller->Auth->setConfig('loginAction', [
'prefix' => 'admin',
'plugin' => 'Croogo/Users',
'controller' => 'Users',
'action' => 'login',
]);
}
$this->_controller->Auth->setConfig('logoutRedirect', [
'plugin' => 'Croogo/Users',
'controller' => 'Users',
'action' => 'login',
]);
if ($this->request->getParam('prefix') == 'admin') {
$dashboardUrl = Configure::read('Site.dashboard_url');
if (is_string($dashboardUrl)) {
$converter = new StringConverter();
$dashboardUrl = $converter->linkStringToArray($dashboardUrl);
}
$loginRedirect = $dashboardUrl ?: '/admin';
$this->_controller->Auth->setConfig('loginRedirect', $loginRedirect);
} else {
$loginRedirect = Configure::read('Croogo.homeUrl') ?: '/';
$this->_controller->Auth->setConfig('loginRedirect', $loginRedirect);
}
if ($this->_controller->request->is('ajax')) {
$this->_controller->Auth->setConfig('unauthorizedRedirect', false);
} else {
$this->_controller->Auth->setConfig('unauthorizedRedirect', [
'plugin' => 'Croogo/Users',
'controller' => 'Users',
'action' => 'login',
]);
}
$config = Configure::read('Acl');
if (!empty($config['Auth']) && is_array($config['Auth'])) {
$isAdminRequest = !empty($this->_controller->request->getParam('admin'));
$authActions = [
'loginAction',
'loginRedirect',
'logoutRedirect',
'unauthorizedRedirect',
];
foreach ($config['Auth'] as $property => $value) {
$isAdminRoute = !empty($value['admin']);
$isAuthAction = in_array($property, $authActions);
if (!is_string($value) && $isAdminRequest !== $isAdminRoute && $isAuthAction) {
continue;
}
$this->_controller->Auth->config($property, $value);
}
}
}
/**
* acl and auth
*
* @return void
*/
public function auth()
{
$this->_configure();
$user = $this->_controller->Auth->user();
// authorization for authenticated user is handled by authorize object
if ($user) {
return;
}
$authorizer = $this->_controller->Auth->getAuthorize('Croogo/Acl.AclCached');
if ($this->_controller->Acl->check('Role-public', $authorizer->action($this->_controller->request))) {
$this->_controller->Auth->allow(
$this->_controller->request->getParam('action')
);
}
}
}