// appmodel.php
// ...
function checkModelAccess($id) {
$return = false;
// allow by ownership of session user
$permissions = $this->sessionUserHasOwnership($id);
if(is_array($permissions)) {
foreach($permissions as $permission) {
if($permission == true) {
$return = true;
}
}
}
return $return;
}
var $sessionUserHasOwnershipRecursion = 10;
function sessionUserHasOwnership($id, $recursion = 0) {
// pr('Call from '.$this->name.'');
$return = false;
foreach($this->belongsTo as $belongsTo) {
$className = $belongsTo['className'];
$this->recursive = 0;
// TODO: Optimize following query
$parentsData = $this->find(array($this->name . '.id' => $id));
// pr("Looking on..." . $className);
if(isset($parentsData[$className]['id'])) {
if($recursion < $this->sessionUserHasOwnershipRecursion) {
$permissions = $this->{$className}->sessionUserHasOwnership($parentsData[$className]['id'], $recursion + 1);
if(is_array($permissions)) {
foreach($permissions as $permission) {
$return[] = $permission;
}
}
}
else {
trigger_error("Infinite Loop Protection - Stopped at Level: " . $this->sessionUserHasOwnershipRecursion);
}
}
}
return $return;
}
//...
// app_controller.php
// ...
function beforeFilter() {
$this->_setGlobalVariables();
$this->_setSessionUserId();
$this->_setDefaultRoute(array('controller' => 'pages', 'action' => '/index'));
if($this->checkControllerAccess() == false) {
if('Admin' != $this->User->sessionUserType) {
$this->Session->setFlash($this->msgAccessDenied);
$this->redirect($this->default_route);
}
}
}
// empty prototype to be overwritten/specified by every controller
function checkControllerAccess() {
return true; // TODO: set this to on production mode
}
function _setSessionUserId() {
// Guest / Visitor
$this->User->sessionUserId = '-1';
$this->User->sessionUserType = 'Guest';
$this->sessionUserId = '-1';
$this->sessionUserType = 'Guest';
$this->set('sessionUserId', '-1');
$this->set('sessionUserType', 'Guest');
// Logged in User
if($this->Session->valid()) {
$session_user = $this->Session->read('user_data');
if(is_array($session_user)) {
$this->User->sessionUserId = $session_user['id'];
$this->User->sessionUserType = $session_user['type'];
$this->sessionUserId = $session_user['id'];;
$this->sessionUserType = $session_user['type'];
$this->set('sessionUserId', $session_user['id']);
$this->set('sessionUserType', $session_user['type']);
}
}
}
// ...
// user.php (model)
// ...
var $sessionUserId = -1;
var $sessionUserType = "Guest";
function sessionUserHasOwnership($id) {
if($id == $this->sessionUserId) {
return array(true);
}
else {
return array(false);
}
}
// ...
// address_controller.php
//...
function beforeFilter() {
parent::beforeFilter();
}
function checkControllerAccess() {
// basically we disallow any access,
// and then, by rules specified below, allow it
$hasAccess = false;
switch($this->action) {
case 'view':
if(isset($this->passedArgs['address_id'])) {
$this->id = $this->passedArgs['address_id'];
// check by session user ownership
if($this->Address->checkModelAccess($this->id)) {
$hasAccess = true;
}
// check by session user type
$address = $this->Address->find(array('Address.id' => $this->id), array(), null, -1);
if(('Profile' == $this->User->sessionUserType && empty($address['Address']['profile_id']))
|| ('Company' == $this->User->sessionUserType && empty($address['Address']['company_id']))) {
$hasAccess = true;
}
}
else {
$this->Session->setFlash(__('Invalid Address.', true));
}
break;
case 'add':
if (isset($this->passedArgs['profile_id'])) {
$this->id = $this->passedArgs['profile_id'];
// check by session user ownership
if($this->Profile->checkModelAccess($this->id)) {
$hasAccess = true;
}
}
else if (isset($this->passedArgs['company_id'])) {
$this->id = $this->passedArgs['company_id'];
// check by session user ownership
if($this->Company->checkModelAccess($this->id)) {
$hasAccess = true;
}
}
else {
$this->Session->setFlash(__('Invalid Address.', true));
}
break;
case 'edit':
case 'delete':
if(isset($this->passedArgs['address_id'])) {
$this->id = $this->passedArgs['address_id'];
// check by user session ownership
if($this->Address->checkModelAccess($this->id)) {
$hasAccess = true;
}
}
else {
$this->Session->setFlash(__('Invalid Address.', true));
}
break;
default:
$hasAccess = true;
break;
}
return $hasAccess;
}
// ...