diff --git a/apps/oauth2/lib/Controller/OauthApiController.php b/apps/oauth2/lib/Controller/OauthApiController.php index b7de44f11f8..9d0b8830533 100644 --- a/apps/oauth2/lib/Controller/OauthApiController.php +++ b/apps/oauth2/lib/Controller/OauthApiController.php @@ -23,7 +23,10 @@ namespace OCA\OAuth2\Controller; use OC\Authentication\Token\DefaultTokenMapper; use OCA\OAuth2\Db\AccessTokenMapper; +use OCA\OAuth2\Db\ClientMapper; +use OCA\OAuth2\Exceptions\AccessTokenNotFoundException; use OCP\AppFramework\Controller; +use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; use OCP\IRequest; use OCP\Security\ICrypto; @@ -32,6 +35,8 @@ use OCP\Security\ISecureRandom; class OauthApiController extends Controller { /** @var AccessTokenMapper */ private $accessTokenMapper; + /** @var ClientMapper */ + private $clientMapper; /** @var ICrypto */ private $crypto; /** @var DefaultTokenMapper */ @@ -44,6 +49,7 @@ class OauthApiController extends Controller { * @param IRequest $request * @param ICrypto $crypto * @param AccessTokenMapper $accessTokenMapper + * @param ClientMapper $clientMapper * @param DefaultTokenMapper $defaultTokenMapper * @param ISecureRandom $secureRandom */ @@ -51,11 +57,13 @@ class OauthApiController extends Controller { IRequest $request, ICrypto $crypto, AccessTokenMapper $accessTokenMapper, + ClientMapper $clientMapper, DefaultTokenMapper $defaultTokenMapper, ISecureRandom $secureRandom) { parent::__construct($appName, $request); $this->crypto = $crypto; $this->accessTokenMapper = $accessTokenMapper; + $this->clientMapper = $clientMapper; $this->defaultTokenMapper = $defaultTokenMapper; $this->secureRandom = $secureRandom; } @@ -64,13 +72,48 @@ class OauthApiController extends Controller { * @PublicPage * @NoCSRFRequired * + * @param string $grant_type * @param string $code + * @param string $refresh_token * @param string $client_id * @param string $client_secret * @return JSONResponse */ - public function getToken($code, $client_id, $client_secret) { - $accessToken = $this->accessTokenMapper->getByCode($code); + public function getToken($grant_type, $code, $refresh_token, $client_id, $client_secret) { + + if ($grant_type !== 'authorization_code' && $grant_type !== 'refresh_token') { + return new JSONResponse([ + 'error' => 'invalid_grant', + ], Http::STATUS_BAD_REQUEST); + } + + // We handle the initial and refresh tokens the same way + if ($grant_type === 'refresh_token' ) { + $code = $refresh_token; + } + + try { + $accessToken = $this->accessTokenMapper->getByCode($code); + } catch (AccessTokenNotFoundException $e) { + return new JSONResponse([ + 'error' => 'invalid_request', + ], Http::STATUS_BAD_REQUEST); + } + + try { + $client = $this->clientMapper->getByUid($accessToken->getClientId()); + } catch (ClientNotFoundException $e) { + return new JSONResponse([ + 'error' => 'invalid_request', + ], Http::STATUS_BAD_REQUEST); + } + + if ($client->getClientIdentifier() !== $client_id || $client->getSecret() !== $client_secret) { + return new JSONResponse([ + 'error' => 'invalid_client', + ], Http::STATUS_BAD_REQUEST); + } + $decryptedToken = $this->crypto->decrypt($accessToken->getEncryptedToken(), $code); $newCode = $this->secureRandom->generate(128); $accessToken->setHashedCode(hash('sha512', $newCode));