Add tests for ClientFlowLoginController

Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
This commit is contained in:
Lukas Reschke 2017-05-18 16:31:14 +02:00
parent a4116220cb
commit 26ee889fec
No known key found for this signature in database
GPG key ID: B9F6980CF6E759B1
2 changed files with 187 additions and 27 deletions

View file

@ -109,7 +109,8 @@ class ClientFlowLoginController extends Controller {
* @return string
*/
private function getClientName() {
return $this->request->getHeader('USER_AGENT') !== null ? $this->request->getHeader('USER_AGENT') : 'unknown';
$userAgent = $this->request->getHeader('USER_AGENT');
return $userAgent !== null ? $userAgent : 'unknown';
}
/**
@ -265,11 +266,10 @@ class ClientFlowLoginController extends Controller {
}
$clientName = $this->getClientName();
$oAuthClient = false;
$client = false;
if($clientIdentifier !== '') {
$client = $this->clientMapper->getByIdentifier($clientIdentifier);
$clientName = $client->getName();
$oAuthClient = true;
}
$token = $this->random->generate(72, ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_DIGITS);
@ -284,9 +284,7 @@ class ClientFlowLoginController extends Controller {
IToken::DO_NOT_REMEMBER
);
if($oAuthClient) {
$client = $this->clientMapper->getByIdentifier($clientIdentifier);
if($client) {
$code = $this->random->generate(128);
$accessToken = new AccessToken();
$accessToken->setClientId($client->getId());

View file

@ -26,6 +26,9 @@ use OC\Authentication\Exceptions\PasswordlessTokenException;
use OC\Authentication\Token\IProvider;
use OC\Authentication\Token\IToken;
use OC\Core\Controller\ClientFlowLoginController;
use OCA\OAuth2\Db\AccessTokenMapper;
use OCA\OAuth2\Db\Client;
use OCA\OAuth2\Db\ClientMapper;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\Defaults;
@ -35,6 +38,7 @@ use OCP\ISession;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserSession;
use OCP\Security\ICrypto;
use OCP\Security\ISecureRandom;
use OCP\Session\Exceptions\SessionNotAvailableException;
use Test\TestCase;
@ -56,6 +60,13 @@ class ClientFlowLoginControllerTest extends TestCase {
private $random;
/** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */
private $urlGenerator;
/** @var ClientMapper|\PHPUnit_Framework_MockObject_MockObject */
private $clientMapper;
/** @var AccessTokenMapper|\PHPUnit_Framework_MockObject_MockObject */
private $accessTokenMapper;
/** @var ICrypto|\PHPUnit_Framework_MockObject_MockObject */
private $crypto;
/** @var ClientFlowLoginController */
private $clientFlowLoginController;
@ -76,6 +87,9 @@ class ClientFlowLoginControllerTest extends TestCase {
$this->tokenProvider = $this->createMock(IProvider::class);
$this->random = $this->createMock(ISecureRandom::class);
$this->urlGenerator = $this->createMock(IURLGenerator::class);
$this->clientMapper = $this->createMock(ClientMapper::class);
$this->accessTokenMapper = $this->createMock(AccessTokenMapper::class);
$this->crypto = $this->createMock(ICrypto::class);
$this->clientFlowLoginController = new ClientFlowLoginController(
'core',
@ -86,32 +100,43 @@ class ClientFlowLoginControllerTest extends TestCase {
$this->session,
$this->tokenProvider,
$this->random,
$this->urlGenerator
$this->urlGenerator,
$this->clientMapper,
$this->accessTokenMapper,
$this->crypto
);
}
public function testShowAuthPickerPageNotAuthenticated() {
$this->userSession
->expects($this->once())
->method('isLoggedIn')
->willReturn(true);
public function testShowAuthPickerPageNoClientOrOauthRequest() {
$expected = new TemplateResponse(
'core',
'403',
'error',
[
'file' => 'Auth flow can only be started unauthenticated.',
'errors' =>
[
[
'error' => 'Access Forbidden',
'hint' => 'Invalid request',
],
],
],
'guest'
);
$this->assertEquals($expected, $this->clientFlowLoginController->showAuthPickerPage());
}
public function testShowAuthPickerPage() {
$this->userSession
->expects($this->once())
->method('isLoggedIn')
->willReturn(false);
public function testShowAuthPickerPageWithOcsHeader() {
$this->request
->expects($this->at(0))
->method('getHeader')
->with('USER_AGENT')
->willReturn('Mac OS X Sync Client');
$this->request
->expects($this->at(1))
->method('getHeader')
->with('OCS-APIREQUEST')
->willReturn('true');
$this->random
->expects($this->once())
->method('generate')
@ -124,11 +149,6 @@ class ClientFlowLoginControllerTest extends TestCase {
->expects($this->once())
->method('set')
->with('client.flow.state.token', 'StateToken');
$this->request
->expects($this->exactly(2))
->method('getHeader')
->with('USER_AGENT')
->willReturn('Mac OS X Sync Client');
$this->defaults
->expects($this->once())
->method('getName')
@ -143,6 +163,7 @@ class ClientFlowLoginControllerTest extends TestCase {
'loginflow/authpicker',
[
'client' => 'Mac OS X Sync Client',
'clientIdentifier' => '',
'instanceName' => 'ExampleCloud',
'urlGenerator' => $this->urlGenerator,
'stateToken' => 'StateToken',
@ -153,6 +174,56 @@ class ClientFlowLoginControllerTest extends TestCase {
$this->assertEquals($expected, $this->clientFlowLoginController->showAuthPickerPage());
}
public function testShowAuthPickerPageWithOauth() {
$this->request
->expects($this->at(0))
->method('getHeader')
->with('USER_AGENT')
->willReturn('Mac OS X Sync Client');
$client = new Client();
$client->setName('My external service');
$this->clientMapper
->expects($this->once())
->method('getByIdentifier')
->with('MyClientIdentifier')
->willReturn($client);
$this->random
->expects($this->once())
->method('generate')
->with(
64,
ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_DIGITS
)
->willReturn('StateToken');
$this->session
->expects($this->once())
->method('set')
->with('client.flow.state.token', 'StateToken');
$this->defaults
->expects($this->once())
->method('getName')
->willReturn('ExampleCloud');
$this->request
->expects($this->once())
->method('getServerHost')
->willReturn('example.com');
$expected = new TemplateResponse(
'core',
'loginflow/authpicker',
[
'client' => 'My external service',
'clientIdentifier' => 'MyClientIdentifier',
'instanceName' => 'ExampleCloud',
'urlGenerator' => $this->urlGenerator,
'stateToken' => 'StateToken',
'serverHost' => 'example.com',
],
'guest'
);
$this->assertEquals($expected, $this->clientFlowLoginController->showAuthPickerPage('MyClientIdentifier'));
}
public function testRedirectPageWithInvalidToken() {
$this->session
->expects($this->once())
@ -193,10 +264,15 @@ class ClientFlowLoginControllerTest extends TestCase {
public function testRedirectPage() {
$this->session
->expects($this->once())
->expects($this->at(0))
->method('get')
->with('client.flow.state.token')
->willReturn('MyStateToken');
$this->session
->expects($this->at(1))
->method('get')
->with('oauth.state')
->willReturn('MyOauthStateToken');
$expected = new TemplateResponse(
'core',
@ -204,10 +280,12 @@ class ClientFlowLoginControllerTest extends TestCase {
[
'urlGenerator' => $this->urlGenerator,
'stateToken' => 'MyStateToken',
'clientIdentifier' => 'Identifier',
'oauthState' => 'MyOauthStateToken',
],
'empty'
);
$this->assertEquals($expected, $this->clientFlowLoginController->redirectPage('MyStateToken'));
$this->assertEquals($expected, $this->clientFlowLoginController->redirectPage('MyStateToken', 'Identifier'));
}
public function testGenerateAppPasswordWithInvalidToken() {
@ -342,6 +420,90 @@ class ClientFlowLoginControllerTest extends TestCase {
$this->assertEquals($expected, $this->clientFlowLoginController->generateAppPassword('MyStateToken'));
}
public function testGeneratePasswordWithPasswordForOauthClient() {
$this->session
->expects($this->at(0))
->method('get')
->with('client.flow.state.token')
->willReturn('MyStateToken');
$this->session
->expects($this->at(1))
->method('remove')
->with('client.flow.state.token');
$this->session
->expects($this->at(3))
->method('get')
->with('oauth.state')
->willReturn('MyOauthState');
$this->session
->expects($this->at(4))
->method('remove')
->with('oauth.state');
$this->session
->expects($this->once())
->method('getId')
->willReturn('SessionId');
$myToken = $this->createMock(IToken::class);
$myToken
->expects($this->once())
->method('getLoginName')
->willReturn('MyLoginName');
$this->tokenProvider
->expects($this->once())
->method('getToken')
->with('SessionId')
->willReturn($myToken);
$this->tokenProvider
->expects($this->once())
->method('getPassword')
->with($myToken, 'SessionId')
->willReturn('MyPassword');
$this->random
->expects($this->at(0))
->method('generate')
->with(72)
->willReturn('MyGeneratedToken');
$this->random
->expects($this->at(1))
->method('generate')
->with(128)
->willReturn('MyAccessCode');
$user = $this->createMock(IUser::class);
$user
->expects($this->once())
->method('getUID')
->willReturn('MyUid');
$this->userSession
->expects($this->once())
->method('getUser')
->willReturn($user);
$token = $this->createMock(IToken::class);
$this->tokenProvider
->expects($this->once())
->method('generateToken')
->with(
'MyGeneratedToken',
'MyUid',
'MyLoginName',
'MyPassword',
'My OAuth client',
IToken::PERMANENT_TOKEN,
IToken::DO_NOT_REMEMBER
)
->willReturn($token);
$client = new Client();
$client->setName('My OAuth client');
$client->setRedirectUri('https://example.com/redirect.php');
$this->clientMapper
->expects($this->once())
->method('getByIdentifier')
->with('MyClientIdentifier')
->willReturn($client);
$expected = new Http\RedirectResponse('https://example.com/redirect.php?state=MyOauthState&code=MyAccessCode');
$this->assertEquals($expected, $this->clientFlowLoginController->generateAppPassword('MyStateToken', 'MyClientIdentifier'));
}
public function testGeneratePasswordWithoutPassword() {
$this->session
->expects($this->once())