Skip to content

Commit d2f21b5

Browse files
committed
handle oauth client secret decryption errors
Signed-off-by: Julien Veyssier <julien-nc@posteo.net>
1 parent a5456d1 commit d2f21b5

3 files changed

Lines changed: 42 additions & 41 deletions

File tree

apps/oauth2/lib/Controller/OauthApiController.php

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -42,40 +42,23 @@
4242
use OCP\IRequest;
4343
use OCP\Security\ICrypto;
4444
use OCP\Security\ISecureRandom;
45+
use Psr\Log\LoggerInterface;
4546

4647
class OauthApiController extends Controller {
47-
/** @var AccessTokenMapper */
48-
private $accessTokenMapper;
49-
/** @var ClientMapper */
50-
private $clientMapper;
51-
/** @var ICrypto */
52-
private $crypto;
53-
/** @var TokenProvider */
54-
private $tokenProvider;
55-
/** @var ISecureRandom */
56-
private $secureRandom;
57-
/** @var ITimeFactory */
58-
private $time;
59-
/** @var Throttler */
60-
private $throttler;
61-
62-
public function __construct(string $appName,
63-
IRequest $request,
64-
ICrypto $crypto,
65-
AccessTokenMapper $accessTokenMapper,
66-
ClientMapper $clientMapper,
67-
TokenProvider $tokenProvider,
68-
ISecureRandom $secureRandom,
69-
ITimeFactory $time,
70-
Throttler $throttler) {
48+
49+
public function __construct(
50+
string $appName,
51+
IRequest $request,
52+
private ICrypto $crypto,
53+
private AccessTokenMapper $accessTokenMapper,
54+
private ClientMapper $clientMapper,
55+
private TokenProvider $tokenProvider,
56+
private ISecureRandom $secureRandom,
57+
private ITimeFactory $time,
58+
private LoggerInterface $logger,
59+
private Throttler $throttler
60+
) {
7161
parent::__construct($appName, $request);
72-
$this->crypto = $crypto;
73-
$this->accessTokenMapper = $accessTokenMapper;
74-
$this->clientMapper = $clientMapper;
75-
$this->tokenProvider = $tokenProvider;
76-
$this->secureRandom = $secureRandom;
77-
$this->time = $time;
78-
$this->throttler = $throttler;
7962
}
8063

8164
/**
@@ -124,8 +107,15 @@ public function getToken($grant_type, $code, $refresh_token, $client_id, $client
124107
$client_secret = $this->request->server['PHP_AUTH_PW'];
125108
}
126109

110+
try {
111+
$storedClientSecret = $this->crypto->decrypt($client->getSecret());
112+
} catch (\Exception $e) {
113+
$this->logger->info('OAuth client secret decryption error', ['exception' => $e]);
114+
return new JSONResponse([
115+
'error' => 'invalid_client',
116+
], Http::STATUS_BAD_REQUEST);
117+
}
127118
// The client id and secret must match. Else we don't provide an access token!
128-
$storedClientSecret = $this->crypto->decrypt($client->getSecret());
129119
if ($client->getClientIdentifier() !== $client_id || $storedClientSecret !== $client_secret) {
130120
return new JSONResponse([
131121
'error' => 'invalid_client',

apps/oauth2/lib/Settings/Admin.php

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,16 @@
3232
use OCP\Security\ICrypto;
3333
use OCP\Settings\ISettings;
3434
use OCP\IURLGenerator;
35+
use Psr\Log\LoggerInterface;
3536

3637
class Admin implements ISettings {
3738

3839
public function __construct(
3940
private IInitialState $initialState,
4041
private ClientMapper $clientMapper,
4142
private IURLGenerator $urlGenerator,
42-
private ICrypto $crypto
43+
private ICrypto $crypto,
44+
private LoggerInterface $logger,
4345
) {
4446
}
4547

@@ -48,14 +50,18 @@ public function getForm(): TemplateResponse {
4850
$result = [];
4951

5052
foreach ($clients as $client) {
51-
$secret = $this->crypto->decrypt($client->getSecret());
52-
$result[] = [
53-
'id' => $client->getId(),
54-
'name' => $client->getName(),
55-
'redirectUri' => $client->getRedirectUri(),
56-
'clientId' => $client->getClientIdentifier(),
57-
'clientSecret' => $secret,
58-
];
53+
try {
54+
$secret = $this->crypto->decrypt($client->getSecret());
55+
$result[] = [
56+
'id' => $client->getId(),
57+
'name' => $client->getName(),
58+
'redirectUri' => $client->getRedirectUri(),
59+
'clientId' => $client->getClientIdentifier(),
60+
'clientSecret' => $secret,
61+
];
62+
} catch (\Exception $e) {
63+
$this->logger->info('[Settings] OAuth client secret decryption error', ['exception' => $e]);
64+
}
5965
}
6066
$this->initialState->provideInitialState('clients', $result);
6167
$this->initialState->provideInitialState('oauth2-doc-link', $this->urlGenerator->linkToDocs('admin-oauth2'));

apps/oauth2/tests/Controller/OauthApiControllerTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
use OCP\IRequest;
4444
use OCP\Security\ICrypto;
4545
use OCP\Security\ISecureRandom;
46+
use Psr\Log\LoggerInterface;
4647
use Test\TestCase;
4748

4849
/* We have to use this to add a property to the mocked request and avoid warnings about dynamic properties on PHP>=8.2 */
@@ -67,6 +68,8 @@ class OauthApiControllerTest extends TestCase {
6768
private $time;
6869
/** @var Throttler|\PHPUnit\Framework\MockObject\MockObject */
6970
private $throttler;
71+
/** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */
72+
private $logger;
7073
/** @var OauthApiController */
7174
private $oauthApiController;
7275

@@ -81,6 +84,7 @@ protected function setUp(): void {
8184
$this->secureRandom = $this->createMock(ISecureRandom::class);
8285
$this->time = $this->createMock(ITimeFactory::class);
8386
$this->throttler = $this->createMock(Throttler::class);
87+
$this->logger = $this->createMock(LoggerInterface::class);
8488

8589
$this->oauthApiController = new OauthApiController(
8690
'oauth2',
@@ -91,6 +95,7 @@ protected function setUp(): void {
9195
$this->tokenProvider,
9296
$this->secureRandom,
9397
$this->time,
98+
$this->logger,
9499
$this->throttler
95100
);
96101
}

0 commit comments

Comments
 (0)