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
22 changes: 19 additions & 3 deletions apps/files_external/lib/Lib/Storage/SMB.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
use OCP\Files\Notify\IChange;
use OCP\Files\Notify\IRenameChange;
use OCP\Files\Storage\INotifyStorage;
use OCP\Files\StorageAuthException;
use OCP\Files\StorageNotAvailableException;
use OCP\ILogger;

Expand Down Expand Up @@ -160,7 +161,7 @@ protected function relativePath($fullPath) {
/**
* @param string $path
* @return \Icewind\SMB\IFileInfo
* @throws StorageNotAvailableException
* @throws StorageAuthException
*/
protected function getFileInfo($path) {
try {
Expand All @@ -170,11 +171,26 @@ protected function getFileInfo($path) {
}
return $this->statCache[$path];
} catch (ConnectException $e) {
$this->logger->logException($e, ['message' => 'Error while getting file info']);
throw new StorageNotAvailableException($e->getMessage(), $e->getCode(), $e);
$this->throwUnavailable($e);
} catch (ForbiddenException $e) {
// with php-smbclient, this exceptions is thrown when the provided password is invalid.
// Possible is also ForbiddenException with a different error code, so we check it.
if($e->getCode() === 1) {
$this->throwUnavailable($e);
}
throw $e;
}
}

/**
* @param \Exception $e
* @throws StorageAuthException
*/
protected function throwUnavailable(\Exception $e) {
$this->logger->logException($e, ['message' => 'Error while getting file info']);
throw new StorageAuthException($e->getMessage(), $e);
}

/**
* @param string $path
* @return \Icewind\SMB\IFileInfo[]
Expand Down
11 changes: 11 additions & 0 deletions config/config.sample.php
Original file line number Diff line number Diff line change
Expand Up @@ -1480,6 +1480,17 @@
*/
'quota_include_external_storage' => false,

/**
* When an external storage is unavailable for some reasons, it will be flagged
* as such for 10 minutes. When the trigger is a failed authentication attempt
* the delay is higher and can be controlled with this option. The motivation
* is to make account lock outs at Active Directories (and compatible) more
* unlikely.
*
* Defaults to ``1800`` (seconds)
*/
'external_storage.auth_availability_delay' => 1800,

/**
* Specifies how often the local filesystem (the Nextcloud data/ directory, and
* NFS mounts in data/) is checked for changes made outside Nextcloud. This
Expand Down
5 changes: 3 additions & 2 deletions lib/private/Files/Cache/Storage.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,12 @@ public function getAvailability() {

/**
* @param bool $isAvailable
* @param int $delay amount of seconds to delay reconsidering that storage further
*/
public function setAvailability($isAvailable) {
public function setAvailability($isAvailable, int $delay = 0) {
$sql = 'UPDATE `*PREFIX*storages` SET `available` = ?, `last_checked` = ? WHERE `id` = ?';
$available = $isAvailable ? 1 : 0;
\OC_DB::executeAudited($sql, array($available, time(), $this->storageId));
\OC_DB::executeAudited($sql, [$available, time() + $delay, $this->storageId]);
}

/**
Expand Down
Loading