From ebeb85bc73580fa10ab15a299e244634621878b1 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 15 Jan 2024 19:20:05 +0100 Subject: [PATCH] add extention interface to provide a debug description of storages Signed-off-by: Robin Appelman --- .../lib/Lib/Storage/AmazonS3.php | 7 ++- apps/files_external/lib/Lib/Storage/FTP.php | 7 ++- apps/files_external/lib/Lib/Storage/SFTP.php | 7 ++- apps/files_external/lib/Lib/Storage/SMB.php | 26 +++++++++- apps/files_external/lib/Lib/Storage/Swift.php | 7 ++- apps/files_sharing/lib/External/Storage.php | 7 ++- apps/files_sharing/lib/SharedStorage.php | 38 +++++++++++++- core/Command/Info/FileUtils.php | 50 ++++--------------- .../ObjectStore/HomeObjectStoreStorage.php | 7 ++- lib/private/Files/Storage/DAV.php | 7 ++- lib/private/Files/Storage/Home.php | 4 ++ lib/private/Files/Storage/Local.php | 7 ++- .../Files/Storage/IStorageDebugInfo.php | 33 ++++++++++++ 13 files changed, 157 insertions(+), 50 deletions(-) create mode 100644 lib/public/Files/Storage/IStorageDebugInfo.php diff --git a/apps/files_external/lib/Lib/Storage/AmazonS3.php b/apps/files_external/lib/Lib/Storage/AmazonS3.php index e5fa98313d5..838d2fe94fb 100644 --- a/apps/files_external/lib/Lib/Storage/AmazonS3.php +++ b/apps/files_external/lib/Lib/Storage/AmazonS3.php @@ -49,12 +49,13 @@ use OCP\Cache\CappedMemoryCache; use OCP\Constants; use OCP\Files\FileInfo; use OCP\Files\IMimeTypeDetector; +use OCP\Files\Storage\IStorageDebugInfo; use OCP\ICache; use OCP\ICacheFactory; use OCP\Server; use Psr\Log\LoggerInterface; -class AmazonS3 extends \OC\Files\Storage\Common { +class AmazonS3 extends \OC\Files\Storage\Common implements IStorageDebugInfo { use S3ConnectionTrait; use S3ObjectTrait; @@ -787,4 +788,8 @@ class AmazonS3 extends \OC\Files\Storage\Common { return true; } } + + function debugInfo(): string { + return "s3 bucket {$this->bucket}"; + } } diff --git a/apps/files_external/lib/Lib/Storage/FTP.php b/apps/files_external/lib/Lib/Storage/FTP.php index 72b97f5a42f..ff21c4f0c10 100644 --- a/apps/files_external/lib/Lib/Storage/FTP.php +++ b/apps/files_external/lib/Lib/Storage/FTP.php @@ -28,10 +28,11 @@ use OC\Files\Storage\Common; use OC\Files\Storage\PolyFill\CopyDirectory; use OCP\Constants; use OCP\Files\FileInfo; +use OCP\Files\Storage\IStorageDebugInfo; use OCP\Files\StorageNotAvailableException; use Psr\Log\LoggerInterface; -class FTP extends Common { +class FTP extends Common implements IStorageDebugInfo { use CopyDirectory; private $root; @@ -377,4 +378,8 @@ class FTP extends Common { yield $data; } } + + function debugInfo(): string { + return "ftp share {$this->username}@{$this->host}/{$this->root}"; + } } diff --git a/apps/files_external/lib/Lib/Storage/SFTP.php b/apps/files_external/lib/Lib/Storage/SFTP.php index 3fa04209fa0..a45093dbc98 100644 --- a/apps/files_external/lib/Lib/Storage/SFTP.php +++ b/apps/files_external/lib/Lib/Storage/SFTP.php @@ -43,13 +43,14 @@ use OC\Files\Storage\Common; use OCP\Constants; use OCP\Files\FileInfo; use OCP\Files\IMimeTypeDetector; +use OCP\Files\Storage\IStorageDebugInfo; use phpseclib\Net\SFTP\Stream; /** * Uses phpseclib's Net\SFTP class and the Net\SFTP\Stream stream wrapper to * provide access to SFTP servers. */ -class SFTP extends Common { +class SFTP extends Common implements IStorageDebugInfo { private $host; private $user; private $root; @@ -584,4 +585,8 @@ class SFTP extends Common { $keys = ['size', 'mtime', 'mimetype', 'etag', 'storage_mtime', 'permissions', 'name']; return array_intersect_key($stat, array_flip($keys)); } + + function debugInfo(): string { + return "sftp share {$this->user}@{$this->host}/{$this->root}"; + } } diff --git a/apps/files_external/lib/Lib/Storage/SMB.php b/apps/files_external/lib/Lib/Storage/SMB.php index 2c0a412d341..b237c66137b 100644 --- a/apps/files_external/lib/Lib/Storage/SMB.php +++ b/apps/files_external/lib/Lib/Storage/SMB.php @@ -37,6 +37,7 @@ namespace OCA\Files_External\Lib\Storage; use Icewind\SMB\ACL; +use Icewind\SMB\AnonymousAuth; use Icewind\SMB\BasicAuth; use Icewind\SMB\Exception\AlreadyExistsException; use Icewind\SMB\Exception\ConnectException; @@ -47,7 +48,9 @@ use Icewind\SMB\Exception\InvalidTypeException; use Icewind\SMB\Exception\NotFoundException; use Icewind\SMB\Exception\OutOfSpaceException; use Icewind\SMB\Exception\TimedOutException; +use Icewind\SMB\IAuth; use Icewind\SMB\IFileInfo; +use Icewind\SMB\KerberosAuth; use Icewind\SMB\Native\NativeServer; use Icewind\SMB\Options; use Icewind\SMB\ServerFactory; @@ -64,11 +67,12 @@ use OCP\Files\Notify\IChange; use OCP\Files\Notify\IRenameChange; use OCP\Files\NotPermittedException; use OCP\Files\Storage\INotifyStorage; +use OCP\Files\Storage\IStorageDebugInfo; use OCP\Files\StorageAuthException; use OCP\Files\StorageNotAvailableException; use Psr\Log\LoggerInterface; -class SMB extends Common implements INotifyStorage { +class SMB extends Common implements INotifyStorage, IStorageDebugInfo { /** * @var \Icewind\SMB\IServer */ @@ -98,10 +102,14 @@ class SMB extends Common implements INotifyStorage { /** @var bool */ protected $checkAcl; + private array $params; + private IAuth $auth; + public function __construct($params) { if (!isset($params['host'])) { throw new \Exception('Invalid configuration, no host provided'); } + $this->params = $params; if (isset($params['auth'])) { $auth = $params['auth']; @@ -133,6 +141,7 @@ class SMB extends Common implements INotifyStorage { } } $serverFactory = new ServerFactory($options); + $this->auth = $auth; $this->server = $serverFactory->createServer($params['host'], $auth); $this->share = $this->server->getShare(trim($params['share'], '/')); @@ -782,4 +791,19 @@ class SMB extends Common implements INotifyStorage { $shareNotifyHandler = $this->share->notify($this->buildPath($path)); return new SMBNotifyHandler($shareNotifyHandler, $this->root); } + + public function debugInfo(): string { + $share = "//{$this->server->getHost()}/{$this->share->getName()}{$this->root}"; + if (isset($this->params['user'])) { + $share = "{$this->params['user']}@$share"; + } + if ($this->auth instanceof KerberosAuth) { + $auth = "kerberos"; + } else if ($this->auth instanceof AnonymousAuth) { + $auth = "anonymous"; + } else { + $auth = "password"; + } + return "SMB share $share using $auth authentication"; + } } diff --git a/apps/files_external/lib/Lib/Storage/Swift.php b/apps/files_external/lib/Lib/Storage/Swift.php index 19c83b29bc8..aca6b9c60cb 100644 --- a/apps/files_external/lib/Lib/Storage/Swift.php +++ b/apps/files_external/lib/Lib/Storage/Swift.php @@ -47,12 +47,13 @@ use Icewind\Streams\CallbackWrapper; use Icewind\Streams\IteratorDirectory; use OC\Files\ObjectStore\SwiftFactory; use OCP\Files\IMimeTypeDetector; +use OCP\Files\Storage\IStorageDebugInfo; use OCP\Files\StorageBadConfigException; use OpenStack\Common\Error\BadResponseError; use OpenStack\ObjectStore\v1\Models\StorageObject; use Psr\Log\LoggerInterface; -class Swift extends \OC\Files\Storage\Common { +class Swift extends \OC\Files\Storage\Common implements IStorageDebugInfo { /** @var SwiftFactory */ private $connectionFactory; /** @@ -627,4 +628,8 @@ class Swift extends \OC\Files\Storage\Common { public static function checkDependencies() { return true; } + + function debugInfo(): string { + return "swift bucket {$this->bucket}"; + } } diff --git a/apps/files_sharing/lib/External/Storage.php b/apps/files_sharing/lib/External/Storage.php index 7b64690d53e..81194949969 100644 --- a/apps/files_sharing/lib/External/Storage.php +++ b/apps/files_sharing/lib/External/Storage.php @@ -48,6 +48,7 @@ use OCP\Federation\ICloudId; use OCP\Files\NotFoundException; use OCP\Files\Storage\IDisableEncryptionStorage; use OCP\Files\Storage\IReliableEtagStorage; +use OCP\Files\Storage\IStorageDebugInfo; use OCP\Files\StorageInvalidException; use OCP\Files\StorageNotAvailableException; use OCP\Http\Client\IClientService; @@ -60,7 +61,7 @@ use OCP\OCM\IOCMDiscoveryService; use OCP\Server; use Psr\Log\LoggerInterface; -class Storage extends DAV implements ISharedStorage, IDisableEncryptionStorage, IReliableEtagStorage { +class Storage extends DAV implements ISharedStorage, IDisableEncryptionStorage, IReliableEtagStorage, IStorageDebugInfo { private ICloudId $cloudId; private string $mountPoint; private string $token; @@ -453,4 +454,8 @@ class Storage extends DAV implements ISharedStorage, IDisableEncryptionStorage, public function free_space($path) { return parent::free_space(""); } + + function debugInfo(): string { + return "external share from {$this->getRemoteUser()}@{$this->getRemote()}"; + } } diff --git a/apps/files_sharing/lib/SharedStorage.php b/apps/files_sharing/lib/SharedStorage.php index de49e3c4294..5b6604269d9 100644 --- a/apps/files_sharing/lib/SharedStorage.php +++ b/apps/files_sharing/lib/SharedStorage.php @@ -52,6 +52,7 @@ use OCP\Files\Node; use OCP\Files\NotFoundException; use OCP\Files\Storage\IDisableEncryptionStorage; use OCP\Files\Storage\IStorage; +use OCP\Files\Storage\IStorageDebugInfo; use OCP\Lock\ILockingProvider; use OCP\Share\IShare; use Psr\Log\LoggerInterface; @@ -59,7 +60,7 @@ use Psr\Log\LoggerInterface; /** * Convert target path to source path and pass the function call to the correct storage provider */ -class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage, IDisableEncryptionStorage { +class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage, IDisableEncryptionStorage, IStorageDebugInfo { /** @var \OCP\Share\IShare */ private $superShare; @@ -562,4 +563,39 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto $this->init(); return parent::getUnjailedPath($path); } + + function debugInfo(): string { + $share = $this->getShare(); + $shares = $this->groupedShares; + $sharedBy = array_map(function (IShare $share) { + $shareType = $this->formatShareType($share); + if ($shareType) { + return $share->getSharedBy() . " (via " . $shareType . " " . $share->getSharedWith() . ")"; + } else { + return $share->getSharedBy(); + } + }, $shares); + $description = "shared by " . implode(', ', $sharedBy); + if ($share->getSharedBy() !== $share->getShareOwner()) { + $description .= " owned by " . $share->getShareOwner(); + } + return $description; + } + + private function formatShareType(IShare $share): ?string { + switch ($share->getShareType()) { + case IShare::TYPE_GROUP: + return "group"; + case IShare::TYPE_CIRCLE: + return "circle"; + case IShare::TYPE_DECK: + return "deck"; + case IShare::TYPE_ROOM: + return "room"; + case IShare::TYPE_USER: + return null; + default: + return "Unknown (" . $share->getShareType() . ")"; + } + } } diff --git a/core/Command/Info/FileUtils.php b/core/Command/Info/FileUtils.php index 694f30f78b4..5ab03ca1732 100644 --- a/core/Command/Info/FileUtils.php +++ b/core/Command/Info/FileUtils.php @@ -36,6 +36,7 @@ use OCP\Files\IRootFolder; use OCP\Files\Mount\IMountPoint; use OCP\Files\Node; use OCP\Files\NotFoundException; +use OCP\Files\Storage\IStorageDebugInfo; use OCP\Share\IShare; use OCP\Util; use Symfony\Component\Console\Output\OutputInterface; @@ -123,48 +124,17 @@ class FileUtils { */ public function formatMountType(IMountPoint $mountPoint): string { $storage = $mountPoint->getStorage(); - if ($storage && $storage->instanceOfStorage(IHomeStorage::class)) { - return "home storage"; - } elseif ($mountPoint instanceof SharedMount) { - $share = $mountPoint->getShare(); - $shares = $mountPoint->getGroupedShares(); - $sharedBy = array_map(function (IShare $share) { - $shareType = $this->formatShareType($share); - if ($shareType) { - return $share->getSharedBy() . " (via " . $shareType . " " . $share->getSharedWith() . ")"; - } else { - return $share->getSharedBy(); - } - }, $shares); - $description = "shared by " . implode(', ', $sharedBy); - if ($share->getSharedBy() !== $share->getShareOwner()) { - $description .= " owned by " . $share->getShareOwner(); - } - return $description; - } elseif ($mountPoint instanceof GroupMountPoint) { - return "groupfolder " . $mountPoint->getFolderId(); - } elseif ($mountPoint instanceof ExternalMountPoint) { - return "external storage " . $mountPoint->getStorageConfig()->getId(); + + if ($mountPoint instanceof ExternalMountPoint) { + $prefix = "external storage " . $mountPoint->getStorageConfig()->getId() . ": "; } elseif ($mountPoint instanceof CircleMount) { - return "circle"; + $prefix = "circle: "; } - return get_class($mountPoint); - } - - public function formatShareType(IShare $share): ?string { - switch ($share->getShareType()) { - case IShare::TYPE_GROUP: - return "group"; - case IShare::TYPE_CIRCLE: - return "circle"; - case IShare::TYPE_DECK: - return "deck"; - case IShare::TYPE_ROOM: - return "room"; - case IShare::TYPE_USER: - return null; - default: - return "Unknown (" . $share->getShareType() . ")"; + if ($storage->instanceOfStorage(IStorageDebugInfo::class)) { + /** @var IStorageDebugInfo $storage */ + return $prefix . $storage->debugInfo(); + } else { + return $prefix . get_class($mountPoint); } } diff --git a/lib/private/Files/ObjectStore/HomeObjectStoreStorage.php b/lib/private/Files/ObjectStore/HomeObjectStoreStorage.php index b361249ff47..4bcdf6732f5 100644 --- a/lib/private/Files/ObjectStore/HomeObjectStoreStorage.php +++ b/lib/private/Files/ObjectStore/HomeObjectStoreStorage.php @@ -26,9 +26,10 @@ namespace OC\Files\ObjectStore; use OC\User\User; +use OCP\Files\Storage\IStorageDebugInfo; use OCP\IUser; -class HomeObjectStoreStorage extends ObjectStoreStorage implements \OCP\Files\IHomeStorage { +class HomeObjectStoreStorage extends ObjectStoreStorage implements \OCP\Files\IHomeStorage, IStorageDebugInfo { /** * The home user storage requires a user object to create a unique storage id * @param array $params @@ -65,4 +66,8 @@ class HomeObjectStoreStorage extends ObjectStoreStorage implements \OCP\Files\IH public function getUser($path = null): IUser { return $this->user; } + + public function debugInfo(): string { + return "Home storage for {$this->user->getUID()} in {$this->getObjectStore()->getStorageId()} object store"; + } } diff --git a/lib/private/Files/Storage/DAV.php b/lib/private/Files/Storage/DAV.php index 35add2c606b..8f82bcb19cd 100644 --- a/lib/private/Files/Storage/DAV.php +++ b/lib/private/Files/Storage/DAV.php @@ -48,6 +48,7 @@ use OCP\Diagnostics\IEventLogger; use OCP\Files\FileInfo; use OCP\Files\ForbiddenException; use OCP\Files\IMimeTypeDetector; +use OCP\Files\Storage\IStorageDebugInfo; use OCP\Files\StorageInvalidException; use OCP\Files\StorageNotAvailableException; use OCP\Http\Client\IClientService; @@ -67,7 +68,7 @@ use Sabre\HTTP\RequestInterface; * * @package OC\Files\Storage */ -class DAV extends Common { +class DAV extends Common implements IStorageDebugInfo { /** @var string */ protected $password; /** @var string */ @@ -931,4 +932,8 @@ class DAV extends Common { $this->convertException($e, $directory); } } + + function debugInfo(): string { + return "webdav share {$this->user}@{$this->host}/{$this->root}"; + } } diff --git a/lib/private/Files/Storage/Home.php b/lib/private/Files/Storage/Home.php index 5100b15215b..3210d401fb3 100644 --- a/lib/private/Files/Storage/Home.php +++ b/lib/private/Files/Storage/Home.php @@ -108,4 +108,8 @@ class Home extends Local implements \OCP\Files\IHomeStorage { public function getOwner($path) { return $this->user->getUID(); } + + public function debugInfo(): string { + return "Home storage for {$this->user->getUID()} at {$this->getSourcePath('')}"; + } } diff --git a/lib/private/Files/Storage/Local.php b/lib/private/Files/Storage/Local.php index 0fca853da59..b427490b13f 100644 --- a/lib/private/Files/Storage/Local.php +++ b/lib/private/Files/Storage/Local.php @@ -52,6 +52,7 @@ use OCP\Files\GenericFileException; use OCP\Files\IMimeTypeDetector; use OCP\Files\Storage\IStorage; use OCP\Files\StorageNotAvailableException; +use OCP\Files\Storage\IStorageDebugInfo; use OCP\IConfig; use OCP\Util; use Psr\Log\LoggerInterface; @@ -59,7 +60,7 @@ use Psr\Log\LoggerInterface; /** * for local filestore, we only have to map the paths */ -class Local extends \OC\Files\Storage\Common { +class Local extends \OC\Files\Storage\Common implements IStorageDebugInfo { protected $datadir; protected $dataDirLength; @@ -650,4 +651,8 @@ class Local extends \OC\Files\Storage\Common { return $result; } } + + public function debugInfo(): string { + return "Local storage rooted at " . $this->datadir; + } } diff --git a/lib/public/Files/Storage/IStorageDebugInfo.php b/lib/public/Files/Storage/IStorageDebugInfo.php new file mode 100644 index 00000000000..fbc1bf833a7 --- /dev/null +++ b/lib/public/Files/Storage/IStorageDebugInfo.php @@ -0,0 +1,33 @@ + + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCP\Files\Storage; + +interface IStorageDebugInfo { + /** + * Provide a human-readable description of the storage intended as debug information + * + * @return string + */ + function debugInfo(): string; +} -- 2.39.5