From 198346d1a025941dd6435799d809d8e23021d29e Mon Sep 17 00:00:00 2001 From: Roman Schmid Date: Wed, 15 Jul 2015 21:58:12 +0200 Subject: [PATCH] Implemented `canLogIn` check for `authenticate` method. Added tests to check `canLogIn` calls. --- .../RESTfulAPI_TokenAuthenticator.php | 4 + .../RESTfulAPI_TokenAuthenticator_Test.php | 89 ++++++++++++++++++- 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/code/authenticator/RESTfulAPI_TokenAuthenticator.php b/code/authenticator/RESTfulAPI_TokenAuthenticator.php index 58c8a01..17c6ceb 100644 --- a/code/authenticator/RESTfulAPI_TokenAuthenticator.php +++ b/code/authenticator/RESTfulAPI_TokenAuthenticator.php @@ -452,6 +452,10 @@ private function validateAPIToken($token) //all good, log Member in if ( is_a($tokenOwner, 'Member') ) { + $loginCheck = $tokenOwner->canLogIn(); + if(!$loginCheck->valid()){ + return new RESTfulAPI_Error(403, $loginCheck->message()); + } $tokenOwner->logIn(); } diff --git a/tests/authenticator/RESTfulAPI_TokenAuthenticator_Test.php b/tests/authenticator/RESTfulAPI_TokenAuthenticator_Test.php index 984b949..d2a0e1b 100644 --- a/tests/authenticator/RESTfulAPI_TokenAuthenticator_Test.php +++ b/tests/authenticator/RESTfulAPI_TokenAuthenticator_Test.php @@ -13,7 +13,7 @@ class RESTfulAPI_TokenAuthenticator_Test extends RESTfulAPI_Tester { protected $requiredExtensions = array( - 'Member' => array('RESTfulAPI_TokenAuthExtension') + 'Member' => array('RESTfulAPI_TokenAuthExtension', 'TestCanLoginExtension') ); protected function getAuthenticator() @@ -35,6 +35,11 @@ public function setUpOnce() 'Email' => 'test@test.com', 'Password' => 'test' ))->write(); + + Member::create(array( + 'Email' => 'balrog@moria.mine', + 'Password' => 'flame.sword' + )); } @@ -209,4 +214,84 @@ public function testAuthenticate() "TokenAuth authentication failure should return a RESTfulAPI_Error" ); } -} \ No newline at end of file + + public function testCanLogin(){ + $auth = $this->getAuthenticator(); + + // check login when canLogIn check fails + $request = new SS_HTTPRequest( + 'GET', + 'api/auth/login', + array( + 'email' => 'balrog@moria.mine', + 'pwd' => 'flame.sword' + ) + ); + + $result = $auth->login($request); + + $this->assertEquals( + $result['code'], + RESTfulAPI_TokenAuthenticator::AUTH_CODE_LOGIN_FAIL, + "Logging in a member whose `canLogIn` check fails should not be allowed." + ); + + // check authenticate when canLogIn check fails + + $request = new SS_HTTPRequest( + 'GET', + 'api/auth/login', + array( + 'email' => 'test@test.com', + 'pwd' => 'test' + ) + ); + + $result = $auth->login($request); + + $this->assertEquals( + $result['code'], + RESTfulAPI_TokenAuthenticator::AUTH_CODE_LOGGED_IN, + "Logging in a member whose `canLogIn` check doesn't fail should be allowed." + ); + + $request = new SS_HTTPRequest( + 'GET', + 'api/ApiTest_Book/1' + ); + $request->addHeader('X-Silverstripe-Apitoken', $result['token']); + + // deny all users for the authenticate request + TestCanLoginExtension::$denyAll = true; + + $result = $auth->authenticate($request); + + TestCanLoginExtension::$denyAll = false; + + $this->assertContainsOnlyInstancesOf( + 'RESTfulAPI_Error', + array($result), + "TokenAuth authentication should fail when 'canLogIn' fails" + ); + } +} + +/** + * Extension to test "canLogin" + */ +class TestCanLoginExtension extends DataExtension +{ + public static $denyAll = false; + + public function canLogIn(ValidationResult &$result) + { + if(self::$denyAll){ + $result->error('All access denied'); + } + + if($this->owner->Email === 'balrog@moria.mine'){ + // deny access to the balrog! + $result->error('You shall not pass!'); + } + } +}