prevent users from deleting their own session token

This commit is contained in:
Christoph Wurst 2016-06-27 15:23:52 +02:00
parent 20b1ba0771
commit dc6c2344f6
No known key found for this signature in database
GPG Key ID: FEECD2543CA6EAF0
3 changed files with 70 additions and 12 deletions

View File

@ -81,7 +81,28 @@ class AuthSettingsController extends Controller {
if (is_null($user)) { if (is_null($user)) {
return []; 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 { try {
$sessionId = $this->session->getId(); $sessionId = $this->session->getId();
} catch (SessionNotAvailableException $ex) { } catch (SessionNotAvailableException $ex) {
$resp = new JSONResponse(); return $this->getServiceNotAvailableResponse();
$resp->setStatus(Http::STATUS_SERVICE_UNAVAILABLE);
return $resp;
} }
try { try {
@ -108,9 +127,7 @@ class AuthSettingsController extends Controller {
$password = null; $password = null;
} }
} catch (InvalidTokenException $ex) { } catch (InvalidTokenException $ex) {
$resp = new JSONResponse(); return $this->getServiceNotAvailableResponse();
$resp->setStatus(Http::STATUS_SERVICE_UNAVAILABLE);
return $resp;
} }
$token = $this->generateRandomDeviceToken(); $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 * Return a 20 digit device password
* *

View File

@ -29,7 +29,11 @@
'<tr data-id="{{id}}">' '<tr data-id="{{id}}">'
+ '<td class="has-tooltip" title="{{name}}"><span class="token-name">{{name}}</span></td>' + '<td class="has-tooltip" title="{{name}}"><span class="token-name">{{name}}</span></td>'
+ '<td><span class="last-activity has-tooltip" title="{{lastActivityTime}}">{{lastActivity}}</span></td>' + '<td><span class="last-activity has-tooltip" title="{{lastActivityTime}}">{{lastActivity}}</span></td>'
+ '{{#if canDelete}}'
+ '<td><a class="icon-delete has-tooltip" title="' + t('core', 'Disconnect') + '"></a></td>' + '<td><a class="icon-delete has-tooltip" title="' + t('core', 'Disconnect') + '"></a></td>'
+ '{{else}}'
+ '<td></td>'
+ '{{/if}}'
+ '<tr>'; + '<tr>';
var SubView = OC.Backbone.View.extend({ var SubView = OC.Backbone.View.extend({

View File

@ -24,6 +24,7 @@ namespace Test\Settings\Controller;
use OC\AppFramework\Http; use OC\AppFramework\Http;
use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\InvalidTokenException;
use OC\Authentication\Token\DefaultToken;
use OC\Authentication\Token\IToken; use OC\Authentication\Token\IToken;
use OC\Settings\Controller\AuthSettingsController; use OC\Settings\Controller\AuthSettingsController;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
@ -56,10 +57,17 @@ class AuthSettingsControllerTest extends TestCase {
} }
public function testIndex() { public function testIndex() {
$result = [ $token1 = new DefaultToken();
'token1', $token1->setId(100);
'token2', $token2 = new DefaultToken();
$token2->setId(200);
$tokens = [
$token1,
$token2,
]; ];
$sessionToken = new DefaultToken();
$sessionToken->setId(100);
$this->userManager->expects($this->once()) $this->userManager->expects($this->once())
->method('get') ->method('get')
->with($this->uid) ->with($this->uid)
@ -67,9 +75,31 @@ class AuthSettingsControllerTest extends TestCase {
$this->tokenProvider->expects($this->once()) $this->tokenProvider->expects($this->once())
->method('getTokenByUser') ->method('getTokenByUser')
->with($this->user) ->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() { public function testCreate() {
@ -107,6 +137,7 @@ class AuthSettingsControllerTest extends TestCase {
$expected = [ $expected = [
'token' => $newToken, 'token' => $newToken,
'deviceToken' => $deviceToken, 'deviceToken' => $deviceToken,
'loginName' => 'User13',
]; ];
$this->assertEquals($expected, $this->controller->create($name)); $this->assertEquals($expected, $this->controller->create($name));
} }