diff options
Diffstat (limited to 'apps/oauth2/lib')
-rw-r--r-- | apps/oauth2/lib/Command/ImportLegacyOcClient.php | 76 | ||||
-rw-r--r-- | apps/oauth2/lib/Controller/LoginRedirectorController.php | 15 |
2 files changed, 90 insertions, 1 deletions
diff --git a/apps/oauth2/lib/Command/ImportLegacyOcClient.php b/apps/oauth2/lib/Command/ImportLegacyOcClient.php new file mode 100644 index 00000000000..acdc57cf991 --- /dev/null +++ b/apps/oauth2/lib/Command/ImportLegacyOcClient.php @@ -0,0 +1,76 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCA\OAuth2\Command; + +use OCA\OAuth2\Db\Client; +use OCA\OAuth2\Db\ClientMapper; +use OCP\IConfig; +use OCP\Security\ICrypto; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class ImportLegacyOcClient extends Command { + private const ARGUMENT_CLIENT_ID = 'client-id'; + private const ARGUMENT_CLIENT_SECRET = 'client-secret'; + + public function __construct( + private readonly IConfig $config, + private readonly ICrypto $crypto, + private readonly ClientMapper $clientMapper, + ) { + parent::__construct(); + } + + protected function configure(): void { + $this->setName('oauth2:import-legacy-oc-client'); + $this->setDescription('This command is only required to be run on instances which were migrated from ownCloud without the oauth2.enable_oc_clients system config! Import a legacy Oauth2 client from an ownCloud instance and migrate it. The data is expected to be straight out of the database table oc_oauth2_clients.'); + $this->addArgument( + self::ARGUMENT_CLIENT_ID, + InputArgument::REQUIRED, + 'Value of the "identifier" column', + ); + $this->addArgument( + self::ARGUMENT_CLIENT_SECRET, + InputArgument::REQUIRED, + 'Value of the "secret" column', + ); + } + + public function isEnabled(): bool { + return $this->config->getSystemValueBool('oauth2.enable_oc_clients', false); + } + + protected function execute(InputInterface $input, OutputInterface $output): int { + /** @var string $clientId */ + $clientId = $input->getArgument(self::ARGUMENT_CLIENT_ID); + + /** @var string $clientSecret */ + $clientSecret = $input->getArgument(self::ARGUMENT_CLIENT_SECRET); + + // Should not happen but just to be sure + if (empty($clientId) || empty($clientSecret)) { + return 1; + } + + $hashedClientSecret = bin2hex($this->crypto->calculateHMAC($clientSecret)); + + $client = new Client(); + $client->setName('ownCloud Desktop Client'); + $client->setRedirectUri('http://localhost:*'); + $client->setClientIdentifier($clientId); + $client->setSecret($hashedClientSecret); + $this->clientMapper->insert($client); + + $output->writeln('<info>Client imported successfully</info>'); + return 0; + } +} diff --git a/apps/oauth2/lib/Controller/LoginRedirectorController.php b/apps/oauth2/lib/Controller/LoginRedirectorController.php index db233e7956e..7241b35cdcf 100644 --- a/apps/oauth2/lib/Controller/LoginRedirectorController.php +++ b/apps/oauth2/lib/Controller/LoginRedirectorController.php @@ -20,6 +20,7 @@ use OCP\AppFramework\Http\Attribute\UseSession; use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Http\TemplateResponse; use OCP\IAppConfig; +use OCP\IConfig; use OCP\IL10N; use OCP\IRequest; use OCP\ISession; @@ -45,6 +46,7 @@ class LoginRedirectorController extends Controller { private IL10N $l, private ISecureRandom $random, private IAppConfig $appConfig, + private IConfig $config, ) { parent::__construct($appName, $request); } @@ -55,6 +57,7 @@ class LoginRedirectorController extends Controller { * @param string $client_id Client ID * @param string $state State of the flow * @param string $response_type Response type for the flow + * @param string $redirect_uri URI to redirect to after the flow (is only used for legacy ownCloud clients) * @return TemplateResponse<Http::STATUS_OK, array{}>|RedirectResponse<Http::STATUS_SEE_OTHER, array{}> * * 200: Client not found @@ -65,7 +68,8 @@ class LoginRedirectorController extends Controller { #[UseSession] public function authorize($client_id, $state, - $response_type): TemplateResponse|RedirectResponse { + $response_type, + string $redirect_uri = ''): TemplateResponse|RedirectResponse { try { $client = $this->clientMapper->getByIdentifier($client_id); } catch (ClientNotFoundException $e) { @@ -81,6 +85,13 @@ class LoginRedirectorController extends Controller { return new RedirectResponse($url); } + $enableOcClients = $this->config->getSystemValueBool('oauth2.enable_oc_clients', false); + + $providedRedirectUri = ''; + if ($enableOcClients && $client->getRedirectUri() === 'http://localhost:*') { + $providedRedirectUri = $redirect_uri; + } + $this->session->set('oauth.state', $state); if (in_array($client->getName(), $this->appConfig->getValueArray('oauth2', 'skipAuthPickerApplications', []))) { @@ -95,6 +106,7 @@ class LoginRedirectorController extends Controller { [ 'stateToken' => $stateToken, 'clientIdentifier' => $client->getClientIdentifier(), + 'providedRedirectUri' => $providedRedirectUri, ] ); } else { @@ -102,6 +114,7 @@ class LoginRedirectorController extends Controller { 'core.ClientFlowLogin.showAuthPickerPage', [ 'clientIdentifier' => $client->getClientIdentifier(), + 'providedRedirectUri' => $providedRedirectUri, ] ); } |