Skip to content

Commit

Permalink
feat: improve method to search external storage from file ID
Browse files Browse the repository at this point in the history
  • Loading branch information
FlorianRuen committed Jun 19, 2024
1 parent b93bc84 commit 14f42c0
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 61 deletions.
2 changes: 1 addition & 1 deletion lib/Controller/ExternalStorageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public function getExternalStorageConfigurationForSpecificFile(int $fileId): Dat
return new DataResponse(['error' => 'user not logged in'], Http::STATUS_INTERNAL_SERVER_ERROR);
}

$externalStorageConfiguration = $this->externalStorageService->getExternalStorageConfigurationForSpecificFile($user, $fileId, false);
$externalStorageConfiguration = $this->externalStorageService->test($user, $fileId, false);

if (!isset($externalStorageConfiguration['error'])) {
return new DataResponse(['success' => true, 'configuration' => $externalStorageConfiguration], Http::STATUS_OK);
Expand Down
80 changes: 22 additions & 58 deletions lib/Service/ExternalStorageService.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,18 @@

use Exception;
use OCP\IUser;
use OCP\Files\Config\IUserMountCache;
use OCP\Files\IRootFolder;
use OCA\Files_External\Service\GlobalStoragesService;
use Psr\Log\LoggerInterface;
use OCP\Files\File;
use OCA\Files_External\Lib\StorageConfig;

use OCA\Files_External\NotFoundException;
use OCP\Files\StorageNotAvailableException;

class ExternalStorageService {

public function __construct(private LoggerInterface $logger, private IRootFolder $rootFolder, private GlobalStoragesService $globalStoragesService, private HttpRequestService $httpClient) {}
public function __construct(private LoggerInterface $logger, private IUserMountCache $test, private IRootFolder $rootFolder, private GlobalStoragesService $globalStoragesService, private HttpRequestService $httpClient) {}

/**
* Get the metadata from the external storage metadata endpoint for specific file
Expand Down Expand Up @@ -73,30 +76,31 @@ public function getMetadataForSpecificFile(IUser $nextcloudUser, int $fileId): a
*/
public function getExternalStorageConfigurationForSpecificFile(IUser $nextcloudUser, int $fileId, bool $includeAuthSettings): array {
try {
$userFolder = $this->rootFolder->getUserFolder($nextcloudUser->getUID());
$files = $userFolder->getById($fileId);
if (count($files) <= 0 || !$files[0] instanceof File) {
return ['message' => 'file ' . $fileId . ' not found', 'error' => 'file_not_found'];
$mountsForFile = $this->test->getMountsForFileId($fileId, $nextcloudUser->getUID());
$this->logger->error("test mounts from fileId", ["getMountsForFileId" => $mountsForFile]);

if (empty($mountsForFile)) {
return ['message' => 'no external storage found for file ' . $fileId, 'error' => 'external_storage_not_found'];
}

// get the file according to the provided $fileId
$file = $files[0];

// fetch all configured external storages
$externalStorages = $this->globalStoragesService->getStorages();
// get configuration for external storage from ID
$externalStorage = $this->globalStoragesService->getStorage($mountsForFile[0]->getMountId());

// loop through each external storage to find the one related to your file
foreach ($externalStorages as $externalStorage) {
if ($this->isFileInExternalStorage($file, $externalStorage)) {
return $this->buildExternalStorageConfiguration($externalStorage, $includeAuthSettings);
}
// check external storage type is a CIDgravity storage
// if not, it means storage not found (for our use case)
if ($externalStorage->getBackend()->getIdentifier() != "cidgravity") {
return ['message' => 'external storage type for file ' . $fileId . ' is not a cidgravity storage', 'error' => 'external_storage_invalid_type'];
}

return $this->buildExternalStorageConfiguration($externalStorage, false);

} catch (Exception $e) {
return ['message' => 'error getting external storage config', 'error' => $e->getMessage()];
} catch (NotFoundException $e) {
return ['message' => 'external storage not found for file ' . $fileId, 'error' => $e->getMessage()];
} catch (StorageNotAvailableException $e) {
return ['message' => 'external storage not available for file ' . $fileId, 'error' => $e->getMessage()];
}

return ['message' => 'external storage for file ' . $fileId . ' not found', 'error' => 'external_storage_not_found'];
}

/**
Expand All @@ -105,11 +109,6 @@ public function getExternalStorageConfigurationForSpecificFile(IUser $nextcloudU
* @return array
*/
private function buildExternalStorageConfiguration(StorageConfig $externalStorage, bool $includeAuthSettings): array {

$this->logger->error("buildExternalStorageConfiguration", [
'externalStorage' => json_encode($externalStorage),
]);

$configuration = [];
$configuration['is_cidgravity'] = $externalStorage->getBackend()->getIdentifier() == "cidgravity";
$configuration['id'] = $externalStorage->getId();
Expand All @@ -125,39 +124,4 @@ private function buildExternalStorageConfiguration(StorageConfig $externalStorag

return $configuration;
}

/**
* Check if specific file belongs to a specific external storage configuration
* @param File $file File to search for
* @param StorageConfig $externalStorage External storage configuration
* @return bool
*/
private function isFileInExternalStorage(File $file, StorageConfig $externalStorage): bool {
$fileStorage = $file->getStorage();

if ($fileStorage->instanceOfStorage('\OC\Files\Storage\DAV')) {
if ($externalStorage->getBackend()->getIdentifier() == "cidgravity") {
// according to the code, this ID format will be webdav::[EXTERNAL_STORAGE_USER]@[EXTERNAL_STORAGE_HOST]/[EXTERNAL_STORAGE_ROOT]/
$fileStorageID = $fileStorage->getId();

// to check if this file belongs to this external storage
// create same ID format using external storage configuration
$protocol = 'http://';

if ($externalStorage->getBackendOption('secure')) {
$protocol = 'https://';
}

$externalStorageHost = str_replace($protocol, "", $externalStorage->getBackendOption('host'));
$externalStorageID = 'webdav::' . $externalStorage->getBackendOption('user') . '@' . $externalStorageHost . '/' . $externalStorage->getBackendOption('root');

// check if the fileStorageID falls under externalStorageID
if (strpos($fileStorageID, $externalStorageID) === 0) {
return true;
}
}
}

return false;
}
}
10 changes: 8 additions & 2 deletions lib/Service/HttpRequestService.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function __construct(private LoggerInterface $logger) {
$this->ch = curl_init();
}

public function post($url, $data, $headers = ['Content-Type: application/json']) {
public function post($url, $data, $headers = ['Content-Type: application/json'], $username = null, $password = null) {
$jsonData = json_encode($data);

// set CURL configuration
Expand All @@ -44,6 +44,12 @@ public function post($url, $data, $headers = ['Content-Type: application/json'])
curl_setopt($this->ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);

// if username and password provided, setup basic authentication
if ($username !== null && $password !== null) {
curl_setopt($this->ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($this->ch, CURLOPT_USERPWD, "$username:$password");
}

// execute the request
$response = curl_exec($this->ch);

Expand All @@ -53,7 +59,7 @@ public function post($url, $data, $headers = ['Content-Type: application/json'])
throw new Exception("cURL Error: $errorMessage");
}

return $response;
return json_decode($response, true);
}

public function __destruct() {
Expand Down

0 comments on commit 14f42c0

Please sign in to comment.