diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ae8c36b73..4a4e49fb3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,6 +39,7 @@ jobs: php-version: ${{ matrix.phpVersion }} tools: composer, phpunit coverage: xdebug + extensions: gd, sqlite3 - name: Get composer cache directory id: composer-cache @@ -240,7 +241,7 @@ jobs: with: php-version: ${{ format('{0}.{1}', matrix.phpVersionMajor,matrix.phpVersionMinor) }} tools: composer - extensions: intl + extensions: intl, gd - name: Get composer cache directory id: composer-cache diff --git a/appinfo/info.xml b/appinfo/info.xml index 5d31b6e4d..2b4da35ab 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -19,7 +19,7 @@ On the OpenProject end, users are able to: For more information on how to set up and use the OpenProject application, please refer to [integration setup guide](https://www.openproject.org/docs/system-admin-guide/integrations/nextcloud/) for administrators and [the user guide](https://www.openproject.org/docs/user-guide/nextcloud-integration/). ]]> - 2.3.7 + 2.3.8 agpl Julien Veyssier OpenProject diff --git a/lib/Service/OauthService.php b/lib/Service/OauthService.php index afe3e29c6..471ffd116 100644 --- a/lib/Service/OauthService.php +++ b/lib/Service/OauthService.php @@ -15,6 +15,8 @@ use OCA\OAuth2\Db\ClientMapper; use OCA\OAuth2\Exceptions\ClientNotFoundException; use OCP\Security\ISecureRandom; +use OCP\Security\ICrypto; +use OC_Util; class OauthService { /** @@ -28,14 +30,21 @@ class OauthService { */ private $clientMapper; + /** + * @var ICrypto + */ + private $crypto; + /** * Service to manipulate Nextcloud oauth clients */ public function __construct(ClientMapper $clientMapper, - ISecureRandom $secureRandom + ISecureRandom $secureRandom, + ICrypto $crypto ) { $this->secureRandom = $secureRandom; $this->clientMapper = $clientMapper; + $this->crypto = $crypto; } /** @@ -48,11 +57,27 @@ public function createNcOauthClient(string $name, string $redirectUri): array { $client = new Client(); $client->setName($name); $client->setRedirectUri(sprintf($redirectUri, $clientId)); - $client->setSecret($this->secureRandom->generate(64, self::validChars)); + $secret = $this->secureRandom->generate(64, self::validChars); + if (version_compare(OC_Util::getVersionString(), '27.0.1') >= 0) { + $encryptedSecret = $this->crypto->encrypt($secret); + } elseif (version_compare(OC_Util::getVersionString(), '26.0.4') >= 0 && version_compare(OC_Util::getVersionString(), '27.0.0') < 0) { + $encryptedSecret = $this->crypto->encrypt($secret); + } elseif (version_compare(OC_Util::getVersionString(), '25.0.8') >= 0 && version_compare(OC_Util::getVersionString(), '26.0.0') < 0) { + $encryptedSecret = $this->crypto->encrypt($secret); + } else { + $encryptedSecret = $secret; + } + $client->setSecret($encryptedSecret); $client->setClientIdentifier($clientId); $client = $this->clientMapper->insert($client); - return $this->generateClientInfo($client); + return [ + 'id' => $client->getId(), + 'nextcloud_oauth_client_name' => $client->getName(), + 'openproject_redirect_uri' => $client->getRedirectUri(), + 'nextcloud_client_id' => $client->getClientIdentifier(), + 'nextcloud_client_secret' => $secret, + ]; } /** @@ -62,7 +87,12 @@ public function createNcOauthClient(string $name, string $redirectUri): array { public function getClientInfo(int $id): ?array { try { $client = $this->clientMapper->getByUid($id); - return $this->generateClientInfo($client); + return [ + 'id' => $client->getId(), + 'nextcloud_oauth_client_name' => $client->getName(), + 'openproject_redirect_uri' => $client->getRedirectUri(), + 'nextcloud_client_id' => $client->getClientIdentifier(), + ]; } catch (ClientNotFoundException $e) { return null; } @@ -85,18 +115,4 @@ public function setClientRedirectUri(int $id, string $opUrl): bool { return false; } } - - /** - * @param Client $client - * @return array - */ - private function generateClientInfo(Client $client): array { - return [ - 'id' => $client->getId(), - 'nextcloud_oauth_client_name' => $client->getName(), - 'openproject_redirect_uri' => $client->getRedirectUri(), - 'nextcloud_client_id' => $client->getClientIdentifier(), - 'nextcloud_client_secret' => $client->getSecret(), - ]; - } } diff --git a/src/components/AdminSettings.vue b/src/components/AdminSettings.vue index 6c48a528b..87ae1c78b 100644 --- a/src/components/AdminSettings.vue +++ b/src/components/AdminSettings.vue @@ -137,12 +137,11 @@ title="Nextcloud OAuth client secret" is-required encrypt-value - with-inspection :value="ncClientSecret" /> @@ -252,7 +251,8 @@ export default { return this.state.nc_oauth_client?.nextcloud_client_id }, ncClientSecret() { - return this.state.nc_oauth_client?.nextcloud_client_secret + return '*******' + }, serverHostErrorMessage() { if ( diff --git a/tests/acceptance/features/api/setup.feature b/tests/acceptance/features/api/setup.feature index f0e0c81fd..132327639 100644 --- a/tests/acceptance/features/api/setup.feature +++ b/tests/acceptance/features/api/setup.feature @@ -220,14 +220,12 @@ Feature: setup the integration through an API "required": [ "nextcloud_oauth_client_name", "openproject_redirect_uri", - "nextcloud_client_id", - "nextcloud_client_secret" + "nextcloud_client_id" ], "properties": { "nextcloud_oauth_client_name": {"type": "string", "pattern": "^OpenProject client$"}, "openproject_redirect_uri": {"type": "string", "pattern": "^http:\/\/.*\/oauth_clients\/[A-Za-z0-9]+\/callback$"}, - "nextcloud_client_id": {"type": "string", "pattern": "[A-Za-z0-9]+"}, - "nextcloud_client_secret": {"type": "string", "pattern": "[A-Za-z0-9]+"} + "nextcloud_client_id": {"type": "string", "pattern": "[A-Za-z0-9]+"} }, "not": { "required": [ @@ -263,14 +261,12 @@ Feature: setup the integration through an API "required": [ "nextcloud_oauth_client_name", "openproject_redirect_uri", - "nextcloud_client_id", - "nextcloud_client_secret" + "nextcloud_client_id" ], "properties": { "nextcloud_oauth_client_name": {"type": "string", "pattern": "^OpenProject client$"}, "openproject_redirect_uri": {"type": "string", "pattern": "^http:\/\/.*\/oauth_clients\/[A-Za-z0-9]+\/callback$"}, - "nextcloud_client_id": {"type": "string", "pattern": "[A-Za-z0-9]+"}, - "nextcloud_client_secret": {"type": "string", "pattern": "[A-Za-z0-9]+"} + "nextcloud_client_id": {"type": "string", "pattern": "[A-Za-z0-9]+"} }, "not": { "required": [ @@ -407,8 +403,7 @@ Feature: setup the integration through an API "required": [ "nextcloud_oauth_client_name", "openproject_redirect_uri", - "nextcloud_client_id", - "nextcloud_client_secret" + "nextcloud_client_id" ] }, "not": { diff --git a/tests/jest/components/__snapshots__/AdminSettings.spec.js.snap b/tests/jest/components/__snapshots__/AdminSettings.spec.js.snap index 423560b85..d7b2ee079 100644 --- a/tests/jest/components/__snapshots__/AdminSettings.spec.js.snap +++ b/tests/jest/components/__snapshots__/AdminSettings.spec.js.snap @@ -20,7 +20,7 @@ exports[`AdminSettings.vue Nextcloud OAuth values form view mode with complete v - + Replace Nextcloud OAuth values