security.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: controller_2components_2security_8php-source.html 675 2008-12-26 00:27:14Z gwoo $ */
00003 /**
00004  * Short description for file.
00005  *
00006  * Long description for file
00007  *
00008  * PHP versions 4 and 5
00009  *
00010  * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
00011  * Copyright 2005-2008, Cake Software Foundation, Inc.
00012  *                              1785 E. Sahara Avenue, Suite 490-204
00013  *                              Las Vegas, Nevada 89104
00014  *
00015  * Licensed under The MIT License
00016  * Redistributions of files must retain the above copyright notice.
00017  *
00018  * @filesource
00019  * @copyright       Copyright 2005-2008, Cake Software Foundation, Inc.
00020  * @link                http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00021  * @package         cake
00022  * @subpackage      cake.cake.libs.controller.components
00023  * @since           CakePHP(tm) v 0.10.8.2156
00024  * @version         $Revision: 675 $
00025  * @modifiedby      $LastChangedBy: gwoo $
00026  * @lastmodified    $Date: 2008-12-25 16:27:14 -0800 (Thu, 25 Dec 2008) $
00027  * @license         http://www.opensource.org/licenses/mit-license.php The MIT License
00028  */
00029 /**
00030  * Short description for file.
00031  *
00032  * Long description for file
00033  *
00034  * @package     cake
00035  * @subpackage  cake.cake.libs.controller.components
00036  */
00037 class SecurityComponent extends Object {
00038 /**
00039  * Holds an instance of the core Security object
00040  *
00041  * @var object Security
00042  * @access public
00043  */
00044     var $Security = null;
00045 /**
00046  * The controller method that will be called if this request is black-hole'd
00047  *
00048  * @var string
00049  * @access public
00050  */
00051     var $blackHoleCallback = null;
00052 /**
00053  * List of controller actions for which a POST request is required
00054  *
00055  * @var array
00056  * @access public
00057  * @see SecurityComponent::requirePost()
00058  */
00059     var $requirePost = array();
00060 /**
00061  * List of actions that require a valid authentication key
00062  *
00063  * @var array
00064  * @access public
00065  * @see SecurityComponent::requireAuth()
00066  */
00067     var $requireAuth = array();
00068 /**
00069  * Controllers from which actions of the current controller are allowed to receive
00070  * requests.
00071  *
00072  * @var array
00073  * @see SecurityComponent::requireAuth()
00074  */
00075     var $allowedControllers = array();
00076 /**
00077  * Actions from which actions of the current controller are allowed to receive
00078  * requests.
00079  *
00080  * @var array
00081  * @see SecurityComponent::requireAuth()
00082  */
00083     var $allowedActions = array();
00084 /**
00085  * Other components used by the Security component
00086  *
00087  * @var array
00088  * @access public
00089  */
00090     var $components = array('RequestHandler', 'Session');
00091 /**
00092  * Security class constructor
00093  */
00094     function __construct () {
00095         $this->Security = Security::getInstance();
00096     }
00097 /**
00098  * Component startup.  All security checking happens here.
00099  *
00100  * @param object $controller
00101  * @return unknown
00102  * @access public
00103  */
00104     function startup(&$controller) {
00105         if (is_array($this->requirePost) && !empty($this->requirePost)) {
00106 
00107             if (in_array($controller->action, $this->requirePost)) {
00108 
00109                 if (!$this->RequestHandler->isPost()) {
00110 
00111                     if (!$this->blackHole($controller)) {
00112                         return null;
00113                     }
00114                 }
00115             }
00116         }
00117 
00118         if (is_array($this->requireAuth) && !empty($this->requireAuth) && !empty($controller->params['form'])) {
00119             if (in_array($controller->action, $this->requireAuth)) {
00120 
00121                 if (!isset($controller->params['data']['_Token'])) {
00122 
00123                     if (!$this->blackHole($controller)) {
00124                         return null;
00125                     }
00126                 }
00127                 $token = $controller->params['data']['_Token']['key'];
00128 
00129                 if ($this->Session->check('_Token')) {
00130                     $tData = $this->Session->read('_Token');
00131                     if (!(intval($tData['expires']) > strtotime('now')) || $tData['key'] !== $token) {
00132 
00133                         if (!$this->blackHole($controller)) {
00134                             return null;
00135                         }
00136                     }
00137 
00138                     if (!empty($tData['allowedControllers']) && !in_array($controller->params['controller'], $tData['allowedControllers']) ||!empty($tData['allowedActions']) && !in_array($controller->params['action'], $tData['allowedActions'])) {
00139                         if (!$this->blackHole($controller)) {
00140                             return null;
00141                         }
00142                     }
00143                 } else {
00144                     if (!$this->blackHole($controller)) {
00145                         return null;
00146                     }
00147                 }
00148             }
00149         }
00150 
00151         if (!isset($controller->params['requested']) || $controller->params['requested'] != 1) {
00152             // Add auth key for new form posts
00153             $authKey = Security::generateAuthKey();
00154             $expires = strtotime('+'.Security::inactiveMins().' minutes');
00155             $token = array(
00156                 'key' => $authKey,
00157                 'expires' => $expires,
00158                 'allowedControllers' => $this->allowedControllers,
00159                 'allowedActions' => $this->allowedActions
00160             );
00161             if (!isset($controller->params['data'])) {
00162                 $controller->params['data'] = array();
00163             }
00164             $controller->params['_Token'] = $token;
00165             $this->Session->write('_Token', $token);
00166         }
00167     }
00168 /**
00169  * Black-hole an invalid request with a 404 error or custom callback
00170  *
00171  * @param object $controller
00172  * @return callback in controller
00173  * @access public
00174  */
00175     function blackHole(&$controller) {
00176         if ($this->blackHoleCallback == null) {
00177             header('HTTP/1.0 404 Not Found');
00178             exit();
00179         } elseif (method_exists($controller, $this->blackHoleCallback)) {
00180             return $controller->{$this->blackHoleCallback}();
00181         }
00182     }
00183 /**
00184  * Sets the actions that require a POST request, or empty for all actions
00185  *
00186  * @access public
00187  * @return void
00188  */
00189     function requirePost() {
00190         $this->requirePost = func_get_args();
00191     }
00192 /**
00193  * Sets the actions that require an authenticated request, or empty for all actions
00194  *
00195  * @access public
00196  * @return void
00197  */
00198     function requireAuth() {
00199         $this->requireAuth = func_get_args();
00200     }
00201 }
00202 ?>