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;
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;
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;
$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',
$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')
->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' => 'Mac OS X Sync Client',
+ 'clientIdentifier' => '',
+ 'instanceName' => 'ExampleCloud',
+ 'urlGenerator' => $this->urlGenerator,
+ 'stateToken' => 'StateToken',
+ 'serverHost' => 'example.com',
+ ],
+ 'guest'
+ );
+ $this->assertEquals($expected, $this->clientFlowLoginController->showAuthPickerPage());
+ }
+
+ public function testShowAuthPickerPageWithOauth() {
$this->request
- ->expects($this->exactly(2))
+ ->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')
'core',
'loginflow/authpicker',
[
- 'client' => 'Mac OS X Sync Client',
+ 'client' => 'My external service',
+ 'clientIdentifier' => 'MyClientIdentifier',
'instanceName' => 'ExampleCloud',
'urlGenerator' => $this->urlGenerator,
'stateToken' => 'StateToken',
],
'guest'
);
- $this->assertEquals($expected, $this->clientFlowLoginController->showAuthPickerPage());
+ $this->assertEquals($expected, $this->clientFlowLoginController->showAuthPickerPage('MyClientIdentifier'));
}
public function testRedirectPageWithInvalidToken() {
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',
[
'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() {
$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())