From 2e928f672acb9d279c3dd5660ef92ff9f3145a16 Mon Sep 17 00:00:00 2001 From: Chris Hallgren Date: Thu, 3 Jan 2019 00:57:27 -0600 Subject: [PATCH] Improvements So before we just blindly did out own thing with rebuilding the UserModel and setting the Auth. Now we check to see if they are using a custom UserModal and/or finder and support login using the finder defined in the Auth Config. --- phpunit.xml.dist | 5 +- .../Component/ImpersonateComponent.php | 57 +++++++++++++++---- .../Component/ImpersonateComponentTest.php | 13 +++++ .../Controller/ImpersonateTestController.php | 2 + 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 5d9d385..c5c3b29 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -11,7 +11,7 @@ - + @@ -36,8 +36,5 @@ src/ - - src/Template/ - diff --git a/src/Controller/Component/ImpersonateComponent.php b/src/Controller/Component/ImpersonateComponent.php index a07a152..7d24b5c 100644 --- a/src/Controller/Component/ImpersonateComponent.php +++ b/src/Controller/Component/ImpersonateComponent.php @@ -10,7 +10,7 @@ namespace CakeImpersonate\Controller\Component; use Cake\Controller\Component; -use Cake\ORM\Entity; +use Cake\Event\Event; /** * Impersonate component @@ -23,24 +23,29 @@ class ImpersonateComponent extends Component * * @var array */ - protected $_defaultConfig = []; + protected $_defaultConfig = [ + 'userModel' => 'Users', + 'finder' => 'all', + ]; /** * Function impersonate * - * @param mixed $id + * @param mixed $id ID of user to impersonate * @return bool + * @throws \Exception If userModal is not loaded in the Controller */ public function login($id) { - $this->getController()->loadModel('Users'); + $userModel = $this->getConfig('userModal', 'Users'); + $this->getController()->loadModel($userModel); - $originalAuth = $this->getController()->getRequest()->getSession()->read('Auth'); - - /** @var Entity $users */ - $users = $this->getController()->Users->get($id); - $this->getController()->Auth->setUser($users->toArray()); - $this->getController()->getRequest()->getSession()->write('OriginalAuth', $originalAuth); + $finder = $this->getConfig('finder'); + /** @var \Cake\ORM\Table $userTable */ + $userTable = $this->getController()->{$userModel}; + $userArray = $userTable->find($finder)->where([$userTable->getAlias() . '.id' => $id])->firstOrFail()->toArray(); + $this->getController()->Auth->setUser($userArray); + $this->getController()->getRequest()->getSession()->write('OriginalAuth', $this->getController()->getRequest()->getSession()->read('Auth')); return true; } @@ -54,7 +59,6 @@ public function login($id) public function isImpersonate() { if ($this->getController()->getRequest()->getSession()->read('OriginalAuth')) { - return true; } @@ -78,4 +82,35 @@ public function logout() return true; } + + /** + * {@inheritdoc} + */ + public function implementedEvents() + { + $eventMap = [ + 'Controller.initialize' => 'updateConfig', + 'Controller.startup' => 'updateConfig', + ]; + $events = []; + foreach ($eventMap as $event => $method) { + if (method_exists($this, $method)) { + $events[$event] = $method; + } + } + + return $events; + } + + /** + * Updates the userModel and finder based on the AuthComponent. + * + * @param Event $event Event that started the update. + * @return void + */ + public function updateConfig(Event $event) + { + $this->setConfig('userModel', $this->getController()->Auth->getConfig('authorize.all.userModel', $this->getConfig('userModel'))); + $this->setConfig('finder', $this->getController()->Auth->getConfig('authorize.all.finder', $this->getConfig('finder'))); + } } diff --git a/tests/TestCase/Controller/Component/ImpersonateComponentTest.php b/tests/TestCase/Controller/Component/ImpersonateComponentTest.php index c9a6a13..0e93652 100644 --- a/tests/TestCase/Controller/Component/ImpersonateComponentTest.php +++ b/tests/TestCase/Controller/Component/ImpersonateComponentTest.php @@ -90,6 +90,19 @@ public function testLogout() */ public function testLogin() { + $this->Impersonate->getRequest()->getSession()->write('Auth', $this->Auth); + $this->assertTrue($this->Impersonate->Impersonate->login(1)); + + $this->assertEquals($this->Auth, $this->Impersonate->getRequest()->getSession()->read('OriginalAuth')); + } + + /** + * @return void + * @expectedException \Exception + */ + public function testLoginException() + { + $this->Impersonate->Impersonate->setConfig('userModal', 'UserNotFound'); $this->Impersonate->getRequest()->getSession()->write('Auth', $this->Auth); $this->assertTrue($this->Impersonate->Impersonate->login(2)); diff --git a/tests/test_app/Controller/ImpersonateTestController.php b/tests/test_app/Controller/ImpersonateTestController.php index ed7ca29..522d793 100644 --- a/tests/test_app/Controller/ImpersonateTestController.php +++ b/tests/test_app/Controller/ImpersonateTestController.php @@ -14,6 +14,7 @@ * Use Controller instead of AppController to avoid conflicts * * @property \CakeImpersonate\Controller\Component\ImpersonateComponent $Impersonate + * @property \App\Model\Table\UsersTable $Users */ class ImpersonateTestController extends Controller { @@ -24,6 +25,7 @@ class ImpersonateTestController extends Controller public function initialize() { $this->loadComponent('Auth'); + $this->loadModel('Users'); $this->loadComponent('CakeImpersonate.Impersonate'); parent::initialize(); }