Skip to content

Commit

Permalink
Allowing li3_access to take into account Dispatcher rule modifications.
Browse files Browse the repository at this point in the history
  • Loading branch information
mariano committed Feb 25, 2012
1 parent d5160ae commit 19ebec3
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 83 deletions.
56 changes: 31 additions & 25 deletions extensions/adapter/security/access/AuthRbac.php
Expand Up @@ -28,12 +28,13 @@ class AuthRbac extends \lithium\core\Object {
* the user requesting access. Or false (because Auth::check() can return false).
* This is an optional parameter, bercause we will fetch the users data trough Auth
* seperately.
* @param object $request The Lithium Request object.
* @param mixed $params The Lithium `Request` object, or an array with at least
* 'request', and 'params'
* @param array $options An array of additional options for the _getRolesByAuth method.
* @return Array An empty array if access is allowed or
* an array with reasons for denial if denied.
*/
public function check($requester, $request, array $options = array()) {
public function check($requester, $params, array $options = array()) {
if (empty($this->_roles)) {
throw new ConfigException('No roles defined for adapter configuration.');
}
Expand All @@ -57,11 +58,11 @@ public function check($requester, $request, array $options = array()) {
}

// Check to see if this role applies to this request
if (!static::parseMatch($role['match'], $request)) {
if (!static::parseMatch($role['match'], $params)) {
continue;
}

$accessible = static::_isAccessible($role, $request, $options);
$accessible = static::_isAccessible($role, $params, $options);

if (!$accessible) {
$message = !empty($role['message']) ? $role['message'] : $message;
Expand All @@ -80,19 +81,19 @@ public function check($requester, $request, array $options = array()) {
* Otherwise => grants access
*
* @param array $role Array Set of Roles (dereferenced)
* @param mixed $request A lithium Request object.
* @param mixed $quest A lithium Request object.
* @param array $options An array of additional options for the _getRolesByAuth method.
* @return boolean $accessable
*/
protected static function _isAccessible(&$role, $request, $options) {
protected static function _isAccessible(&$role, $params, $options) {
if ($role['allow'] === false) {
return false;
}
if (!static::_hasRole($role['requesters'], $request, $options)) {
if (!static::_hasRole($role['requesters'], $params, $options)) {
return false;
}
if (is_array($role['allow'])) {
return static::_parseClosures($role['allow'], $request, $role);
return static::_parseClosures($role['allow'], $params['request'], $role);
}
return true;
}
Expand All @@ -104,37 +105,41 @@ protected static function _isAccessible(&$role, $request, $options) {
* to validate. * Is also acceptable to match a parameter without a specific value.
*
* @param mixed $match A set of parameters to validate the request against.
* @param mixed $request A lithium Request object.
* @param mixed $params The Lithium `Request` object, or an array with at least
* 'request', and 'params'
* @access public
* @return boolean True if a match is found.
*/
public static function parseMatch($match, $request) {
public static function parseMatch($match, $params) {
if (empty($match)) {
return false;
}

if (is_array($match)) {
if (!static::_parseClosures($match, $request)) {
$_params = $params;
if (!static::_parseClosures($match, $params['request'], $_params)) {
return false;
}
} elseif (is_callable($match)) {
return (boolean) $match($params['request'], $params);
}

$params = array();
$matchParams = array();
foreach ((array) $match as $key => $param) {
if (is_string($param)) {
if (preg_match('/^([A-Za-z0-9_\*\\\]+)::([A-Za-z0-9_\*]+)$/', $param, $regexMatches)) {
$params += array(
$matchParams += array(
'controller' => $regexMatches[1],
'action' => $regexMatches[2]
);
continue;
}
}

$params[$key] = $param;
$matchParams[$key] = $param;
}

foreach ($params as $type => $value) {
foreach ($matchParams as $type => $value) {
if ($value === '*') {
continue;
}
Expand All @@ -143,8 +148,8 @@ public static function parseMatch($match, $request) {
$value = Inflector::underscore($value);
}

$exists_in_request = array_key_exists($type, $request->params);
if (!$exists_in_request || $value !== Inflector::underscore($request->params[$type])) {
$exists_in_request = array_key_exists($type, $params['params']);
if (!$exists_in_request || $value !== Inflector::underscore($params['params'][$type])) {
return false;
}
}
Expand All @@ -161,11 +166,11 @@ public static function parseMatch($match, $request) {
* @access protected
*
* @param array $data dereferenced Array
* @param mixed $request
* @param object $request The Lithium `Request` object
* @param array $roleOptions dereferenced Array
* @return boolean
*/
protected static function _parseClosures(array &$data, $request, array &$roleOptions = array()){
protected static function _parseClosures(array &$data, $request, array &$roleOptions = array()) {
$return = true;
foreach ($data as $key => $item) {
if (is_callable($item)) {
Expand All @@ -181,14 +186,15 @@ protected static function _parseClosures(array &$data, $request, array &$roleOpt
/**
* @todo reduce Model Overhead (will duplicated in each model)
*
* @param Request $request Object
* @param mixed $params The Lithium `Request` object, or an array with at least
* 'request', and 'params'
* @param array $options
* @return array|mixed $roles Roles with attachted User Models
*/
protected static function _getRolesByAuth($request, array $options = array()) {
protected static function _getRolesByAuth($params, array $options = array()) {
$roles = array('*' => '*');
foreach (array_keys(Auth::config()) as $key) {
if ($check = Auth::check($key, $request, $options)) {
if ($check = Auth::check($key, $params['request'], $options)) {
$roles[$key] = $check;
}
}
Expand All @@ -199,13 +205,13 @@ protected static function _getRolesByAuth($request, array $options = array()) {
* _hasRole Compares the results from _getRolesByAuth with the array passed to it.
*
* @param mixed $requesters
* @param mixed $request
* @param mixed $params
* @param array $options
* @access protected
* @return void
*/
protected static function _hasRole($requesters, $request, array $options = array()) {
$authed = array_keys(static::_getRolesByAuth($request, $options));
protected static function _hasRole($requesters, $params, array $options = array()) {
$authed = array_keys(static::_getRolesByAuth($params, $options));

$requesters = (array) $requesters;
if (in_array('*', $requesters)) {
Expand Down
9 changes: 5 additions & 4 deletions extensions/adapter/security/access/Rules.php
Expand Up @@ -96,12 +96,13 @@ protected function _init() {
*
* @param mixed $user The user data array that holds all necessary information about
* the user requesting access. Or false (because `Auth::check()` can return `false`).
* @param object $request The Lithium `Request` object.
* @param mixed $params The Lithium `Request` object, or an array with at least
* 'request', and 'params'
* @param array $options An array of additional options.
* @return array An empty array if access is allowed and an array with reasons for denial
* if denied.
*/
public function check($user, $request, array $options = array()) {
public function check($user, $params, array $options = array()) {
$defaults = array(
'rules' => $this->_config['default'],
'allowAny' => $this->_config['allowAny']
Expand All @@ -121,7 +122,7 @@ public function check($user, $request, array $options = array()) {
if (is_string($rule)) {
$rule = compact('rule');
}
$ruleResult = $this->_call($rule, $user, $request, $options);
$ruleResult = $this->_call($rule, $user, $params['request'], $options);

switch (true) {
case ($ruleResult === false && $options['allowAny']):
Expand Down Expand Up @@ -198,4 +199,4 @@ public function getRules($name = null) {
}
}

?>
?>
7 changes: 4 additions & 3 deletions extensions/adapter/security/access/Simple.php
Expand Up @@ -15,14 +15,15 @@ class Simple extends \lithium\core\Object {
*
* @param mixed $user The user data array that holds all necessary information about
* the user requesting access. Or `false` (because `Auth::check()` can return `false`).
* @param object $request The Lithium `Request` object.
* @param mixed $params The Lithium `Request` object, or an array with at least
* 'request', and 'params'
* @param array $options An array of additional options.
* @return Array An empty array if access is allowed and an array with reasons for denial
* if denied.
*/
public function check($user, $request, array $options = array()) {
public function check($user, $params, array $options = array()) {
return !$user ? $options : array();
}
}

?>
?>
22 changes: 14 additions & 8 deletions security/Access.php
Expand Up @@ -75,12 +75,13 @@ protected static function _initConfig($name, $config) {
* @param string $name The name of the `Access` configuration/adapter to check against.
* @param mixed $user The user data that holds all necessary information about
* the user requesting access. Or `false` (because Auth::check() can return `false`).
* @param object $request The Lithium Request object.
* @param mixed $params The Lithium `Request` object, or an array with at least
* 'request', and 'params'
* @param array $options An array of additional options.
* @return Array An empty array if access is allowed and an array with reasons for denial
* if denied.
*/
public static function check($name, $user, $request, array $options = array()) {
public static function check($name, $user, $params, array $options = array()) {
$defaults = array(
'message' => 'You are not permitted to access this area.',
'redirect' => '/'
Expand All @@ -90,15 +91,20 @@ public static function check($name, $user, $request, array $options = array()) {
if (($config = static::_config($name)) === null) {
throw new ConfigException("Configuration `{$name}` has not been defined.");
}
if (!is_array($params)) {
$params = array(
'request' => $params,
'params' => isset($params->params) ? $params->params : array()
);
}
$filter = function($self, $params) use ($name) {
$user = $params['user'];
$request = $params['request'];
$options = $params['options'];
return $self::adapter($name)->check($user, $request, $options);
return $self::adapter($name)->check(
$params['user'], $params['params'], $params['options']
);
};
$params = compact('user', 'request', 'options');
$params = compact('user', 'params', 'options');
return static::_filter(__FUNCTION__, $params, $filter, (array) $config['filters']);
}
}

?>
?>

0 comments on commit 19ebec3

Please sign in to comment.