From c9a2790893a160a5967a672051e15142fe5f779e Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Mon, 27 Jun 2016 15:23:52 +0200 Subject: [PATCH] prevent users from deleting their own session token --- .../Controller/AuthSettingsController.php | 37 +++++++++++++---- settings/js/authtoken_view.js | 4 ++ .../Controller/AuthSettingsControllerTest.php | 41 ++++++++++++++++--- 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/settings/Controller/AuthSettingsController.php b/settings/Controller/AuthSettingsController.php index db2db6e5bf..e7fc2d916b 100644 --- a/settings/Controller/AuthSettingsController.php +++ b/settings/Controller/AuthSettingsController.php @@ -81,7 +81,28 @@ class AuthSettingsController extends Controller { if (is_null($user)) { return []; } - return $this->tokenProvider->getTokenByUser($user); + $tokens = $this->tokenProvider->getTokenByUser($user); + + try { + $sessionId = $this->session->getId(); + } catch (SessionNotAvailableException $ex) { + return $this->getServiceNotAvailableResponse(); + } + try { + $sessionToken = $this->tokenProvider->getToken($sessionId); + } catch (InvalidTokenException $ex) { + return $this->getServiceNotAvailableResponse(); + } + + return array_map(function(IToken $token) use ($sessionToken) { + $data = $token->jsonSerialize(); + if ($sessionToken->getId() === $token->getId()) { + $data['canDelete'] = false; + } else { + $data['canDelete'] = true; + } + return $data; + }, $tokens); } /** @@ -94,9 +115,7 @@ class AuthSettingsController extends Controller { try { $sessionId = $this->session->getId(); } catch (SessionNotAvailableException $ex) { - $resp = new JSONResponse(); - $resp->setStatus(Http::STATUS_SERVICE_UNAVAILABLE); - return $resp; + return $this->getServiceNotAvailableResponse(); } try { @@ -108,9 +127,7 @@ class AuthSettingsController extends Controller { $password = null; } } catch (InvalidTokenException $ex) { - $resp = new JSONResponse(); - $resp->setStatus(Http::STATUS_SERVICE_UNAVAILABLE); - return $resp; + return $this->getServiceNotAvailableResponse(); } $token = $this->generateRandomDeviceToken(); @@ -123,6 +140,12 @@ class AuthSettingsController extends Controller { ]; } + private function getServiceNotAvailableResponse() { + $resp = new JSONResponse(); + $resp->setStatus(Http::STATUS_SERVICE_UNAVAILABLE); + return $resp; + } + /** * Return a 20 digit device password * diff --git a/settings/js/authtoken_view.js b/settings/js/authtoken_view.js index 01fc1b2ea3..472b841c23 100644 --- a/settings/js/authtoken_view.js +++ b/settings/js/authtoken_view.js @@ -29,7 +29,11 @@ '' + '{{name}}' + '{{lastActivity}}' + + '{{#if canDelete}}' + '' + + '{{else}}' + + '' + + '{{/if}}' + ''; var SubView = OC.Backbone.View.extend({ diff --git a/tests/Settings/Controller/AuthSettingsControllerTest.php b/tests/Settings/Controller/AuthSettingsControllerTest.php index ee67b22102..1705cb5ddf 100644 --- a/tests/Settings/Controller/AuthSettingsControllerTest.php +++ b/tests/Settings/Controller/AuthSettingsControllerTest.php @@ -24,6 +24,7 @@ namespace Test\Settings\Controller; use OC\AppFramework\Http; use OC\Authentication\Exceptions\InvalidTokenException; +use OC\Authentication\Token\DefaultToken; use OC\Authentication\Token\IToken; use OC\Settings\Controller\AuthSettingsController; use OCP\AppFramework\Http\JSONResponse; @@ -56,10 +57,17 @@ class AuthSettingsControllerTest extends TestCase { } public function testIndex() { - $result = [ - 'token1', - 'token2', + $token1 = new DefaultToken(); + $token1->setId(100); + $token2 = new DefaultToken(); + $token2->setId(200); + $tokens = [ + $token1, + $token2, ]; + $sessionToken = new DefaultToken(); + $sessionToken->setId(100); + $this->userManager->expects($this->once()) ->method('get') ->with($this->uid) @@ -67,9 +75,31 @@ class AuthSettingsControllerTest extends TestCase { $this->tokenProvider->expects($this->once()) ->method('getTokenByUser') ->with($this->user) - ->will($this->returnValue($result)); + ->will($this->returnValue($tokens)); + $this->session->expects($this->once()) + ->method('getId') + ->will($this->returnValue('session123')); + $this->tokenProvider->expects($this->once()) + ->method('getToken') + ->with('session123') + ->will($this->returnValue($sessionToken)); - $this->assertEquals($result, $this->controller->index()); + $this->assertEquals([ + [ + 'id' => 100, + 'name' => null, + 'lastActivity' => null, + 'type' => null, + 'canDelete' => false, + ], + [ + 'id' => 200, + 'name' => null, + 'lastActivity' => null, + 'type' => null, + 'canDelete' => true, + ] + ], $this->controller->index()); } public function testCreate() { @@ -107,6 +137,7 @@ class AuthSettingsControllerTest extends TestCase { $expected = [ 'token' => $newToken, 'deviceToken' => $deviceToken, + 'loginName' => 'User13', ]; $this->assertEquals($expected, $this->controller->create($name)); }