Skip to content

Commit

Permalink
Hotfix: Change http status code for client 2.4.2
Browse files Browse the repository at this point in the history
  • Loading branch information
micbar committed Aug 8, 2018
1 parent 61a71b4 commit 60a1d0c
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 4 deletions.
12 changes: 9 additions & 3 deletions lib/Controller/OAuthApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,21 +156,27 @@ public function generateToken($grant_type, $code = null,

break;
case 'refresh_token':
$statusCode = Http::STATUS_BAD_REQUEST;
// This fixes the infinite loop issue with desktop client 2.4.2
if (preg_match('/\bmirall\b.+2\.4\.2/i', $this->request->getHeader('User-Agent'))) {
$statusCode = Http::STATUS_OK;
}

if (!is_string($refresh_token)) {
return new JSONResponse(['error' => 'invalid_request'], Http::STATUS_BAD_REQUEST);
return new JSONResponse(['error' => 'invalid_request'], $statusCode);
}

try {
/** @var RefreshToken $refreshToken */
$refreshToken = $this->refreshTokenMapper->findByToken($refresh_token);
} catch (DoesNotExistException $exception) {
\OC::$server->getLogger()->logException($exception, ['app'=>__CLASS__]);
return new JSONResponse(['error' => 'invalid_grant'], Http::STATUS_BAD_REQUEST);
return new JSONResponse(['error' => 'invalid_grant'], $statusCode);
}

if (strcmp($refreshToken->getClientId(), $client->getId()) !== 0) {
\OC::$server->getLogger()->debug("refresh grant client ids mismatch: {$refreshToken->getClientId()} != {$client->getId()}", ['app'=>__CLASS__]);
return new JSONResponse(['error' => 'invalid_grant'], Http::STATUS_BAD_REQUEST);
return new JSONResponse(['error' => 'invalid_grant'], $statusCode);
}

$this->logger->info('A refresh token has been used by the client "' . $client->getName() . '" to request an access token.', ['app' => $this->appName]);
Expand Down
89 changes: 88 additions & 1 deletion tests/Unit/Controller/OAuthApiControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use OCA\OAuth2\Db\RefreshToken;
use OCA\OAuth2\Db\RefreshTokenMapper;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IRequest;
use OCP\IURLGenerator;
use PHPUnit_Framework_TestCase;

Expand All @@ -38,6 +39,9 @@ class OAuthApiControllerTest extends PHPUnit_Framework_TestCase {
/** @var OAuthApiController $controller */
private $controller;

/** @var IRequest | \PHPUnit_Framework_MockObject_MockObject */
private $request;

/** @var ClientMapper $clientMapper */
private $clientMapper;

Expand Down Expand Up @@ -143,9 +147,11 @@ public function setUp() {
$container->query('AppName') . '.page.authorizationSuccessful'
);

$this->request = $this->createMock(IRequest::class);

$this->controller = new OAuthApiController(
$container->query('AppName'),
$this->getMockBuilder('OCP\IRequest')->getMock(),
$this->request,
$this->clientMapper,
$this->authorizationCodeMapper,
$this->accessTokenMapper,
Expand Down Expand Up @@ -358,4 +364,85 @@ public function testGenerateTokenWithRefreshToken() {
$this->assertEquals(1, count($this->refreshTokenMapper->findAll()));
}

public function testGenerateTokenWithRefreshTokenClient242() {
$this->request
->method('getHeader')
->with('User-Agent')
->willReturn('Mozilla\/5.0 (Macintosh) mirall\/2.4.2 (build 10200)');
$_SERVER['PHP_AUTH_USER'] = null;
$_SERVER['PHP_AUTH_PW'] = null;

$result = $this->controller->generateToken('refresh_token', null, null, $this->refreshToken->getToken());
$this->assertTrue($result instanceof JSONResponse);
$json = json_decode($result->render());
$this->assertNotEmpty($json->error);
$this->assertEquals('invalid_request', $json->error);
$this->assertEquals(400, $result->getStatus());

$_SERVER['PHP_AUTH_USER'] = 'test';
$_SERVER['PHP_AUTH_PW'] = $this->clientSecret;

$result = $this->controller->generateToken('refresh_token', null, null, $this->refreshToken->getToken());
$this->assertTrue($result instanceof JSONResponse);
$json = json_decode($result->render());
$this->assertNotEmpty($json->error);
$this->assertEquals('invalid_client', $json->error);
$this->assertEquals(400, $result->getStatus());

$_SERVER['PHP_AUTH_USER'] = $this->clientIdentifier1;
$_SERVER['PHP_AUTH_PW'] = 'test';

$result = $this->controller->generateToken('refresh_token', null, null, $this->refreshToken->getToken());
$this->assertTrue($result instanceof JSONResponse);
$json = json_decode($result->render());
$this->assertNotEmpty($json->error);
$this->assertEquals('invalid_client', $json->error);
$this->assertEquals(400, $result->getStatus());

$_SERVER['PHP_AUTH_PW'] = $this->clientSecret;

$result = $this->controller->generateToken('refresh_token', null, null, null);
$this->assertTrue($result instanceof JSONResponse);
$json = json_decode($result->render());
$this->assertNotEmpty($json->error);
$this->assertEquals('invalid_request', $json->error);
$this->assertEquals(200, $result->getStatus());

$_SERVER['PHP_AUTH_USER'] = $this->clientIdentifier2;

$result = $this->controller->generateToken('refresh_token', null, null, $this->refreshToken->getToken());
$this->assertTrue($result instanceof JSONResponse);
$json = json_decode($result->render());
$this->assertNotEmpty($json->error);
$this->assertEquals('invalid_grant', $json->error);
$this->assertEquals(200, $result->getStatus());

$_SERVER['PHP_AUTH_USER'] = $this->clientIdentifier1;

$result = $this->controller->generateToken('refresh_token', null, null, 'test');
$this->assertTrue($result instanceof JSONResponse);
$json = json_decode($result->render());
$this->assertNotEmpty($json->error);
$this->assertEquals('invalid_grant', $json->error);
$this->assertEquals(200, $result->getStatus());

$result = $this->controller->generateToken('refresh_token', null, null, $this->refreshToken->getToken());
$this->assertTrue($result instanceof JSONResponse);
$json = json_decode($result->render());
$this->assertNotEmpty($json->access_token);
$this->assertEquals(64, strlen($json->access_token));
$this->assertNotEmpty($json->token_type);
$this->assertEquals('Bearer', $json->token_type);
$this->assertNotEmpty($json->expires_in);
$this->assertEquals(AccessToken::EXPIRATION_TIME, $json->expires_in);
$this->assertNotEmpty($json->refresh_token);
$this->assertEquals(64, strlen($json->refresh_token));
$this->assertNotEmpty($json->user_id);
$this->assertEquals($this->userId, $json->user_id);
$this->assertNotEmpty($json->message_url);
$this->assertEquals($this->authorizationSuccessfulMessageUrl, $json->message_url);
$this->assertEquals(200, $result->getStatus());
$this->assertEquals(1, count($this->accessTokenMapper->findAll()));
$this->assertEquals(1, count($this->refreshTokenMapper->findAll()));
}
}

0 comments on commit 60a1d0c

Please sign in to comment.