0

Please bear with me, as I'm a programming/cakephp noob, but I do not know how to restrict the user from access to other user data. When a user logs in, they get a dashboard of their listings (which come from several models....restaurants, hotels, golf courses, images for each listing, location information, coupons, etc..).

Depending on the model/controller, I could have user '3' (who has hotel listings) type into the browser bar /restaurants/edit/1 and edit the restaurant information of user '17' who has a restaurant with ID='1'. Worse, they can even access /users/dashboard/17. How do I limit a user to only access their own data? I was hoping there was some sort of 'beforeAllow()' part of the AuthComponent I could use in the AppController that checks user id beforehand and kicks them back out to their dashboard if they try to perform a CRUD action on other users' data.

Even if I was using ACL (I know I should but it's frankly a little too over my head at this stage of learning), I'd still have to know the right code to limit user access, correct?

Below is my AppController:

class AppController extends Controller {

 public $components = array(
    'Session',
    'Auth' => array(
        'loginRedirect' => array('controller' => 'users', 'action' => 'view'),
        'logoutRedirect' => array('controller' => 'docs', 'action' => 'index'),
        'authError' => 'Sorry, you are not authorized to view this page.'
    )
);


function beforeFilter() {



    $this->Auth->userModel = 'User'; 
    $this->Auth->allow('join_now','debug','index', 'condos', 'houses', 'hotels_and_motels', 'print_all_coupons', 'print_coupon', 'search', 'golf', 'charters', 'events', 'nightlife', 'shopping', 'visitors_info', 'contact_us', 'view', 'results');

}


}

and here is a sample edit function (the edit function from my UnitsController):

function edit($id) {
   $this->set('title', 'Edit your property');
   $this->Unit->id = $id;  

    if (empty($this->request->data)) {        
      $this->request->data = $this->Unit->read();    
} else { 

    if ($this->Unit->saveAll($this->request->data)) {  

        $this->Session->setFlash('Your property has been updated.', 'success'); 

    } 
}
}

I will say that every one of my db tables has a user_id field so the logged in user can be matched with the user_id of each model.

I thought that this SO question was what I was looking for but they ended up getting off on a tangent in it and never answered the original question the user asked.

Community
  • 1
  • 1
huzzah
  • 1,793
  • 2
  • 22
  • 40

2 Answers2

1

If you where using cakes acl and auth, then no, you wouldn't have to write a bunch of code, checking the user ids for each action, but you'd have to write the code to tie together the acl's. You'd tell the Component that your controller and actions require acl privelages. And it doesnt the look ups in the aros and acos tables to make sure that your object requesting the content has the proper permissions.

I HIGHLY recommend you take a look at the tutorial and figure out how to get it to work

If you don't go that route, then you will have to add in the checking to every action that loads dependent content. Basically you'll, when a action is requested, you'll feature the object, then get the user associated to that object and check to see if the id of the user the same as the id as the requesting the object.

if ( $this->Unit->User->uid != $this->Session->User->uid ) {
    throw new NotFoundException('Could not find that Unit');
} else {
    ...
}

The other thing you can do, for pages that are the same, but customized, is not use the url /user/dashboard/17 and instead just use /user/dashboard then in the dashboard action, pull the user id from the session data and load the profile for the user that is authenticated

Ryan Gibbons
  • 3,511
  • 31
  • 32
  • I knew I was going to get several "no, seriously USE the ACL component" answers, heh heh. (Insert another 'the cake manual is terrible' comment) Honestly, I'm ok with it, I just had no idea how to throttle an action based on the logged in user id, your code above is pretty much what I was looking for. THANK YOU! – huzzah Mar 28 '12 at 15:41
1

I think you will need to use CRUD authorization for adding EditOwn actions. The answer described in CakePHP ACL Database Setup: ARO / ACO structure? handles much of the logic that you need.

Please note that the solution is still not complete and you will get access to actions that can render other users' data. Example: scaffold 'index' methods. To restrict access to other users' data here, you can modify the query to add filters based on User ID that you get from Session.

Community
  • 1
  • 1
Mayank
  • 308
  • 1
  • 2
  • 15