Skip to content

Commit

Permalink
Allow running initial auth checks earlier.
Browse files Browse the repository at this point in the history
If 'earlyAuth' config is set to true initial auth checks are done
in beforeFilter() allback instead of startup(), thus making user
info available in controller's beforeFilter().
  • Loading branch information
ADmad committed Jun 29, 2015
1 parent 7ddbdf8 commit dce5db0
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 4 deletions.
39 changes: 35 additions & 4 deletions src/Controller/Component/AuthComponent.php
Expand Up @@ -138,6 +138,10 @@ class AuthComponent extends Component
* - `storage` - Storage class to use for persisting user record. When using
* stateless authenticator you should set this to 'Memory'. Defaults to 'Session'.
*
* - 'earlyAuth' - If set to true initial auth checks are done in beforeFilter()
* callback instead of startup(), i.e. before controller's beforeFilter().
* Defaults to false for backwards compatibility.
*
* @var array
*/
protected $_defaultConfig = [
Expand All @@ -150,7 +154,8 @@ class AuthComponent extends Component
'logoutRedirect' => null,
'authError' => null,
'unauthorizedRedirect' => true,
'storage' => 'Session'
'storage' => 'Session',
'earlyAuth' => false
];

/**
Expand Down Expand Up @@ -243,13 +248,39 @@ public function initialize(array $config)
}

/**
* Main execution method. Handles redirecting of invalid users, and processing
* of login form data.
* Callback for Controller.initialize event.
*
* @param \Cake\Event\Event $event The Controller.initialize event instance.
* @return void|\Cake\Network\Response
*/
public function beforeFilter(Event $event)
{
if ($this->_config['earlyAuth']) {
return $this->_authCheck($event);
}
}

/**
* Callback for Controller.startup event.
*
* @param \Cake\Event\Event $event The startup event.
* @param \Cake\Event\Event $event The Controller.startup event instance.
* @return void|\Cake\Network\Response
*/
public function startup(Event $event)
{
if (!$this->_config['earlyAuth']) {
return $this->_authCheck($event);
}
}

/**
* Main execution method. Handles initial authentication check and redirecting
* of invalid users.
*
* @param \Cake\Event\Event $event Event instance.
* @return void|\Cake\Network\Response
*/
public function _authCheck(Event $event)
{
$controller = $event->subject();

Expand Down
20 changes: 20 additions & 0 deletions tests/TestCase/Controller/Component/AuthComponentTest.php
Expand Up @@ -1396,4 +1396,24 @@ public function testSessionKeyBC()
$this->Auth->sessionKey = false;
$this->assertInstanceOf('Cake\Auth\Storage\MemoryStorage', $this->Auth->storage());
}

/**
* Test that setting config 'earlyAuth' to true make AuthComponent do the initial
* checks in beforeFilter() instead of startup().
*
* @return void
*/
public function testEarlyAuthConfig()
{
$this->Controller->components()->set('Auth', $this->Auth);
$this->Auth->earlyAuthTest = true;

$this->Controller->startupProcess();
$this->assertEquals('Controller.startup', $this->Auth->authCheckCalledFrom);

$this->Auth->authCheckCalledFrom = null;
$this->Auth->config('earlyAuth', true);
$this->Controller->startupProcess();
$this->assertEquals('Controller.initialize', $this->Auth->authCheckCalledFrom);
}
}
10 changes: 10 additions & 0 deletions tests/test_app/TestApp/Controller/Component/TestAuthComponent.php
Expand Up @@ -14,13 +14,23 @@
namespace TestApp\Controller\Component;

use Cake\Controller\Component\AuthComponent;
use Cake\Event\Event;

/**
* TestAuthComponent class
*
*/
class TestAuthComponent extends AuthComponent
{
public function _authCheck(Event $event)
{
if (isset($this->earlyAuthTest)) {
$this->authCheckCalledFrom = $event->name;
return;
}

return parent::_authCheck($event);
}

/**
* Helper method to add/set an authenticate object instance
Expand Down

0 comments on commit dce5db0

Please sign in to comment.