mirror of
https://github.com/brmlab/brmsklad.git
synced 2025-10-30 07:43:59 +01:00
Upgrade CakePHP from 2.2.5 to 2.9.5
This commit is contained in:
parent
5a580df460
commit
235a541597
793 changed files with 60746 additions and 23753 deletions
|
|
@ -1,16 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Controller.Component.Acl
|
||||
* @since CakePHP(tm) v 0.10.0.1076
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
@ -27,6 +28,7 @@ interface AclInterface {
|
|||
* @param string $aro ARO The requesting object identifier.
|
||||
* @param string $aco ACO The controlled object identifier.
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return bool Success
|
||||
*/
|
||||
public function check($aro, $aco, $action = "*");
|
||||
|
||||
|
|
@ -36,7 +38,7 @@ interface AclInterface {
|
|||
* @param string $aro ARO The requesting object identifier.
|
||||
* @param string $aco ACO The controlled object identifier.
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
*/
|
||||
public function allow($aro, $aco, $action = "*");
|
||||
|
||||
|
|
@ -46,7 +48,7 @@ interface AclInterface {
|
|||
* @param string $aro ARO The requesting object identifier.
|
||||
* @param string $aco ACO The controlled object identifier.
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
*/
|
||||
public function deny($aro, $aco, $action = "*");
|
||||
|
||||
|
|
@ -56,14 +58,15 @@ interface AclInterface {
|
|||
* @param string $aro ARO The requesting object identifier.
|
||||
* @param string $aco ACO The controlled object identifier.
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
*/
|
||||
public function inherit($aro, $aco, $action = "*");
|
||||
|
||||
/**
|
||||
* Initialization method for the Acl implementation
|
||||
*
|
||||
* @param AclComponent $component
|
||||
* @param Component $component The AclComponent instance.
|
||||
* @return void
|
||||
*/
|
||||
public function initialize(Component $component);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,26 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Controller.Component.Acl
|
||||
* @since CakePHP(tm) v 0.10.0.1076
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('AclInterface', 'Controller/Component/Acl');
|
||||
App::uses('Hash', 'Utility');
|
||||
App::uses('ClassRegistry', 'Utility');
|
||||
|
||||
/**
|
||||
* DbAcl implements an ACL control system in the database. ARO's and ACO's are
|
||||
* structured into trees and a linking table is used to define permissions. You
|
||||
* DbAcl implements an ACL control system in the database. ARO's and ACO's are
|
||||
* structured into trees and a linking table is used to define permissions. You
|
||||
* can install the schema for DbAcl with the Schema Shell.
|
||||
*
|
||||
* `$aco` and `$aro` parameters can be slash delimited paths to tree nodes.
|
||||
|
|
@ -26,19 +29,18 @@ App::uses('Hash', 'Utility');
|
|||
*
|
||||
* Would point to a tree structure like
|
||||
*
|
||||
* {{{
|
||||
* ```
|
||||
* controllers
|
||||
* Users
|
||||
* edit
|
||||
* }}}
|
||||
* ```
|
||||
*
|
||||
* @package Cake.Controller.Component.Acl
|
||||
*/
|
||||
class DbAcl extends Object implements AclInterface {
|
||||
class DbAcl extends CakeObject implements AclInterface {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
|
@ -50,7 +52,7 @@ class DbAcl extends Object implements AclInterface {
|
|||
/**
|
||||
* Initializes the containing component and sets the Aro/Aco objects to it.
|
||||
*
|
||||
* @param AclComponent $component
|
||||
* @param AclComponent $component The AclComponent instance.
|
||||
* @return void
|
||||
*/
|
||||
public function initialize(Component $component) {
|
||||
|
|
@ -64,7 +66,7 @@ class DbAcl extends Object implements AclInterface {
|
|||
* @param string $aro ARO The requesting object identifier.
|
||||
* @param string $aco ACO The controlled object identifier.
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success (true if ARO has access to action in ACO, false otherwise)
|
||||
* @return bool Success (true if ARO has access to action in ACO, false otherwise)
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/access-control-lists.html#checking-permissions-the-acl-component
|
||||
*/
|
||||
public function check($aro, $aco, $action = "*") {
|
||||
|
|
@ -77,8 +79,8 @@ class DbAcl extends Object implements AclInterface {
|
|||
* @param string $aro ARO The requesting object identifier.
|
||||
* @param string $aco ACO The controlled object identifier.
|
||||
* @param string $actions Action (defaults to *)
|
||||
* @param integer $value Value to indicate access type (1 to give access, -1 to deny, 0 to inherit)
|
||||
* @return boolean Success
|
||||
* @param int $value Value to indicate access type (1 to give access, -1 to deny, 0 to inherit)
|
||||
* @return bool Success
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/access-control-lists.html#assigning-permissions
|
||||
*/
|
||||
public function allow($aro, $aco, $actions = "*", $value = 1) {
|
||||
|
|
@ -91,7 +93,7 @@ class DbAcl extends Object implements AclInterface {
|
|||
* @param string $aro ARO The requesting object identifier.
|
||||
* @param string $aco ACO The controlled object identifier.
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/access-control-lists.html#assigning-permissions
|
||||
*/
|
||||
public function deny($aro, $aco, $action = "*") {
|
||||
|
|
@ -104,7 +106,7 @@ class DbAcl extends Object implements AclInterface {
|
|||
* @param string $aro ARO The requesting object identifier.
|
||||
* @param string $aco ACO The controlled object identifier.
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
*/
|
||||
public function inherit($aro, $aco, $action = "*") {
|
||||
return $this->allow($aro, $aco, $action, 0);
|
||||
|
|
@ -116,7 +118,7 @@ class DbAcl extends Object implements AclInterface {
|
|||
* @param string $aro ARO The requesting object identifier.
|
||||
* @param string $aco ACO The controlled object identifier.
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
* @see allow()
|
||||
*/
|
||||
public function grant($aro, $aco, $action = "*") {
|
||||
|
|
@ -129,7 +131,7 @@ class DbAcl extends Object implements AclInterface {
|
|||
* @param string $aro ARO The requesting object identifier.
|
||||
* @param string $aco ACO The controlled object identifier.
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
* @see deny()
|
||||
*/
|
||||
public function revoke($aro, $aco, $action = "*") {
|
||||
|
|
|
|||
|
|
@ -1,26 +1,28 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Controller.Component.Acl
|
||||
* @since CakePHP(tm) v 0.10.0.1076
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('AclInterface', 'Controller/Component/Acl');
|
||||
|
||||
/**
|
||||
* IniAcl implements an access control system using an INI file. An example
|
||||
* IniAcl implements an access control system using an INI file. An example
|
||||
* of the ini file used can be found in /config/acl.ini.php.
|
||||
*
|
||||
* @package Cake.Controller.Component.Acl
|
||||
*/
|
||||
class IniAcl extends Object implements AclInterface {
|
||||
class IniAcl extends CakeObject implements AclInterface {
|
||||
|
||||
/**
|
||||
* Array with configuration, parsed from ini file
|
||||
|
|
@ -31,7 +33,7 @@ class IniAcl extends Object implements AclInterface {
|
|||
|
||||
/**
|
||||
* The Hash::extract() path to the user/aro identifier in the
|
||||
* acl.ini file. This path will be used to extract the string
|
||||
* acl.ini file. This path will be used to extract the string
|
||||
* representation of a user used in the ini file.
|
||||
*
|
||||
* @var string
|
||||
|
|
@ -41,7 +43,7 @@ class IniAcl extends Object implements AclInterface {
|
|||
/**
|
||||
* Initialize method
|
||||
*
|
||||
* @param AclBase $component
|
||||
* @param Component $component The AclComponent instance.
|
||||
* @return void
|
||||
*/
|
||||
public function initialize(Component $component) {
|
||||
|
|
@ -53,7 +55,7 @@ class IniAcl extends Object implements AclInterface {
|
|||
* @param string $aro ARO The requesting object identifier.
|
||||
* @param string $aco ACO The controlled object identifier.
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
*/
|
||||
public function allow($aro, $aco, $action = "*") {
|
||||
}
|
||||
|
|
@ -64,7 +66,7 @@ class IniAcl extends Object implements AclInterface {
|
|||
* @param string $aro ARO The requesting object identifier.
|
||||
* @param string $aco ACO The controlled object identifier.
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
*/
|
||||
public function deny($aro, $aco, $action = "*") {
|
||||
}
|
||||
|
|
@ -75,7 +77,7 @@ class IniAcl extends Object implements AclInterface {
|
|||
* @param string $aro ARO The requesting object identifier.
|
||||
* @param string $aco ACO The controlled object identifier.
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
*/
|
||||
public function inherit($aro, $aco, $action = "*") {
|
||||
}
|
||||
|
|
@ -88,10 +90,10 @@ class IniAcl extends Object implements AclInterface {
|
|||
* @param string $aro ARO
|
||||
* @param string $aco ACO
|
||||
* @param string $action Action
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
*/
|
||||
public function check($aro, $aco, $action = null) {
|
||||
if ($this->config == null) {
|
||||
if (!$this->config) {
|
||||
$this->config = $this->readConfigFile(APP . 'Config' . DS . 'acl.ini.php');
|
||||
}
|
||||
$aclConfig = $this->config;
|
||||
|
|
|
|||
|
|
@ -2,19 +2,18 @@
|
|||
/**
|
||||
* PHP configuration based AclInterface implementation
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Controller.Component.Acl
|
||||
* @since CakePHP(tm) v 2.1
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
@ -23,9 +22,20 @@
|
|||
*
|
||||
* @package Cake.Controller.Component.Acl
|
||||
*/
|
||||
class PhpAcl extends Object implements AclInterface {
|
||||
class PhpAcl extends CakeObject implements AclInterface {
|
||||
|
||||
/**
|
||||
* Constant for deny
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
const DENY = false;
|
||||
|
||||
/**
|
||||
* Constant for allow
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
const ALLOW = true;
|
||||
|
||||
/**
|
||||
|
|
@ -58,7 +68,7 @@ class PhpAcl extends Object implements AclInterface {
|
|||
*/
|
||||
public function __construct() {
|
||||
$this->options = array(
|
||||
'policy' => self::DENY,
|
||||
'policy' => static::DENY,
|
||||
'config' => APP . 'Config' . DS . 'acl.php',
|
||||
);
|
||||
}
|
||||
|
|
@ -71,7 +81,7 @@ class PhpAcl extends Object implements AclInterface {
|
|||
*/
|
||||
public function initialize(Component $Component) {
|
||||
if (!empty($Component->settings['adapter'])) {
|
||||
$this->options = array_merge($this->options, $Component->settings['adapter']);
|
||||
$this->options = $Component->settings['adapter'] + $this->options;
|
||||
}
|
||||
|
||||
App::uses('PhpReader', 'Configure');
|
||||
|
|
@ -91,11 +101,11 @@ class PhpAcl extends Object implements AclInterface {
|
|||
*/
|
||||
public function build(array $config) {
|
||||
if (empty($config['roles'])) {
|
||||
throw new AclException(__d('cake_dev','"roles" section not found in configuration.'));
|
||||
throw new AclException(__d('cake_dev', '"roles" section not found in configuration.'));
|
||||
}
|
||||
|
||||
if (empty($config['rules']['allow']) && empty($config['rules']['deny'])) {
|
||||
throw new AclException(__d('cake_dev','Neither "allow" nor "deny" rules were provided in configuration.'));
|
||||
throw new AclException(__d('cake_dev', 'Neither "allow" nor "deny" rules were provided in configuration.'));
|
||||
}
|
||||
|
||||
$rules['allow'] = !empty($config['rules']['allow']) ? $config['rules']['allow'] : array();
|
||||
|
|
@ -114,7 +124,7 @@ class PhpAcl extends Object implements AclInterface {
|
|||
* @param string $aro ARO The requesting object identifier.
|
||||
* @param string $aco ACO The controlled object identifier.
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
*/
|
||||
public function allow($aro, $aco, $action = "*") {
|
||||
return $this->Aco->access($this->Aro->resolve($aro), $aco, $action, 'allow');
|
||||
|
|
@ -126,7 +136,7 @@ class PhpAcl extends Object implements AclInterface {
|
|||
* @param string $aro ARO The requesting object identifier.
|
||||
* @param string $aco ACO The controlled object identifier.
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
*/
|
||||
public function deny($aro, $aco, $action = "*") {
|
||||
return $this->Aco->access($this->Aro->resolve($aro), $aco, $action, 'deny');
|
||||
|
|
@ -138,7 +148,7 @@ class PhpAcl extends Object implements AclInterface {
|
|||
* @param string $aro ARO The requesting object identifier.
|
||||
* @param string $aco ACO The controlled object identifier.
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
*/
|
||||
public function inherit($aro, $aco, $action = "*") {
|
||||
return false;
|
||||
|
|
@ -151,13 +161,13 @@ class PhpAcl extends Object implements AclInterface {
|
|||
* @param string $aro ARO
|
||||
* @param string $aco ACO
|
||||
* @param string $action Action
|
||||
* @return boolean true if access is granted, false otherwise
|
||||
* @return bool true if access is granted, false otherwise
|
||||
*/
|
||||
public function check($aro, $aco, $action = "*") {
|
||||
$allow = $this->options['policy'];
|
||||
$prioritizedAros = $this->Aro->roles($aro);
|
||||
|
||||
if ($action && $action != "*") {
|
||||
if ($action && $action !== "*") {
|
||||
$aco .= '/' . $action;
|
||||
}
|
||||
|
||||
|
|
@ -167,14 +177,14 @@ class PhpAcl extends Object implements AclInterface {
|
|||
return $allow;
|
||||
}
|
||||
|
||||
foreach ($path as $depth => $node) {
|
||||
foreach ($path as $node) {
|
||||
foreach ($prioritizedAros as $aros) {
|
||||
if (!empty($node['allow'])) {
|
||||
$allow = $allow || count(array_intersect($node['allow'], $aros)) > 0;
|
||||
$allow = $allow || count(array_intersect($node['allow'], $aros));
|
||||
}
|
||||
|
||||
if (!empty($node['deny'])) {
|
||||
$allow = $allow && count(array_intersect($node['deny'], $aros)) == 0;
|
||||
$allow = $allow && !count(array_intersect($node['deny'], $aros));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -186,7 +196,6 @@ class PhpAcl extends Object implements AclInterface {
|
|||
|
||||
/**
|
||||
* Access Control Object
|
||||
*
|
||||
*/
|
||||
class PhpAco {
|
||||
|
||||
|
|
@ -206,6 +215,11 @@ class PhpAco {
|
|||
'*' => '.*',
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $rules Rules array
|
||||
*/
|
||||
public function __construct(array $rules = array()) {
|
||||
foreach (array('allow', 'deny') as $type) {
|
||||
if (empty($rules[$type])) {
|
||||
|
|
@ -219,6 +233,7 @@ class PhpAco {
|
|||
/**
|
||||
* return path to the requested ACO with allow and deny rules attached on each level
|
||||
*
|
||||
* @param string $aco ACO string
|
||||
* @return array
|
||||
*/
|
||||
public function path($aco) {
|
||||
|
|
@ -236,7 +251,7 @@ class PhpAco {
|
|||
}
|
||||
|
||||
foreach ($root as $node => $elements) {
|
||||
$pattern = '/^' . str_replace(array_keys(self::$modifiers), array_values(self::$modifiers), $node) . '$/';
|
||||
$pattern = '/^' . str_replace(array_keys(static::$modifiers), array_values(static::$modifiers), $node) . '$/';
|
||||
|
||||
if ($node == $aco[$level] || preg_match($pattern, $aco[$level])) {
|
||||
// merge allow/denies with $path of current level
|
||||
|
|
@ -263,6 +278,10 @@ class PhpAco {
|
|||
/**
|
||||
* allow/deny ARO access to ARO
|
||||
*
|
||||
* @param string $aro ARO string
|
||||
* @param string $aco ACO string
|
||||
* @param string $action Action string
|
||||
* @param string $type access type
|
||||
* @return void
|
||||
*/
|
||||
public function access($aro, $aco, $action, $type = 'deny') {
|
||||
|
|
@ -273,7 +292,7 @@ class PhpAco {
|
|||
|
||||
foreach ($aco as $i => $node) {
|
||||
if (!isset($tree[$node])) {
|
||||
$tree[$node] = array(
|
||||
$tree[$node] = array(
|
||||
'children' => array(),
|
||||
);
|
||||
}
|
||||
|
|
@ -303,7 +322,7 @@ class PhpAco {
|
|||
return array_map('strtolower', $aco);
|
||||
}
|
||||
|
||||
// strip multiple occurences of '/'
|
||||
// strip multiple occurrences of '/'
|
||||
$aco = preg_replace('#/+#', '/', $aco);
|
||||
// make case insensitive
|
||||
$aco = ltrim(strtolower($aco), '/');
|
||||
|
|
@ -319,7 +338,6 @@ class PhpAco {
|
|||
*/
|
||||
public function build(array $allow, array $deny = array()) {
|
||||
$this->_tree = array();
|
||||
$tree = array();
|
||||
|
||||
foreach ($allow as $dotPath => $aros) {
|
||||
if (is_string($aros)) {
|
||||
|
|
@ -342,7 +360,6 @@ class PhpAco {
|
|||
|
||||
/**
|
||||
* Access Request Object
|
||||
*
|
||||
*/
|
||||
class PhpAro {
|
||||
|
||||
|
|
@ -385,6 +402,13 @@ class PhpAro {
|
|||
*/
|
||||
protected $_tree = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $aro The aro data
|
||||
* @param array $map The identifier mappings
|
||||
* @param array $aliases The aliases to map.
|
||||
*/
|
||||
public function __construct(array $aro = array(), array $map = array(), array $aliases = array()) {
|
||||
if (!empty($map)) {
|
||||
$this->map = $map;
|
||||
|
|
@ -436,7 +460,7 @@ class PhpAro {
|
|||
$mapped = '';
|
||||
|
||||
if (is_array($aro)) {
|
||||
if (isset($aro['model']) && isset($aro['foreign_key']) && $aro['model'] == $aroGroup) {
|
||||
if (isset($aro['model']) && isset($aro['foreign_key']) && $aro['model'] === $aroGroup) {
|
||||
$mapped = $aroGroup . '/' . $aro['foreign_key'];
|
||||
} elseif (isset($aro[$model][$field])) {
|
||||
$mapped = $aroGroup . '/' . $aro[$model][$field];
|
||||
|
|
@ -453,7 +477,7 @@ class PhpAro {
|
|||
|
||||
$aroModel = Inflector::camelize($aroModel);
|
||||
|
||||
if ($aroModel == $model || $aroModel == $aroGroup) {
|
||||
if ($aroModel === $model || $aroModel === $aroGroup) {
|
||||
$mapped = $aroGroup . '/' . $aroValue;
|
||||
}
|
||||
}
|
||||
|
|
@ -468,7 +492,7 @@ class PhpAro {
|
|||
return $this->aliases[$mapped];
|
||||
}
|
||||
}
|
||||
return self::DEFAULT_ROLE;
|
||||
return static::DEFAULT_ROLE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -519,8 +543,8 @@ class PhpAro {
|
|||
* @param array $alias alias from => to (e.g. Role/13 -> Role/editor)
|
||||
* @return void
|
||||
*/
|
||||
public function addAlias(array $alias) {
|
||||
$this->aliases = array_merge($this->aliases, $alias);
|
||||
public function addAlias(array $alias) {
|
||||
$this->aliases = $alias + $this->aliases;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,17 +1,19 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Controller.Component
|
||||
* @since CakePHP(tm) v 0.10.0.1076
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('Component', 'Controller');
|
||||
App::uses('AclInterface', 'Controller/Component/Acl');
|
||||
|
||||
|
|
@ -19,8 +21,8 @@ App::uses('AclInterface', 'Controller/Component/Acl');
|
|||
* Access Control List factory class.
|
||||
*
|
||||
* Uses a strategy pattern to allow custom ACL implementations to be used with the same component interface.
|
||||
* You can define by changing `Configure::write('Acl.classname', 'DbAcl');` in your core.php. Concrete ACL
|
||||
* implementations should extend `AclBase` and implement the methods it defines.
|
||||
* You can define by changing `Configure::write('Acl.classname', 'DbAcl');` in your core.php. The adapter
|
||||
* you specify must implement `AclInterface`
|
||||
*
|
||||
* @package Cake.Controller.Component
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/access-control-lists.html
|
||||
|
|
@ -51,8 +53,8 @@ class AclComponent extends Component {
|
|||
/**
|
||||
* Constructor. Will return an instance of the correct ACL class as defined in `Configure::read('Acl.classname')`
|
||||
*
|
||||
* @param ComponentCollection $collection
|
||||
* @param array $settings
|
||||
* @param ComponentCollection $collection Collection instance.
|
||||
* @param array $settings Settings list.
|
||||
* @throws CakeException when Acl.classname could not be loaded.
|
||||
*/
|
||||
public function __construct(ComponentCollection $collection, $settings = array()) {
|
||||
|
|
@ -77,7 +79,7 @@ class AclComponent extends Component {
|
|||
* Will call the initialize method on the adapter if setting a new one.
|
||||
*
|
||||
* @param AclInterface|string $adapter Instance of AclInterface or a string name of the class to use. (optional)
|
||||
* @return AclInterface|void either null, or the adapter implementation.
|
||||
* @return AclInterface|null Either null, or the adapter implementation.
|
||||
* @throws CakeException when the given class is not an instance of AclInterface
|
||||
*/
|
||||
public function adapter($adapter = null) {
|
||||
|
|
@ -90,19 +92,19 @@ class AclComponent extends Component {
|
|||
}
|
||||
$this->_Instance = $adapter;
|
||||
$this->_Instance->initialize($this);
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
return $this->_Instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass-thru function for ACL check instance. Check methods
|
||||
* Pass-thru function for ACL check instance. Check methods
|
||||
* are used to check whether or not an ARO can access an ACO
|
||||
*
|
||||
* @param array|string|Model $aro ARO The requesting object identifier. See `AclNode::node()` for possible formats
|
||||
* @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
*/
|
||||
public function check($aro, $aco, $action = "*") {
|
||||
return $this->_Instance->check($aro, $aco, $action);
|
||||
|
|
@ -115,7 +117,7 @@ class AclComponent extends Component {
|
|||
* @param array|string|Model $aro ARO The requesting object identifier. See `AclNode::node()` for possible formats
|
||||
* @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
*/
|
||||
public function allow($aro, $aco, $action = "*") {
|
||||
return $this->_Instance->allow($aro, $aco, $action);
|
||||
|
|
@ -128,7 +130,7 @@ class AclComponent extends Component {
|
|||
* @param array|string|Model $aro ARO The requesting object identifier. See `AclNode::node()` for possible formats
|
||||
* @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
*/
|
||||
public function deny($aro, $aco, $action = "*") {
|
||||
return $this->_Instance->deny($aro, $aco, $action);
|
||||
|
|
@ -141,7 +143,7 @@ class AclComponent extends Component {
|
|||
* @param array|string|Model $aro ARO The requesting object identifier. See `AclNode::node()` for possible formats
|
||||
* @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
*/
|
||||
public function inherit($aro, $aco, $action = "*") {
|
||||
return $this->_Instance->inherit($aro, $aco, $action);
|
||||
|
|
@ -153,11 +155,11 @@ class AclComponent extends Component {
|
|||
* @param array|string|Model $aro ARO The requesting object identifier. See `AclNode::node()` for possible formats
|
||||
* @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @deprecated
|
||||
* @return bool Success
|
||||
* @deprecated 3.0.0 Will be removed in 3.0.
|
||||
*/
|
||||
public function grant($aro, $aco, $action = "*") {
|
||||
trigger_error(__d('cake_dev', 'AclComponent::grant() is deprecated, use allow() instead'), E_USER_WARNING);
|
||||
trigger_error(__d('cake_dev', '%s is deprecated, use %s instead', 'AclComponent::grant()', 'allow()'), E_USER_WARNING);
|
||||
return $this->_Instance->allow($aro, $aco, $action);
|
||||
}
|
||||
|
||||
|
|
@ -167,11 +169,11 @@ class AclComponent extends Component {
|
|||
* @param array|string|Model $aro ARO The requesting object identifier. See `AclNode::node()` for possible formats
|
||||
* @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @deprecated
|
||||
* @return bool Success
|
||||
* @deprecated 3.0.0 Will be removed in 3.0.
|
||||
*/
|
||||
public function revoke($aro, $aco, $action = "*") {
|
||||
trigger_error(__d('cake_dev', 'AclComponent::revoke() is deprecated, use deny() instead'), E_USER_WARNING);
|
||||
trigger_error(__d('cake_dev', '%s is deprecated, use %s instead', 'AclComponent::revoke()', 'deny()'), E_USER_WARNING);
|
||||
return $this->_Instance->deny($aro, $aco, $action);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @since CakePHP(tm) v 2.4.0
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract password hashing class
|
||||
*
|
||||
* @package Cake.Controller.Component.Auth
|
||||
*/
|
||||
abstract class AbstractPasswordHasher {
|
||||
|
||||
/**
|
||||
* Configurations for this object. Settings passed from authenticator class to
|
||||
* the constructor are merged with this property.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_config = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $config Array of config.
|
||||
*/
|
||||
public function __construct($config = array()) {
|
||||
$this->config($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get/Set the config
|
||||
*
|
||||
* @param array $config Sets config, if null returns existing config
|
||||
* @return array Returns configs
|
||||
*/
|
||||
public function config($config = null) {
|
||||
if (is_array($config)) {
|
||||
$this->_config = array_merge($this->_config, $config);
|
||||
}
|
||||
return $this->_config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates password hash.
|
||||
*
|
||||
* @param string|array $password Plain text password to hash or array of data
|
||||
* required to generate password hash.
|
||||
* @return string Password hash
|
||||
*/
|
||||
abstract public function hash($password);
|
||||
|
||||
/**
|
||||
* Check hash. Generate hash from user provided password string or data array
|
||||
* and check against existing hash.
|
||||
*
|
||||
* @param string|array $password Plain text password to hash or data array.
|
||||
* @param string $hashedPassword Existing hashed password.
|
||||
* @return bool True if hashes match else false.
|
||||
*/
|
||||
abstract public function check($password, $hashedPassword);
|
||||
|
||||
}
|
||||
|
|
@ -1,22 +1,21 @@
|
|||
<?php
|
||||
/**
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('BaseAuthorize', 'Controller/Component/Auth');
|
||||
|
||||
/**
|
||||
* An authorization adapter for AuthComponent. Provides the ability to authorize using the AclComponent,
|
||||
* An authorization adapter for AuthComponent. Provides the ability to authorize using the AclComponent,
|
||||
* If AclComponent is not already loaded it will be loaded using the Controller's ComponentCollection.
|
||||
*
|
||||
* @package Cake.Controller.Component.Auth
|
||||
|
|
@ -31,7 +30,7 @@ class ActionsAuthorize extends BaseAuthorize {
|
|||
*
|
||||
* @param array $user The user to authorize
|
||||
* @param CakeRequest $request The request needing authorization.
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize($user, CakeRequest $request) {
|
||||
$Acl = $this->_Collection->load('Acl');
|
||||
|
|
|
|||
|
|
@ -1,36 +1,41 @@
|
|||
<?php
|
||||
/**
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('Security', 'Utility');
|
||||
App::uses('Hash', 'Utility');
|
||||
App::uses('CakeEventListener', 'Event');
|
||||
|
||||
/**
|
||||
* Base Authentication class with common methods and properties.
|
||||
*
|
||||
* @package Cake.Controller.Component.Auth
|
||||
*/
|
||||
abstract class BaseAuthenticate {
|
||||
abstract class BaseAuthenticate implements CakeEventListener {
|
||||
|
||||
/**
|
||||
* Settings for this object.
|
||||
*
|
||||
* - `fields` The fields to use to identify a user by.
|
||||
* - `userModel` The model name of the User, defaults to User.
|
||||
* - `userFields` Array of fields to retrieve from User model, null to retrieve all. Defaults to null.
|
||||
* - `scope` Additional conditions to use when looking up and authenticating users,
|
||||
* i.e. `array('User.is_active' => 1).`
|
||||
* - `recursive` The value of the recursive key passed to find(). Defaults to 0.
|
||||
* - `contain` Extra models to contain and store in session.
|
||||
* - `passwordHasher` Password hasher class. Can be a string specifying class name
|
||||
* or an array containing `className` key, any other keys will be passed as
|
||||
* settings to the class. Defaults to 'Simple'.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
|
|
@ -40,9 +45,11 @@ abstract class BaseAuthenticate {
|
|||
'password' => 'password'
|
||||
),
|
||||
'userModel' => 'User',
|
||||
'userFields' => null,
|
||||
'scope' => array(),
|
||||
'recursive' => 0,
|
||||
'contain' => null,
|
||||
'passwordHasher' => 'Simple'
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
@ -52,6 +59,22 @@ abstract class BaseAuthenticate {
|
|||
*/
|
||||
protected $_Collection;
|
||||
|
||||
/**
|
||||
* Password hasher instance.
|
||||
*
|
||||
* @var AbstractPasswordHasher
|
||||
*/
|
||||
protected $_passwordHasher;
|
||||
|
||||
/**
|
||||
* Implemented events
|
||||
*
|
||||
* @return array of events => callbacks.
|
||||
*/
|
||||
public function implementedEvents() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
|
@ -66,42 +89,102 @@ abstract class BaseAuthenticate {
|
|||
/**
|
||||
* Find a user record using the standard options.
|
||||
*
|
||||
* @param string $username The username/identifier.
|
||||
* @param string $password The unhashed password.
|
||||
* @return Mixed Either false on failure, or an array of user data.
|
||||
* The $username parameter can be a (string)username or an array containing
|
||||
* conditions for Model::find('first'). If the $password param is not provided
|
||||
* the password field will be present in returned array.
|
||||
*
|
||||
* Input passwords will be hashed even when a user doesn't exist. This
|
||||
* helps mitigate timing attacks that are attempting to find valid usernames.
|
||||
*
|
||||
* @param string|array $username The username/identifier, or an array of find conditions.
|
||||
* @param string $password The password, only used if $username param is string.
|
||||
* @return bool|array Either false on failure, or an array of user data.
|
||||
*/
|
||||
protected function _findUser($username, $password) {
|
||||
protected function _findUser($username, $password = null) {
|
||||
$userModel = $this->settings['userModel'];
|
||||
list($plugin, $model) = pluginSplit($userModel);
|
||||
list(, $model) = pluginSplit($userModel);
|
||||
$fields = $this->settings['fields'];
|
||||
|
||||
$conditions = array(
|
||||
$model . '.' . $fields['username'] => $username,
|
||||
$model . '.' . $fields['password'] => $this->_password($password),
|
||||
);
|
||||
if (is_array($username)) {
|
||||
$conditions = $username;
|
||||
} else {
|
||||
$conditions = array(
|
||||
$model . '.' . $fields['username'] => $username
|
||||
);
|
||||
}
|
||||
|
||||
if (!empty($this->settings['scope'])) {
|
||||
$conditions = array_merge($conditions, $this->settings['scope']);
|
||||
}
|
||||
|
||||
$userFields = $this->settings['userFields'];
|
||||
if ($password !== null && $userFields !== null) {
|
||||
$userFields[] = $model . '.' . $fields['password'];
|
||||
}
|
||||
|
||||
$result = ClassRegistry::init($userModel)->find('first', array(
|
||||
'conditions' => $conditions,
|
||||
'recursive' => $this->settings['recursive'],
|
||||
'fields' => $userFields,
|
||||
'contain' => $this->settings['contain'],
|
||||
));
|
||||
if (empty($result) || empty($result[$model])) {
|
||||
if (empty($result[$model])) {
|
||||
$this->passwordHasher()->hash($password);
|
||||
return false;
|
||||
}
|
||||
|
||||
$user = $result[$model];
|
||||
unset($user[$fields['password']]);
|
||||
if ($password !== null) {
|
||||
if (!$this->passwordHasher()->check($password, $user[$fields['password']])) {
|
||||
return false;
|
||||
}
|
||||
unset($user[$fields['password']]);
|
||||
}
|
||||
|
||||
unset($result[$model]);
|
||||
return array_merge($user, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return password hasher object
|
||||
*
|
||||
* @return AbstractPasswordHasher Password hasher instance
|
||||
* @throws CakeException If password hasher class not found or
|
||||
* it does not extend AbstractPasswordHasher
|
||||
*/
|
||||
public function passwordHasher() {
|
||||
if ($this->_passwordHasher) {
|
||||
return $this->_passwordHasher;
|
||||
}
|
||||
|
||||
$config = array();
|
||||
if (is_string($this->settings['passwordHasher'])) {
|
||||
$class = $this->settings['passwordHasher'];
|
||||
} else {
|
||||
$class = $this->settings['passwordHasher']['className'];
|
||||
$config = $this->settings['passwordHasher'];
|
||||
unset($config['className']);
|
||||
}
|
||||
list($plugin, $class) = pluginSplit($class, true);
|
||||
$className = $class . 'PasswordHasher';
|
||||
App::uses($className, $plugin . 'Controller/Component/Auth');
|
||||
if (!class_exists($className)) {
|
||||
throw new CakeException(__d('cake_dev', 'Password hasher class "%s" was not found.', $class));
|
||||
}
|
||||
if (!is_subclass_of($className, 'AbstractPasswordHasher')) {
|
||||
throw new CakeException(__d('cake_dev', 'Password hasher must extend AbstractPasswordHasher class.'));
|
||||
}
|
||||
$this->_passwordHasher = new $className($config);
|
||||
return $this->_passwordHasher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash the plain text password so that it matches the hashed/encrypted password
|
||||
* in the datasource.
|
||||
*
|
||||
* @param string $password The plain text password.
|
||||
* @return string The hashed form of the password.
|
||||
* @deprecated 3.0.0 Since 2.4. Use a PasswordHasher class instead.
|
||||
*/
|
||||
protected function _password($password) {
|
||||
return Security::hash($password, null, true);
|
||||
|
|
@ -130,14 +213,25 @@ abstract class BaseAuthenticate {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get a user based on information in the request. Primarily used by stateless authentication
|
||||
* Get a user based on information in the request. Primarily used by stateless authentication
|
||||
* systems like basic and digest auth.
|
||||
*
|
||||
* @param CakeRequest $request Request object.
|
||||
* @return mixed Either false or an array of user information
|
||||
*/
|
||||
public function getUser($request) {
|
||||
public function getUser(CakeRequest $request) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle unauthenticated access attempt.
|
||||
*
|
||||
* @param CakeRequest $request A request object.
|
||||
* @param CakeResponse $response A response object.
|
||||
* @return mixed Either true to indicate the unauthenticated request has been
|
||||
* dealt with and no more action is required by AuthComponent or void (default).
|
||||
*/
|
||||
public function unauthenticated(CakeRequest $request, CakeResponse $response) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('Hash', 'Utility');
|
||||
|
||||
/**
|
||||
|
|
@ -40,10 +40,10 @@ abstract class BaseAuthorize {
|
|||
/**
|
||||
* Settings for authorize objects.
|
||||
*
|
||||
* - `actionPath` - The path to ACO nodes that contains the nodes for controllers. Used as a prefix
|
||||
* - `actionPath` - The path to ACO nodes that contains the nodes for controllers. Used as a prefix
|
||||
* when calling $this->action();
|
||||
* - `actionMap` - Action -> crud mappings. Used by authorization objects that want to map actions to CRUD roles.
|
||||
* - `userModel` - Model name that ARO records can be found under. Defaults to 'User'.
|
||||
* - `userModel` - Model name that ARO records can be found under. Defaults to 'User'.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
|
|
@ -64,7 +64,7 @@ abstract class BaseAuthorize {
|
|||
* Constructor
|
||||
*
|
||||
* @param ComponentCollection $collection The controller for this request.
|
||||
* @param string $settings An array of settings. This class does not use any settings.
|
||||
* @param string $settings An array of settings. This class does not use any settings.
|
||||
*/
|
||||
public function __construct(ComponentCollection $collection, $settings = array()) {
|
||||
$this->_Collection = $collection;
|
||||
|
|
@ -77,8 +77,8 @@ abstract class BaseAuthorize {
|
|||
* Checks user authorization.
|
||||
*
|
||||
* @param array $user Active user data
|
||||
* @param CakeRequest $request
|
||||
* @return boolean
|
||||
* @param CakeRequest $request Request instance.
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function authorize($user, CakeRequest $request);
|
||||
|
||||
|
|
@ -101,14 +101,14 @@ abstract class BaseAuthorize {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the action path for a given request. Primarily used by authorize objects
|
||||
* Get the action path for a given request. Primarily used by authorize objects
|
||||
* that need to get information about the plugin, controller, and action being invoked.
|
||||
*
|
||||
* @param CakeRequest $request The request a path is needed for.
|
||||
* @param string $path
|
||||
* @param string $path Path format.
|
||||
* @return string the action path for the given request.
|
||||
*/
|
||||
public function action($request, $path = '/:plugin/:controller/:action') {
|
||||
public function action(CakeRequest $request, $path = '/:plugin/:controller/:action') {
|
||||
$plugin = empty($request['plugin']) ? null : Inflector::camelize($request['plugin']) . '/';
|
||||
$path = str_replace(
|
||||
array(':controller', ':action', ':plugin/'),
|
||||
|
|
@ -120,24 +120,31 @@ abstract class BaseAuthorize {
|
|||
}
|
||||
|
||||
/**
|
||||
* Maps crud actions to actual action names. Used to modify or get the current mapped actions.
|
||||
* Maps crud actions to actual action names. Used to modify or get the current mapped actions.
|
||||
*
|
||||
* Create additional mappings for a standard CRUD operation:
|
||||
*
|
||||
* {{{
|
||||
* ```
|
||||
* $this->Auth->mapActions(array('create' => array('add', 'register'));
|
||||
* }}}
|
||||
* ```
|
||||
*
|
||||
* Or equivalently:
|
||||
*
|
||||
* ```
|
||||
* $this->Auth->mapActions(array('register' => 'create', 'add' => 'create'));
|
||||
* ```
|
||||
*
|
||||
* Create mappings for custom CRUD operations:
|
||||
*
|
||||
* {{{
|
||||
* $this->Auth->mapActions(array('my_action' => 'admin'));
|
||||
* }}}
|
||||
* ```
|
||||
* $this->Auth->mapActions(array('range' => 'search'));
|
||||
* ```
|
||||
*
|
||||
* You can use the custom CRUD operations to create additional generic permissions
|
||||
* that behave like CRUD operations. Doing this will require additional columns on the
|
||||
* permissions lookup. When using with DbAcl, you'll have to add additional _admin type columns
|
||||
* to the `aros_acos` table.
|
||||
* that behave like CRUD operations. Doing this will require additional columns on the
|
||||
* permissions lookup. For example if one wanted an additional search CRUD operation
|
||||
* one would create and additional column '_search' in the aros_acos table. One could
|
||||
* create a custom admin CRUD operation for administration functions similarly if needed.
|
||||
*
|
||||
* @param array $map Either an array of mappings, or undefined to get current values.
|
||||
* @return mixed Either the current mappings or null when setting.
|
||||
|
|
@ -147,9 +154,8 @@ abstract class BaseAuthorize {
|
|||
if (empty($map)) {
|
||||
return $this->settings['actionMap'];
|
||||
}
|
||||
$crud = array('create', 'read', 'update', 'delete');
|
||||
foreach ($map as $action => $type) {
|
||||
if (in_array($action, $crud) && is_array($type)) {
|
||||
if (is_array($type)) {
|
||||
foreach ($type as $typedAction) {
|
||||
$this->settings['actionMap'][$typedAction] = $action;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,15 @@
|
|||
<?php
|
||||
/**
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('BaseAuthenticate', 'Controller/Component/Auth');
|
||||
|
|
@ -18,55 +17,39 @@ App::uses('BaseAuthenticate', 'Controller/Component/Auth');
|
|||
/**
|
||||
* Basic Authentication adapter for AuthComponent.
|
||||
*
|
||||
* Provides Basic HTTP authentication support for AuthComponent. Basic Auth will authenticate users
|
||||
* against the configured userModel and verify the username and passwords match. Clients using Basic Authentication
|
||||
* must support cookies. Since AuthComponent identifies users based on Session contents, clients using Basic
|
||||
* Auth must support cookies.
|
||||
* Provides Basic HTTP authentication support for AuthComponent. Basic Auth will
|
||||
* authenticate users against the configured userModel and verify the username
|
||||
* and passwords match.
|
||||
*
|
||||
* ### Using Basic auth
|
||||
*
|
||||
* In your controller's components array, add auth + the required settings.
|
||||
* {{{
|
||||
* ```
|
||||
* public $components = array(
|
||||
* 'Auth' => array(
|
||||
* 'authenticate' => array('Basic')
|
||||
* )
|
||||
* );
|
||||
* }}}
|
||||
* ```
|
||||
*
|
||||
* In your login function just call `$this->Auth->login()` without any checks for POST data. This
|
||||
* will send the authentication headers, and trigger the login dialog in the browser/client.
|
||||
* You should also set `AuthComponent::$sessionKey = false;` in your AppController's
|
||||
* beforeFilter() to prevent CakePHP from sending a session cookie to the client.
|
||||
*
|
||||
* Since HTTP Basic Authentication is stateless you don't need a login() action
|
||||
* in your controller. The user credentials will be checked on each request. If
|
||||
* valid credentials are not provided, required authentication headers will be sent
|
||||
* by this authentication provider which triggers the login dialog in the browser/client.
|
||||
*
|
||||
* You may also want to use `$this->Auth->unauthorizedRedirect = false;`.
|
||||
* By default, unauthorized users are redirected to the referrer URL,
|
||||
* `AuthComponent::$loginAction`, or '/'. If unauthorizedRedirect is set to
|
||||
* false, a ForbiddenException exception is thrown instead of redirecting.
|
||||
*
|
||||
* @package Cake.Controller.Component.Auth
|
||||
* @since 2.0
|
||||
*/
|
||||
class BasicAuthenticate extends BaseAuthenticate {
|
||||
|
||||
/**
|
||||
* Settings for this object.
|
||||
*
|
||||
* - `fields` The fields to use to identify a user by.
|
||||
* - `userModel` The model name of the User, defaults to User.
|
||||
* - `scope` Additional conditions to use when looking up and authenticating users,
|
||||
* i.e. `array('User.is_active' => 1).`
|
||||
* - `recursive` The value of the recursive key passed to find(). Defaults to 0.
|
||||
* - `contain` Extra models to contain and store in session.
|
||||
* - `realm` The realm authentication is for. Defaults the server name.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $settings = array(
|
||||
'fields' => array(
|
||||
'username' => 'username',
|
||||
'password' => 'password'
|
||||
),
|
||||
'userModel' => 'User',
|
||||
'scope' => array(),
|
||||
'recursive' => 0,
|
||||
'contain' => null,
|
||||
'realm' => '',
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor, completes configuration for basic authentication.
|
||||
*
|
||||
|
|
@ -81,41 +64,47 @@ class BasicAuthenticate extends BaseAuthenticate {
|
|||
}
|
||||
|
||||
/**
|
||||
* Authenticate a user using basic HTTP auth. Will use the configured User model and attempt a
|
||||
* login using basic HTTP auth.
|
||||
* Authenticate a user using HTTP auth. Will use the configured User model and attempt a
|
||||
* login using HTTP auth.
|
||||
*
|
||||
* @param CakeRequest $request The request to authenticate with.
|
||||
* @param CakeResponse $response The response to add headers to.
|
||||
* @return mixed Either false on failure, or an array of user data on success.
|
||||
*/
|
||||
public function authenticate(CakeRequest $request, CakeResponse $response) {
|
||||
$result = $this->getUser($request);
|
||||
|
||||
if (empty($result)) {
|
||||
$response->header($this->loginHeaders());
|
||||
$response->statusCode(401);
|
||||
$response->send();
|
||||
return false;
|
||||
}
|
||||
return $result;
|
||||
return $this->getUser($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a user based on information in the request. Used by cookie-less auth for stateless clients.
|
||||
* Get a user based on information in the request. Used by cookie-less auth for stateless clients.
|
||||
*
|
||||
* @param CakeRequest $request Request object.
|
||||
* @return mixed Either false or an array of user information
|
||||
*/
|
||||
public function getUser($request) {
|
||||
public function getUser(CakeRequest $request) {
|
||||
$username = env('PHP_AUTH_USER');
|
||||
$pass = env('PHP_AUTH_PW');
|
||||
|
||||
if (empty($username) || empty($pass)) {
|
||||
if (!is_string($username) || $username === '' || !is_string($pass) || $pass === '') {
|
||||
return false;
|
||||
}
|
||||
return $this->_findUser($username, $pass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles an unauthenticated access attempt by sending appropriate login headers
|
||||
*
|
||||
* @param CakeRequest $request A request object.
|
||||
* @param CakeResponse $response A response object.
|
||||
* @return void
|
||||
* @throws UnauthorizedException
|
||||
*/
|
||||
public function unauthenticated(CakeRequest $request, CakeResponse $response) {
|
||||
$Exception = new UnauthorizedException();
|
||||
$Exception->responseHeader(array($this->loginHeaders()));
|
||||
throw $Exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the login headers
|
||||
*
|
||||
|
|
|
|||
53
lib/Cake/Controller/Component/Auth/BlowfishAuthenticate.php
Normal file
53
lib/Cake/Controller/Component/Auth/BlowfishAuthenticate.php
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of the files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('FormAuthenticate', 'Controller/Component/Auth');
|
||||
|
||||
/**
|
||||
* An authentication adapter for AuthComponent. Provides the ability to authenticate using POST data using Blowfish
|
||||
* hashing. Can be used by configuring AuthComponent to use it via the AuthComponent::$authenticate setting.
|
||||
*
|
||||
* ```
|
||||
* $this->Auth->authenticate = array(
|
||||
* 'Blowfish' => array(
|
||||
* 'scope' => array('User.active' => 1)
|
||||
* )
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* When configuring BlowfishAuthenticate you can pass in settings to which fields, model and additional conditions
|
||||
* are used. See FormAuthenticate::$settings for more information.
|
||||
*
|
||||
* For initial password hashing/creation see Security::hash(). Other than how the password is initially hashed,
|
||||
* BlowfishAuthenticate works exactly the same way as FormAuthenticate.
|
||||
*
|
||||
* @package Cake.Controller.Component.Auth
|
||||
* @since CakePHP(tm) v 2.3
|
||||
* @see AuthComponent::$authenticate
|
||||
* @deprecated 3.0.0 Since 2.4. Just use FormAuthenticate with 'passwordHasher' setting set to 'Blowfish'
|
||||
*/
|
||||
class BlowfishAuthenticate extends FormAuthenticate {
|
||||
|
||||
/**
|
||||
* Constructor. Sets default passwordHasher to Blowfish
|
||||
*
|
||||
* @param ComponentCollection $collection The Component collection used on this request.
|
||||
* @param array $settings Array of settings to use.
|
||||
*/
|
||||
public function __construct(ComponentCollection $collection, $settings) {
|
||||
$this->settings['passwordHasher'] = 'Blowfish';
|
||||
parent::__construct($collection, $settings);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @since CakePHP(tm) v 2.4.0
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('AbstractPasswordHasher', 'Controller/Component/Auth');
|
||||
App::uses('Security', 'Utility');
|
||||
|
||||
/**
|
||||
* Blowfish password hashing class.
|
||||
*
|
||||
* @package Cake.Controller.Component.Auth
|
||||
*/
|
||||
class BlowfishPasswordHasher extends AbstractPasswordHasher {
|
||||
|
||||
/**
|
||||
* Generates password hash.
|
||||
*
|
||||
* @param string $password Plain text password to hash.
|
||||
* @return string Password hash
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#using-bcrypt-for-passwords
|
||||
*/
|
||||
public function hash($password) {
|
||||
return Security::hash($password, 'blowfish', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check hash. Generate hash for user provided password and check against existing hash.
|
||||
*
|
||||
* @param string $password Plain text password to hash.
|
||||
* @param string $hashedPassword Existing hashed password.
|
||||
* @return bool True if hashes match else false.
|
||||
*/
|
||||
public function check($password, $hashedPassword) {
|
||||
return $hashedPassword === Security::hash($password, 'blowfish', $hashedPassword);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,32 +1,31 @@
|
|||
<?php
|
||||
/**
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('BaseAuthorize', 'Controller/Component/Auth');
|
||||
|
||||
/**
|
||||
* An authorization adapter for AuthComponent. Provides the ability to authorize using a controller callback.
|
||||
* An authorization adapter for AuthComponent. Provides the ability to authorize using a controller callback.
|
||||
* Your controller's isAuthorized() method should return a boolean to indicate whether or not the user is authorized.
|
||||
*
|
||||
* {{{
|
||||
* ```
|
||||
* public function isAuthorized($user) {
|
||||
* if (!empty($this->request->params['admin'])) {
|
||||
* return $user['role'] == 'admin';
|
||||
* return $user['role'] === 'admin';
|
||||
* }
|
||||
* return !empty($user);
|
||||
* }
|
||||
* }}}
|
||||
* ```
|
||||
*
|
||||
* the above is simple implementation that would only authorize users of the 'admin' role to access
|
||||
* admin routing.
|
||||
|
|
@ -38,7 +37,7 @@ App::uses('BaseAuthorize', 'Controller/Component/Auth');
|
|||
class ControllerAuthorize extends BaseAuthorize {
|
||||
|
||||
/**
|
||||
* Get/set the controller this authorize object will be working with. Also checks that isAuthorized is implemented.
|
||||
* Get/set the controller this authorize object will be working with. Also checks that isAuthorized is implemented.
|
||||
*
|
||||
* @param Controller $controller null to get, a controller to set.
|
||||
* @return mixed
|
||||
|
|
@ -47,7 +46,7 @@ class ControllerAuthorize extends BaseAuthorize {
|
|||
public function controller(Controller $controller = null) {
|
||||
if ($controller) {
|
||||
if (!method_exists($controller, 'isAuthorized')) {
|
||||
throw new CakeException(__d('cake_dev', '$controller does not implement an isAuthorized() method.'));
|
||||
throw new CakeException(__d('cake_dev', '$controller does not implement an %s method.', 'isAuthorized()'));
|
||||
}
|
||||
}
|
||||
return parent::controller($controller);
|
||||
|
|
@ -57,8 +56,8 @@ class ControllerAuthorize extends BaseAuthorize {
|
|||
* Checks user authorization using a controller callback.
|
||||
*
|
||||
* @param array $user Active user data
|
||||
* @param CakeRequest $request
|
||||
* @return boolean
|
||||
* @param CakeRequest $request Request instance.
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize($user, CakeRequest $request) {
|
||||
return (bool)$this->_Controller->isAuthorized($user);
|
||||
|
|
|
|||
|
|
@ -1,28 +1,27 @@
|
|||
<?php
|
||||
/**
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('BaseAuthorize', 'Controller/Component/Auth');
|
||||
App::uses('Router', 'Routing');
|
||||
|
||||
/**
|
||||
* An authorization adapter for AuthComponent. Provides the ability to authorize using CRUD mappings.
|
||||
* An authorization adapter for AuthComponent. Provides the ability to authorize using CRUD mappings.
|
||||
* CRUD mappings allow you to translate controller actions into *C*reate *R*ead *U*pdate *D*elete actions.
|
||||
* This is then checked in the AclComponent as specific permissions.
|
||||
*
|
||||
* For example, taking `/posts/index` as the current request. The default mapping for `index`, is a `read` permission
|
||||
* check. The Acl check would then be for the `posts` controller with the `read` permission. This allows you
|
||||
* For example, taking `/posts/index` as the current request. The default mapping for `index`, is a `read` permission
|
||||
* check. The Acl check would then be for the `posts` controller with the `read` permission. This allows you
|
||||
* to create permission systems that focus more on what is being done to resources, rather than the specific actions
|
||||
* being visited.
|
||||
*
|
||||
|
|
@ -37,7 +36,7 @@ class CrudAuthorize extends BaseAuthorize {
|
|||
* Sets up additional actionMap values that match the configured `Routing.prefixes`.
|
||||
*
|
||||
* @param ComponentCollection $collection The component collection from the controller.
|
||||
* @param string $settings An array of settings. This class does not use any settings.
|
||||
* @param string $settings An array of settings. This class does not use any settings.
|
||||
*/
|
||||
public function __construct(ComponentCollection $collection, $settings = array()) {
|
||||
parent::__construct($collection, $settings);
|
||||
|
|
@ -77,7 +76,7 @@ class CrudAuthorize extends BaseAuthorize {
|
|||
*
|
||||
* @param array $user The user to authorize
|
||||
* @param CakeRequest $request The request needing authorization.
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize($user, CakeRequest $request) {
|
||||
if (!isset($this->settings['actionMap'][$request->params['action']])) {
|
||||
|
|
|
|||
|
|
@ -1,72 +1,72 @@
|
|||
<?php
|
||||
/**
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('BaseAuthenticate', 'Controller/Component/Auth');
|
||||
App::uses('BasicAuthenticate', 'Controller/Component/Auth');
|
||||
|
||||
/**
|
||||
* Digest Authentication adapter for AuthComponent.
|
||||
*
|
||||
* Provides Digest HTTP authentication support for AuthComponent. Unlike most AuthComponent adapters,
|
||||
* DigestAuthenticate requires a special password hash that conforms to RFC2617. You can create this
|
||||
* password using `DigestAuthenticate::password()`. If you wish to use digest authentication alongside other
|
||||
* Provides Digest HTTP authentication support for AuthComponent. Unlike most AuthComponent adapters,
|
||||
* DigestAuthenticate requires a special password hash that conforms to RFC2617. You can create this
|
||||
* password using `DigestAuthenticate::password()`. If you wish to use digest authentication alongside other
|
||||
* authentication methods, its recommended that you store the digest authentication separately.
|
||||
*
|
||||
* Clients using Digest Authentication must support cookies. Since AuthComponent identifies users based
|
||||
* Clients using Digest Authentication must support cookies. Since AuthComponent identifies users based
|
||||
* on Session contents, clients without support for cookies will not function properly.
|
||||
*
|
||||
* ### Using Digest auth
|
||||
*
|
||||
* In your controller's components array, add auth + the required settings.
|
||||
* {{{
|
||||
* ```
|
||||
* public $components = array(
|
||||
* 'Auth' => array(
|
||||
* 'authenticate' => array('Digest')
|
||||
* )
|
||||
* );
|
||||
* }}}
|
||||
* ```
|
||||
*
|
||||
* In your login function just call `$this->Auth->login()` without any checks for POST data. This
|
||||
* In your login function just call `$this->Auth->login()` without any checks for POST data. This
|
||||
* will send the authentication headers, and trigger the login dialog in the browser/client.
|
||||
*
|
||||
* ### Generating passwords compatible with Digest authentication.
|
||||
*
|
||||
* Due to the Digest authentication specification, digest auth requires a special password value. You
|
||||
* Due to the Digest authentication specification, digest auth requires a special password value. You
|
||||
* can generate this password using `DigestAuthenticate::password()`
|
||||
*
|
||||
* `$digestPass = DigestAuthenticate::password($username, env('SERVER_NAME'), $password);`
|
||||
*
|
||||
* Its recommended that you store this digest auth only password separate from password hashes used for other
|
||||
* login methods. For example `User.digest_pass` could be used for a digest password, while `User.password` would
|
||||
* login methods. For example `User.digest_pass` could be used for a digest password, while `User.password` would
|
||||
* store the password hash for use with other methods like Basic or Form.
|
||||
*
|
||||
* @package Cake.Controller.Component.Auth
|
||||
* @since 2.0
|
||||
*/
|
||||
class DigestAuthenticate extends BaseAuthenticate {
|
||||
class DigestAuthenticate extends BasicAuthenticate {
|
||||
|
||||
/**
|
||||
* Settings for this object.
|
||||
*
|
||||
* - `fields` The fields to use to identify a user by.
|
||||
* - `userModel` The model name of the User, defaults to User.
|
||||
* - `userFields` Array of fields to retrieve from User model, null to retrieve all. Defaults to null.
|
||||
* - `scope` Additional conditions to use when looking up and authenticating users,
|
||||
* i.e. `array('User.is_active' => 1).`
|
||||
* - `recursive` The value of the recursive key passed to find(). Defaults to 0.
|
||||
* - `contain` Extra models to contain and store in session.
|
||||
* - `realm` The realm authentication is for, Defaults to the servername.
|
||||
* - `nonce` A nonce used for authentication. Defaults to `uniqid()`.
|
||||
* - `nonce` A nonce used for authentication. Defaults to `uniqid()`.
|
||||
* - `qop` Defaults to auth, no other values are supported at this time.
|
||||
* - `opaque` A string that must be returned unchanged by clients.
|
||||
* Defaults to `md5($settings['realm'])`
|
||||
|
|
@ -79,13 +79,15 @@ class DigestAuthenticate extends BaseAuthenticate {
|
|||
'password' => 'password'
|
||||
),
|
||||
'userModel' => 'User',
|
||||
'userFields' => null,
|
||||
'scope' => array(),
|
||||
'recursive' => 0,
|
||||
'contain' => null,
|
||||
'realm' => '',
|
||||
'qop' => 'auth',
|
||||
'nonce' => '',
|
||||
'opaque' => ''
|
||||
'opaque' => '',
|
||||
'passwordHasher' => 'Simple',
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
@ -96,9 +98,6 @@ class DigestAuthenticate extends BaseAuthenticate {
|
|||
*/
|
||||
public function __construct(ComponentCollection $collection, $settings) {
|
||||
parent::__construct($collection, $settings);
|
||||
if (empty($this->settings['realm'])) {
|
||||
$this->settings['realm'] = env('SERVER_NAME');
|
||||
}
|
||||
if (empty($this->settings['nonce'])) {
|
||||
$this->settings['nonce'] = uniqid('');
|
||||
}
|
||||
|
|
@ -108,37 +107,21 @@ class DigestAuthenticate extends BaseAuthenticate {
|
|||
}
|
||||
|
||||
/**
|
||||
* Authenticate a user using Digest HTTP auth. Will use the configured User model and attempt a
|
||||
* login using Digest HTTP auth.
|
||||
*
|
||||
* @param CakeRequest $request The request to authenticate with.
|
||||
* @param CakeResponse $response The response to add headers to.
|
||||
* @return mixed Either false on failure, or an array of user data on success.
|
||||
*/
|
||||
public function authenticate(CakeRequest $request, CakeResponse $response) {
|
||||
$user = $this->getUser($request);
|
||||
|
||||
if (empty($user)) {
|
||||
$response->header($this->loginHeaders());
|
||||
$response->statusCode(401);
|
||||
$response->send();
|
||||
return false;
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a user based on information in the request. Used by cookie-less auth for stateless clients.
|
||||
* Get a user based on information in the request. Used by cookie-less auth for stateless clients.
|
||||
*
|
||||
* @param CakeRequest $request Request object.
|
||||
* @return mixed Either false or an array of user information
|
||||
*/
|
||||
public function getUser($request) {
|
||||
public function getUser(CakeRequest $request) {
|
||||
$digest = $this->_getDigest();
|
||||
if (empty($digest)) {
|
||||
return false;
|
||||
}
|
||||
$user = $this->_findUser($digest['username'], null);
|
||||
|
||||
list(, $model) = pluginSplit($this->settings['userModel']);
|
||||
$user = $this->_findUser(array(
|
||||
$model . '.' . $this->settings['fields']['username'] => $digest['username']
|
||||
));
|
||||
if (empty($user)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -150,34 +133,6 @@ class DigestAuthenticate extends BaseAuthenticate {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a user record using the standard options.
|
||||
*
|
||||
* @param string $username The username/identifier.
|
||||
* @param string $password Unused password, digest doesn't require passwords.
|
||||
* @return Mixed Either false on failure, or an array of user data.
|
||||
*/
|
||||
protected function _findUser($username, $password) {
|
||||
$userModel = $this->settings['userModel'];
|
||||
list($plugin, $model) = pluginSplit($userModel);
|
||||
$fields = $this->settings['fields'];
|
||||
|
||||
$conditions = array(
|
||||
$model . '.' . $fields['username'] => $username,
|
||||
);
|
||||
if (!empty($this->settings['scope'])) {
|
||||
$conditions = array_merge($conditions, $this->settings['scope']);
|
||||
}
|
||||
$result = ClassRegistry::init($userModel)->find('first', array(
|
||||
'conditions' => $conditions,
|
||||
'recursive' => $this->settings['recursive']
|
||||
));
|
||||
if (empty($result) || empty($result[$model])) {
|
||||
return false;
|
||||
}
|
||||
return $result[$model];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the digest headers from the request/environment.
|
||||
*
|
||||
|
|
@ -187,7 +142,7 @@ class DigestAuthenticate extends BaseAuthenticate {
|
|||
$digest = env('PHP_AUTH_DIGEST');
|
||||
if (empty($digest) && function_exists('apache_request_headers')) {
|
||||
$headers = apache_request_headers();
|
||||
if (!empty($headers['Authorization']) && substr($headers['Authorization'], 0, 7) == 'Digest ') {
|
||||
if (!empty($headers['Authorization']) && substr($headers['Authorization'], 0, 7) === 'Digest ') {
|
||||
$digest = substr($headers['Authorization'], 7);
|
||||
}
|
||||
}
|
||||
|
|
@ -201,15 +156,15 @@ class DigestAuthenticate extends BaseAuthenticate {
|
|||
* Parse the digest authentication headers and split them up.
|
||||
*
|
||||
* @param string $digest The raw digest authentication headers.
|
||||
* @return array An array of digest authentication headers
|
||||
* @return array|null An array of digest authentication headers
|
||||
*/
|
||||
public function parseAuthData($digest) {
|
||||
if (substr($digest, 0, 7) == 'Digest ') {
|
||||
if (substr($digest, 0, 7) === 'Digest ') {
|
||||
$digest = substr($digest, 7);
|
||||
}
|
||||
$keys = $match = array();
|
||||
$req = array('nonce' => 1, 'nc' => 1, 'cnonce' => 1, 'qop' => 1, 'username' => 1, 'uri' => 1, 'response' => 1);
|
||||
preg_match_all('/(\w+)=([\'"]?)([a-zA-Z0-9@=.\/_-]+)\2/', $digest, $match, PREG_SET_ORDER);
|
||||
preg_match_all('/(\w+)=([\'"]?)([a-zA-Z0-9\:\#\%\?\&@=\.\/_-]+)\2/', $digest, $match, PREG_SET_ORDER);
|
||||
|
||||
foreach ($match as $i) {
|
||||
$keys[$i[1]] = $i[3];
|
||||
|
|
|
|||
|
|
@ -1,31 +1,30 @@
|
|||
<?php
|
||||
/**
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('BaseAuthenticate', 'Controller/Component/Auth');
|
||||
|
||||
/**
|
||||
* An authentication adapter for AuthComponent. Provides the ability to authenticate using POST
|
||||
* data. Can be used by configuring AuthComponent to use it via the AuthComponent::$authenticate setting.
|
||||
* An authentication adapter for AuthComponent. Provides the ability to authenticate using POST
|
||||
* data. Can be used by configuring AuthComponent to use it via the AuthComponent::$authenticate setting.
|
||||
*
|
||||
* {{{
|
||||
* ```
|
||||
* $this->Auth->authenticate = array(
|
||||
* 'Form' => array(
|
||||
* 'scope' => array('User.active' => 1)
|
||||
* )
|
||||
* )
|
||||
* }}}
|
||||
* ```
|
||||
*
|
||||
* When configuring FormAuthenticate you can pass in settings to which fields, model and additional conditions
|
||||
* are used. See FormAuthenticate::$settings for more information.
|
||||
|
|
@ -37,26 +36,41 @@ App::uses('BaseAuthenticate', 'Controller/Component/Auth');
|
|||
class FormAuthenticate extends BaseAuthenticate {
|
||||
|
||||
/**
|
||||
* Authenticates the identity contained in a request. Will use the `settings.userModel`, and `settings.fields`
|
||||
* to find POST data that is used to find a matching record in the `settings.userModel`. Will return false if
|
||||
* there is no post data, either username or password is missing, of if the scope conditions have not been met.
|
||||
* Checks the fields to ensure they are supplied.
|
||||
*
|
||||
* @param CakeRequest $request The request that contains login information.
|
||||
* @param CakeResponse $response Unused response object.
|
||||
* @return mixed. False on login failure. An array of User data on success.
|
||||
* @param string $model The model used for login verification.
|
||||
* @param array $fields The fields to be checked.
|
||||
* @return bool False if the fields have not been supplied. True if they exist.
|
||||
*/
|
||||
public function authenticate(CakeRequest $request, CakeResponse $response) {
|
||||
$userModel = $this->settings['userModel'];
|
||||
list($plugin, $model) = pluginSplit($userModel);
|
||||
|
||||
$fields = $this->settings['fields'];
|
||||
protected function _checkFields(CakeRequest $request, $model, $fields) {
|
||||
if (empty($request->data[$model])) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
empty($request->data[$model][$fields['username']]) ||
|
||||
empty($request->data[$model][$fields['password']])
|
||||
) {
|
||||
foreach (array($fields['username'], $fields['password']) as $field) {
|
||||
$value = $request->data($model . '.' . $field);
|
||||
if (empty($value) && $value !== '0' || !is_string($value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticates the identity contained in a request. Will use the `settings.userModel`, and `settings.fields`
|
||||
* to find POST data that is used to find a matching record in the `settings.userModel`. Will return false if
|
||||
* there is no post data, either username or password is missing, or if the scope conditions have not been met.
|
||||
*
|
||||
* @param CakeRequest $request The request that contains login information.
|
||||
* @param CakeResponse $response Unused response object.
|
||||
* @return mixed False on login failure. An array of User data on success.
|
||||
*/
|
||||
public function authenticate(CakeRequest $request, CakeResponse $response) {
|
||||
$userModel = $this->settings['userModel'];
|
||||
list(, $model) = pluginSplit($userModel);
|
||||
|
||||
$fields = $this->settings['fields'];
|
||||
if (!$this->_checkFields($request, $model, $fields)) {
|
||||
return false;
|
||||
}
|
||||
return $this->_findUser(
|
||||
|
|
|
|||
55
lib/Cake/Controller/Component/Auth/SimplePasswordHasher.php
Normal file
55
lib/Cake/Controller/Component/Auth/SimplePasswordHasher.php
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @since CakePHP(tm) v 2.4.0
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('AbstractPasswordHasher', 'Controller/Component/Auth');
|
||||
App::uses('Security', 'Utility');
|
||||
|
||||
/**
|
||||
* Simple password hashing class.
|
||||
*
|
||||
* @package Cake.Controller.Component.Auth
|
||||
*/
|
||||
class SimplePasswordHasher extends AbstractPasswordHasher {
|
||||
|
||||
/**
|
||||
* Config for this object.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_config = array('hashType' => null);
|
||||
|
||||
/**
|
||||
* Generates password hash.
|
||||
*
|
||||
* @param string $password Plain text password to hash.
|
||||
* @return string Password hash
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#hashing-passwords
|
||||
*/
|
||||
public function hash($password) {
|
||||
return Security::hash($password, $this->_config['hashType'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check hash. Generate hash for user provided password and check against existing hash.
|
||||
*
|
||||
* @param string $password Plain text password to hash.
|
||||
* @param string $hashedPassword Existing hashed password.
|
||||
* @return bool True if hashes match else false.
|
||||
*/
|
||||
public function check($password, $hashedPassword) {
|
||||
return $hashedPassword === $this->hash($password);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4,19 +4,18 @@
|
|||
*
|
||||
* Manages user logins and permissions.
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Controller.Component
|
||||
* @since CakePHP(tm) v 0.10.0.1076
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('Component', 'Controller');
|
||||
|
|
@ -27,6 +26,7 @@ App::uses('Hash', 'Utility');
|
|||
App::uses('CakeSession', 'Model/Datasource');
|
||||
App::uses('BaseAuthorize', 'Controller/Component/Auth');
|
||||
App::uses('BaseAuthenticate', 'Controller/Component/Auth');
|
||||
App::uses('CakeEvent', 'Event');
|
||||
|
||||
/**
|
||||
* Authentication control component class
|
||||
|
|
@ -38,6 +38,11 @@ App::uses('BaseAuthenticate', 'Controller/Component/Auth');
|
|||
*/
|
||||
class AuthComponent extends Component {
|
||||
|
||||
/**
|
||||
* Constant for 'all'
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const ALL = 'all';
|
||||
|
||||
/**
|
||||
|
|
@ -45,25 +50,25 @@ class AuthComponent extends Component {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public $components = array('Session', 'RequestHandler');
|
||||
public $components = array('Session', 'Flash', 'RequestHandler');
|
||||
|
||||
/**
|
||||
* An array of authentication objects to use for authenticating users. You can configure
|
||||
* An array of authentication objects to use for authenticating users. You can configure
|
||||
* multiple adapters and they will be checked sequentially when users are identified.
|
||||
*
|
||||
* {{{
|
||||
* ```
|
||||
* $this->Auth->authenticate = array(
|
||||
* 'Form' => array(
|
||||
* 'userModel' => 'Users.User'
|
||||
* )
|
||||
* );
|
||||
* }}}
|
||||
* ```
|
||||
*
|
||||
* Using the class name without 'Authenticate' as the key, you can pass in an array of settings for each
|
||||
* authentication object. Additionally you can define settings that should be set to all authentications objects
|
||||
* authentication object. Additionally you can define settings that should be set to all authentications objects
|
||||
* using the 'all' key:
|
||||
*
|
||||
* {{{
|
||||
* ```
|
||||
* $this->Auth->authenticate = array(
|
||||
* 'all' => array(
|
||||
* 'userModel' => 'Users.User',
|
||||
|
|
@ -72,7 +77,7 @@ class AuthComponent extends Component {
|
|||
* 'Form',
|
||||
* 'Basic'
|
||||
* );
|
||||
* }}}
|
||||
* ```
|
||||
*
|
||||
* You can also use AuthComponent::ALL instead of the string 'all'.
|
||||
*
|
||||
|
|
@ -84,27 +89,27 @@ class AuthComponent extends Component {
|
|||
/**
|
||||
* Objects that will be used for authentication checks.
|
||||
*
|
||||
* @var array
|
||||
* @var BaseAuthenticate[]
|
||||
*/
|
||||
protected $_authenticateObjects = array();
|
||||
|
||||
/**
|
||||
* An array of authorization objects to use for authorizing users. You can configure
|
||||
* An array of authorization objects to use for authorizing users. You can configure
|
||||
* multiple adapters and they will be checked sequentially when authorization checks are done.
|
||||
*
|
||||
* {{{
|
||||
* ```
|
||||
* $this->Auth->authorize = array(
|
||||
* 'Crud' => array(
|
||||
* 'actionPath' => 'controllers/'
|
||||
* )
|
||||
* );
|
||||
* }}}
|
||||
* ```
|
||||
*
|
||||
* Using the class name without 'Authorize' as the key, you can pass in an array of settings for each
|
||||
* authorization object. Additionally you can define settings that should be set to all authorization objects
|
||||
* authorization object. Additionally you can define settings that should be set to all authorization objects
|
||||
* using the 'all' key:
|
||||
*
|
||||
* {{{
|
||||
* ```
|
||||
* $this->Auth->authorize = array(
|
||||
* 'all' => array(
|
||||
* 'actionPath' => 'controllers/'
|
||||
|
|
@ -112,7 +117,7 @@ class AuthComponent extends Component {
|
|||
* 'Crud',
|
||||
* 'CustomAuth'
|
||||
* );
|
||||
* }}}
|
||||
* ```
|
||||
*
|
||||
* You can also use AuthComponent::ALL instead of the string 'all'
|
||||
*
|
||||
|
|
@ -124,7 +129,7 @@ class AuthComponent extends Component {
|
|||
/**
|
||||
* Objects that will be used for authorization checks.
|
||||
*
|
||||
* @var array
|
||||
* @var BaseAuthorize[]
|
||||
*/
|
||||
protected $_authorizeObjects = array();
|
||||
|
||||
|
|
@ -153,8 +158,9 @@ class AuthComponent extends Component {
|
|||
);
|
||||
|
||||
/**
|
||||
* The session key name where the record of the current user is stored. If
|
||||
* unspecified, it will be "Auth.User".
|
||||
* The session key name where the record of the current user is stored. Default
|
||||
* key is "Auth.User". If you are using only stateless authenticators set this
|
||||
* to false to ensure session is not started.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
|
@ -170,7 +176,7 @@ class AuthComponent extends Component {
|
|||
|
||||
/**
|
||||
* A URL (defined as a string or array) to the controller action that handles
|
||||
* logins. Defaults to `/users/login`
|
||||
* logins. Defaults to `/users/login`.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
|
|
@ -183,8 +189,8 @@ class AuthComponent extends Component {
|
|||
/**
|
||||
* Normally, if a user is redirected to the $loginAction page, the location they
|
||||
* were redirected from will be stored in the session so that they can be
|
||||
* redirected back after a successful login. If this session value is not
|
||||
* set, the user will be redirected to the page specified in $loginRedirect.
|
||||
* redirected back after a successful login. If this session value is not
|
||||
* set, redirectUrl() method will return the URL specified in $loginRedirect.
|
||||
*
|
||||
* @var mixed
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#AuthComponent::$loginRedirect
|
||||
|
|
@ -192,7 +198,7 @@ class AuthComponent extends Component {
|
|||
public $loginRedirect = null;
|
||||
|
||||
/**
|
||||
* The default action to redirect to after the user is logged out. While AuthComponent does
|
||||
* The default action to redirect to after the user is logged out. While AuthComponent does
|
||||
* not handle post-logout redirection, a redirect URL will be returned from AuthComponent::logout().
|
||||
* Defaults to AuthComponent::$loginAction.
|
||||
*
|
||||
|
|
@ -206,11 +212,22 @@ class AuthComponent extends Component {
|
|||
* Error to display when user attempts to access an object or action to which they do not have
|
||||
* access.
|
||||
*
|
||||
* @var string
|
||||
* @var string|bool
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#AuthComponent::$authError
|
||||
*/
|
||||
public $authError = null;
|
||||
|
||||
/**
|
||||
* Controls handling of unauthorized access.
|
||||
* - For default value `true` unauthorized user is redirected to the referrer URL
|
||||
* or AuthComponent::$loginRedirect or '/'.
|
||||
* - If set to a string or array the value is used as a URL to redirect to.
|
||||
* - If set to false a ForbiddenException exception is thrown instead of redirecting.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $unauthorizedRedirect = true;
|
||||
|
||||
/**
|
||||
* Controller actions for which user validation is not required.
|
||||
*
|
||||
|
|
@ -234,14 +251,14 @@ class AuthComponent extends Component {
|
|||
public $response;
|
||||
|
||||
/**
|
||||
* Method list for bound controller
|
||||
* Method list for bound controller.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_methods = array();
|
||||
|
||||
/**
|
||||
* Initializes AuthComponent for use in the controller
|
||||
* Initializes AuthComponent for use in the controller.
|
||||
*
|
||||
* @param Controller $controller A reference to the instantiating controller object
|
||||
* @return void
|
||||
|
|
@ -257,11 +274,11 @@ class AuthComponent extends Component {
|
|||
}
|
||||
|
||||
/**
|
||||
* Main execution method. Handles redirecting of invalid users, and processing
|
||||
* Main execution method. Handles redirecting of invalid users, and processing
|
||||
* of login form data.
|
||||
*
|
||||
* @param Controller $controller A reference to the instantiating controller object
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function startup(Controller $controller) {
|
||||
$methods = array_flip(array_map('strtolower', $controller->methods));
|
||||
|
|
@ -279,67 +296,137 @@ class AuthComponent extends Component {
|
|||
if (!$this->_setDefaults()) {
|
||||
return false;
|
||||
}
|
||||
$request = $controller->request;
|
||||
|
||||
$url = '';
|
||||
|
||||
if (isset($request->url)) {
|
||||
$url = $request->url;
|
||||
}
|
||||
$url = Router::normalize($url);
|
||||
$loginAction = Router::normalize($this->loginAction);
|
||||
|
||||
$allowedActions = $this->allowedActions;
|
||||
$isAllowed = (
|
||||
$this->allowedActions == array('*') ||
|
||||
in_array($action, array_map('strtolower', $allowedActions))
|
||||
);
|
||||
|
||||
if ($loginAction != $url && $isAllowed) {
|
||||
if ($this->_isAllowed($controller)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($loginAction == $url) {
|
||||
if (empty($request->data)) {
|
||||
if (!$this->Session->check('Auth.redirect') && !$this->loginRedirect && env('HTTP_REFERER')) {
|
||||
if (!$this->_getUser()) {
|
||||
return $this->_unauthenticated($controller);
|
||||
}
|
||||
|
||||
if ($this->_isLoginAction($controller) ||
|
||||
empty($this->authorize) ||
|
||||
$this->isAuthorized($this->user())
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->_unauthorized($controller);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether current action is accessible without authentication.
|
||||
*
|
||||
* @param Controller $controller A reference to the instantiating controller object
|
||||
* @return bool True if action is accessible without authentication else false
|
||||
*/
|
||||
protected function _isAllowed(Controller $controller) {
|
||||
$action = strtolower($controller->request->params['action']);
|
||||
if (in_array($action, array_map('strtolower', $this->allowedActions))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles unauthenticated access attempt. First the `unathenticated()` method
|
||||
* of the last authenticator in the chain will be called. The authenticator can
|
||||
* handle sending response or redirection as appropriate and return `true` to
|
||||
* indicate no furthur action is necessary. If authenticator returns null this
|
||||
* method redirects user to login action. If it's an ajax request and
|
||||
* $ajaxLogin is specified that element is rendered else a 403 http status code
|
||||
* is returned.
|
||||
*
|
||||
* @param Controller $controller A reference to the controller object.
|
||||
* @return bool True if current action is login action else false.
|
||||
*/
|
||||
protected function _unauthenticated(Controller $controller) {
|
||||
if (empty($this->_authenticateObjects)) {
|
||||
$this->constructAuthenticate();
|
||||
}
|
||||
$auth = $this->_authenticateObjects[count($this->_authenticateObjects) - 1];
|
||||
if ($auth->unauthenticated($this->request, $this->response)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->_isLoginAction($controller)) {
|
||||
if (empty($controller->request->data)) {
|
||||
if (!$this->Session->check('Auth.redirect') && env('HTTP_REFERER')) {
|
||||
$this->Session->write('Auth.redirect', $controller->referer(null, true));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if (!$this->_getUser()) {
|
||||
if (!$request->is('ajax')) {
|
||||
$this->flash($this->authError);
|
||||
$this->Session->write('Auth.redirect', $request->here());
|
||||
$controller->redirect($loginAction);
|
||||
return false;
|
||||
} elseif (!empty($this->ajaxLogin)) {
|
||||
$controller->viewPath = 'Elements';
|
||||
echo $controller->render($this->ajaxLogin, $this->RequestHandler->ajaxLayout);
|
||||
$this->_stop();
|
||||
return false;
|
||||
} else {
|
||||
$controller->redirect(null, 403);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($this->authorize) || $this->isAuthorized($this->user())) {
|
||||
return true;
|
||||
|
||||
if (!$controller->request->is('ajax') && !$controller->request->is('json')) {
|
||||
$this->flash($this->authError);
|
||||
$this->Session->write('Auth.redirect', $controller->request->here(false));
|
||||
$controller->redirect($this->loginAction);
|
||||
return false;
|
||||
}
|
||||
if (!empty($this->ajaxLogin)) {
|
||||
$controller->response->statusCode(403);
|
||||
$controller->viewPath = 'Elements';
|
||||
$response = $controller->render($this->ajaxLogin, $this->RequestHandler->ajaxLayout);
|
||||
$response->send();
|
||||
$this->_stop();
|
||||
return false;
|
||||
}
|
||||
$controller->response->statusCode(403);
|
||||
$controller->response->send();
|
||||
$this->_stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes $loginAction and checks if current request URL is same as login action.
|
||||
*
|
||||
* @param Controller $controller A reference to the controller object.
|
||||
* @return bool True if current action is login action else false.
|
||||
*/
|
||||
protected function _isLoginAction(Controller $controller) {
|
||||
$url = '';
|
||||
if (isset($controller->request->url)) {
|
||||
$url = $controller->request->url;
|
||||
}
|
||||
$url = Router::normalize($url);
|
||||
$loginAction = Router::normalize($this->loginAction);
|
||||
|
||||
return $loginAction === $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle unauthorized access attempt
|
||||
*
|
||||
* @param Controller $controller A reference to the controller object
|
||||
* @return bool Returns false
|
||||
* @throws ForbiddenException
|
||||
* @see AuthComponent::$unauthorizedRedirect
|
||||
*/
|
||||
protected function _unauthorized(Controller $controller) {
|
||||
if ($this->unauthorizedRedirect === false) {
|
||||
throw new ForbiddenException($this->authError);
|
||||
}
|
||||
|
||||
$this->flash($this->authError);
|
||||
$default = '/';
|
||||
if (!empty($this->loginRedirect)) {
|
||||
$default = $this->loginRedirect;
|
||||
if ($this->unauthorizedRedirect === true) {
|
||||
$default = '/';
|
||||
if (!empty($this->loginRedirect)) {
|
||||
$default = $this->loginRedirect;
|
||||
}
|
||||
$url = $controller->referer($default, true);
|
||||
} else {
|
||||
$url = $this->unauthorizedRedirect;
|
||||
}
|
||||
$controller->redirect($controller->referer($default, true), null, true);
|
||||
$controller->redirect($url);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to introspect the correct values for object properties.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool True
|
||||
*/
|
||||
protected function _setDefaults() {
|
||||
$defaults = array(
|
||||
|
|
@ -347,7 +434,7 @@ class AuthComponent extends Component {
|
|||
'authError' => __d('cake', 'You are not authorized to access that location.')
|
||||
);
|
||||
foreach ($defaults as $key => $value) {
|
||||
if (empty($this->{$key})) {
|
||||
if (!isset($this->{$key}) || $this->{$key} === true) {
|
||||
$this->{$key} = $value;
|
||||
}
|
||||
}
|
||||
|
|
@ -355,18 +442,21 @@ class AuthComponent extends Component {
|
|||
}
|
||||
|
||||
/**
|
||||
* Check if the provided user is authorized for the request.
|
||||
*
|
||||
* Uses the configured Authorization adapters to check whether or not a user is authorized.
|
||||
* Each adapter will be checked in sequence, if any of them return true, then the user will
|
||||
* be authorized for the request.
|
||||
*
|
||||
* @param array $user The user to check the authorization of. If empty the user in the session will be used.
|
||||
* @param CakeRequest $request The request to authenticate for. If empty, the current request will be used.
|
||||
* @return boolean True if $user is authorized, otherwise false
|
||||
* @param array|null $user The user to check the authorization of. If empty the user in the session will be used.
|
||||
* @param CakeRequest|null $request The request to authenticate for. If empty, the current request will be used.
|
||||
* @return bool True if $user is authorized, otherwise false
|
||||
*/
|
||||
public function isAuthorized($user = null, $request = null) {
|
||||
public function isAuthorized($user = null, CakeRequest $request = null) {
|
||||
if (empty($user) && !$this->user()) {
|
||||
return false;
|
||||
} elseif (empty($user)) {
|
||||
}
|
||||
if (empty($user)) {
|
||||
$user = $this->user();
|
||||
}
|
||||
if (empty($request)) {
|
||||
|
|
@ -391,7 +481,7 @@ class AuthComponent extends Component {
|
|||
*/
|
||||
public function constructAuthorize() {
|
||||
if (empty($this->authorize)) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
$this->_authorizeObjects = array();
|
||||
$config = Hash::normalize((array)$this->authorize);
|
||||
|
|
@ -408,7 +498,7 @@ class AuthComponent extends Component {
|
|||
throw new CakeException(__d('cake_dev', 'Authorization adapter "%s" was not found.', $class));
|
||||
}
|
||||
if (!method_exists($className, 'authorize')) {
|
||||
throw new CakeException(__d('cake_dev', 'Authorization objects must implement an authorize method.'));
|
||||
throw new CakeException(__d('cake_dev', 'Authorization objects must implement an %s method.', 'authorize()'));
|
||||
}
|
||||
$settings = array_merge($global, (array)$settings);
|
||||
$this->_authorizeObjects[] = new $className($this->_Collection, $settings);
|
||||
|
|
@ -426,7 +516,7 @@ class AuthComponent extends Component {
|
|||
* `$this->Auth->allow('edit', 'add');` or
|
||||
* `$this->Auth->allow();` to allow all actions
|
||||
*
|
||||
* @param string|array $action,... Controller action name or array of actions
|
||||
* @param string|array|null $action Controller action name or array of actions
|
||||
* @return void
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#making-actions-public
|
||||
*/
|
||||
|
|
@ -434,12 +524,12 @@ class AuthComponent extends Component {
|
|||
$args = func_get_args();
|
||||
if (empty($args) || $action === null) {
|
||||
$this->allowedActions = $this->_methods;
|
||||
} else {
|
||||
if (isset($args[0]) && is_array($args[0])) {
|
||||
$args = $args[0];
|
||||
}
|
||||
$this->allowedActions = array_merge($this->allowedActions, $args);
|
||||
return;
|
||||
}
|
||||
if (isset($args[0]) && is_array($args[0])) {
|
||||
$args = $args[0];
|
||||
}
|
||||
$this->allowedActions = array_merge($this->allowedActions, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -451,7 +541,7 @@ class AuthComponent extends Component {
|
|||
* `$this->Auth->deny('edit', 'add');` or
|
||||
* `$this->Auth->deny();` to remove all items from the allowed list
|
||||
*
|
||||
* @param string|array $action,... Controller action name or array of actions
|
||||
* @param string|array|null $action Controller action name or array of actions
|
||||
* @return void
|
||||
* @see AuthComponent::allow()
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#making-actions-require-authorization
|
||||
|
|
@ -460,47 +550,58 @@ class AuthComponent extends Component {
|
|||
$args = func_get_args();
|
||||
if (empty($args) || $action === null) {
|
||||
$this->allowedActions = array();
|
||||
} else {
|
||||
if (isset($args[0]) && is_array($args[0])) {
|
||||
$args = $args[0];
|
||||
}
|
||||
foreach ($args as $arg) {
|
||||
$i = array_search($arg, $this->allowedActions);
|
||||
if (is_int($i)) {
|
||||
unset($this->allowedActions[$i]);
|
||||
}
|
||||
}
|
||||
$this->allowedActions = array_values($this->allowedActions);
|
||||
return;
|
||||
}
|
||||
if (isset($args[0]) && is_array($args[0])) {
|
||||
$args = $args[0];
|
||||
}
|
||||
foreach ($args as $arg) {
|
||||
$i = array_search($arg, $this->allowedActions);
|
||||
if (is_int($i)) {
|
||||
unset($this->allowedActions[$i]);
|
||||
}
|
||||
}
|
||||
$this->allowedActions = array_values($this->allowedActions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps action names to CRUD operations. Used for controller-based authentication. Make sure
|
||||
* Maps action names to CRUD operations.
|
||||
*
|
||||
* Used for controller-based authentication. Make sure
|
||||
* to configure the authorize property before calling this method. As it delegates $map to all the
|
||||
* attached authorize objects.
|
||||
*
|
||||
* @param array $map Actions to map
|
||||
* @return void
|
||||
* @return array
|
||||
* @see BaseAuthorize::mapActions()
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#mapping-actions-when-using-crudauthorize
|
||||
* @deprecated 3.0.0 Map actions using `actionMap` config key on authorize objects instead
|
||||
*/
|
||||
public function mapActions($map = array()) {
|
||||
if (empty($this->_authorizeObjects)) {
|
||||
$this->constructAuthorize();
|
||||
}
|
||||
$mappedActions = array();
|
||||
foreach ($this->_authorizeObjects as $auth) {
|
||||
$auth->mapActions($map);
|
||||
$mappedActions = Hash::merge($mappedActions, $auth->mapActions($map));
|
||||
}
|
||||
if (empty($map)) {
|
||||
return $mappedActions;
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a user in. If a $user is provided that data will be stored as the logged in user. If `$user` is empty or not
|
||||
* Log a user in.
|
||||
*
|
||||
* If a $user is provided that data will be stored as the logged in user. If `$user` is empty or not
|
||||
* specified, the request will be used to identify a user. If the identification was successful,
|
||||
* the user record is written to the session key specified in AuthComponent::$sessionKey. Logging in
|
||||
* will also change the session id in order to help mitigate session replays.
|
||||
*
|
||||
* @param array $user Either an array of user data, or null to identify a user using the current request.
|
||||
* @return boolean True on login success, false on failure
|
||||
* @param array|null $user Either an array of user data, or null to identify a user using the current request.
|
||||
* @return bool True on login success, false on failure
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#identifying-users-and-logging-them-in
|
||||
*/
|
||||
public function login($user = null) {
|
||||
|
|
@ -510,18 +611,26 @@ class AuthComponent extends Component {
|
|||
$user = $this->identify($this->request, $this->response);
|
||||
}
|
||||
if ($user) {
|
||||
$this->Session->renew();
|
||||
$this->Session->write(self::$sessionKey, $user);
|
||||
if (static::$sessionKey) {
|
||||
$this->Session->renew();
|
||||
$this->Session->write(static::$sessionKey, $user);
|
||||
} else {
|
||||
static::$_user = $user;
|
||||
}
|
||||
$event = new CakeEvent('Auth.afterIdentify', $this, array('user' => $user));
|
||||
$this->_Collection->getController()->getEventManager()->dispatch($event);
|
||||
}
|
||||
return $this->loggedIn();
|
||||
return (bool)$this->user();
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a user out, and returns the login action to redirect to.
|
||||
* Triggers the logout() method of all the authenticate objects, so they can perform
|
||||
* custom logout logic. AuthComponent will remove the session data, so
|
||||
* there is no need to do that in an authentication object. Logging out
|
||||
* will also renew the session id. This helps mitigate issues with session replays.
|
||||
* Log a user out.
|
||||
*
|
||||
* Returns the logout action to redirect to. Triggers the logout() method of
|
||||
* all the authenticate objects, so they can perform custom logout logic.
|
||||
* AuthComponent will remove the session data, so there is no need to do that
|
||||
* in an authentication object. Logging out will also renew the session id.
|
||||
* This helps mitigate issues with session replays.
|
||||
*
|
||||
* @return string AuthComponent::$logoutRedirect
|
||||
* @see AuthComponent::$logoutRedirect
|
||||
|
|
@ -536,7 +645,7 @@ class AuthComponent extends Component {
|
|||
foreach ($this->_authenticateObjects as $auth) {
|
||||
$auth->logout($user);
|
||||
}
|
||||
$this->Session->delete(self::$sessionKey);
|
||||
$this->Session->delete(static::$sessionKey);
|
||||
$this->Session->delete('Auth.redirect');
|
||||
$this->Session->renew();
|
||||
return Router::normalize($this->logoutRedirect);
|
||||
|
|
@ -545,22 +654,21 @@ class AuthComponent extends Component {
|
|||
/**
|
||||
* Get the current user.
|
||||
*
|
||||
* Will prefer the static user cache over sessions. The static user
|
||||
* cache is primarily used for stateless authentication. For stateful authentication,
|
||||
* Will prefer the static user cache over sessions. The static user
|
||||
* cache is primarily used for stateless authentication. For stateful authentication,
|
||||
* cookies + sessions will be used.
|
||||
*
|
||||
* @param string $key field to retrieve. Leave null to get entire User record
|
||||
* @return mixed User record. or null if no user is logged in.
|
||||
* @param string|null $key field to retrieve. Leave null to get entire User record
|
||||
* @return mixed|null User record. or null if no user is logged in.
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#accessing-the-logged-in-user
|
||||
*/
|
||||
public static function user($key = null) {
|
||||
if (empty(self::$_user) && !CakeSession::check(self::$sessionKey)) {
|
||||
return null;
|
||||
}
|
||||
if (!empty(self::$_user)) {
|
||||
$user = self::$_user;
|
||||
if (!empty(static::$_user)) {
|
||||
$user = static::$_user;
|
||||
} elseif (static::$sessionKey && CakeSession::check(static::$sessionKey)) {
|
||||
$user = CakeSession::read(static::$sessionKey);
|
||||
} else {
|
||||
$user = CakeSession::read(self::$sessionKey);
|
||||
return null;
|
||||
}
|
||||
if ($key === null) {
|
||||
return $user;
|
||||
|
|
@ -570,51 +678,80 @@ class AuthComponent extends Component {
|
|||
|
||||
/**
|
||||
* Similar to AuthComponent::user() except if the session user cannot be found, connected authentication
|
||||
* objects will have their getUser() methods called. This lets stateless authentication methods function correctly.
|
||||
* objects will have their getUser() methods called. This lets stateless authentication methods function correctly.
|
||||
*
|
||||
* @return boolean true if a user can be found, false if one cannot.
|
||||
* @return bool True if a user can be found, false if one cannot.
|
||||
*/
|
||||
protected function _getUser() {
|
||||
$user = $this->user();
|
||||
if ($user) {
|
||||
$this->Session->delete('Auth.redirect');
|
||||
return true;
|
||||
}
|
||||
|
||||
if (empty($this->_authenticateObjects)) {
|
||||
$this->constructAuthenticate();
|
||||
}
|
||||
foreach ($this->_authenticateObjects as $auth) {
|
||||
$result = $auth->getUser($this->request);
|
||||
if (!empty($result) && is_array($result)) {
|
||||
self::$_user = $result;
|
||||
static::$_user = $result;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If no parameter is passed, gets the authentication redirect URL. Pass a url in to
|
||||
* set the destination a user should be redirected to upon logging in. Will fallback to
|
||||
* AuthComponent::$loginRedirect if there is no stored redirect value.
|
||||
* Backwards compatible alias for AuthComponent::redirectUrl().
|
||||
*
|
||||
* @param string|array $url Optional URL to write as the login redirect URL.
|
||||
* @param string|array|null $url Optional URL to write as the login redirect URL.
|
||||
* @return string Redirect URL
|
||||
* @deprecated 3.0.0 Since 2.3.0, use AuthComponent::redirectUrl() instead
|
||||
*/
|
||||
public function redirect($url = null) {
|
||||
if (!is_null($url)) {
|
||||
return $this->redirectUrl($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL a user should be redirected to upon login.
|
||||
*
|
||||
* Pass a URL in to set the destination a user should be redirected to upon
|
||||
* logging in.
|
||||
*
|
||||
* If no parameter is passed, gets the authentication redirect URL. The URL
|
||||
* returned is as per following rules:
|
||||
*
|
||||
* - Returns the normalized URL from session Auth.redirect value if it is
|
||||
* present and for the same domain the current app is running on.
|
||||
* - If there is no session value and there is a $loginRedirect, the $loginRedirect
|
||||
* value is returned.
|
||||
* - If there is no session and no $loginRedirect, / is returned.
|
||||
*
|
||||
* @param string|array|null $url Optional URL to write as the login redirect URL.
|
||||
* @return string Redirect URL
|
||||
*/
|
||||
public function redirectUrl($url = null) {
|
||||
if ($url !== null) {
|
||||
$redir = $url;
|
||||
$this->Session->write('Auth.redirect', $redir);
|
||||
} elseif ($this->Session->check('Auth.redirect')) {
|
||||
$redir = $this->Session->read('Auth.redirect');
|
||||
$this->Session->delete('Auth.redirect');
|
||||
|
||||
if (Router::normalize($redir) == Router::normalize($this->loginAction)) {
|
||||
$redir = $this->loginRedirect;
|
||||
if (Router::normalize($redir) === Router::normalize($this->loginAction)) {
|
||||
$redir = $this->loginRedirect ?: '/';
|
||||
}
|
||||
} else {
|
||||
} elseif ($this->loginRedirect) {
|
||||
$redir = $this->loginRedirect;
|
||||
} else {
|
||||
$redir = '/';
|
||||
}
|
||||
return Router::normalize($redir);
|
||||
if (is_array($redir)) {
|
||||
return Router::url($redir + array('base' => false));
|
||||
}
|
||||
return $redir;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -639,14 +776,14 @@ class AuthComponent extends Component {
|
|||
}
|
||||
|
||||
/**
|
||||
* loads the configured authentication objects.
|
||||
* Loads the configured authentication objects.
|
||||
*
|
||||
* @return mixed either null on empty authenticate value, or an array of loaded objects.
|
||||
* @return mixed Either null on empty authenticate value, or an array of loaded objects.
|
||||
* @throws CakeException
|
||||
*/
|
||||
public function constructAuthenticate() {
|
||||
if (empty($this->authenticate)) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
$this->_authenticateObjects = array();
|
||||
$config = Hash::normalize((array)$this->authenticate);
|
||||
|
|
@ -656,6 +793,10 @@ class AuthComponent extends Component {
|
|||
unset($config[AuthComponent::ALL]);
|
||||
}
|
||||
foreach ($config as $class => $settings) {
|
||||
if (!empty($settings['className'])) {
|
||||
$class = $settings['className'];
|
||||
unset($settings['className']);
|
||||
}
|
||||
list($plugin, $class) = pluginSplit($class, true);
|
||||
$className = $class . 'Authenticate';
|
||||
App::uses($className, $plugin . 'Controller/Component/Auth');
|
||||
|
|
@ -663,10 +804,12 @@ class AuthComponent extends Component {
|
|||
throw new CakeException(__d('cake_dev', 'Authentication adapter "%s" was not found.', $class));
|
||||
}
|
||||
if (!method_exists($className, 'authenticate')) {
|
||||
throw new CakeException(__d('cake_dev', 'Authentication objects must implement an authenticate method.'));
|
||||
throw new CakeException(__d('cake_dev', 'Authentication objects must implement an %s method.', 'authenticate()'));
|
||||
}
|
||||
$settings = array_merge($global, (array)$settings);
|
||||
$this->_authenticateObjects[] = new $className($this->_Collection, $settings);
|
||||
$auth = new $className($this->_Collection, $settings);
|
||||
$this->_Collection->getController()->getEventManager()->attach($auth);
|
||||
$this->_authenticateObjects[] = $auth;
|
||||
}
|
||||
return $this->_authenticateObjects;
|
||||
}
|
||||
|
|
@ -674,46 +817,38 @@ class AuthComponent extends Component {
|
|||
/**
|
||||
* Hash a password with the application's salt value (as defined with Configure::write('Security.salt');
|
||||
*
|
||||
* This method is intended as a convenience wrapper for Security::hash(). If you want to use
|
||||
* This method is intended as a convenience wrapper for Security::hash(). If you want to use
|
||||
* a hashing/encryption system not supported by that method, do not use this method.
|
||||
*
|
||||
* @param string $password Password to hash
|
||||
* @return string Hashed password
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#hashing-passwords
|
||||
* @deprecated 3.0.0 Since 2.4. Use Security::hash() directly or a password hasher object.
|
||||
*/
|
||||
public static function password($password) {
|
||||
return Security::hash($password, null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Component shutdown. If user is logged in, wipe out redirect.
|
||||
*
|
||||
* @param Controller $controller Instantiating controller
|
||||
* @return void
|
||||
*/
|
||||
public function shutdown(Controller $controller) {
|
||||
if ($this->loggedIn()) {
|
||||
$this->Session->delete('Auth.redirect');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether or not the current user has data in the session, and is considered logged in.
|
||||
*
|
||||
* @return boolean true if the user is logged in, false otherwise
|
||||
* @return bool true if the user is logged in, false otherwise
|
||||
* @deprecated 3.0.0 Since 2.5. Use AuthComponent::user() directly.
|
||||
*/
|
||||
public function loggedIn() {
|
||||
return $this->user() != array();
|
||||
return (bool)$this->user();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a flash message. Uses the Session component, and values from AuthComponent::$flash.
|
||||
* Set a flash message. Uses the Session component, and values from AuthComponent::$flash.
|
||||
*
|
||||
* @param string $message The message to set.
|
||||
* @return void
|
||||
*/
|
||||
public function flash($message) {
|
||||
$this->Session->setFlash($message, $this->flash['element'], $this->flash['params'], $this->flash['key']);
|
||||
if ($message === false) {
|
||||
return;
|
||||
}
|
||||
$this->Flash->set($message, $this->flash);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,19 +2,18 @@
|
|||
/**
|
||||
* Cookie Component
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Controller.Component
|
||||
* @since CakePHP(tm) v 1.2.0.4213
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('Component', 'Controller');
|
||||
|
|
@ -28,7 +27,6 @@ App::uses('Hash', 'Utility');
|
|||
*
|
||||
* @package Cake.Controller.Component
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html
|
||||
*
|
||||
*/
|
||||
class CookieComponent extends Component {
|
||||
|
||||
|
|
@ -61,7 +59,7 @@ class CookieComponent extends Component {
|
|||
* $this->Cookie->path = '/';
|
||||
*
|
||||
* The path on the server in which the cookie will be available on.
|
||||
* If public $cookiePath is set to '/foo/', the cookie will only be available
|
||||
* If public $cookiePath is set to '/foo/', the cookie will only be available
|
||||
* within the /foo/ directory and all sub-directories such as /foo/bar/ of domain.
|
||||
* The default value is the entire domain.
|
||||
*
|
||||
|
|
@ -93,7 +91,7 @@ class CookieComponent extends Component {
|
|||
* Indicates that the cookie should only be transmitted over a secure HTTPS connection.
|
||||
* When set to true, the cookie will only be set if a secure connection exists.
|
||||
*
|
||||
* @var boolean
|
||||
* @var bool
|
||||
*/
|
||||
public $secure = false;
|
||||
|
||||
|
|
@ -110,10 +108,10 @@ class CookieComponent extends Component {
|
|||
/**
|
||||
* HTTP only cookie
|
||||
*
|
||||
* Set to true to make HTTP only cookies. Cookies that are HTTP only
|
||||
* are not accessible in Javascript.
|
||||
* Set to true to make HTTP only cookies. Cookies that are HTTP only
|
||||
* are not accessible in JavaScript.
|
||||
*
|
||||
* @var boolean
|
||||
* @var bool
|
||||
*/
|
||||
public $httpOnly = false;
|
||||
|
||||
|
|
@ -131,7 +129,9 @@ class CookieComponent extends Component {
|
|||
* Type of encryption to use.
|
||||
*
|
||||
* Currently two methods are available: cipher and rijndael
|
||||
* Defaults to Security::cipher();
|
||||
* Defaults to Security::cipher(). Cipher is horribly insecure and only
|
||||
* the default because of backwards compatibility. In new applications you should
|
||||
* always change this to 'aes' or 'rijndael'.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
|
@ -177,14 +177,14 @@ class CookieComponent extends Component {
|
|||
if ($controller && isset($controller->response)) {
|
||||
$this->_response = $controller->response;
|
||||
} else {
|
||||
$this->_response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
|
||||
$this->_response = new CakeResponse();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start CookieComponent for use in the controller
|
||||
*
|
||||
* @param Controller $controller
|
||||
* @param Controller $controller Controller instance.
|
||||
* @return void
|
||||
*/
|
||||
public function startup(Controller $controller) {
|
||||
|
|
@ -207,8 +207,9 @@ class CookieComponent extends Component {
|
|||
*
|
||||
* @param string|array $key Key for the value
|
||||
* @param mixed $value Value
|
||||
* @param boolean $encrypt Set to true to encrypt value, false otherwise
|
||||
* @param integer|string $expires Can be either Unix timestamp, or date string
|
||||
* @param bool $encrypt Set to true to encrypt value, false otherwise
|
||||
* @param int|string $expires Can be either the number of seconds until a cookie
|
||||
* expires, or a strtotime compatible time offset.
|
||||
* @return void
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#CookieComponent::write
|
||||
*/
|
||||
|
|
@ -217,7 +218,7 @@ class CookieComponent extends Component {
|
|||
$this->read();
|
||||
}
|
||||
|
||||
if (is_null($encrypt)) {
|
||||
if ($encrypt === null) {
|
||||
$encrypt = true;
|
||||
}
|
||||
$this->_encrypted = $encrypt;
|
||||
|
|
@ -228,17 +229,27 @@ class CookieComponent extends Component {
|
|||
}
|
||||
|
||||
foreach ($key as $name => $value) {
|
||||
if (strpos($name, '.') === false) {
|
||||
$this->_values[$this->name][$name] = $value;
|
||||
$this->_write("[$name]", $value);
|
||||
} else {
|
||||
$names = array($name);
|
||||
if (strpos($name, '.') !== false) {
|
||||
$names = explode('.', $name, 2);
|
||||
if (!isset($this->_values[$this->name][$names[0]])) {
|
||||
$this->_values[$this->name][$names[0]] = array();
|
||||
}
|
||||
$this->_values[$this->name][$names[0]] = Hash::insert($this->_values[$this->name][$names[0]], $names[1], $value);
|
||||
$this->_write('[' . implode('][', $names) . ']', $value);
|
||||
}
|
||||
$firstName = $names[0];
|
||||
$isMultiValue = (is_array($value) || count($names) > 1);
|
||||
|
||||
if (!isset($this->_values[$this->name][$firstName]) && $isMultiValue) {
|
||||
$this->_values[$this->name][$firstName] = array();
|
||||
}
|
||||
|
||||
if (count($names) > 1) {
|
||||
$this->_values[$this->name][$firstName] = Hash::insert(
|
||||
$this->_values[$this->name][$firstName],
|
||||
$names[1],
|
||||
$value
|
||||
);
|
||||
} else {
|
||||
$this->_values[$this->name][$firstName] = $value;
|
||||
}
|
||||
$this->_write('[' . $firstName . ']', $this->_values[$this->name][$firstName]);
|
||||
}
|
||||
$this->_encrypted = true;
|
||||
}
|
||||
|
|
@ -250,7 +261,7 @@ class CookieComponent extends Component {
|
|||
* $this->Cookie->read(Name.key);
|
||||
*
|
||||
* @param string $key Key of the value to be obtained. If none specified, obtain map key => values
|
||||
* @return string or null, value for specified key
|
||||
* @return string|null Value for specified key
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#CookieComponent::read
|
||||
*/
|
||||
public function read($key = null) {
|
||||
|
|
@ -260,7 +271,7 @@ class CookieComponent extends Component {
|
|||
if (empty($this->_values[$this->name])) {
|
||||
$this->_values[$this->name] = array();
|
||||
}
|
||||
if (is_null($key)) {
|
||||
if ($key === null) {
|
||||
return $this->_values[$this->name];
|
||||
}
|
||||
|
||||
|
|
@ -273,20 +284,42 @@ class CookieComponent extends Component {
|
|||
}
|
||||
|
||||
if (!empty($names[1])) {
|
||||
return Hash::get($this->_values[$this->name][$key], $names[1]);
|
||||
if (is_array($this->_values[$this->name][$key])) {
|
||||
return Hash::get($this->_values[$this->name][$key], $names[1]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return $this->_values[$this->name][$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given variable is set in cookie.
|
||||
*
|
||||
* @param string $key Variable name to check for
|
||||
* @return bool True if variable is there
|
||||
*/
|
||||
public function check($key = null) {
|
||||
if (empty($key)) {
|
||||
return false;
|
||||
}
|
||||
return $this->read($key) !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a cookie value
|
||||
*
|
||||
* Optional [Name.], required key
|
||||
* $this->Cookie->read('Name.key);
|
||||
* $this->Cookie->delete('Name.key);
|
||||
*
|
||||
* You must use this method before any output is sent to the browser.
|
||||
* Failure to do so will result in header already sent errors.
|
||||
*
|
||||
* This method will delete both the top level and 2nd level cookies set.
|
||||
* For example assuming that $name = App, deleting `User` will delete
|
||||
* both `App[User]` and any other cookie values like `App[User][email]`
|
||||
* This is done to clean up cookie storage from before 2.4.3, where cookies
|
||||
* were stored inconsistently.
|
||||
*
|
||||
* @param string $key Key of the value to be deleted
|
||||
* @return void
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#CookieComponent::delete
|
||||
|
|
@ -306,7 +339,7 @@ class CookieComponent extends Component {
|
|||
return;
|
||||
}
|
||||
$names = explode('.', $key, 2);
|
||||
if (isset($this->_values[$this->name][$names[0]])) {
|
||||
if (isset($this->_values[$this->name][$names[0]]) && is_array($this->_values[$this->name][$names[0]])) {
|
||||
$this->_values[$this->name][$names[0]] = Hash::remove($this->_values[$this->name][$names[0]], $names[1]);
|
||||
}
|
||||
$this->_delete('[' . implode('][', $names) . ']');
|
||||
|
|
@ -349,10 +382,11 @@ class CookieComponent extends Component {
|
|||
public function type($type = 'cipher') {
|
||||
$availableTypes = array(
|
||||
'cipher',
|
||||
'rijndael'
|
||||
'rijndael',
|
||||
'aes'
|
||||
);
|
||||
if (!in_array($type, $availableTypes)) {
|
||||
trigger_error(__d('cake_dev', 'You must use cipher or rijndael for cookie encryption type'), E_USER_WARNING);
|
||||
trigger_error(__d('cake_dev', 'You must use cipher, rijndael or aes for cookie encryption type'), E_USER_WARNING);
|
||||
$type = 'cipher';
|
||||
}
|
||||
$this->_type = $type;
|
||||
|
|
@ -368,24 +402,24 @@ class CookieComponent extends Component {
|
|||
* CookieComponent::write(string, string, boolean, 8400);
|
||||
* CookieComponent::write(string, string, boolean, '5 Days');
|
||||
*
|
||||
* @param integer|string $expires Can be either Unix timestamp, or date string
|
||||
* @return integer Unix timestamp
|
||||
* @param int|string $expires Can be either Unix timestamp, or date string
|
||||
* @return int Unix timestamp
|
||||
*/
|
||||
protected function _expire($expires = null) {
|
||||
$now = time();
|
||||
if (is_null($expires)) {
|
||||
if ($expires === null) {
|
||||
return $this->_expires;
|
||||
}
|
||||
$this->_reset = $this->_expires;
|
||||
|
||||
if ($expires == 0) {
|
||||
if (!$expires) {
|
||||
return $this->_expires = 0;
|
||||
}
|
||||
$now = new DateTime();
|
||||
|
||||
if (is_integer($expires) || is_numeric($expires)) {
|
||||
return $this->_expires = $now + intval($expires);
|
||||
if (is_int($expires) || is_numeric($expires)) {
|
||||
return $this->_expires = $now->format('U') + (int)$expires;
|
||||
}
|
||||
return $this->_expires = strtotime($expires, $now);
|
||||
$now->modify($expires);
|
||||
return $this->_expires = $now->format('U');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -406,7 +440,7 @@ class CookieComponent extends Component {
|
|||
'httpOnly' => $this->httpOnly
|
||||
));
|
||||
|
||||
if (!is_null($this->_reset)) {
|
||||
if (!empty($this->_reset)) {
|
||||
$this->_expires = $this->_reset;
|
||||
$this->_reset = null;
|
||||
}
|
||||
|
|
@ -434,19 +468,26 @@ class CookieComponent extends Component {
|
|||
* Encrypts $value using public $type method in Security class
|
||||
*
|
||||
* @param string $value Value to encrypt
|
||||
* @return string encrypted string
|
||||
* @return string Encoded values
|
||||
*/
|
||||
protected function _encrypt($value) {
|
||||
if (is_array($value)) {
|
||||
$value = $this->_implode($value);
|
||||
}
|
||||
|
||||
if ($this->_encrypted === true) {
|
||||
$type = $this->_type;
|
||||
$value = "Q2FrZQ==." . base64_encode(Security::$type($value, $this->key, 'encrypt'));
|
||||
if (!$this->_encrypted) {
|
||||
return $value;
|
||||
}
|
||||
return $value;
|
||||
$prefix = "Q2FrZQ==.";
|
||||
if ($this->_type === 'rijndael') {
|
||||
$cipher = Security::rijndael($value, $this->key, 'encrypt');
|
||||
}
|
||||
if ($this->_type === 'cipher') {
|
||||
$cipher = Security::cipher($value, $this->key);
|
||||
}
|
||||
if ($this->_type === 'aes') {
|
||||
$cipher = Security::encrypt($value, $this->key);
|
||||
}
|
||||
return $prefix . base64_encode($cipher);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -462,27 +503,40 @@ class CookieComponent extends Component {
|
|||
foreach ((array)$values as $name => $value) {
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $key => $val) {
|
||||
$pos = strpos($val, 'Q2FrZQ==.');
|
||||
$decrypted[$name][$key] = $this->_explode($val);
|
||||
|
||||
if ($pos !== false) {
|
||||
$val = substr($val, 8);
|
||||
$decrypted[$name][$key] = $this->_explode(Security::$type(base64_decode($val), $this->key, 'decrypt'));
|
||||
}
|
||||
$decrypted[$name][$key] = $this->_decode($val);
|
||||
}
|
||||
} else {
|
||||
$pos = strpos($value, 'Q2FrZQ==.');
|
||||
$decrypted[$name] = $this->_explode($value);
|
||||
|
||||
if ($pos !== false) {
|
||||
$value = substr($value, 8);
|
||||
$decrypted[$name] = $this->_explode(Security::$type(base64_decode($value), $this->key, 'decrypt'));
|
||||
}
|
||||
$decrypted[$name] = $this->_decode($value);
|
||||
}
|
||||
}
|
||||
return $decrypted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes and decrypts a single value.
|
||||
*
|
||||
* @param string $value The value to decode & decrypt.
|
||||
* @return string Decoded value.
|
||||
*/
|
||||
protected function _decode($value) {
|
||||
$prefix = 'Q2FrZQ==.';
|
||||
$pos = strpos($value, $prefix);
|
||||
if ($pos === false) {
|
||||
return $this->_explode($value);
|
||||
}
|
||||
$value = base64_decode(substr($value, strlen($prefix)));
|
||||
if ($this->_type === 'rijndael') {
|
||||
$plain = Security::rijndael($value, $this->key, 'decrypt');
|
||||
}
|
||||
if ($this->_type === 'cipher') {
|
||||
$plain = Security::cipher($value, $this->key);
|
||||
}
|
||||
if ($this->_type === 'aes') {
|
||||
$plain = Security::decrypt($value, $this->key);
|
||||
}
|
||||
return $this->_explode($plain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implode method to keep keys are multidimensional arrays
|
||||
*
|
||||
|
|
@ -504,7 +558,7 @@ class CookieComponent extends Component {
|
|||
$first = substr($string, 0, 1);
|
||||
if ($first === '{' || $first === '[') {
|
||||
$ret = json_decode($string, true);
|
||||
return ($ret != null) ? $ret : $string;
|
||||
return ($ret !== null) ? $ret : $string;
|
||||
}
|
||||
$array = array();
|
||||
foreach (explode(',', $string) as $pair) {
|
||||
|
|
@ -517,4 +571,3 @@ class CookieComponent extends Component {
|
|||
return $array;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,19 +2,18 @@
|
|||
/**
|
||||
* Email Component
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Controller.Component
|
||||
* @since CakePHP(tm) v 1.2.0.3467
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('Component', 'Controller');
|
||||
|
|
@ -28,9 +27,9 @@ App::uses('CakeEmail', 'Network/Email');
|
|||
* based on the standard outlined in http://www.rfc-editor.org/rfc/rfc2822.txt
|
||||
*
|
||||
* @package Cake.Controller.Component
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/email.html
|
||||
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/email.html
|
||||
* @deprecated Use Network/CakeEmail
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/email.html
|
||||
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/email.html
|
||||
* @deprecated 3.0.0 Will be removed in 3.0. Use Network/CakeEmail instead
|
||||
*/
|
||||
class EmailComponent extends Component {
|
||||
|
||||
|
|
@ -239,7 +238,7 @@ class EmailComponent extends Component {
|
|||
* it be handled by sendmail (or similar) or a string
|
||||
* to completely override the Message-ID.
|
||||
*
|
||||
* If you are sending Email from a shell, be sure to set this value. As you
|
||||
* If you are sending Email from a shell, be sure to set this value. As you
|
||||
* could encounter delivery issues if you do not.
|
||||
*
|
||||
* @var mixed
|
||||
|
|
@ -283,7 +282,7 @@ class EmailComponent extends Component {
|
|||
* If you are rendering a template this variable will be sent to the templates as `$content`
|
||||
* @param string $template Template to use when sending email
|
||||
* @param string $layout Layout to use to enclose email body
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
*/
|
||||
public function send($content = null, $template = null, $layout = null) {
|
||||
$lib = new CakeEmail();
|
||||
|
|
@ -310,14 +309,15 @@ class EmailComponent extends Component {
|
|||
$lib->readReceipt($this->_formatAddresses((array)$this->readReceipt));
|
||||
}
|
||||
|
||||
$lib->subject($this->subject)->messageID($this->messageId);
|
||||
$lib->subject($this->subject);
|
||||
$lib->messageID($this->messageId);
|
||||
$lib->helpers($this->_controller->helpers);
|
||||
|
||||
$headers = array('X-Mailer' => $this->xMailer);
|
||||
foreach ($this->headers as $key => $value) {
|
||||
$headers['X-' . $key] = $value;
|
||||
}
|
||||
if ($this->date != false) {
|
||||
if ($this->date) {
|
||||
$headers['Date'] = $this->date;
|
||||
}
|
||||
$lib->setHeaders($headers);
|
||||
|
|
@ -406,7 +406,7 @@ class EmailComponent extends Component {
|
|||
* Find the specified attachment in the list of file paths
|
||||
*
|
||||
* @param string $attachment Attachment file name to find
|
||||
* @return string Path to located file
|
||||
* @return string|null Path to located file
|
||||
*/
|
||||
protected function _findFiles($attachment) {
|
||||
if (file_exists($attachment)) {
|
||||
|
|
@ -424,7 +424,7 @@ class EmailComponent extends Component {
|
|||
/**
|
||||
* Format addresses to be an array with email as key and alias as value
|
||||
*
|
||||
* @param array $addresses
|
||||
* @param array $addresses Address to format.
|
||||
* @return array
|
||||
*/
|
||||
protected function _formatAddresses($addresses) {
|
||||
|
|
@ -445,11 +445,11 @@ class EmailComponent extends Component {
|
|||
* Helps prevent header injection / manipulation on user content.
|
||||
*
|
||||
* @param string $value Value to strip
|
||||
* @param boolean $message Set to true to indicate main message content
|
||||
* @param bool $message Set to true to indicate main message content
|
||||
* @return string Stripped value
|
||||
*/
|
||||
protected function _strip($value, $message = false) {
|
||||
$search = '%0a|%0d|Content-(?:Type|Transfer-Encoding)\:';
|
||||
$search = '%0a|%0d|Content-(?:Type|Transfer-Encoding)\:';
|
||||
$search .= '|charset\=|mime-version\:|multipart/mixed|(?:[^a-z]to|b?cc)\:.*';
|
||||
|
||||
if ($message !== true) {
|
||||
|
|
|
|||
118
lib/Cake/Controller/Component/FlashComponent.php
Normal file
118
lib/Cake/Controller/Component/FlashComponent.php
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
/**
|
||||
* Flash Component
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Controller.Component
|
||||
* @since CakePHP(tm) v 2.7.0-dev
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('Component', 'Controller');
|
||||
App::uses('Inflector', 'Utility');
|
||||
App::uses('CakeSession', 'Model/Datasource');
|
||||
|
||||
/**
|
||||
* The CakePHP FlashComponent provides a way for you to write a flash variable
|
||||
* to the session from your controllers, to be rendered in a view with the
|
||||
* FlashHelper.
|
||||
*
|
||||
* @package Cake.Controller.Component
|
||||
*/
|
||||
class FlashComponent extends Component {
|
||||
|
||||
/**
|
||||
* Default configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_defaultConfig = array(
|
||||
'key' => 'flash',
|
||||
'element' => 'default',
|
||||
'params' => array(),
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ComponentCollection $collection The ComponentCollection object
|
||||
* @param array $settings Settings passed via controller
|
||||
*/
|
||||
public function __construct(ComponentCollection $collection, $settings = array()) {
|
||||
$this->_defaultConfig = Hash::merge($this->_defaultConfig, $settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to set a session variable that can be used to output messages in the view.
|
||||
*
|
||||
* In your controller: $this->Flash->set('This has been saved');
|
||||
*
|
||||
* ### Options:
|
||||
*
|
||||
* - `key` The key to set under the session's Flash key
|
||||
* - `element` The element used to render the flash message. Default to 'default'.
|
||||
* - `params` An array of variables to make available when using an element
|
||||
*
|
||||
* @param string $message Message to be flashed. If an instance
|
||||
* of Exception the exception message will be used and code will be set
|
||||
* in params.
|
||||
* @param array $options An array of options.
|
||||
* @return void
|
||||
*/
|
||||
|
||||
public function set($message, $options = array()) {
|
||||
$options += $this->_defaultConfig;
|
||||
|
||||
if ($message instanceof Exception) {
|
||||
$options['params'] += array('code' => $message->getCode());
|
||||
$message = $message->getMessage();
|
||||
}
|
||||
|
||||
list($plugin, $element) = pluginSplit($options['element'], true);
|
||||
if (!empty($options['plugin'])) {
|
||||
$plugin = $options['plugin'] . '.';
|
||||
}
|
||||
$options['element'] = $plugin . 'Flash/' . $element;
|
||||
|
||||
CakeSession::write('Message.' . $options['key'], array(
|
||||
'message' => $message,
|
||||
'key' => $options['key'],
|
||||
'element' => $options['element'],
|
||||
'params' => $options['params']
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method for verbose flash methods based on element names.
|
||||
*
|
||||
* For example: $this->Flash->success('My message') would use the
|
||||
* success.ctp element under `app/View/Element/Flash` for rendering the
|
||||
* flash message.
|
||||
*
|
||||
* @param string $name Element name to use.
|
||||
* @param array $args Parameters to pass when calling `FlashComponent::set()`.
|
||||
* @return void
|
||||
* @throws InternalErrorException If missing the flash message.
|
||||
*/
|
||||
public function __call($name, $args) {
|
||||
$options = array('element' => Inflector::underscore($name));
|
||||
|
||||
if (count($args) < 1) {
|
||||
throw new InternalErrorException('Flash message missing.');
|
||||
}
|
||||
|
||||
if (!empty($args[1])) {
|
||||
$options += (array)$args[1];
|
||||
}
|
||||
|
||||
$this->set($args[0], $options);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,43 +2,44 @@
|
|||
/**
|
||||
* Paginator Component
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Controller.Component
|
||||
* @since CakePHP(tm) v 2.0
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('Component', 'Controller');
|
||||
App::uses('Hash', 'Utility');
|
||||
|
||||
/**
|
||||
* This component is used to handle automatic model data pagination. The primary way to use this
|
||||
* This component is used to handle automatic model data pagination. The primary way to use this
|
||||
* component is to call the paginate() method. There is a convenience wrapper on Controller as well.
|
||||
*
|
||||
* ### Configuring pagination
|
||||
*
|
||||
* You configure pagination using the PaginatorComponent::$settings. This allows you to configure
|
||||
* You configure pagination using the PaginatorComponent::$settings. This allows you to configure
|
||||
* the default pagination behavior in general or for a specific model. General settings are used when there
|
||||
* are no specific model configuration, or the model you are paginating does not have specific settings.
|
||||
*
|
||||
* {{{
|
||||
* ```
|
||||
* $this->Paginator->settings = array(
|
||||
* 'limit' => 20,
|
||||
* 'maxLimit' => 100
|
||||
* );
|
||||
* }}}
|
||||
* ```
|
||||
*
|
||||
* The above settings will be used to paginate any model. You can configure model specific settings by
|
||||
* The above settings will be used to paginate any model. You can configure model specific settings by
|
||||
* keying the settings with the model name.
|
||||
*
|
||||
* {{{
|
||||
* ```
|
||||
* $this->Paginator->settings = array(
|
||||
* 'Post' => array(
|
||||
* 'limit' => 20,
|
||||
|
|
@ -46,21 +47,35 @@ App::uses('Hash', 'Utility');
|
|||
* ),
|
||||
* 'Comment' => array( ... )
|
||||
* );
|
||||
* }}}
|
||||
* ```
|
||||
*
|
||||
* This would allow you to have different pagination settings for `Comment` and `Post` models.
|
||||
*
|
||||
* #### Paginating with custom finders
|
||||
*
|
||||
* You can paginate with any find type defined on your model using the `findType` option.
|
||||
*
|
||||
* ```
|
||||
* $this->Paginator->settings = array(
|
||||
* 'Post' => array(
|
||||
* 'findType' => 'popular'
|
||||
* )
|
||||
* );
|
||||
* ```
|
||||
*
|
||||
* Would paginate using the `find('popular')` method.
|
||||
*
|
||||
* @package Cake.Controller.Component
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/pagination.html
|
||||
*/
|
||||
class PaginatorComponent extends Component {
|
||||
|
||||
/**
|
||||
* Pagination settings. These settings control pagination at a general level.
|
||||
* Pagination settings. These settings control pagination at a general level.
|
||||
* You can also define sub arrays for pagination settings for specific models.
|
||||
*
|
||||
* - `maxLimit` The maximum limit users can choose to view. Defaults to 100
|
||||
* - `limit` The initial number of items per page. Defaults to 20.
|
||||
* - `limit` The initial number of items per page. Defaults to 20.
|
||||
* - `page` The starting page, defaults to 1.
|
||||
* - `paramType` What type of parameters you want pagination to use?
|
||||
* - `named` Use named parameters / routed parameters.
|
||||
|
|
@ -76,7 +91,7 @@ class PaginatorComponent extends Component {
|
|||
);
|
||||
|
||||
/**
|
||||
* A list of parameters users are allowed to set using request parameters. Modifying
|
||||
* A list of parameters users are allowed to set using request parameters. Modifying
|
||||
* this list will allow users to have more influence over pagination,
|
||||
* be careful with what you permit.
|
||||
*
|
||||
|
|
@ -103,10 +118,12 @@ class PaginatorComponent extends Component {
|
|||
*
|
||||
* @param Model|string $object Model to paginate (e.g: model instance, or 'Model', or 'Model.InnerModel')
|
||||
* @param string|array $scope Additional find conditions to use while paginating
|
||||
* @param array $whitelist List of allowed fields for ordering. This allows you to prevent ordering
|
||||
* on non-indexed, or undesirable columns.
|
||||
* @param array $whitelist List of allowed fields for ordering. This allows you to prevent ordering
|
||||
* on non-indexed, or undesirable columns. See PaginatorComponent::validateSort() for additional details
|
||||
* on how the whitelisting and sort field validation works.
|
||||
* @return array Model query results
|
||||
* @throws MissingModelException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function paginate($object = null, $scope = array(), $whitelist = array()) {
|
||||
if (is_array($object)) {
|
||||
|
|
@ -152,11 +169,17 @@ class PaginatorComponent extends Component {
|
|||
$extra = array_diff_key($options, compact(
|
||||
'conditions', 'fields', 'order', 'limit', 'page', 'recursive'
|
||||
));
|
||||
|
||||
if (!empty($extra['findType'])) {
|
||||
$type = $extra['findType'];
|
||||
unset($extra['findType']);
|
||||
}
|
||||
|
||||
if ($type !== 'all') {
|
||||
$extra['type'] = $type;
|
||||
}
|
||||
|
||||
if (intval($page) < 1) {
|
||||
if ((int)$page < 1) {
|
||||
$page = 1;
|
||||
}
|
||||
$page = $options['page'] = (int)$page;
|
||||
|
|
@ -175,8 +198,12 @@ class PaginatorComponent extends Component {
|
|||
$defaults = $this->getDefaults($object->alias);
|
||||
unset($defaults[0]);
|
||||
|
||||
if ($object->hasMethod('paginateCount')) {
|
||||
if (!$results) {
|
||||
$count = 0;
|
||||
} elseif ($object->hasMethod('paginateCount')) {
|
||||
$count = $object->paginateCount($conditions, $recursive, $extra);
|
||||
} elseif ($page === 1 && count($results) < $limit) {
|
||||
$count = count($results);
|
||||
} else {
|
||||
$parameters = compact('conditions');
|
||||
if ($recursive != $object->recursive) {
|
||||
|
|
@ -184,7 +211,8 @@ class PaginatorComponent extends Component {
|
|||
}
|
||||
$count = $object->find('count', array_merge($parameters, $extra));
|
||||
}
|
||||
$pageCount = intval(ceil($count / $limit));
|
||||
$pageCount = (int)ceil($count / $limit);
|
||||
$requestedPage = $page;
|
||||
$page = max(min($page, $pageCount), 1);
|
||||
|
||||
$paging = array(
|
||||
|
|
@ -199,6 +227,7 @@ class PaginatorComponent extends Component {
|
|||
'options' => Hash::diff($options, $defaults),
|
||||
'paramType' => $options['paramType']
|
||||
);
|
||||
|
||||
if (!isset($this->Controller->request['paging'])) {
|
||||
$this->Controller->request['paging'] = array();
|
||||
}
|
||||
|
|
@ -207,8 +236,11 @@ class PaginatorComponent extends Component {
|
|||
array($object->alias => $paging)
|
||||
);
|
||||
|
||||
if (
|
||||
!in_array('Paginator', $this->Controller->helpers) &&
|
||||
if ($requestedPage > $page) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
if (!in_array('Paginator', $this->Controller->helpers) &&
|
||||
!array_key_exists('Paginator', $this->Controller->helpers)
|
||||
) {
|
||||
$this->Controller->helpers[] = 'Paginator';
|
||||
|
|
@ -228,36 +260,34 @@ class PaginatorComponent extends Component {
|
|||
if (strpos($object, '.') !== false) {
|
||||
list($object, $assoc) = pluginSplit($object);
|
||||
}
|
||||
|
||||
if ($assoc && isset($this->Controller->{$object}->{$assoc})) {
|
||||
$object = $this->Controller->{$object}->{$assoc};
|
||||
} elseif (
|
||||
$assoc && isset($this->Controller->{$this->Controller->modelClass}) &&
|
||||
isset($this->Controller->{$this->Controller->modelClass}->{$assoc}
|
||||
)) {
|
||||
$object = $this->Controller->{$this->Controller->modelClass}->{$assoc};
|
||||
} elseif (isset($this->Controller->{$object})) {
|
||||
$object = $this->Controller->{$object};
|
||||
} elseif (
|
||||
isset($this->Controller->{$this->Controller->modelClass}) && isset($this->Controller->{$this->Controller->modelClass}->{$object}
|
||||
)) {
|
||||
$object = $this->Controller->{$this->Controller->modelClass}->{$object};
|
||||
return $this->Controller->{$object}->{$assoc};
|
||||
}
|
||||
} elseif (empty($object) || $object === null) {
|
||||
if ($assoc && isset($this->Controller->{$this->Controller->modelClass}->{$assoc})) {
|
||||
return $this->Controller->{$this->Controller->modelClass}->{$assoc};
|
||||
}
|
||||
if (isset($this->Controller->{$object})) {
|
||||
return $this->Controller->{$object};
|
||||
}
|
||||
if (isset($this->Controller->{$this->Controller->modelClass}->{$object})) {
|
||||
return $this->Controller->{$this->Controller->modelClass}->{$object};
|
||||
}
|
||||
}
|
||||
if (empty($object) || $object === null) {
|
||||
if (isset($this->Controller->{$this->Controller->modelClass})) {
|
||||
$object = $this->Controller->{$this->Controller->modelClass};
|
||||
} else {
|
||||
$className = null;
|
||||
$name = $this->Controller->uses[0];
|
||||
if (strpos($this->Controller->uses[0], '.') !== false) {
|
||||
list($name, $className) = explode('.', $this->Controller->uses[0]);
|
||||
}
|
||||
if ($className) {
|
||||
$object = $this->Controller->{$className};
|
||||
} else {
|
||||
$object = $this->Controller->{$name};
|
||||
}
|
||||
return $this->Controller->{$this->Controller->modelClass};
|
||||
}
|
||||
|
||||
$className = null;
|
||||
$name = $this->Controller->uses[0];
|
||||
if (strpos($this->Controller->uses[0], '.') !== false) {
|
||||
list($name, $className) = explode('.', $this->Controller->uses[0]);
|
||||
}
|
||||
if ($className) {
|
||||
return $this->Controller->{$className};
|
||||
}
|
||||
|
||||
return $this->Controller->{$name};
|
||||
}
|
||||
return $object;
|
||||
}
|
||||
|
|
@ -270,7 +300,7 @@ class PaginatorComponent extends Component {
|
|||
* - Model specific settings.
|
||||
* - Request parameters
|
||||
*
|
||||
* The result of this method is the aggregate of all the option sets combined together. You can change
|
||||
* The result of this method is the aggregate of all the option sets combined together. You can change
|
||||
* PaginatorComponent::$whitelist to modify which options/values can be set using request parameters.
|
||||
*
|
||||
* @param string $alias Model alias being paginated, if the general settings has a key with this value
|
||||
|
|
@ -292,44 +322,53 @@ class PaginatorComponent extends Component {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the default settings for a $model. If there are no settings for a specific model, the general settings
|
||||
* Get the default settings for a $model. If there are no settings for a specific model, the general settings
|
||||
* will be used.
|
||||
*
|
||||
* @param string $alias Model name to get default settings for.
|
||||
* @return array An array of pagination defaults for a model, or the general settings.
|
||||
*/
|
||||
public function getDefaults($alias) {
|
||||
$defaults = $this->settings;
|
||||
if (isset($this->settings[$alias])) {
|
||||
$defaults = $this->settings[$alias];
|
||||
} else {
|
||||
$defaults = $this->settings;
|
||||
}
|
||||
return array_merge(
|
||||
array('page' => 1, 'limit' => 20, 'maxLimit' => 100, 'paramType' => 'named'),
|
||||
$defaults
|
||||
$defaults += array(
|
||||
'page' => 1,
|
||||
'limit' => 20,
|
||||
'maxLimit' => 100,
|
||||
'paramType' => 'named'
|
||||
);
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the desired sorting can be performed on the $object. Only fields or
|
||||
* virtualFields can be sorted on. The direction param will also be sanitized. Lastly
|
||||
* Validate that the desired sorting can be performed on the $object. Only fields or
|
||||
* virtualFields can be sorted on. The direction param will also be sanitized. Lastly
|
||||
* sort + direction keys will be converted into the model friendly order key.
|
||||
*
|
||||
* You can use the whitelist parameter to control which columns/fields are available for sorting.
|
||||
* This helps prevent users from ordering large result sets on un-indexed values.
|
||||
*
|
||||
* Any columns listed in the sort whitelist will be implicitly trusted. You can use this to sort
|
||||
* on synthetic columns, or columns added in custom find operations that may not exist in the schema.
|
||||
*
|
||||
* @param Model $object The model being paginated.
|
||||
* @param array $options The pagination options being used for this request.
|
||||
* @param array $whitelist The list of columns that can be used for sorting. If empty all keys are allowed.
|
||||
* @param array $whitelist The list of columns that can be used for sorting. If empty all keys are allowed.
|
||||
* @return array An array of options with sort + direction removed and replaced with order if possible.
|
||||
*/
|
||||
public function validateSort($object, $options, $whitelist = array()) {
|
||||
public function validateSort(Model $object, array $options, array $whitelist = array()) {
|
||||
if (empty($options['order']) && is_array($object->order)) {
|
||||
$options['order'] = $object->order;
|
||||
}
|
||||
|
||||
if (isset($options['sort'])) {
|
||||
$direction = null;
|
||||
if (isset($options['direction'])) {
|
||||
$direction = strtolower($options['direction']);
|
||||
}
|
||||
if ($direction != 'asc' && $direction != 'desc') {
|
||||
if (!in_array($direction, array('asc', 'desc'))) {
|
||||
$direction = 'asc';
|
||||
}
|
||||
$options['order'] = array($options['sort'] => $direction);
|
||||
|
|
@ -337,23 +376,30 @@ class PaginatorComponent extends Component {
|
|||
|
||||
if (!empty($whitelist) && isset($options['order']) && is_array($options['order'])) {
|
||||
$field = key($options['order']);
|
||||
if (!in_array($field, $whitelist)) {
|
||||
$inWhitelist = in_array($field, $whitelist, true);
|
||||
if (!$inWhitelist) {
|
||||
$options['order'] = null;
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
if (!empty($options['order']) && is_array($options['order'])) {
|
||||
$order = array();
|
||||
foreach ($options['order'] as $key => $value) {
|
||||
if (is_int($key)) {
|
||||
$key = $value;
|
||||
$value = 'asc';
|
||||
}
|
||||
$field = $key;
|
||||
$alias = $object->alias;
|
||||
if (strpos($key, '.') !== false) {
|
||||
list($alias, $field) = explode('.', $key);
|
||||
}
|
||||
$correctAlias = ($object->alias === $alias);
|
||||
|
||||
if ($object->hasField($field)) {
|
||||
$order[$alias . '.' . $field] = $value;
|
||||
} elseif ($object->hasField($key, true)) {
|
||||
if ($correctAlias && $object->hasField($field)) {
|
||||
$order[$object->alias . '.' . $field] = $value;
|
||||
} elseif ($correctAlias && $object->hasField($key, true)) {
|
||||
$order[$field] = $value;
|
||||
} elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field, true)) {
|
||||
$order[$alias . '.' . $field] = $value;
|
||||
|
|
@ -371,7 +417,7 @@ class PaginatorComponent extends Component {
|
|||
* @param array $options An array of options with a limit key to be checked.
|
||||
* @return array An array of options for pagination
|
||||
*/
|
||||
public function checkLimit($options) {
|
||||
public function checkLimit(array $options) {
|
||||
$options['limit'] = (int)$options['limit'];
|
||||
if (empty($options['limit']) || $options['limit'] < 1) {
|
||||
$options['limit'] = 1;
|
||||
|
|
|
|||
|
|
@ -3,22 +3,24 @@
|
|||
* Request object for handling alternative HTTP requests
|
||||
*
|
||||
* Alternative HTTP requests can come from wireless units like mobile phones, palmtop computers,
|
||||
* and the like. These units have no use for Ajax requests, and this Component can tell how Cake
|
||||
* and the like. These units have no use for Ajax requests, and this Component can tell how Cake
|
||||
* should respond to the different needs of a handheld computer and a desktop machine.
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Controller.Component
|
||||
* @since CakePHP(tm) v 0.10.4.1076
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('Component', 'Controller');
|
||||
App::uses('Xml', 'Utility');
|
||||
|
||||
/**
|
||||
|
|
@ -30,7 +32,6 @@ App::uses('Xml', 'Utility');
|
|||
*
|
||||
* @package Cake.Controller.Component
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/request-handling.html
|
||||
*
|
||||
*/
|
||||
class RequestHandlerComponent extends Component {
|
||||
|
||||
|
|
@ -45,7 +46,7 @@ class RequestHandlerComponent extends Component {
|
|||
/**
|
||||
* Determines whether or not callbacks will be fired on this component
|
||||
*
|
||||
* @var boolean
|
||||
* @var bool
|
||||
*/
|
||||
public $enabled = true;
|
||||
|
||||
|
|
@ -88,6 +89,17 @@ class RequestHandlerComponent extends Component {
|
|||
'json' => array('json_decode', true)
|
||||
);
|
||||
|
||||
/**
|
||||
* A mapping between type and viewClass
|
||||
* By default only JSON and XML are mapped, use RequestHandlerComponent::viewClassMap()
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_viewClassMap = array(
|
||||
'json' => 'Json',
|
||||
'xml' => 'Xml'
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor. Parses the accepted content types accepted by the client using HTTP_ACCEPT
|
||||
*
|
||||
|
|
@ -95,8 +107,7 @@ class RequestHandlerComponent extends Component {
|
|||
* @param array $settings Array of settings.
|
||||
*/
|
||||
public function __construct(ComponentCollection $collection, $settings = array()) {
|
||||
$default = array('checkHttpCache' => true);
|
||||
parent::__construct($collection, $settings + $default);
|
||||
parent::__construct($collection, $settings + array('checkHttpCache' => true));
|
||||
$this->addInputType('xml', array(array($this, 'convertXml')));
|
||||
|
||||
$Controller = $collection->getController();
|
||||
|
|
@ -111,19 +122,20 @@ class RequestHandlerComponent extends Component {
|
|||
* and the requested mime-types, RequestHandler::$ext is set to that value.
|
||||
*
|
||||
* @param Controller $controller A reference to the controller
|
||||
* @param array $settings Array of settings to _set().
|
||||
* @return void
|
||||
* @see Router::parseExtensions()
|
||||
*/
|
||||
public function initialize(Controller $controller, $settings = array()) {
|
||||
public function initialize(Controller $controller) {
|
||||
if (isset($this->request->params['ext'])) {
|
||||
$this->ext = $this->request->params['ext'];
|
||||
}
|
||||
if (empty($this->ext) || $this->ext == 'html') {
|
||||
if (empty($this->ext) || $this->ext === 'html') {
|
||||
$this->_setExtension();
|
||||
}
|
||||
$this->params = $controller->params;
|
||||
$this->_set($settings);
|
||||
if (!empty($this->settings['viewClassMap'])) {
|
||||
$this->viewClassMap($this->settings['viewClassMap']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -131,6 +143,9 @@ class RequestHandlerComponent extends Component {
|
|||
* Compares the accepted types and configured extensions.
|
||||
* If there is one common type, that is assigned as the ext/content type
|
||||
* for the response.
|
||||
* Type with the highest weight will be set. If the highest weight has more
|
||||
* then one type matching the extensions, the order in which extensions are specified
|
||||
* determines which type will be set.
|
||||
*
|
||||
* If html is one of the preferred types, no content type will be set, this
|
||||
* is to avoid issues with browsers that prefer html and several other content types.
|
||||
|
|
@ -142,12 +157,20 @@ class RequestHandlerComponent extends Component {
|
|||
if (empty($accept)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$accepts = $this->response->mapType($accept);
|
||||
$preferedTypes = current($accepts);
|
||||
if (array_intersect($preferedTypes, array('html', 'xhtml'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
$extensions = Router::extensions();
|
||||
$preferred = array_shift($accept);
|
||||
$preferredTypes = $this->response->mapType($preferred);
|
||||
$similarTypes = array_intersect($extensions, $preferredTypes);
|
||||
if (count($similarTypes) === 1 && !in_array('xhtml', $preferredTypes) && !in_array('html', $preferredTypes)) {
|
||||
$this->ext = array_shift($similarTypes);
|
||||
foreach ($accepts as $types) {
|
||||
$ext = array_intersect($extensions, $types);
|
||||
if ($ext) {
|
||||
$this->ext = current($ext);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -157,11 +180,11 @@ class RequestHandlerComponent extends Component {
|
|||
*
|
||||
* - Disabling layout rendering for Ajax requests (based on the HTTP_X_REQUESTED_WITH header)
|
||||
* - If Router::parseExtensions() is enabled, the layout and template type are
|
||||
* switched based on the parsed extension or Accept-Type header. For example, if `controller/action.xml`
|
||||
* switched based on the parsed extension or Accept-Type header. For example, if `controller/action.xml`
|
||||
* is requested, the view path becomes `app/View/Controller/xml/action.ctp`. Also if
|
||||
* `controller/action` is requested with `Accept-Type: application/xml` in the headers
|
||||
* the view path will become `app/View/Controller/xml/action.ctp`. Layout and template
|
||||
* types will only switch to mime-types recognized by CakeResponse. If you need to declare
|
||||
* the view path will become `app/View/Controller/xml/action.ctp`. Layout and template
|
||||
* types will only switch to mime-types recognized by CakeResponse. If you need to declare
|
||||
* additional mime-types, you can do so using CakeResponse::type() in your controllers beforeFilter()
|
||||
* method.
|
||||
* - If a helper with the same name as the extension exists, it is added to the controller.
|
||||
|
|
@ -200,12 +223,12 @@ class RequestHandlerComponent extends Component {
|
|||
* Helper method to parse xml input data, due to lack of anonymous functions
|
||||
* this lives here.
|
||||
*
|
||||
* @param string $xml
|
||||
* @param string $xml XML string.
|
||||
* @return array Xml array data
|
||||
*/
|
||||
public function convertXml($xml) {
|
||||
try {
|
||||
$xml = Xml::build($xml);
|
||||
$xml = Xml::build($xml, array('readFile' => false));
|
||||
if (isset($xml->data)) {
|
||||
return Xml::toArray($xml->data);
|
||||
}
|
||||
|
|
@ -221,14 +244,17 @@ class RequestHandlerComponent extends Component {
|
|||
*
|
||||
* @param Controller $controller A reference to the controller
|
||||
* @param string|array $url A string or array containing the redirect location
|
||||
* @param integer|array $status HTTP Status for redirect
|
||||
* @param boolean $exit
|
||||
* @param int|array $status HTTP Status for redirect
|
||||
* @param bool $exit Whether to exit script, defaults to `true`.
|
||||
* @return void
|
||||
*/
|
||||
public function beforeRedirect(Controller $controller, $url, $status = null, $exit = true) {
|
||||
if (!$this->request->is('ajax')) {
|
||||
return;
|
||||
}
|
||||
if (empty($url)) {
|
||||
return;
|
||||
}
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
foreach ($_POST as $key => $val) {
|
||||
unset($_POST[$key]);
|
||||
|
|
@ -252,12 +278,11 @@ class RequestHandlerComponent extends Component {
|
|||
* render process is skipped. And the client will get a blank response with a
|
||||
* "304 Not Modified" header.
|
||||
*
|
||||
* @params Controller $controller
|
||||
* @return boolean false if the render process should be aborted
|
||||
**/
|
||||
* @param Controller $controller Controller instance.
|
||||
* @return bool False if the render process should be aborted.
|
||||
*/
|
||||
public function beforeRender(Controller $controller) {
|
||||
$shouldCheck = $this->settings['checkHttpCache'];
|
||||
if ($shouldCheck && $this->response->checkNotModified($this->request)) {
|
||||
if ($this->settings['checkHttpCache'] && $this->response->checkNotModified($this->request)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -265,8 +290,8 @@ class RequestHandlerComponent extends Component {
|
|||
/**
|
||||
* Returns true if the current HTTP request is Ajax, false otherwise
|
||||
*
|
||||
* @return boolean True if call is Ajax
|
||||
* @deprecated use `$this->request->is('ajax')` instead.
|
||||
* @return bool True if call is Ajax
|
||||
* @deprecated 3.0.0 Use `$this->request->is('ajax')` instead.
|
||||
*/
|
||||
public function isAjax() {
|
||||
return $this->request->is('ajax');
|
||||
|
|
@ -275,8 +300,8 @@ class RequestHandlerComponent extends Component {
|
|||
/**
|
||||
* Returns true if the current HTTP request is coming from a Flash-based client
|
||||
*
|
||||
* @return boolean True if call is from Flash
|
||||
* @deprecated use `$this->request->is('flash')` instead.
|
||||
* @return bool True if call is from Flash
|
||||
* @deprecated 3.0.0 Use `$this->request->is('flash')` instead.
|
||||
*/
|
||||
public function isFlash() {
|
||||
return $this->request->is('flash');
|
||||
|
|
@ -285,8 +310,8 @@ class RequestHandlerComponent extends Component {
|
|||
/**
|
||||
* Returns true if the current request is over HTTPS, false otherwise.
|
||||
*
|
||||
* @return boolean True if call is over HTTPS
|
||||
* @deprecated use `$this->request->is('ssl')` instead.
|
||||
* @return bool True if call is over HTTPS
|
||||
* @deprecated 3.0.0 Use `$this->request->is('ssl')` instead.
|
||||
*/
|
||||
public function isSSL() {
|
||||
return $this->request->is('ssl');
|
||||
|
|
@ -295,7 +320,7 @@ class RequestHandlerComponent extends Component {
|
|||
/**
|
||||
* Returns true if the current call accepts an XML response, false otherwise
|
||||
*
|
||||
* @return boolean True if client accepts an XML response
|
||||
* @return bool True if client accepts an XML response
|
||||
*/
|
||||
public function isXml() {
|
||||
return $this->prefers('xml');
|
||||
|
|
@ -304,7 +329,7 @@ class RequestHandlerComponent extends Component {
|
|||
/**
|
||||
* Returns true if the current call accepts an RSS response, false otherwise
|
||||
*
|
||||
* @return boolean True if client accepts an RSS response
|
||||
* @return bool True if client accepts an RSS response
|
||||
*/
|
||||
public function isRss() {
|
||||
return $this->prefers('rss');
|
||||
|
|
@ -313,7 +338,7 @@ class RequestHandlerComponent extends Component {
|
|||
/**
|
||||
* Returns true if the current call accepts an Atom response, false otherwise
|
||||
*
|
||||
* @return boolean True if client accepts an RSS response
|
||||
* @return bool True if client accepts an RSS response
|
||||
*/
|
||||
public function isAtom() {
|
||||
return $this->prefers('atom');
|
||||
|
|
@ -323,7 +348,7 @@ class RequestHandlerComponent extends Component {
|
|||
* Returns true if user agent string matches a mobile web browser, or if the
|
||||
* client accepts WAP content.
|
||||
*
|
||||
* @return boolean True if user agent is a mobile web browser
|
||||
* @return bool True if user agent is a mobile web browser
|
||||
*/
|
||||
public function isMobile() {
|
||||
return $this->request->is('mobile') || $this->accepts('wap');
|
||||
|
|
@ -332,7 +357,7 @@ class RequestHandlerComponent extends Component {
|
|||
/**
|
||||
* Returns true if the client accepts WAP content
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isWap() {
|
||||
return $this->prefers('wap');
|
||||
|
|
@ -341,8 +366,8 @@ class RequestHandlerComponent extends Component {
|
|||
/**
|
||||
* Returns true if the current call a POST request
|
||||
*
|
||||
* @return boolean True if call is a POST
|
||||
* @deprecated Use $this->request->is('post'); from your controller.
|
||||
* @return bool True if call is a POST
|
||||
* @deprecated 3.0.0 Use $this->request->is('post'); from your controller.
|
||||
*/
|
||||
public function isPost() {
|
||||
return $this->request->is('post');
|
||||
|
|
@ -351,8 +376,8 @@ class RequestHandlerComponent extends Component {
|
|||
/**
|
||||
* Returns true if the current call a PUT request
|
||||
*
|
||||
* @return boolean True if call is a PUT
|
||||
* @deprecated Use $this->request->is('put'); from your controller.
|
||||
* @return bool True if call is a PUT
|
||||
* @deprecated 3.0.0 Use $this->request->is('put'); from your controller.
|
||||
*/
|
||||
public function isPut() {
|
||||
return $this->request->is('put');
|
||||
|
|
@ -361,8 +386,8 @@ class RequestHandlerComponent extends Component {
|
|||
/**
|
||||
* Returns true if the current call a GET request
|
||||
*
|
||||
* @return boolean True if call is a GET
|
||||
* @deprecated Use $this->request->is('get'); from your controller.
|
||||
* @return bool True if call is a GET
|
||||
* @deprecated 3.0.0 Use $this->request->is('get'); from your controller.
|
||||
*/
|
||||
public function isGet() {
|
||||
return $this->request->is('get');
|
||||
|
|
@ -371,8 +396,8 @@ class RequestHandlerComponent extends Component {
|
|||
/**
|
||||
* Returns true if the current call a DELETE request
|
||||
*
|
||||
* @return boolean True if call is a DELETE
|
||||
* @deprecated Use $this->request->is('delete'); from your controller.
|
||||
* @return bool True if call is a DELETE
|
||||
* @deprecated 3.0.0 Use $this->request->is('delete'); from your controller.
|
||||
*/
|
||||
public function isDelete() {
|
||||
return $this->request->is('delete');
|
||||
|
|
@ -382,17 +407,15 @@ class RequestHandlerComponent extends Component {
|
|||
* Gets Prototype version if call is Ajax, otherwise empty string.
|
||||
* The Prototype library sets a special "Prototype version" HTTP header.
|
||||
*
|
||||
* @return string Prototype version of component making Ajax call
|
||||
* @return string|bool When Ajax the prototype version of component making the call otherwise false
|
||||
*/
|
||||
public function getAjaxVersion() {
|
||||
if (env('HTTP_X_PROTOTYPE_VERSION') != null) {
|
||||
return env('HTTP_X_PROTOTYPE_VERSION');
|
||||
}
|
||||
return false;
|
||||
$httpX = env('HTTP_X_PROTOTYPE_VERSION');
|
||||
return ($httpX === null) ? false : $httpX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds/sets the Content-type(s) for the given name. This method allows
|
||||
* Adds/sets the Content-type(s) for the given name. This method allows
|
||||
* content-types to be mapped to friendly aliases (or extensions), which allows
|
||||
* RequestHandler to automatically respond to requests of that type in the
|
||||
* startup method.
|
||||
|
|
@ -401,7 +424,7 @@ class RequestHandlerComponent extends Component {
|
|||
* @param string|array $type The Content-type or array of Content-types assigned to the name,
|
||||
* i.e. "text/html", or "application/xml"
|
||||
* @return void
|
||||
* @deprecated use `$this->response->type()` instead.
|
||||
* @deprecated 3.0.0 Use `$this->response->type()` instead.
|
||||
*/
|
||||
public function setContent($name, $type = null) {
|
||||
$this->response->type(array($name => $type));
|
||||
|
|
@ -411,7 +434,7 @@ class RequestHandlerComponent extends Component {
|
|||
* Gets the server name from which this request was referred
|
||||
*
|
||||
* @return string Server address
|
||||
* @deprecated use $this->request->referer() from your controller instead
|
||||
* @deprecated 3.0.0 Use $this->request->referer() from your controller instead
|
||||
*/
|
||||
public function getReferer() {
|
||||
return $this->request->referer(false);
|
||||
|
|
@ -420,16 +443,17 @@ class RequestHandlerComponent extends Component {
|
|||
/**
|
||||
* Gets remote client IP
|
||||
*
|
||||
* @param boolean $safe
|
||||
* @param bool $safe Use safe = false when you think the user might manipulate
|
||||
* their HTTP_CLIENT_IP header. Setting $safe = false will also look at HTTP_X_FORWARDED_FOR
|
||||
* @return string Client IP address
|
||||
* @deprecated use $this->request->clientIp() from your, controller instead.
|
||||
* @deprecated 3.0.0 Use $this->request->clientIp() from your, controller instead.
|
||||
*/
|
||||
public function getClientIP($safe = true) {
|
||||
return $this->request->clientIp($safe);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines which content types the client accepts. Acceptance is based on
|
||||
* Determines which content types the client accepts. Acceptance is based on
|
||||
* the file extension parsed by the Router (if present), and by the HTTP_ACCEPT
|
||||
* header. Unlike CakeRequest::accepts() this method deals entirely with mapped content types.
|
||||
*
|
||||
|
|
@ -446,17 +470,18 @@ class RequestHandlerComponent extends Component {
|
|||
* @param string|array $type Can be null (or no parameter), a string type name, or an
|
||||
* array of types
|
||||
* @return mixed If null or no parameter is passed, returns an array of content
|
||||
* types the client accepts. If a string is passed, returns true
|
||||
* if the client accepts it. If an array is passed, returns true
|
||||
* types the client accepts. If a string is passed, returns true
|
||||
* if the client accepts it. If an array is passed, returns true
|
||||
* if the client accepts one or more elements in the array.
|
||||
* @see RequestHandlerComponent::setContent()
|
||||
*/
|
||||
public function accepts($type = null) {
|
||||
$accepted = $this->request->accepts();
|
||||
|
||||
if ($type == null) {
|
||||
if (!$type) {
|
||||
return $this->mapType($accepted);
|
||||
} elseif (is_array($type)) {
|
||||
}
|
||||
if (is_array($type)) {
|
||||
foreach ($type as $t) {
|
||||
$t = $this->mapAlias($t);
|
||||
if (in_array($t, $accepted)) {
|
||||
|
|
@ -464,9 +489,9 @@ class RequestHandlerComponent extends Component {
|
|||
}
|
||||
}
|
||||
return false;
|
||||
} elseif (is_string($type)) {
|
||||
$type = $this->mapAlias($type);
|
||||
return in_array($type, $accepted);
|
||||
}
|
||||
if (is_string($type)) {
|
||||
return in_array($this->mapAlias($type), $accepted);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -475,33 +500,43 @@ class RequestHandlerComponent extends Component {
|
|||
* Determines the content type of the data the client has sent (i.e. in a POST request)
|
||||
*
|
||||
* @param string|array $type Can be null (or no parameter), a string type name, or an array of types
|
||||
* @return mixed If a single type is supplied a boolean will be returned. If no type is provided
|
||||
* @return mixed If a single type is supplied a boolean will be returned. If no type is provided
|
||||
* The mapped value of CONTENT_TYPE will be returned. If an array is supplied the first type
|
||||
* in the request content type will be returned.
|
||||
*/
|
||||
public function requestedWith($type = null) {
|
||||
if (!$this->request->is('post') && !$this->request->is('put')) {
|
||||
if (
|
||||
!$this->request->is('patch') &&
|
||||
!$this->request->is('post') &&
|
||||
!$this->request->is('put') &&
|
||||
!$this->request->is('delete')
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
list($contentType) = explode(';', env('CONTENT_TYPE'));
|
||||
if ($type == null) {
|
||||
return $this->mapType($contentType);
|
||||
} elseif (is_array($type)) {
|
||||
if (is_array($type)) {
|
||||
foreach ($type as $t) {
|
||||
if ($this->requestedWith($t)) {
|
||||
return $t;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} elseif (is_string($type)) {
|
||||
return ($type == $this->mapType($contentType));
|
||||
}
|
||||
|
||||
list($contentType) = explode(';', env('CONTENT_TYPE'));
|
||||
if ($contentType === '') {
|
||||
list($contentType) = explode(';', CakeRequest::header('CONTENT_TYPE'));
|
||||
}
|
||||
if (!$type) {
|
||||
return $this->mapType($contentType);
|
||||
}
|
||||
if (is_string($type)) {
|
||||
return ($type === $this->mapType($contentType));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines which content-types the client prefers. If no parameters are given,
|
||||
* the single content-type that the client most likely prefers is returned. If $type is
|
||||
* Determines which content-types the client prefers. If no parameters are given,
|
||||
* the single content-type that the client most likely prefers is returned. If $type is
|
||||
* an array, the first item in the array that the client accepts is returned.
|
||||
* Preference is determined primarily by the file extension parsed by the Router
|
||||
* if provided, and secondarily by the list of content-types provided in
|
||||
|
|
@ -510,7 +545,7 @@ class RequestHandlerComponent extends Component {
|
|||
* @param string|array $type An optional array of 'friendly' content-type names, i.e.
|
||||
* 'html', 'xml', 'js', etc.
|
||||
* @return mixed If $type is null or not provided, the first content-type in the
|
||||
* list, based on preference, is returned. If a single type is provided
|
||||
* list, based on preference, is returned. If a single type is provided
|
||||
* a boolean will be returned if that type is preferred.
|
||||
* If an array of types are provided then the first preferred type is returned.
|
||||
* If no type is provided the first preferred type is returned.
|
||||
|
|
@ -522,10 +557,9 @@ class RequestHandlerComponent extends Component {
|
|||
if (empty($acceptRaw)) {
|
||||
return $this->ext;
|
||||
}
|
||||
$accepts = array_shift($acceptRaw);
|
||||
$accepts = $this->mapType($accepts);
|
||||
$accepts = $this->mapType(array_shift($acceptRaw));
|
||||
|
||||
if ($type == null) {
|
||||
if (!$type) {
|
||||
if (empty($this->ext) && !empty($accepts)) {
|
||||
return $accepts[0];
|
||||
}
|
||||
|
|
@ -574,26 +608,34 @@ class RequestHandlerComponent extends Component {
|
|||
if (Configure::read('App.encoding') !== null) {
|
||||
$defaults['charset'] = Configure::read('App.encoding');
|
||||
}
|
||||
$options = array_merge($defaults, $options);
|
||||
$options += $defaults;
|
||||
|
||||
if ($type == 'ajax') {
|
||||
if ($type === 'ajax') {
|
||||
$controller->layout = $this->ajaxLayout;
|
||||
return $this->respondAs('html', $options);
|
||||
}
|
||||
$controller->ext = '.ctp';
|
||||
|
||||
$viewClass = Inflector::classify($type);
|
||||
$pluginDot = null;
|
||||
$viewClassMap = $this->viewClassMap();
|
||||
if (array_key_exists($type, $viewClassMap)) {
|
||||
list($pluginDot, $viewClass) = pluginSplit($viewClassMap[$type], true);
|
||||
} else {
|
||||
$viewClass = Inflector::classify($type);
|
||||
}
|
||||
$viewName = $viewClass . 'View';
|
||||
if (!class_exists($viewName)) {
|
||||
App::uses($viewName, 'View');
|
||||
App::uses($viewName, $pluginDot . 'View');
|
||||
}
|
||||
if (class_exists($viewName)) {
|
||||
$controller->viewClass = $viewClass;
|
||||
} elseif (empty($this->_renderType)) {
|
||||
$controller->viewPath .= DS . $type;
|
||||
} else {
|
||||
$remove = preg_replace("/([\/\\\\]{$this->_renderType})$/", DS . $type, $controller->viewPath);
|
||||
$controller->viewPath = $remove;
|
||||
$controller->viewPath = preg_replace(
|
||||
"/([\/\\\\]{$this->_renderType})$/",
|
||||
DS . $type,
|
||||
$controller->viewPath
|
||||
);
|
||||
}
|
||||
$this->_renderType = $type;
|
||||
$controller->layoutPath = $type;
|
||||
|
|
@ -603,12 +645,8 @@ class RequestHandlerComponent extends Component {
|
|||
}
|
||||
|
||||
$helper = ucfirst($type);
|
||||
$isAdded = (
|
||||
in_array($helper, $controller->helpers) ||
|
||||
array_key_exists($helper, $controller->helpers)
|
||||
);
|
||||
|
||||
if (!$isAdded) {
|
||||
if (!in_array($helper, $controller->helpers) && empty($controller->helpers[$helper])) {
|
||||
App::uses('AppHelper', 'View/Helper');
|
||||
App::uses($helper . 'Helper', 'View/Helper');
|
||||
if (class_exists($helper . 'Helper')) {
|
||||
|
|
@ -618,14 +656,14 @@ class RequestHandlerComponent extends Component {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the response header based on type map index name. This wraps several methods
|
||||
* Sets the response header based on type map index name. This wraps several methods
|
||||
* available on CakeResponse. It also allows you to use Content-Type aliases.
|
||||
*
|
||||
* @param string|array $type Friendly type name, i.e. 'html' or 'xml', or a full content-type,
|
||||
* like 'application/x-shockwave'.
|
||||
* @param array $options If $type is a friendly type name that is associated with
|
||||
* more than one type of content, $index is used to select which content-type to use.
|
||||
* @return boolean Returns false if the friendly type name given in $type does
|
||||
* @return bool Returns false if the friendly type name given in $type does
|
||||
* not exist in the type map, or if the Content-type header has
|
||||
* already been set by this method.
|
||||
* @see RequestHandlerComponent::setContent()
|
||||
|
|
@ -634,39 +672,35 @@ class RequestHandlerComponent extends Component {
|
|||
$defaults = array('index' => null, 'charset' => null, 'attachment' => false);
|
||||
$options = $options + $defaults;
|
||||
|
||||
$cType = $type;
|
||||
if (strpos($type, '/') === false) {
|
||||
$cType = $this->response->getMimeType($type);
|
||||
if ($cType === false) {
|
||||
return false;
|
||||
}
|
||||
if (is_array($cType) && isset($cType[$options['index']])) {
|
||||
}
|
||||
if (is_array($cType)) {
|
||||
if (isset($cType[$options['index']])) {
|
||||
$cType = $cType[$options['index']];
|
||||
}
|
||||
if (is_array($cType)) {
|
||||
if ($this->prefers($cType)) {
|
||||
$cType = $this->prefers($cType);
|
||||
} else {
|
||||
$cType = $cType[0];
|
||||
}
|
||||
|
||||
if ($this->prefers($cType)) {
|
||||
$cType = $this->prefers($cType);
|
||||
} else {
|
||||
$cType = $cType[0];
|
||||
}
|
||||
} else {
|
||||
$cType = $type;
|
||||
}
|
||||
|
||||
if ($cType != null) {
|
||||
if (empty($this->request->params['requested'])) {
|
||||
$this->response->type($cType);
|
||||
}
|
||||
|
||||
if (!empty($options['charset'])) {
|
||||
$this->response->charset($options['charset']);
|
||||
}
|
||||
if (!empty($options['attachment'])) {
|
||||
$this->response->download($options['attachment']);
|
||||
}
|
||||
return true;
|
||||
if (!$type) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
if (empty($this->request->params['requested'])) {
|
||||
$this->response->type($cType);
|
||||
}
|
||||
if (!empty($options['charset'])) {
|
||||
$this->response->charset($options['charset']);
|
||||
}
|
||||
if (!empty($options['attachment'])) {
|
||||
$this->response->download($options['attachment']);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -684,7 +718,7 @@ class RequestHandlerComponent extends Component {
|
|||
*
|
||||
* @param string|array $cType Either a string content type to map, or an array of types.
|
||||
* @return string|array Aliases for the types provided.
|
||||
* @deprecated Use $this->response->mapType() in your controller instead.
|
||||
* @deprecated 3.0.0 Use $this->response->mapType() in your controller instead.
|
||||
*/
|
||||
public function mapType($cType) {
|
||||
return $this->response->mapType($cType);
|
||||
|
|
@ -694,7 +728,7 @@ class RequestHandlerComponent extends Component {
|
|||
* Maps a content type alias back to its mime-type(s)
|
||||
*
|
||||
* @param string|array $alias String alias to convert back into a content type. Or an array of aliases to map.
|
||||
* @return string Null on an undefined alias. String value of the mapped alias type. If an
|
||||
* @return string|null Null on an undefined alias. String value of the mapped alias type. If an
|
||||
* alias maps to more than one content type, the first one will be returned.
|
||||
*/
|
||||
public function mapAlias($alias) {
|
||||
|
|
@ -712,11 +746,11 @@ class RequestHandlerComponent extends Component {
|
|||
}
|
||||
|
||||
/**
|
||||
* Add a new mapped input type. Mapped input types are automatically
|
||||
* Add a new mapped input type. Mapped input types are automatically
|
||||
* converted by RequestHandlerComponent during the startup() callback.
|
||||
*
|
||||
* @param string $type The type alias being converted, ie. json
|
||||
* @param array $handler The handler array for the type. The first index should
|
||||
* @param array $handler The handler array for the type. The first index should
|
||||
* be the handling callback, all other arguments should be additional parameters
|
||||
* for the handler.
|
||||
* @return void
|
||||
|
|
@ -729,4 +763,25 @@ class RequestHandlerComponent extends Component {
|
|||
$this->_inputTypeMap[$type] = $handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter/setter for viewClassMap
|
||||
*
|
||||
* @param array|string $type The type string or array with format `array('type' => 'viewClass')` to map one or more
|
||||
* @param array $viewClass The viewClass to be used for the type without `View` appended
|
||||
* @return array|string Returns viewClass when only string $type is set, else array with viewClassMap
|
||||
*/
|
||||
public function viewClassMap($type = null, $viewClass = null) {
|
||||
if (!$viewClass && is_string($type) && isset($this->_viewClassMap[$type])) {
|
||||
return $this->_viewClassMap[$type];
|
||||
}
|
||||
if (is_string($type)) {
|
||||
$this->_viewClassMap[$type] = $viewClass;
|
||||
} elseif (is_array($type)) {
|
||||
foreach ($type as $key => $value) {
|
||||
$this->viewClassMap($key, $value);
|
||||
}
|
||||
}
|
||||
return $this->_viewClassMap;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,23 +2,22 @@
|
|||
/**
|
||||
* Security Component
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Controller.Component
|
||||
* @since CakePHP(tm) v 0.10.8.2156
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('Component', 'Controller');
|
||||
App::uses('String', 'Utility');
|
||||
App::uses('CakeText', 'Utility');
|
||||
App::uses('Hash', 'Utility');
|
||||
App::uses('Security', 'Utility');
|
||||
|
||||
|
|
@ -48,6 +47,7 @@ class SecurityComponent extends Component {
|
|||
* List of controller actions for which a POST request is required
|
||||
*
|
||||
* @var array
|
||||
* @deprecated 3.0.0 Use CakeRequest::allowMethod() instead.
|
||||
* @see SecurityComponent::requirePost()
|
||||
*/
|
||||
public $requirePost = array();
|
||||
|
|
@ -56,6 +56,7 @@ class SecurityComponent extends Component {
|
|||
* List of controller actions for which a GET request is required
|
||||
*
|
||||
* @var array
|
||||
* @deprecated 3.0.0 Use CakeRequest::allowMethod() instead.
|
||||
* @see SecurityComponent::requireGet()
|
||||
*/
|
||||
public $requireGet = array();
|
||||
|
|
@ -64,6 +65,7 @@ class SecurityComponent extends Component {
|
|||
* List of controller actions for which a PUT request is required
|
||||
*
|
||||
* @var array
|
||||
* @deprecated 3.0.0 Use CakeRequest::allowMethod() instead.
|
||||
* @see SecurityComponent::requirePut()
|
||||
*/
|
||||
public $requirePut = array();
|
||||
|
|
@ -72,6 +74,7 @@ class SecurityComponent extends Component {
|
|||
* List of controller actions for which a DELETE request is required
|
||||
*
|
||||
* @var array
|
||||
* @deprecated 3.0.0 Use CakeRequest::allowMethod() instead.
|
||||
* @see SecurityComponent::requireDelete()
|
||||
*/
|
||||
public $requireDelete = array();
|
||||
|
|
@ -89,6 +92,7 @@ class SecurityComponent extends Component {
|
|||
*
|
||||
* @var array
|
||||
* @see SecurityComponent::requireAuth()
|
||||
* @deprecated 2.8.1 This feature is confusing and not useful.
|
||||
*/
|
||||
public $requireAuth = array();
|
||||
|
||||
|
|
@ -114,7 +118,7 @@ class SecurityComponent extends Component {
|
|||
* Deprecated property, superseded by unlockedFields.
|
||||
*
|
||||
* @var array
|
||||
* @deprecated
|
||||
* @deprecated 3.0.0 Superseded by unlockedFields.
|
||||
* @see SecurityComponent::$unlockedFields
|
||||
*/
|
||||
public $disabledFields = array();
|
||||
|
|
@ -130,17 +134,26 @@ class SecurityComponent extends Component {
|
|||
public $unlockedFields = array();
|
||||
|
||||
/**
|
||||
* Whether to validate POST data. Set to false to disable for data coming from 3rd party
|
||||
* Actions to exclude from CSRF and POST validation checks.
|
||||
* Other checks like requireAuth(), requireSecure(),
|
||||
* requirePost(), requireGet() etc. will still be applied.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $unlockedActions = array();
|
||||
|
||||
/**
|
||||
* Whether to validate POST data. Set to false to disable for data coming from 3rd party
|
||||
* services, etc.
|
||||
*
|
||||
* @var boolean
|
||||
* @var bool
|
||||
*/
|
||||
public $validatePost = true;
|
||||
|
||||
/**
|
||||
* Whether to use CSRF protected forms. Set to false to disable CSRF protection on forms.
|
||||
* Whether to use CSRF protected forms. Set to false to disable CSRF protection on forms.
|
||||
*
|
||||
* @var boolean
|
||||
* @var bool
|
||||
* @see http://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
|
||||
* @see SecurityComponent::$csrfExpires
|
||||
*/
|
||||
|
|
@ -149,32 +162,32 @@ class SecurityComponent extends Component {
|
|||
/**
|
||||
* The duration from when a CSRF token is created that it will expire on.
|
||||
* Each form/page request will generate a new token that can only be submitted once unless
|
||||
* it expires. Can be any value compatible with strtotime()
|
||||
* it expires. Can be any value compatible with strtotime()
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $csrfExpires = '+30 minutes';
|
||||
|
||||
/**
|
||||
* Controls whether or not CSRF tokens are use and burn. Set to false to not generate
|
||||
* new tokens on each request. One token will be reused until it expires. This reduces
|
||||
* Controls whether or not CSRF tokens are use and burn. Set to false to not generate
|
||||
* new tokens on each request. One token will be reused until it expires. This reduces
|
||||
* the chances of users getting invalid requests because of token consumption.
|
||||
* It has the side effect of making CSRF less secure, as tokens are reusable.
|
||||
*
|
||||
* @var boolean
|
||||
* @var bool
|
||||
*/
|
||||
public $csrfUseOnce = true;
|
||||
|
||||
/**
|
||||
* Control the number of tokens a user can keep open.
|
||||
* This is most useful with one-time use tokens. Since new tokens
|
||||
* This is most useful with one-time use tokens. Since new tokens
|
||||
* are created on each request, having a hard limit on the number of open tokens
|
||||
* can be useful in controlling the size of the session file.
|
||||
*
|
||||
* When tokens are evicted, the oldest ones will be removed, as they are the most likely
|
||||
* to be dead/expired.
|
||||
*
|
||||
* @var integer
|
||||
* @var int
|
||||
*/
|
||||
public $csrfLimit = 100;
|
||||
|
||||
|
|
@ -212,28 +225,26 @@ class SecurityComponent extends Component {
|
|||
$this->_secureRequired($controller);
|
||||
$this->_authRequired($controller);
|
||||
|
||||
$isPost = ($this->request->is('post') || $this->request->is('put'));
|
||||
$hasData = !empty($this->request->data);
|
||||
$isNotRequestAction = (
|
||||
!isset($controller->request->params['requested']) ||
|
||||
$controller->request->params['requested'] != 1
|
||||
);
|
||||
|
||||
if ($this->_action == $this->blackHoleCallback) {
|
||||
return $this->blackhole($controller, 'auth');
|
||||
if ($this->_action === $this->blackHoleCallback) {
|
||||
return $this->blackHole($controller, 'auth');
|
||||
}
|
||||
|
||||
if ($isPost && $isNotRequestAction && $this->validatePost) {
|
||||
if ($this->_validatePost($controller) === false) {
|
||||
if (!in_array($this->_action, (array)$this->unlockedActions) && $hasData && $isNotRequestAction) {
|
||||
if ($this->validatePost && $this->_validatePost($controller) === false) {
|
||||
return $this->blackHole($controller, 'auth');
|
||||
}
|
||||
}
|
||||
if ($isPost && $isNotRequestAction && $this->csrfCheck) {
|
||||
if ($this->_validateCsrf($controller) === false) {
|
||||
if ($this->csrfCheck && $this->_validateCsrf($controller) === false) {
|
||||
return $this->blackHole($controller, 'csrf');
|
||||
}
|
||||
}
|
||||
$this->generateToken($controller->request);
|
||||
if ($isPost && is_array($controller->request->data)) {
|
||||
if ($hasData && is_array($controller->request->data)) {
|
||||
unset($controller->request->data['_Token']);
|
||||
}
|
||||
}
|
||||
|
|
@ -242,6 +253,7 @@ class SecurityComponent extends Component {
|
|||
* Sets the actions that require a POST request, or empty for all actions
|
||||
*
|
||||
* @return void
|
||||
* @deprecated 3.0.0 Use CakeRequest::onlyAllow() instead.
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#SecurityComponent::requirePost
|
||||
*/
|
||||
public function requirePost() {
|
||||
|
|
@ -252,6 +264,7 @@ class SecurityComponent extends Component {
|
|||
/**
|
||||
* Sets the actions that require a GET request, or empty for all actions
|
||||
*
|
||||
* @deprecated 3.0.0 Use CakeRequest::onlyAllow() instead.
|
||||
* @return void
|
||||
*/
|
||||
public function requireGet() {
|
||||
|
|
@ -262,6 +275,7 @@ class SecurityComponent extends Component {
|
|||
/**
|
||||
* Sets the actions that require a PUT request, or empty for all actions
|
||||
*
|
||||
* @deprecated 3.0.0 Use CakeRequest::onlyAllow() instead.
|
||||
* @return void
|
||||
*/
|
||||
public function requirePut() {
|
||||
|
|
@ -272,6 +286,7 @@ class SecurityComponent extends Component {
|
|||
/**
|
||||
* Sets the actions that require a DELETE request, or empty for all actions
|
||||
*
|
||||
* @deprecated 3.0.0 Use CakeRequest::onlyAllow() instead.
|
||||
* @return void
|
||||
*/
|
||||
public function requireDelete() {
|
||||
|
|
@ -291,7 +306,11 @@ class SecurityComponent extends Component {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the actions that require an authenticated request, or empty for all actions
|
||||
* Sets the actions that require whitelisted form submissions.
|
||||
*
|
||||
* Adding actions with this method will enforce the restrictions
|
||||
* set in SecurityComponent::$allowedControllers and
|
||||
* SecurityComponent::$allowedActions.
|
||||
*
|
||||
* @return void
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#SecurityComponent::requireAuth
|
||||
|
|
@ -330,24 +349,24 @@ class SecurityComponent extends Component {
|
|||
if (isset($actions[0]) && is_array($actions[0])) {
|
||||
$actions = $actions[0];
|
||||
}
|
||||
$this->{'require' . $method} = (empty($actions)) ? array('*'): $actions;
|
||||
$this->{'require' . $method} = (empty($actions)) ? array('*') : $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if HTTP methods are required
|
||||
*
|
||||
* @param Controller $controller Instantiating controller
|
||||
* @return boolean true if $method is required
|
||||
* @return bool True if $method is required
|
||||
*/
|
||||
protected function _methodsRequired(Controller $controller) {
|
||||
foreach (array('Post', 'Get', 'Put', 'Delete') as $method) {
|
||||
$property = 'require' . $method;
|
||||
if (is_array($this->$property) && !empty($this->$property)) {
|
||||
$require = $this->$property;
|
||||
if (in_array($this->_action, $require) || $this->$property == array('*')) {
|
||||
if (in_array($this->_action, $require) || $this->$property === array('*')) {
|
||||
if (!$this->request->is($method)) {
|
||||
if (!$this->blackHole($controller, $method)) {
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -360,16 +379,16 @@ class SecurityComponent extends Component {
|
|||
* Check if access requires secure connection
|
||||
*
|
||||
* @param Controller $controller Instantiating controller
|
||||
* @return boolean true if secure connection required
|
||||
* @return bool True if secure connection required
|
||||
*/
|
||||
protected function _secureRequired(Controller $controller) {
|
||||
if (is_array($this->requireSecure) && !empty($this->requireSecure)) {
|
||||
$requireSecure = $this->requireSecure;
|
||||
|
||||
if (in_array($this->_action, $requireSecure) || $this->requireSecure == array('*')) {
|
||||
if (in_array($this->_action, $requireSecure) || $this->requireSecure === array('*')) {
|
||||
if (!$this->request->is('ssl')) {
|
||||
if (!$this->blackHole($controller, 'secure')) {
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -381,14 +400,15 @@ class SecurityComponent extends Component {
|
|||
* Check if authentication is required
|
||||
*
|
||||
* @param Controller $controller Instantiating controller
|
||||
* @return boolean true if authentication required
|
||||
* @return bool|null True if authentication required
|
||||
* @deprecated 2.8.1 This feature is confusing and not useful.
|
||||
*/
|
||||
protected function _authRequired(Controller $controller) {
|
||||
if (is_array($this->requireAuth) && !empty($this->requireAuth) && !empty($this->request->data)) {
|
||||
$requireAuth = $this->requireAuth;
|
||||
|
||||
if (in_array($this->request->params['action'], $requireAuth) || $this->requireAuth == array('*')) {
|
||||
if (!isset($controller->request->data['_Token'] )) {
|
||||
if (in_array($this->request->params['action'], $requireAuth) || $this->requireAuth === array('*')) {
|
||||
if (!isset($controller->request->data['_Token'])) {
|
||||
if (!$this->blackHole($controller, 'auth')) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -397,8 +417,7 @@ class SecurityComponent extends Component {
|
|||
if ($this->Session->check('_Token')) {
|
||||
$tData = $this->Session->read('_Token');
|
||||
|
||||
if (
|
||||
!empty($tData['allowedControllers']) &&
|
||||
if (!empty($tData['allowedControllers']) &&
|
||||
!in_array($this->request->params['controller'], $tData['allowedControllers']) ||
|
||||
!empty($tData['allowedActions']) &&
|
||||
!in_array($this->request->params['action'], $tData['allowedActions'])
|
||||
|
|
@ -421,7 +440,7 @@ class SecurityComponent extends Component {
|
|||
* Validate submitted form
|
||||
*
|
||||
* @param Controller $controller Instantiating controller
|
||||
* @return boolean true if submitted form is valid
|
||||
* @return bool true if submitted form is valid
|
||||
*/
|
||||
protected function _validatePost(Controller $controller) {
|
||||
if (empty($controller->request->data)) {
|
||||
|
|
@ -452,8 +471,8 @@ class SecurityComponent extends Component {
|
|||
$multi = array();
|
||||
|
||||
foreach ($fieldList as $i => $key) {
|
||||
if (preg_match('/(\.\d+)+$/', $key)) {
|
||||
$multi[$i] = preg_replace('/(\.\d+)+$/', '', $key);
|
||||
if (preg_match('/(\.\d+){1,10}$/', $key)) {
|
||||
$multi[$i] = preg_replace('/(\.\d+){1,10}$/', '', $key);
|
||||
unset($fieldList[$i]);
|
||||
}
|
||||
}
|
||||
|
|
@ -492,7 +511,13 @@ class SecurityComponent extends Component {
|
|||
|
||||
$fieldList += $lockedFields;
|
||||
$unlocked = implode('|', $unlocked);
|
||||
$check = Security::hash(serialize($fieldList) . $unlocked . Configure::read('Security.salt'));
|
||||
$hashParts = array(
|
||||
$this->request->here(),
|
||||
serialize($fieldList),
|
||||
$unlocked,
|
||||
Configure::read('Security.salt')
|
||||
);
|
||||
$check = Security::hash(implode('', $hashParts), 'sha1');
|
||||
return ($token === $check);
|
||||
}
|
||||
|
||||
|
|
@ -500,7 +525,7 @@ class SecurityComponent extends Component {
|
|||
* Manually add CSRF token information into the provided request object.
|
||||
*
|
||||
* @param CakeRequest $request The request object to add into.
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function generateToken(CakeRequest $request) {
|
||||
if (isset($request->params['requested']) && $request->params['requested'] === 1) {
|
||||
|
|
@ -509,7 +534,7 @@ class SecurityComponent extends Component {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
$authKey = Security::generateAuthKey();
|
||||
$authKey = hash('sha512', Security::randomBytes(16), false);
|
||||
$token = array(
|
||||
'key' => $authKey,
|
||||
'allowedControllers' => $this->allowedControllers,
|
||||
|
|
@ -530,7 +555,9 @@ class SecurityComponent extends Component {
|
|||
}
|
||||
if (!$this->csrfUseOnce) {
|
||||
$csrfTokens = array_keys($token['csrfTokens']);
|
||||
$token['key'] = $csrfTokens[0];
|
||||
$authKey = $csrfTokens[0];
|
||||
$token['key'] = $authKey;
|
||||
$token['csrfTokens'][$authKey] = strtotime($this->csrfExpires);
|
||||
}
|
||||
$this->Session->write('_Token', $token);
|
||||
$request->params['_Token'] = array(
|
||||
|
|
@ -542,11 +569,11 @@ class SecurityComponent extends Component {
|
|||
|
||||
/**
|
||||
* Validate that the controller has a CSRF token in the POST data
|
||||
* and that the token is legit/not expired. If the token is valid
|
||||
* and that the token is legit/not expired. If the token is valid
|
||||
* it will be removed from the list of valid tokens.
|
||||
*
|
||||
* @param Controller $controller A controller to check
|
||||
* @return boolean Valid csrf token.
|
||||
* @return bool Valid csrf token.
|
||||
*/
|
||||
protected function _validateCsrf(Controller $controller) {
|
||||
$token = $this->Session->read('_Token');
|
||||
|
|
@ -591,11 +618,10 @@ class SecurityComponent extends Component {
|
|||
* @throws BadRequestException When a the blackholeCallback is not callable.
|
||||
*/
|
||||
protected function _callback(Controller $controller, $method, $params = array()) {
|
||||
if (is_callable(array($controller, $method))) {
|
||||
return call_user_func_array(array(&$controller, $method), empty($params) ? null : $params);
|
||||
} else {
|
||||
if (!is_callable(array($controller, $method))) {
|
||||
throw new BadRequestException(__d('cake_dev', 'The request has been black-holed'));
|
||||
}
|
||||
return call_user_func_array(array(&$controller, $method), empty($params) ? null : $params);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,19 +2,18 @@
|
|||
/**
|
||||
* SessionComponent. Provides access to Sessions from the Controller layer
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Controller.Component
|
||||
* @since CakePHP(tm) v 0.10.0.1232
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('Component', 'Controller');
|
||||
|
|
@ -35,21 +34,21 @@ class SessionComponent extends Component {
|
|||
* Get / Set the userAgent
|
||||
*
|
||||
* @param string $userAgent Set the userAgent
|
||||
* @return void
|
||||
* @return string Current user agent.
|
||||
*/
|
||||
public function userAgent($userAgent = null) {
|
||||
return CakeSession::userAgent($userAgent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to write a value to a session key.
|
||||
* Writes a value to a session key.
|
||||
*
|
||||
* In your controller: $this->Session->write('Controller.sessKey', 'session value');
|
||||
*
|
||||
* @param string $name The name of the key your are setting in the session.
|
||||
* This should be in a Controller.key format for better organizing
|
||||
* @param string $value The value you want to store in a session.
|
||||
* @return boolean Success
|
||||
* @return bool Success
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#SessionComponent::write
|
||||
*/
|
||||
public function write($name, $value = null) {
|
||||
|
|
@ -57,7 +56,7 @@ class SessionComponent extends Component {
|
|||
}
|
||||
|
||||
/**
|
||||
* Used to read a session values for a key or return values for all keys.
|
||||
* Reads a session value for a key or returns values for all keys.
|
||||
*
|
||||
* In your controller: $this->Session->read('Controller.sessKey');
|
||||
* Calling the method without a param will return all session vars
|
||||
|
|
@ -71,12 +70,12 @@ class SessionComponent extends Component {
|
|||
}
|
||||
|
||||
/**
|
||||
* Wrapper for SessionComponent::del();
|
||||
* Deletes a session value for a key.
|
||||
*
|
||||
* In your controller: $this->Session->delete('Controller.sessKey');
|
||||
*
|
||||
* @param string $name the name of the session key you want to delete
|
||||
* @return boolean true is session variable is set and can be deleted, false is variable was not set.
|
||||
* @return bool true is session variable is set and can be deleted, false is variable was not set.
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#SessionComponent::delete
|
||||
*/
|
||||
public function delete($name) {
|
||||
|
|
@ -84,12 +83,24 @@ class SessionComponent extends Component {
|
|||
}
|
||||
|
||||
/**
|
||||
* Used to check if a session variable is set
|
||||
* Reads and deletes a session value for a key.
|
||||
*
|
||||
* In your controller: `$this->Session->consume('Controller.sessKey');`
|
||||
*
|
||||
* @param string $name the name of the session key you want to read
|
||||
* @return mixed values from the session vars
|
||||
*/
|
||||
public function consume($name) {
|
||||
return CakeSession::consume($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a session variable is set.
|
||||
*
|
||||
* In your controller: $this->Session->check('Controller.sessKey');
|
||||
*
|
||||
* @param string $name the name of the session key you want to check
|
||||
* @return boolean true is session variable is set, false if not
|
||||
* @return bool true is session variable is set, false if not
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#SessionComponent::check
|
||||
*/
|
||||
public function check($name) {
|
||||
|
|
@ -122,6 +133,7 @@ class SessionComponent extends Component {
|
|||
* @param string $key Message key, default is 'flash'
|
||||
* @return void
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#creating-notification-messages
|
||||
* @deprecated 3.0.0 Since 2.7, use the FlashComponent instead.
|
||||
*/
|
||||
public function setFlash($message, $element = 'default', $params = array(), $key = 'flash') {
|
||||
CakeSession::write('Message.' . $key, compact('message', 'element', 'params'));
|
||||
|
|
@ -143,7 +155,7 @@ class SessionComponent extends Component {
|
|||
*
|
||||
* In your controller: $this->Session->valid();
|
||||
*
|
||||
* @return boolean true is session is valid, false is session is invalid
|
||||
* @return bool true is session is valid, false is session is invalid
|
||||
*/
|
||||
public function valid() {
|
||||
return CakeSession::valid();
|
||||
|
|
@ -165,7 +177,7 @@ class SessionComponent extends Component {
|
|||
* Get/Set the session id.
|
||||
*
|
||||
* When fetching the session id, the session will be started
|
||||
* if it has not already been started. When setting the session id,
|
||||
* if it has not already been started. When setting the session id,
|
||||
* the session will not be started.
|
||||
*
|
||||
* @param string $id Id to use (optional)
|
||||
|
|
@ -181,7 +193,7 @@ class SessionComponent extends Component {
|
|||
/**
|
||||
* Returns a bool, whether or not the session has been started.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function started() {
|
||||
return CakeSession::started();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue