Add tests for ClientFlowLoginController
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
This commit is contained in:
parent
a4116220cb
commit
26ee889fec
2 changed files with 187 additions and 27 deletions
|
@ -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());
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Reference in a new issue