CakePhp ACL permissions - cakephp

Checking my application, I saw that every user can access to all the actions in it.
I'm using cakePhp build-in ACL Component...
Checking permissions through terminal displays correctly is the user is allowed or not to call a certain action. But once I'm checking the application on the browser all users have access to every action. Any clue what could be doing this?

You can have CakePHP automatically handle things for you if you're using the built-in Auth and ACL components. To start, you can make sure you have an app_controller.php file in the App folder. Mine looks something like this:
<?php
class AppController extends Controller {
var $helpers = array('Form', 'Html', 'Javascript', 'Time');
var $components = array( 'Acl', 'Auth', 'Session', 'Cookie');
function beforeFilter() {
$this->Auth->authorize = 'actions';
$this->Auth->actionPath = 'controllers/';
$this->Auth->authError = ' Access Denied!';
$this->Auth->loginRedirect = '/registrations';
$this->__checkAuth();
}
private function __checkAuth() {
$currentUser = $this->Auth->user();
$currentUser = $currentUser['User'];
$this->set(compact('currentUser'));
}
}
?>
If you're authorizing 'actions' then try including that code in your app_controller.php file, or create one if you don't already have one. Then start browsing to see if it has made any changes.
If you have custom code in each controller's beforeFilter, you'll also need to add a single line of code to each controller.
function beforeFilter(){
parent::beforeFilter();
}
Any beforeFilter (even a blank one) placed in a controller will override the beforeFilter of the AppController unless you specifically call the AppController's beforeFilter using the code above.
You can also find some of the best tutorials on using CakePHP's ACL here: http://aranworld.com/article/161/cakephp-acl-tutorial-what-is-it

Related

CakePHP mapping HTTP request to the correct action

I have been trying to set up RESTful functionality in my app and I face a problem of whatever action I call it is router to that particular controllers index action. I have been trying to call add and view actions, but they are just not being routed properly. Here is the resposne I get when trying to call the view action:
{"code":404,"url":"\/application\/rest_customers\/54.json","name":"Action RestCustomersController::54() could not be found."}
And here is the way it is all set up in. RestCustomersController:
class RestCustomersController extends AppController {
public $uses = array('Customer');
public $helpers = array('Html', 'Form');
public $components = array('RequestHandler');
public function index() {
}
public function view($id=null){
$customer = $this->Customer->find('first', array(
'conditions'=>array('Customer.id'=> $id)));
$this->set(array(
'customer' => $customer,
'_serialize' => array('customer')
)); }}
Here are the routes:
Router::mapResources('customers');
Router::parseExtensions('json', 'xml', 'csv', 'pdf');
And here os the AppControllers beforeFitler function:
if(in_array($this->params['controller'], array('rest_customers'))){
$this->Auth->allow();
$this->Security->unlockedActions = array('add','index', 'view');
}else{
$this->Security->unlockedActions = array('add', 'edit');
$this->Auth->allow('index', 'view');
$this->set('logged_in', $this->Auth->loggedIn());
$this->set('current_user', $this->Auth->user());
}}
Any help is very much appreciated.
You are creating REST routes for a controller named Customers, but you are actually accessing a controller named RestCustomers, so what you are experiencing is the expected behavior as there simply are no REST routes connected for the RestCustomers controller.
You should either rename your controller to CustomersController, or change your mapping to use the correct name so that it will connect the routes to RestCustomersController
Router::mapResources('rest_customers');

CakePHP 2 Basic Auth Authentication

I am moving from CakePHP 1.3 to CakePHP 2.2.2 and want to use Basic Http authentication for a simple admin area. I am just not able to make it work and I am thinking that I understood something wrong in the documentation.
From the documentation I understood I have to do something like
public $components = array(
'Auth' => array(
'authenticate' => array(
'Basic'
),
'authError' => 'You may not access this area.',
'authorize' => array('Controller')
)
);
I understand that further I need to extend the BaseAuthenticate Component to return valid user date but even with the above configuration I would expect that the browser's Http Access Dialog would open up in a popup window. But nothing like this happens, instead I am redirected to /users/login which does not exist. Why do I need a login view for Http Access? I am confused.
Add the Auth component to your controller (or to the AppController)
class ThingsController extends AppController {
var $components = array('Auth');
}
CakePHP requires a login action, so even if you use Basic authentication, where the HTTP agent is responsible for the UI to collect authentication details, you need to designate an action in some controller which will handle the login (in the Basic case, it will send the WWW-Authenticate: Basic header if the user is not authenticated yet).
You can set the AuthCompoment's $loginAction, but this defaults (and is advisable not to break conventions) to the login method in the UsersController. So, first create an empty template at View/Users/login.ctp, then add the following to your UsersController
class UsersController extends AppController {
public $components = array(
'Session',
'Auth' => array(
'authenticate' => array('Basic')
)
);
public function login() {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash('Not able to login');
}
}
public function logout() {
$this->redirect($this->Auth->logout());
}
}

Why isAuthorized() is never called when running Controller tests?

Im trying to test authorization in one of my controllers to make sure that only certains kind of user can access some actions. But the isAuthorized() method on AppController is never called when running tests. This is how the method looks like:
public function isAuthorized($user = null){
if(!isset($this->request->params['admin'])){
return true;
}
return in_array($user['role'], array('admin', 'root'));
}
My test function:
public function testArticlesIndex() {
$this->generate('Articles', array(
'components' => array('Auth')
));
$this->testAction('/admin/articles', array('return' => 'view'));
$this->assertEmpty($this->view);
}
I tried a lot of stuff mocking AuthComponent and not mocking it. I couldnt get a way to reproduce this situation, which would require isAuthorized(), where a user with a role other than admin or root tries to access an action on admin and fails.
When you mock the Auth component without defining what methods to mock, by default, all methods are mocked. The solution would be to mock the particular AuthComponent method you wish to mock:
$this->generate('Articles', array(
'components' => array(
'Auth' => array(
'redirect' // only mocks AuthComponent::redirect()
)
)
));
From the book:
You can choose to stub an entire class by not passing methods to it,
like Session in the example above.
See: http://book.cakephp.org/2.0/en/development/testing.html#using-mocks-with-testaction

CakePHP Auth Deny Admin Routing Pages

I have been reading Stack Overflow questions all afternoon trying to figure this out..
I have a users controller with index/login/logout/register functions but also has admin_index/admin_add/admin_edit/admin_delete etc.
I have Auth component enabled and in my users_controller i am trying to deny access to the admin_* pages if the Auth.User.role != 'admin', when i enable the $this->Auth->authorize = 'controller'; it denies access to the site.com/admin/users/ page and also seems to kill the logout function even tho my account has the role set to admin.
However if i type the url in i get redirected back to the main homepage.
users_controller.php
<?php
class UsersController extends AppController {
var $name = 'Users';
function beforeFilter(){
parent::beforeFilter();
$this->Auth->authorize = 'controller';
$this->Auth->allow('register');
}
function isAuthorized() {
if ($this->Auth->user('role') != 'admin') {
$this->Auth->deny('admin_index','admin_view', 'admin_add', 'admin_edit','admin_delete');
}
}
app_controller.php
<?php
class AppController extends Controller {
var $components = array('Auth', 'Session');
function beforeFilter() {
$this->Auth->loginAction = array('controller'=>'users','action'=>'login', 'admin'=>false);
$this->Auth->logoutRedirect = array('controller'=>'users','action'=>'logout');
$this->Auth->loginRedirect = array('controller'=>'shows', 'action'=>'index');
$this->Auth->autoRedirect = false;
$this->Auth->allow('home');
}
My Second question relates to the way $this->Auth->deny('page'); redirects the user, as far as i can tell it redirects to / but i need it to redirect back to the users controller.
Hope it all makes sense and i have provided enough info..
The root of your problem is probably your isAuthorized() method. This should simply return true or false, and indicates whether an authenticated user is AUTHORIZED to access a particular action.
It's difficult to say why you'd be redirected to the home page instead of the login page. But it's possible that you have other code somewhere that's messing things up.
Try modifying your code as below and see if that doesn't help get things working:
app_controller.php
<?php
class AppController extends Controller {
var $components = array('Session', 'Auth' => array(
'loginAction' => array('controller'=>'users','action'=>'login', 'admin'=>false),
'logoutRedirect' => array('controller'=>'users','action'=>'logout'),
'loginRedirect' => array('controller'=>'shows', 'action'=>'index'),
'autoRedirect' => false,
'authorize' => 'controller'
);
function beforeFilter() {
$this->Auth->allow('home');
}
function isAuthorized() {
if (!empty($this->params['prefix']) && $this->params['prefix'] == 'admin') {
if ($this->Auth->user('role') != 'admin') {
return false;
}
}
return true;
}
?>
users_controller.php
<?php
class UsersController extends AppController {
var $name = 'Users';
function beforeFilter(){
parent::beforeFilter();
$this->Auth->allow('register');
}
?>
I moved all the Auth settings to the declaration in the $components variable because it seems cleaner and to make more sense to declare default values there. But this is more a matter of personal preference and it shouldn't have a real effect on the code's functioning.
Also, note that if you set autoRedirect to false, you'll have to redirect logged-in users manually in your Users::login() action, getting the loginRedirect value with $this->Auth->redirect().
I don't see any reason why you should be sent to / when you're not logged in and you try to access a blocked action, but maybe it will be easier to figure out after you fix the above. **
you should do this like...
function beforeFilter()
{
if($this->Auth->user('role')=='admin'){
$this->Auth->allow('admin_view','admin_controls');//put your all admin actions separated by comma
}
else
{
$this->Auth->allow('home');//put your all non-admin actions separated by comma
}
}
hope it will work... if any problem let me know....

Why CakePHP 2.0 is not using my AppController?

I have just upgraded to Cakephp 2.0 alpha, and immediately faced a problem. The app_controller.php in the app/ folder is not loaded in my controllers. Instead controllers use the CakePHP own AppController.php in the lib/Cake/Controller/AppController.php.
I have tried renaming the app_controller to AppController.php aswell but its not working. I have tried deleting the whole file and then copying the lib/Cake/Controller/AppController.php file and then editing it but not working.
I have also tried deleting cache files.
I just simply use:
class AppController extends Controller {
public function beforeFilter() {
die;
}
}
And the application wont die.
My controller is also simply just:
class NewsController extends AppController {
function beforeFilter() {
parent::beforeFilter();
}
function index() {
}
}
So what I could be doing wrong? Im also using Windows 7 + Netbeans with Subversion to update project (if that has anything to do with it :p).
Did much of searching and didn't look from most obvious place: Github cakephp docs: https://github.com/cakephp/docs/blob/master/en/controllers.rst . I thought they were still 1.3 docs but it appears they are updated. Since they are now updated, it says that I should put the old app_controller.php into Controller folder and camel case it to AppController.php.
Create file AppController.php in app/Controller directory
class AppController extends Controller {
public $helpers = array('Html', 'Form', 'Javascript');
public function beforeFilter() {
die('app/Controller/AppController.php file called');
parent::beforeFilter();
}
}

Resources