Signed-off-by: Joas Schilling <coding@schilljs.com>tags/v11.0RC2
@@ -67,13 +67,21 @@ trait Auth { | |||
* @Given a new client token is used | |||
*/ | |||
public function aNewClientTokenIsUsed() { | |||
$this->loggingInUsingWebAs('user0'); | |||
$fullUrl = substr($this->baseUrl, 0, -5) . '/index.php/settings/personal/authtokens'; | |||
$client = new Client(); | |||
$resp = $client->post(substr($this->baseUrl, 0, -5) . '/token/generate', [ | |||
'json' => [ | |||
'user' => 'user0', | |||
'password' => '123456', | |||
] | |||
]); | |||
$options = [ | |||
'auth' => ['user0', '123456'], | |||
'body' => [ | |||
'requesttoken' => $this->requestToken, | |||
'name' => md5(microtime()), | |||
], | |||
'cookies' => $this->cookieJar, | |||
]; | |||
$resp = $client->send($client->createRequest('POST', $fullUrl, $options)); | |||
$this->clientToken = json_decode($resp->getBody()->getContents())->token; | |||
} | |||
@@ -49,6 +49,5 @@ class Application extends App { | |||
$container->registerService('defaultMailAddress', function() { | |||
return Util::getDefaultEmailAddress('lostpassword-noreply'); | |||
}); | |||
$container->registerAlias(IProvider::class, DefaultTokenProvider::class); | |||
} | |||
} |
@@ -1,105 +0,0 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||
* | |||
* @author Christoph Wurst <christoph@owncloud.com> | |||
* @author Lukas Reschke <lukas@statuscode.ch> | |||
* | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace OC\Core\Controller; | |||
use OC\AppFramework\Http; | |||
use OC\Authentication\Token\IProvider; | |||
use OC\Authentication\Token\IToken; | |||
use OC\Authentication\TwoFactorAuth\Manager as TwoFactorAuthManager; | |||
use OCP\AppFramework\Controller; | |||
use OCP\AppFramework\Http\JSONResponse; | |||
use OCP\IRequest; | |||
use OCP\IUserManager; | |||
use OCP\Security\ISecureRandom; | |||
class TokenController extends Controller { | |||
/** @var IUserManager */ | |||
private $userManager; | |||
/** @var IProvider */ | |||
private $tokenProvider; | |||
/** @var TwoFactorAuthManager */ | |||
private $twoFactorAuthManager; | |||
/** @var ISecureRandom */ | |||
private $secureRandom; | |||
/** | |||
* @param string $appName | |||
* @param IRequest $request | |||
* @param IUserManager $userManager | |||
* @param IProvider $tokenProvider | |||
* @param TwoFactorAuthManager $twoFactorAuthManager | |||
* @param ISecureRandom $secureRandom | |||
*/ | |||
public function __construct($appName, | |||
IRequest $request, | |||
IUserManager $userManager, | |||
IProvider $tokenProvider, | |||
TwoFactorAuthManager $twoFactorAuthManager, | |||
ISecureRandom $secureRandom) { | |||
parent::__construct($appName, $request); | |||
$this->userManager = $userManager; | |||
$this->tokenProvider = $tokenProvider; | |||
$this->secureRandom = $secureRandom; | |||
$this->twoFactorAuthManager = $twoFactorAuthManager; | |||
} | |||
/** | |||
* Generate a new access token clients can authenticate with | |||
* | |||
* @PublicPage | |||
* @NoCSRFRequired | |||
* | |||
* @param string $user | |||
* @param string $password | |||
* @param string $name the name of the client | |||
* @return JSONResponse | |||
*/ | |||
public function generateToken($user, $password, $name = 'unknown client') { | |||
if (is_null($user) || is_null($password)) { | |||
$response = new JSONResponse(); | |||
$response->setStatus(Http::STATUS_UNPROCESSABLE_ENTITY); | |||
return $response; | |||
} | |||
$loginName = $user; | |||
$user = $this->userManager->checkPassword($loginName, $password); | |||
if ($user === false) { | |||
$response = new JSONResponse(); | |||
$response->setStatus(Http::STATUS_UNAUTHORIZED); | |||
return $response; | |||
} | |||
if ($this->twoFactorAuthManager->isTwoFactorAuthenticated($user)) { | |||
$resp = new JSONResponse(); | |||
$resp->setStatus(Http::STATUS_UNAUTHORIZED); | |||
return $resp; | |||
} | |||
$token = $this->secureRandom->generate(128); | |||
$this->tokenProvider->generateToken($token, $user->getUID(), $loginName, $password, $name, IToken::PERMANENT_TOKEN); | |||
return new JSONResponse([ | |||
'token' => $token, | |||
]); | |||
} | |||
} |
@@ -48,7 +48,6 @@ $application->registerRoutes($this, [ | |||
['name' => 'login#tryLogin', 'url' => '/login', 'verb' => 'POST'], | |||
['name' => 'login#showLoginForm', 'url' => '/login', 'verb' => 'GET'], | |||
['name' => 'login#logout', 'url' => '/logout', 'verb' => 'GET'], | |||
['name' => 'token#generateToken', 'url' => '/token/generate', 'verb' => 'POST'], | |||
['name' => 'TwoFactorChallenge#selectChallenge', 'url' => '/login/selectchallenge', 'verb' => 'GET'], | |||
['name' => 'TwoFactorChallenge#showChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'GET'], | |||
['name' => 'TwoFactorChallenge#solveChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'POST'], |
@@ -399,7 +399,6 @@ return array( | |||
'OC\\Core\\Controller\\LostController' => $baseDir . '/core/Controller/LostController.php', | |||
'OC\\Core\\Controller\\OCSController' => $baseDir . '/core/Controller/OCSController.php', | |||
'OC\\Core\\Controller\\SetupController' => $baseDir . '/core/Controller/SetupController.php', | |||
'OC\\Core\\Controller\\TokenController' => $baseDir . '/core/Controller/TokenController.php', | |||
'OC\\Core\\Controller\\TwoFactorChallengeController' => $baseDir . '/core/Controller/TwoFactorChallengeController.php', | |||
'OC\\Core\\Controller\\UserController' => $baseDir . '/core/Controller/UserController.php', | |||
'OC\\Core\\Middleware\\TwoFactorMiddleware' => $baseDir . '/core/Middleware/TwoFactorMiddleware.php', |
@@ -429,7 +429,6 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c | |||
'OC\\Core\\Controller\\LostController' => __DIR__ . '/../../..' . '/core/Controller/LostController.php', | |||
'OC\\Core\\Controller\\OCSController' => __DIR__ . '/../../..' . '/core/Controller/OCSController.php', | |||
'OC\\Core\\Controller\\SetupController' => __DIR__ . '/../../..' . '/core/Controller/SetupController.php', | |||
'OC\\Core\\Controller\\TokenController' => __DIR__ . '/../../..' . '/core/Controller/TokenController.php', | |||
'OC\\Core\\Controller\\TwoFactorChallengeController' => __DIR__ . '/../../..' . '/core/Controller/TwoFactorChallengeController.php', | |||
'OC\\Core\\Controller\\UserController' => __DIR__ . '/../../..' . '/core/Controller/UserController.php', | |||
'OC\\Core\\Middleware\\TwoFactorMiddleware' => __DIR__ . '/../../..' . '/core/Middleware/TwoFactorMiddleware.php', |
@@ -1,130 +0,0 @@ | |||
<?php | |||
/** | |||
* @author Christoph Wurst <christoph@owncloud.com> | |||
* | |||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace Tests\Core\Controller; | |||
use OC\AppFramework\Http; | |||
use OC\Authentication\Token\IToken; | |||
use OC\Core\Controller\TokenController; | |||
use OCP\AppFramework\Http\JSONResponse; | |||
use Test\TestCase; | |||
class TokenControllerTest extends TestCase { | |||
/** \OC\Core\Controller\TokenController */ | |||
private $tokenController; | |||
private $request; | |||
private $userManager; | |||
private $tokenProvider; | |||
private $twoFactorAuthManager; | |||
private $secureRandom; | |||
protected function setUp() { | |||
parent::setUp(); | |||
$this->request = $this->getMockBuilder('\OCP\IRequest')->getMock(); | |||
$this->userManager = $this->getMockBuilder('\OC\User\Manager') | |||
->disableOriginalConstructor() | |||
->getMock(); | |||
$this->tokenProvider = $this->getMockBuilder('\OC\Authentication\Token\IProvider') | |||
->getMock(); | |||
$this->twoFactorAuthManager = $this->getMockBuilder('\OC\Authentication\TwoFactorAuth\Manager') | |||
->disableOriginalConstructor() | |||
->getMock(); | |||
$this->secureRandom = $this->getMockBuilder('\OCP\Security\ISecureRandom') | |||
->getMock(); | |||
$this->tokenController = new TokenController('core', $this->request, $this->userManager, $this->tokenProvider, $this->twoFactorAuthManager, $this->secureRandom); | |||
} | |||
public function testWithoutCredentials() { | |||
$expected = new JSONResponse(); | |||
$expected->setStatus(Http::STATUS_UNPROCESSABLE_ENTITY); | |||
$actual = $this->tokenController->generateToken(null, null); | |||
$this->assertEquals($expected, $actual); | |||
} | |||
public function testWithInvalidCredentials() { | |||
$this->userManager->expects($this->once()) | |||
->method('checkPassword') | |||
->with('john', 'passme') | |||
->will($this->returnValue(false)); | |||
$expected = new JSONResponse(); | |||
$expected->setStatus(Http::STATUS_UNAUTHORIZED); | |||
$actual = $this->tokenController->generateToken('john', 'passme'); | |||
$this->assertEquals($expected, $actual); | |||
} | |||
public function testWithValidCredentials() { | |||
$user = $this->getMockBuilder('\OCP\IUser')->getMock(); | |||
$this->userManager->expects($this->once()) | |||
->method('checkPassword') | |||
->with('john', '123456') | |||
->will($this->returnValue($user)); | |||
$user->expects($this->once()) | |||
->method('getUID') | |||
->will($this->returnValue('john')); | |||
$this->twoFactorAuthManager->expects($this->once()) | |||
->method('isTwoFactorAuthenticated') | |||
->with($user) | |||
->will($this->returnValue(false)); | |||
$this->secureRandom->expects($this->once()) | |||
->method('generate') | |||
->with(128) | |||
->will($this->returnValue('verysecurerandomtoken')); | |||
$this->tokenProvider->expects($this->once()) | |||
->method('generateToken') | |||
->with('verysecurerandomtoken', 'john', 'john', '123456', 'unknown client', IToken::PERMANENT_TOKEN); | |||
$expected = new JSONResponse([ | |||
'token' => 'verysecurerandomtoken' | |||
]); | |||
$actual = $this->tokenController->generateToken('john', '123456'); | |||
$this->assertEquals($expected, $actual); | |||
} | |||
public function testWithValidCredentialsBut2faEnabled() { | |||
$user = $this->getMockBuilder('\OCP\IUser')->getMock(); | |||
$this->userManager->expects($this->once()) | |||
->method('checkPassword') | |||
->with('john', '123456') | |||
->will($this->returnValue($user)); | |||
$this->twoFactorAuthManager->expects($this->once()) | |||
->method('isTwoFactorAuthenticated') | |||
->with($user) | |||
->will($this->returnValue(true)); | |||
$this->secureRandom->expects($this->never()) | |||
->method('generate'); | |||
$expected = new JSONResponse(); | |||
$expected->setStatus(Http::STATUS_UNAUTHORIZED); | |||
$actual = $this->tokenController->generateToken('john', '123456'); | |||
$this->assertEquals($expected, $actual); | |||
} | |||
} |