Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/files_external/appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ External storage can be configured using the GUI or at the command line. This se
<command>OCA\Files_External\Command\Verify</command>
<command>OCA\Files_External\Command\Notify</command>
<command>OCA\Files_External\Command\Scan</command>
<command>OCA\Files_External\Command\Dependencies</command>
</commands>

<settings>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'OCA\\Files_External\\Command\\Config' => $baseDir . '/../lib/Command/Config.php',
'OCA\\Files_External\\Command\\Create' => $baseDir . '/../lib/Command/Create.php',
'OCA\\Files_External\\Command\\Delete' => $baseDir . '/../lib/Command/Delete.php',
'OCA\\Files_External\\Command\\Dependencies' => $baseDir . '/../lib/Command/Dependencies.php',
'OCA\\Files_External\\Command\\Export' => $baseDir . '/../lib/Command/Export.php',
'OCA\\Files_External\\Command\\Import' => $baseDir . '/../lib/Command/Import.php',
'OCA\\Files_External\\Command\\ListCommand' => $baseDir . '/../lib/Command/ListCommand.php',
Expand Down
1 change: 1 addition & 0 deletions apps/files_external/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class ComposerStaticInitFiles_External
'OCA\\Files_External\\Command\\Config' => __DIR__ . '/..' . '/../lib/Command/Config.php',
'OCA\\Files_External\\Command\\Create' => __DIR__ . '/..' . '/../lib/Command/Create.php',
'OCA\\Files_External\\Command\\Delete' => __DIR__ . '/..' . '/../lib/Command/Delete.php',
'OCA\\Files_External\\Command\\Dependencies' => __DIR__ . '/..' . '/../lib/Command/Dependencies.php',
'OCA\\Files_External\\Command\\Export' => __DIR__ . '/..' . '/../lib/Command/Export.php',
'OCA\\Files_External\\Command\\Import' => __DIR__ . '/..' . '/../lib/Command/Import.php',
'OCA\\Files_External\\Command\\ListCommand' => __DIR__ . '/..' . '/../lib/Command/ListCommand.php',
Expand Down
56 changes: 56 additions & 0 deletions apps/files_external/lib/Command/Dependencies.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Files_External\Command;

use OC\Core\Command\Base;
use OCA\Files_External\Service\BackendService;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class Dependencies extends Base {
public function __construct(
private readonly BackendService $backendService,
) {
parent::__construct();
}

protected function configure(): void {
$this
->setName('files_external:dependencies')
->setDescription('Show information about the backend dependencies');
parent::configure();
}

protected function execute(InputInterface $input, OutputInterface $output): int {
$storageBackends = $this->backendService->getBackends();

$anyMissing = false;

foreach ($storageBackends as $backend) {
if ($backend->getDeprecateTo() !== null) {
continue;
}
$missingDependencies = $backend->checkDependencies();
if ($missingDependencies) {
$anyMissing = true;
$output->writeln($backend->getText() . ':');
foreach ($missingDependencies as $missingDependency) {
if ($missingDependency->getMessage()) {
$output->writeln(" - <comment>{$missingDependency->getDependency()}</comment>: {$missingDependency->getMessage()}");
} else {
$output->writeln(" - <comment>{$missingDependency->getDependency()}</comment>");
}
}
}
}

if (!$anyMissing) {
$output->writeln('<info>All dependencies are met</info>');
}

return self::SUCCESS;
}
}
23 changes: 20 additions & 3 deletions apps/files_external/lib/Lib/Backend/SMB.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,20 @@
use Icewind\SMB\BasicAuth;
use Icewind\SMB\KerberosApacheAuth;
use Icewind\SMB\KerberosAuth;
use Icewind\SMB\Native\NativeServer;
use Icewind\SMB\Wrapped\Server;
use OCA\Files_External\Lib\Auth\AuthMechanism;
use OCA\Files_External\Lib\Auth\Password\Password;
use OCA\Files_External\Lib\Auth\SMB\KerberosApacheAuth as KerberosApacheAuthMechanism;
use OCA\Files_External\Lib\DefinitionParameter;
use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException;
use OCA\Files_External\Lib\LegacyDependencyCheckPolyfill;
use OCA\Files_External\Lib\MissingDependency;
use OCA\Files_External\Lib\Storage\SystemBridge;
use OCA\Files_External\Lib\StorageConfig;
use OCP\IL10N;
use OCP\IUser;

class SMB extends Backend {
use LegacyDependencyCheckPolyfill;

public function __construct(IL10N $l, Password $legacyAuth) {
$this
->setIdentifier('smb')
Expand Down Expand Up @@ -122,4 +123,20 @@ public function manipulateStorageConfig(StorageConfig &$storage, ?IUser $user =

$storage->setBackendOption('auth', $smbAuth);
}

public function checkDependencies() {
$system = \OCP\Server::get(SystemBridge::class);
if (NativeServer::available($system)) {
return [];
} elseif (Server::available($system)) {
$missing = new MissingDependency('php-smbclient');
$missing->setOptional(true);
$missing->setMessage('The php-smbclient library provides improved compatibility and performance for SMB storages.');
return [$missing];
} else {
$missing = new MissingDependency('php-smbclient');
$missing->setMessage('Either the php-smbclient library (preferred) or the smbclient binary is required for SMB storages.');
return [$missing, new MissingDependency('smbclient')];
}
}
}
13 changes: 11 additions & 2 deletions apps/files_external/lib/Lib/MissingDependency.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@
class MissingDependency {

/** @var string|null Custom message */
private $message = null;
private ?string $message = null;
private bool $optional = false;

/**
* @param string $dependency
*/
public function __construct(
private $dependency,
private readonly string $dependency,
) {
}

Expand All @@ -38,4 +39,12 @@ public function setMessage($message) {
$this->message = $message;
return $this;
}

public function isOptional(): bool {
return $this->optional;
}

public function setOptional(bool $optional): void {
$this->optional = $optional;
}
}
4 changes: 3 additions & 1 deletion apps/files_external/lib/Service/BackendService.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use OCA\Files_External\Lib\Backend\Backend;
use OCA\Files_External\Lib\Config\IAuthMechanismProvider;
use OCA\Files_External\Lib\Config\IBackendProvider;
use OCA\Files_External\Lib\MissingDependency;
use OCP\EventDispatcher\GenericEvent;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IConfig;
Expand Down Expand Up @@ -193,7 +194,8 @@ public function getBackends() {
*/
public function getAvailableBackends() {
return array_filter($this->getBackends(), function ($backend) {
return !$backend->checkDependencies();
$missing = array_filter($backend->checkDependencies(), fn (MissingDependency $dependency) => !$dependency->isOptional());
return count($missing) === 0;
});
}

Expand Down
Loading