From b815f23fe69e70d8ae3e37b59bc17069b35ac034 Mon Sep 17 00:00:00 2001 From: Sabin Date: Thu, 4 Jul 2024 11:58:26 +0545 Subject: [PATCH 1/6] added code for getting current oCis version --- src/Ocis.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/Ocis.php b/src/Ocis.php index 202cb29a..f1f02bdb 100644 --- a/src/Ocis.php +++ b/src/Ocis.php @@ -306,6 +306,28 @@ private function getServiceUrlFromWebfinger(string $webfingerUrl): string } throw new InvalidResponseException('invalid webfinger response'); } + + /** + * returns current oCIS version in semantic versioning format ( eg "5.0.5" ) + * + * @return string + * @throws InvalidResponseException + */ + public function getOcisVersion(): string + { + $fullUrl = $this->getServiceUrl() . '/ocs/v1.php/cloud/capabilities'; + $client = new Client($this->createGuzzleConfig($this->connectionConfig, $this->accessToken)); + $response = $client->request('GET', $fullUrl); + $responseContent = $response->getBody()->getContents(); + + $body = simplexml_load_string($responseContent); + if (!isset($body->data->capabilities->core->status->productversion)) { + throw new InvalidResponseException('Missing productversion element in XML response'); + } + $version = explode('+', (string)$body->data->capabilities->core->status->productversion); + return $version[0]; + } + /** * Get all available drives * From 92ba5c6eeaf37a04ff70f830d7d5ca340761a877 Mon Sep 17 00:00:00 2001 From: Sabin Date: Thu, 4 Jul 2024 17:19:58 +0545 Subject: [PATCH 2/6] added code to handle exception if no endpoint found --- src/Drive.php | 10 ++++++- .../EndPointNotImplementedException.php | 10 +++++++ src/Ocis.php | 30 ++++++++++++------- .../Owncloud/OcisPhpSdk/DriveTest.php | 8 ++--- 4 files changed, 41 insertions(+), 17 deletions(-) create mode 100644 src/Exception/EndPointNotImplementedException.php diff --git a/src/Drive.php b/src/Drive.php index 59ff3e17..c9bf9777 100644 --- a/src/Drive.php +++ b/src/Drive.php @@ -14,6 +14,7 @@ use OpenAPI\Client\Model\OdataError; use OpenAPI\Client\Model\Quota; use Owncloud\OcisPhpSdk\Exception\BadRequestException; +use Owncloud\OcisPhpSdk\Exception\EndPointNotImplementedException; use Owncloud\OcisPhpSdk\Exception\ExceptionHelper; use Owncloud\OcisPhpSdk\Exception\ForbiddenException; use Owncloud\OcisPhpSdk\Exception\HttpException; @@ -42,6 +43,7 @@ class Drive private array $connectionConfig; private Configuration $graphApiConfig; private string $serviceUrl; + private string $ocisVersion; /** * @ignore The developer using the SDK does not need to create drives manually, but should use the Ocis class @@ -53,11 +55,13 @@ public function __construct( ApiDrive $apiDrive, array $connectionConfig, string $serviceUrl, - string &$accessToken + string &$accessToken, + string $ocisVersion ) { $this->apiDrive = $apiDrive; $this->accessToken = &$accessToken; $this->serviceUrl = $serviceUrl; + $this->ocisVersion = $ocisVersion; if (!Ocis::isConnectionConfigValid($connectionConfig)) { throw new \InvalidArgumentException('connection configuration not valid'); } @@ -583,9 +587,13 @@ public function emptyTrashbin(): bool * @throws UnauthorizedException * @throws InvalidResponseException * @throws InternalServerErrorException + * @throws EndPointNotImplementedException */ public function getRoles(): array { + if((version_compare($this->ocisVersion, '6.0.0', '<'))) { + throw new EndPointNotImplementedException(Ocis::ENDPOINT_NOT_IMPLEMENTED_ERROR_MESSAGE); + }; $guzzle = new Client( Ocis::createGuzzleConfig($this->connectionConfig, $this->accessToken) ); diff --git a/src/Exception/EndPointNotImplementedException.php b/src/Exception/EndPointNotImplementedException.php new file mode 100644 index 00000000..c6da63b8 --- /dev/null +++ b/src/Exception/EndPointNotImplementedException.php @@ -0,0 +1,10 @@ +graphApiConfig = Configuration::getDefaultConfiguration()->setHost( $this->serviceUrl . '/graph' ); - + $this->getOcisVersion(); } public function getServiceUrl(): string @@ -313,19 +316,20 @@ private function getServiceUrlFromWebfinger(string $webfingerUrl): string * @return string * @throws InvalidResponseException */ - public function getOcisVersion(): string + private function getOcisVersion(): void { - $fullUrl = $this->getServiceUrl() . '/ocs/v1.php/cloud/capabilities'; - $client = new Client($this->createGuzzleConfig($this->connectionConfig, $this->accessToken)); - $response = $client->request('GET', $fullUrl); + $fullUrl = self::getServiceUrl() . '/ocs/v1.php/cloud/capabilities'; + $response = $this->guzzle->request('GET', $fullUrl); $responseContent = $response->getBody()->getContents(); $body = simplexml_load_string($responseContent); if (!isset($body->data->capabilities->core->status->productversion)) { throw new InvalidResponseException('Missing productversion element in XML response'); } - $version = explode('+', (string)$body->data->capabilities->core->status->productversion); - return $version[0]; + $version = (string)$body->data->capabilities->core->status->productversion; + $pattern = '(\d.\d.\d)'; + preg_match($pattern, $version, $matches); + $this->ocisVersion = $matches[0]; } /** @@ -380,7 +384,8 @@ public function getAllDrives( $apiDrive, $this->connectionConfig, $this->serviceUrl, - $this->accessToken + $this->accessToken, + $this->ocisVersion ); $drives[] = $drive; } @@ -437,7 +442,8 @@ public function getMyDrives( $apiDrive, $this->connectionConfig, $this->serviceUrl, - $this->accessToken + $this->accessToken, + $this->ocisVersion ); $drives[] = $drive; } @@ -494,7 +500,8 @@ public function getDriveById(string $driveId): Drive $apiDrive, $this->connectionConfig, $this->serviceUrl, - $this->accessToken + $this->accessToken, + $this->ocisVersion ); } @@ -546,7 +553,8 @@ public function createDrive( $newlyCreatedDrive, $this->connectionConfig, $this->serviceUrl, - $this->accessToken + $this->accessToken, + $this->ocisVersion ); } throw new InvalidResponseException( diff --git a/tests/integration/Owncloud/OcisPhpSdk/DriveTest.php b/tests/integration/Owncloud/OcisPhpSdk/DriveTest.php index 97d2f52f..276129bd 100644 --- a/tests/integration/Owncloud/OcisPhpSdk/DriveTest.php +++ b/tests/integration/Owncloud/OcisPhpSdk/DriveTest.php @@ -72,15 +72,13 @@ public function testDeleteEnabledDrive(): void public function testGetDriveRole(): void { - // At the time of writing, "stable" is major version 5 of ocis. - // This functionality works with major version 6. - // When ocis major version 6 has been released as "stable" then remove this test skip. - if (getenv('OCIS_VERSION') === "stable") { + try { + $role = $this->drive->getRoles(); + } catch(\Exception) { $this->markTestSkipped( 'This test is skipped because root endpoint for drive share is not applicable for version 5 of OCIS.' ); }; - $role = $this->drive->getRoles(); $this->assertContainsOnlyInstancesOf( SharingRole::class, $role, From 0fe2314953d7a63c74ae08d8b22c49c1d26a0435 Mon Sep 17 00:00:00 2001 From: Sabin Date: Fri, 5 Jul 2024 09:40:36 +0545 Subject: [PATCH 3/6] addressing reviews --- src/Ocis.php | 8 ++++---- tests/integration/Owncloud/OcisPhpSdk/DriveTest.php | 6 +++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Ocis.php b/src/Ocis.php index a06ed3b1..98a4029a 100644 --- a/src/Ocis.php +++ b/src/Ocis.php @@ -54,7 +54,7 @@ class Ocis public const FUNCTION_NOT_IMPLEMENTED_YET_ERROR_MESSAGE = 'This function is not implemented yet! Place, name and signature of the function might change!'; public const ENDPOINT_NOT_IMPLEMENTED_ERROR_MESSAGE = - 'This method is not implemented in this ocis verion'; + 'This method is not implemented in this ocis version'; private string $serviceUrl; private string $accessToken; private Configuration $graphApiConfig; @@ -311,9 +311,9 @@ private function getServiceUrlFromWebfinger(string $webfingerUrl): string } /** - * returns current oCIS version in semantic versioning format ( eg "5.0.5" ) + * saves current oCIS version in semantic versioning format ( e.g. "5.0.5" ) * - * @return string + * @return void * @throws InvalidResponseException */ private function getOcisVersion(): void @@ -327,7 +327,7 @@ private function getOcisVersion(): void throw new InvalidResponseException('Missing productversion element in XML response'); } $version = (string)$body->data->capabilities->core->status->productversion; - $pattern = '(\d.\d.\d)'; + $pattern = '(\d\.\d\.\d)'; preg_match($pattern, $version, $matches); $this->ocisVersion = $matches[0]; } diff --git a/tests/integration/Owncloud/OcisPhpSdk/DriveTest.php b/tests/integration/Owncloud/OcisPhpSdk/DriveTest.php index 276129bd..d1f92fc4 100644 --- a/tests/integration/Owncloud/OcisPhpSdk/DriveTest.php +++ b/tests/integration/Owncloud/OcisPhpSdk/DriveTest.php @@ -4,6 +4,7 @@ use Owncloud\OcisPhpSdk\Drive; use Owncloud\OcisPhpSdk\Exception\BadRequestException; +use Owncloud\OcisPhpSdk\Exception\EndPointNotImplementedException; use Owncloud\OcisPhpSdk\Exception\NotFoundException; use Owncloud\OcisPhpSdk\Ocis; use Owncloud\OcisPhpSdk\SharingRole; @@ -74,7 +75,10 @@ public function testGetDriveRole(): void { try { $role = $this->drive->getRoles(); - } catch(\Exception) { + } catch(EndPointNotImplementedException) { + if (getenv('OCIS_VERSION') !== "stable") { + $this->fail("EndPointNotImplementedException was thrown unexpectedly"); + } $this->markTestSkipped( 'This test is skipped because root endpoint for drive share is not applicable for version 5 of OCIS.' ); From 25862681cf3aadbbf8d50f1b9a4542c0253e4452 Mon Sep 17 00:00:00 2001 From: Sabin Date: Fri, 5 Jul 2024 12:06:03 +0545 Subject: [PATCH 4/6] updated code and drone env for master and stable --- .drone.env | 4 ++-- src/Drive.php | 2 +- src/Ocis.php | 19 ++++++++----------- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/.drone.env b/.drone.env index 6fbb11e1..074764a8 100644 --- a/.drone.env +++ b/.drone.env @@ -1,5 +1,5 @@ # The version of OCIS to use in pipelines that test against OCIS -OCIS_COMMITID=c18d71788351ac878d2016b178e3e87c673e62a3 +OCIS_COMMITID=aa6041abb6e8094306216fbe354403df14b47c70 OCIS_BRANCH=master -OCIS_STABLE_COMMITID=48ab941943a9eb3b510b7029ba39ba445a6aac1b +OCIS_STABLE_COMMITID=214491134f5674ac735635ea259969663d9ad4c7 OCIS_STABLE_BRANCH=stable-5.0 diff --git a/src/Drive.php b/src/Drive.php index c9bf9777..a762e2bf 100644 --- a/src/Drive.php +++ b/src/Drive.php @@ -591,7 +591,7 @@ public function emptyTrashbin(): bool */ public function getRoles(): array { - if((version_compare($this->ocisVersion, '6.0.0', '<'))) { + if((version_compare($this->ocisVersion, '6.0.0', '<='))) { throw new EndPointNotImplementedException(Ocis::ENDPOINT_NOT_IMPLEMENTED_ERROR_MESSAGE); }; $guzzle = new Client( diff --git a/src/Ocis.php b/src/Ocis.php index 98a4029a..7f51aebd 100644 --- a/src/Ocis.php +++ b/src/Ocis.php @@ -60,7 +60,6 @@ class Ocis private Configuration $graphApiConfig; private Client $guzzle; private string $notificationsEndpoint = '/ocs/v2.php/apps/notifications/api/v1/notifications?format=json'; - private string $ocisVersion; /** * @phpstan-var ConnectionConfig @@ -114,7 +113,6 @@ public function __construct( $this->graphApiConfig = Configuration::getDefaultConfiguration()->setHost( $this->serviceUrl . '/graph' ); - $this->getOcisVersion(); } public function getServiceUrl(): string @@ -313,13 +311,12 @@ private function getServiceUrlFromWebfinger(string $webfingerUrl): string /** * saves current oCIS version in semantic versioning format ( e.g. "5.0.5" ) * - * @return void + * @return string * @throws InvalidResponseException */ - private function getOcisVersion(): void + private function getOcisVersion(): string { - $fullUrl = self::getServiceUrl() . '/ocs/v1.php/cloud/capabilities'; - $response = $this->guzzle->request('GET', $fullUrl); + $response = $this->guzzle->get($this->serviceUrl . '/ocs/v1.php/cloud/capabilities'); $responseContent = $response->getBody()->getContents(); $body = simplexml_load_string($responseContent); @@ -329,7 +326,7 @@ private function getOcisVersion(): void $version = (string)$body->data->capabilities->core->status->productversion; $pattern = '(\d\.\d\.\d)'; preg_match($pattern, $version, $matches); - $this->ocisVersion = $matches[0]; + return $matches[0]; } /** @@ -385,7 +382,7 @@ public function getAllDrives( $this->connectionConfig, $this->serviceUrl, $this->accessToken, - $this->ocisVersion + $this->getOcisVersion() ); $drives[] = $drive; } @@ -443,7 +440,7 @@ public function getMyDrives( $this->connectionConfig, $this->serviceUrl, $this->accessToken, - $this->ocisVersion + $this->getOcisVersion() ); $drives[] = $drive; } @@ -501,7 +498,7 @@ public function getDriveById(string $driveId): Drive $this->connectionConfig, $this->serviceUrl, $this->accessToken, - $this->ocisVersion + $this->getOcisVersion() ); } @@ -554,7 +551,7 @@ public function createDrive( $this->connectionConfig, $this->serviceUrl, $this->accessToken, - $this->ocisVersion + $this->getOcisVersion() ); } throw new InvalidResponseException( From 90d093e9e96fd939dd1948fe90fc80fdbaf17d0e Mon Sep 17 00:00:00 2001 From: Sabin Date: Fri, 5 Jul 2024 14:47:20 +0545 Subject: [PATCH 5/6] adding guzzle mock for getting ocis version --- src/Drive.php | 2 +- src/Ocis.php | 28 +++++++++++++-------- tests/unit/Owncloud/OcisPhpSdk/OcisTest.php | 27 +++++++++++++++++++- 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/src/Drive.php b/src/Drive.php index a762e2bf..c9bf9777 100644 --- a/src/Drive.php +++ b/src/Drive.php @@ -591,7 +591,7 @@ public function emptyTrashbin(): bool */ public function getRoles(): array { - if((version_compare($this->ocisVersion, '6.0.0', '<='))) { + if((version_compare($this->ocisVersion, '6.0.0', '<'))) { throw new EndPointNotImplementedException(Ocis::ENDPOINT_NOT_IMPLEMENTED_ERROR_MESSAGE); }; $guzzle = new Client( diff --git a/src/Ocis.php b/src/Ocis.php index 7f51aebd..3da20ca8 100644 --- a/src/Ocis.php +++ b/src/Ocis.php @@ -65,6 +65,7 @@ class Ocis * @phpstan-var ConnectionConfig */ private array $connectionConfig; + private string $ocisVersion = ''; /** * @phpstan-param ConnectionConfig $connectionConfig @@ -309,24 +310,29 @@ private function getServiceUrlFromWebfinger(string $webfingerUrl): string } /** - * saves current oCIS version in semantic versioning format ( e.g. "5.0.5" ) + * returns the current oCIS version in semantic versioning format ( e.g. "5.0.5" ) * * @return string * @throws InvalidResponseException */ - private function getOcisVersion(): string + public function getOcisVersion(): string { - $response = $this->guzzle->get($this->serviceUrl . '/ocs/v1.php/cloud/capabilities'); - $responseContent = $response->getBody()->getContents(); + if(($this->ocisVersion)) { + return $this->ocisVersion; + } else { + $response = $this->guzzle->get($this->serviceUrl . '/ocs/v1.php/cloud/capabilities'); + $responseContent = $response->getBody()->getContents(); - $body = simplexml_load_string($responseContent); - if (!isset($body->data->capabilities->core->status->productversion)) { - throw new InvalidResponseException('Missing productversion element in XML response'); + $body = simplexml_load_string($responseContent); + if (!isset($body->data->version->productversion)) { + throw new InvalidResponseException('Missing productversion element in XML response'); + } + $version = (string)$body->data->version->productversion; + $pattern = '(\d\.\d\.\d)'; + preg_match($pattern, $version, $matches); + $this->ocisVersion = $matches[0]; + return $this->ocisVersion; } - $version = (string)$body->data->capabilities->core->status->productversion; - $pattern = '(\d\.\d\.\d)'; - preg_match($pattern, $version, $matches); - return $matches[0]; } /** diff --git a/tests/unit/Owncloud/OcisPhpSdk/OcisTest.php b/tests/unit/Owncloud/OcisPhpSdk/OcisTest.php index d52d0f50..8a4e98cd 100644 --- a/tests/unit/Owncloud/OcisPhpSdk/OcisTest.php +++ b/tests/unit/Owncloud/OcisPhpSdk/OcisTest.php @@ -14,6 +14,7 @@ use Owncloud\OcisPhpSdk\Exception\HttpException; use Owncloud\OcisPhpSdk\Exception\InvalidResponseException; use Owncloud\OcisPhpSdk\Ocis; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\StreamInterface; @@ -121,7 +122,8 @@ public function testSetAccessTokenPropagatesToDrives(): void $ocis = new Ocis( 'https://localhost:9200', 'tokenWhenCreated', - ['drivesGetDrivesApi' => $drivesGetDrivesApi] + /* @phpstan-ignore-next-line */ + [ 'guzzle' => $this->setUpMocksForOcisVersion(), 'drivesGetDrivesApi' => $drivesGetDrivesApi] ); $drives = $ocis->getAllDrives(); foreach ($drives as $drive) { @@ -149,6 +151,29 @@ public function testSetAccessTokenPropagatesToNotifications(): void $this->assertSame('changedToken', $notifications[1]->getAccessToken()); } + private function setUpMocksForOcisVersion(?string $responseContent = null): MockObject + { + if ($responseContent === null) { + $responseContent = << + + + 6.0.0 + + + + XML; + }; + $streamMock = $this->createMock(StreamInterface::class); + $streamMock->method('getContents')->willReturn($responseContent); + $responseMock = $this->createMock(ResponseInterface::class); + $responseMock->method('getBody')->willReturn($streamMock); + $guzzleMock = $this->createMock(Client::class); + $guzzleMock->method('get') + ->willReturn($responseMock); + return $guzzleMock; + } + private function setupMocksForNotificationTests( string $responseContent, string $token = 'doesNotMatter' From c6396689b7eca61e7d3e739a4c96f08418265e81 Mon Sep 17 00:00:00 2001 From: Sabin Date: Fri, 5 Jul 2024 15:23:56 +0545 Subject: [PATCH 6/6] adding test for stable ocis for sharing drive via root --- .../Owncloud/OcisPhpSdk/DriveTest.php | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/tests/integration/Owncloud/OcisPhpSdk/DriveTest.php b/tests/integration/Owncloud/OcisPhpSdk/DriveTest.php index d1f92fc4..e0c7686e 100644 --- a/tests/integration/Owncloud/OcisPhpSdk/DriveTest.php +++ b/tests/integration/Owncloud/OcisPhpSdk/DriveTest.php @@ -73,20 +73,22 @@ public function testDeleteEnabledDrive(): void public function testGetDriveRole(): void { + //ocis stable doesn't support root endpoint + if (getenv('OCIS_VERSION') === "stable") { + $this->expectException(EndPointNotImplementedException::class); + $this->expectExceptionMessage("This method is not implemented in this ocis version"); + $this->drive->getRoles(); + } try { $role = $this->drive->getRoles(); - } catch(EndPointNotImplementedException) { - if (getenv('OCIS_VERSION') !== "stable") { - $this->fail("EndPointNotImplementedException was thrown unexpectedly"); - } - $this->markTestSkipped( - 'This test is skipped because root endpoint for drive share is not applicable for version 5 of OCIS.' + $this->assertContainsOnlyInstancesOf( + SharingRole::class, + $role, + "Array contains not only 'SharingRole' items" ); + } catch(EndPointNotImplementedException) { + //test should fail if ocis version is less than 6.0.0 + $this->fail("EndPointNotImplementedException was thrown unexpectedly"); }; - $this->assertContainsOnlyInstancesOf( - SharingRole::class, - $role, - "Array contains not only 'SharingRole' items" - ); } }