mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2025-01-18 18:46:17 +00:00
Adding GET/PUT/DELETE method checks to Security component, refactoring adding tests, closes #4231. Thanks joelmoss.
git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6703 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
parent
d412d7094f
commit
296e8989ba
2 changed files with 230 additions and 99 deletions
|
@ -50,6 +50,30 @@ class SecurityComponent extends Object {
|
|||
* @see SecurityComponent::requirePost()
|
||||
*/
|
||||
var $requirePost = array();
|
||||
/**
|
||||
* List of controller actions for which a GET request is required
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
* @see SecurityComponent::requireGet()
|
||||
*/
|
||||
var $requireGet = array();
|
||||
/**
|
||||
* List of controller actions for which a PUT request is required
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
* @see SecurityComponent::requirePut()
|
||||
*/
|
||||
var $requirePut = array();
|
||||
/**
|
||||
* List of controller actions for which a DELETE request is required
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
* @see SecurityComponent::requireDelete()
|
||||
*/
|
||||
var $requireDelete = array();
|
||||
/**
|
||||
* List of actions that require an SSL-secured connection
|
||||
*
|
||||
|
@ -137,7 +161,7 @@ class SecurityComponent extends Object {
|
|||
*/
|
||||
function startup(&$controller) {
|
||||
$this->__action = strtolower($controller->action);
|
||||
$this->__postRequired($controller);
|
||||
$this->__methodsRequired($controller);
|
||||
$this->__secureRequired($controller);
|
||||
$this->__authRequired($controller);
|
||||
$this->__loginRequired($controller);
|
||||
|
@ -154,10 +178,35 @@ class SecurityComponent extends Object {
|
|||
* @access public
|
||||
*/
|
||||
function requirePost() {
|
||||
$this->requirePost = func_get_args();
|
||||
if (empty($this->requirePost)) {
|
||||
$this->requirePost = array('*');
|
||||
$args = func_get_args();
|
||||
$this->__requireMethod('Post', $args);
|
||||
}
|
||||
/**
|
||||
* Sets the actions that require a GET request, or empty for all actions
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function requireGet() {
|
||||
$args = func_get_args();
|
||||
$this->__requireMethod('Get', $args);
|
||||
}
|
||||
/**
|
||||
* Sets the actions that require a PUT request, or empty for all actions
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function requirePut() {
|
||||
$args = func_get_args();
|
||||
$this->__requireMethod('Put', $args);
|
||||
}
|
||||
/**
|
||||
* Sets the actions that require a DELETE request, or empty for all actions
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function requireDelete() {
|
||||
$args = func_get_args();
|
||||
$this->__requireMethod('Delete', $args);
|
||||
}
|
||||
/**
|
||||
* Sets the actions that require a request that is SSL-secured, or empty for all actions
|
||||
|
@ -165,10 +214,8 @@ class SecurityComponent extends Object {
|
|||
* @access public
|
||||
*/
|
||||
function requireSecure() {
|
||||
$this->requireSecure = func_get_args();
|
||||
if (empty($this->requireSecure)) {
|
||||
$this->requireSecure = array('*');
|
||||
}
|
||||
$args = func_get_args();
|
||||
$this->__requireMethod('Secure', $args);
|
||||
}
|
||||
/**
|
||||
* Sets the actions that require an authenticated request, or empty for all actions
|
||||
|
@ -176,10 +223,8 @@ class SecurityComponent extends Object {
|
|||
* @access public
|
||||
*/
|
||||
function requireAuth() {
|
||||
$this->requireAuth = func_get_args();
|
||||
if (empty($this->requireAuth)) {
|
||||
$this->requireAuth = array('*');
|
||||
}
|
||||
$args = func_get_args();
|
||||
$this->__requireMethod('Auth', $args);
|
||||
}
|
||||
/**
|
||||
* Sets the actions that require an HTTP-authenticated request, or empty for all actions
|
||||
|
@ -190,18 +235,14 @@ class SecurityComponent extends Object {
|
|||
$args = func_get_args();
|
||||
$base = $this->loginOptions;
|
||||
|
||||
foreach ($args as $arg) {
|
||||
foreach ($args as $i => $arg) {
|
||||
if (is_array($arg)) {
|
||||
$this->loginOptions = $arg;
|
||||
} else {
|
||||
$this->requireLogin[] = $arg;
|
||||
unset($args[$i]);
|
||||
}
|
||||
}
|
||||
$this->loginOptions = array_merge($base, $this->loginOptions);
|
||||
|
||||
if (empty($this->requireLogin)) {
|
||||
$this->requireLogin = array('*');
|
||||
}
|
||||
$this->__requireMethod('Login', $args);
|
||||
|
||||
if (isset($this->loginOptions['users'])) {
|
||||
$this->loginUsers =& $this->loginOptions['users'];
|
||||
|
@ -332,24 +373,37 @@ class SecurityComponent extends Object {
|
|||
}
|
||||
}
|
||||
/**
|
||||
* Check if post is required
|
||||
* Sets the actions that require a $method HTTP request, or empty for all actions
|
||||
*
|
||||
* @param object $controller Instantiating controller
|
||||
* @return bool true if post is requred
|
||||
* @param string $method The HTTP method to assign controller actions to
|
||||
* @param array $actions Controller actions to set the required HTTP method to.
|
||||
* @access private
|
||||
*/
|
||||
function __postRequired(&$controller) {
|
||||
if (is_array($this->requirePost) && !empty($this->requirePost)) {
|
||||
$requirePost = array_map('strtolower', $this->requirePost);
|
||||
function __requireMethod($method, $actions = array()) {
|
||||
$this->{'require' . $method} = ife(empty($actions), array('*'), $actions);
|
||||
}
|
||||
/**
|
||||
* Check if HTTP methods are required
|
||||
*
|
||||
* @param object $controller Instantiating controller
|
||||
* @return bool true if $method is required
|
||||
* @access private
|
||||
*/
|
||||
function __methodsRequired(&$controller) {
|
||||
foreach (array('Post', 'Get', 'Put', 'Delete') as $method) {
|
||||
$property = 'require' . $method;
|
||||
if (is_array($this->$property) && !empty($this->$property)) {
|
||||
$require = array_map('strtolower', $this->$property);
|
||||
|
||||
if (in_array($this->__action, $requirePost) || $this->requirePost == array('*')) {
|
||||
if (!$this->RequestHandler->isPost()) {
|
||||
if (!$this->blackHole($controller, 'post')) {
|
||||
if (in_array($this->__action, $require) || $this->$property == array('*')) {
|
||||
if (!$this->RequestHandler->{'is' . $method}()) {
|
||||
if (!$this->blackHole($controller, strtolower($method))) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
|
|
|
@ -38,6 +38,12 @@ class SecurityTestController extends Controller {
|
|||
var $name = 'SecurityTest';
|
||||
var $components = array('Security');
|
||||
|
||||
var $failed = false;
|
||||
|
||||
function fail() {
|
||||
$this->failed = true;
|
||||
}
|
||||
|
||||
function redirect($option, $code, $exit) {
|
||||
return $code;
|
||||
}
|
||||
|
@ -53,9 +59,8 @@ class SecurityComponentTest extends CakeTestCase {
|
|||
|
||||
function setUp() {
|
||||
$this->Controller =& new SecurityTestController();
|
||||
restore_error_handler();
|
||||
@$this->Controller->_initComponents();
|
||||
set_error_handler('simpleTestErrorHandler');
|
||||
$this->Controller->_initComponents();
|
||||
$this->Controller->Security->blackHoleCallback = 'fail';
|
||||
}
|
||||
|
||||
function testStartup() {
|
||||
|
@ -65,44 +70,117 @@ class SecurityComponentTest extends CakeTestCase {
|
|||
$this->assertTrue($this->Controller->Session->check('_Token'));
|
||||
}
|
||||
|
||||
function testRequirePost()
|
||||
{
|
||||
$this->Controller->action = 'posted';
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$this->Controller->Security->requirePost('posted');
|
||||
$this->assertNull($this->Controller->Security->__methodsRequired($this->Controller));
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$this->assertTrue($this->Controller->Security->__methodsRequired($this->Controller));
|
||||
}
|
||||
|
||||
function testRequireGet()
|
||||
{
|
||||
$this->Controller->action = 'getted';
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$this->Controller->Security->requireGet('getted');
|
||||
$this->assertNull($this->Controller->Security->__methodsRequired($this->Controller));
|
||||
function testRequirePostFail() {
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$this->assertTrue($this->Controller->Security->__methodsRequired($this->Controller));
|
||||
$this->Controller->action = 'posted';
|
||||
$this->Controller->Security->requirePost('posted');
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$this->assertTrue($this->Controller->failed);
|
||||
}
|
||||
|
||||
function testRequirePut()
|
||||
{
|
||||
function testRequirePostSucceed() {
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$this->Controller->action = 'posted';
|
||||
$this->Controller->Security->requirePost('posted');
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$this->assertFalse($this->Controller->failed);
|
||||
}
|
||||
|
||||
function testRequirePostSucceedWrongMethod() {
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$this->Controller->action = 'getted';
|
||||
$this->Controller->Security->requirePost('posted');
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$this->assertFalse($this->Controller->failed);
|
||||
}
|
||||
|
||||
function testRequireGetFail() {
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$this->Controller->action = 'getted';
|
||||
$this->Controller->Security->requireGet('getted');
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$this->assertTrue($this->Controller->failed);
|
||||
}
|
||||
|
||||
function testRequireGetSucceed() {
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$this->Controller->action = 'getted';
|
||||
$this->Controller->Security->requireGet('getted');
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$this->assertFalse($this->Controller->failed);
|
||||
}
|
||||
|
||||
function testRequireGetSucceedWrongMethod() {
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$this->Controller->action = 'posted';
|
||||
$this->Controller->Security->requireGet('getted');
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$this->assertFalse($this->Controller->failed);
|
||||
}
|
||||
|
||||
function testRequirePutFail() {
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$this->Controller->action = 'putted';
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$this->Controller->Security->requirePut('putted');
|
||||
$this->assertNull($this->Controller->Security->__methodsRequired($this->Controller));
|
||||
$_SERVER['REQUEST_METHOD'] = 'PUT';
|
||||
$this->assertTrue($this->Controller->Security->__methodsRequired($this->Controller));
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$this->assertTrue($this->Controller->failed);
|
||||
}
|
||||
|
||||
function testRequireDelete()
|
||||
{
|
||||
$this->Controller->action = 'deleted';
|
||||
function testRequirePutSucceed() {
|
||||
$_SERVER['REQUEST_METHOD'] = 'PUT';
|
||||
$this->Controller->action = 'putted';
|
||||
$this->Controller->Security->requirePut('putted');
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$this->assertFalse($this->Controller->failed);
|
||||
}
|
||||
|
||||
function testRequirePutSucceedWrongMethod() {
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$this->Controller->action = 'posted';
|
||||
$this->Controller->Security->requirePut('putted');
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$this->assertFalse($this->Controller->failed);
|
||||
}
|
||||
|
||||
function testRequireDeleteFail() {
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$this->Controller->action = 'deleted';
|
||||
$this->Controller->Security->requireDelete('deleted');
|
||||
$this->assertNull($this->Controller->Security->__methodsRequired($this->Controller));
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$this->assertTrue($this->Controller->failed);
|
||||
}
|
||||
|
||||
function testRequireDeleteSucceed() {
|
||||
$_SERVER['REQUEST_METHOD'] = 'DELETE';
|
||||
$this->assertTrue($this->Controller->Security->__methodsRequired($this->Controller));
|
||||
$this->Controller->action = 'deleted';
|
||||
$this->Controller->Security->requireDelete('deleted');
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$this->assertFalse($this->Controller->failed);
|
||||
}
|
||||
|
||||
function testRequireDeleteSucceedWrongMethod() {
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$this->Controller->action = 'posted';
|
||||
$this->Controller->Security->requireDelete('deleted');
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$this->assertFalse($this->Controller->failed);
|
||||
}
|
||||
|
||||
function testRequireLoginSettings() {
|
||||
$this->Controller->Security->requireLogin(
|
||||
'add', 'edit',
|
||||
array('type' => 'basic', 'users' => array('admin' => 'password'))
|
||||
);
|
||||
$this->assertEqual($this->Controller->Security->requireLogin, array('add', 'edit'));
|
||||
$this->assertEqual($this->Controller->Security->loginUsers, array('admin' => 'password'));
|
||||
}
|
||||
|
||||
function testRequireLoginAllActions() {
|
||||
$this->Controller->Security->requireLogin(
|
||||
array('type' => 'basic', 'users' => array('admin' => 'password'))
|
||||
);
|
||||
$this->assertEqual($this->Controller->Security->requireLogin, array('*'));
|
||||
$this->assertEqual($this->Controller->Security->loginUsers, array('admin' => 'password'));
|
||||
}
|
||||
|
||||
function testValidatePostNoModel() {
|
||||
|
@ -111,18 +189,14 @@ class SecurityComponentTest extends CakeTestCase {
|
|||
|
||||
$data['anything'] = 'some_data';
|
||||
$data['__Token']['key'] = $key;
|
||||
|
||||
$fields = array('anything',
|
||||
'__Token' => array('key' => $key));
|
||||
|
||||
$fields = $this->__sortFields($fields);
|
||||
$fields = $this->__sortFields(array('anything', '__Token' => array('key' => $key)));
|
||||
|
||||
$fields = urlencode(Security::hash(serialize($fields) . Configure::read('Security.salt')));
|
||||
$data['__Token']['fields'] = $fields;
|
||||
$this->Controller->data = $data;
|
||||
$result = $this->Controller->Security->__validatePost($this->Controller);
|
||||
$this->assertTrue($result);
|
||||
$this->assertTrue($this->Controller->data == $data);
|
||||
$this->assertEqual($this->Controller->data, $data);
|
||||
}
|
||||
|
||||
function testValidatePostSimple() {
|
||||
|
@ -133,9 +207,7 @@ class SecurityComponentTest extends CakeTestCase {
|
|||
$data['Model']['password'] = '';
|
||||
$data['__Token']['key'] = $key;
|
||||
|
||||
$fields = array('Model' => array('username','password'),
|
||||
'__Token' => array('key' => $key));
|
||||
|
||||
$fields = array('Model' => array('username','password'), '__Token' => array('key' => $key));
|
||||
$fields = $this->__sortFields($fields);
|
||||
|
||||
$fields = urlencode(Security::hash(serialize($fields) . Configure::read('Security.salt')));
|
||||
|
@ -143,11 +215,10 @@ class SecurityComponentTest extends CakeTestCase {
|
|||
$this->Controller->data = $data;
|
||||
$result = $this->Controller->Security->__validatePost($this->Controller);
|
||||
$this->assertTrue($result);
|
||||
$this->assertTrue($this->Controller->data == $data);
|
||||
$this->assertEqual($this->Controller->data, $data);
|
||||
}
|
||||
|
||||
function testValidatePostCheckbox() {
|
||||
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$key = $this->Controller->params['_Token']['key'];
|
||||
|
||||
|
@ -156,10 +227,11 @@ class SecurityComponentTest extends CakeTestCase {
|
|||
$data['_Model']['valid'] = '0';
|
||||
$data['__Token']['key'] = $key;
|
||||
|
||||
$fields = array('Model' => array('username', 'password', 'valid'),
|
||||
$fields = array(
|
||||
'Model' => array('username', 'password', 'valid'),
|
||||
'_Model' => array('valid' => '0'),
|
||||
'__Token' => array('key' => $key));
|
||||
|
||||
'__Token' => array('key' => $key)
|
||||
);
|
||||
$fields = $this->__sortFields($fields);
|
||||
|
||||
$fields = urlencode(Security::hash(serialize($fields) . Configure::read('Security.salt')));
|
||||
|
@ -171,7 +243,7 @@ class SecurityComponentTest extends CakeTestCase {
|
|||
|
||||
unset($data['_Model']);
|
||||
$data['Model']['valid'] = '0';
|
||||
$this->assertTrue($this->Controller->data == $data);
|
||||
$this->assertEqual($this->Controller->data, $data);
|
||||
}
|
||||
|
||||
function testValidatePostHidden() {
|
||||
|
@ -183,10 +255,11 @@ class SecurityComponentTest extends CakeTestCase {
|
|||
$data['_Model']['hidden'] = '0';
|
||||
$data['__Token']['key'] = $key;
|
||||
|
||||
$fields = array('Model' => array('username', 'password', 'hidden'),
|
||||
$fields = array(
|
||||
'Model' => array('username', 'password', 'hidden'),
|
||||
'_Model' => array('hidden' => '0'),
|
||||
'__Token' => array('key' => $key));
|
||||
|
||||
'__Token' => array('key' => $key)
|
||||
);
|
||||
$fields = $this->__sortFields($fields);
|
||||
|
||||
$fields = urlencode(Security::hash(serialize($fields) . Configure::read('Security.salt')));
|
||||
|
@ -212,17 +285,17 @@ class SecurityComponentTest extends CakeTestCase {
|
|||
$data['_Model3']['valid'] = '0';
|
||||
$data['__Token']['key'] = $key;
|
||||
|
||||
$fields = array('Model' => array('username', 'password', 'valid'),
|
||||
$fields = array(
|
||||
'Model' => array('username', 'password', 'valid'),
|
||||
'Model2'=> array('valid'),
|
||||
'Model3'=> array('valid'),
|
||||
'_Model2'=> array('valid' => '0'),
|
||||
'_Model3'=> array('valid' => '0'),
|
||||
'_Model' => array('valid' => '0'),
|
||||
'__Token' => array('key' => $key));
|
||||
'__Token' => array('key' => $key)
|
||||
);
|
||||
|
||||
$fields = $this->__sortFields($fields);
|
||||
|
||||
$fields = urlencode(Security::hash(serialize($fields) . Configure::read('Security.salt')));
|
||||
$fields = urlencode(Security::hash(serialize($this->__sortFields($fields)) . Configure::read('Security.salt')));
|
||||
$data['__Token']['fields'] = $fields;
|
||||
|
||||
$this->Controller->data = $data;
|
||||
|
@ -236,6 +309,10 @@ class SecurityComponentTest extends CakeTestCase {
|
|||
$this->assertTrue($this->Controller->data == $data);
|
||||
}
|
||||
|
||||
function testLoginValidation() {
|
||||
|
||||
}
|
||||
|
||||
function testValidateHasManyModel() {
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$key = $this->Controller->params['_Token']['key'];
|
||||
|
|
Loading…
Add table
Reference in a new issue