Browse Source

Merge pull request #27538 from nextcloud/scanner-home-not-writable-better-errors

better error messages if the users home is not writable during scanning
Côme Chilliet 1 year ago
parent
commit
e63a6f5cdb
2 changed files with 21 additions and 7 deletions
  1. 1 0
      apps/files/lib/Command/Scan.php
  2. 20 7
      lib/private/Files/Utils/Scanner.php

+ 1 - 0
apps/files/lib/Command/Scan.php

@@ -162,6 +162,7 @@ class Scan extends Base {
 			}
 		} catch (ForbiddenException $e) {
 			$output->writeln("<error>Home storage for user $user not writable or 'files' subdirectory missing</error>");
+			$output->writeln('  ' . $e->getMessage());
 			$output->writeln('Make sure you\'re running the scan command only as the user the web server runs as');
 		} catch (InterruptedException $e) {
 			# exit the function if ctrl-c has been pressed

+ 20 - 7
lib/private/Files/Utils/Scanner.php

@@ -27,11 +27,13 @@
  * along with this program. If not, see <http://www.gnu.org/licenses/>
  *
  */
+
 namespace OC\Files\Utils;
 
 use OC\Files\Cache\Cache;
 use OC\Files\Filesystem;
 use OC\Files\Storage\FailedStorage;
+use OC\Files\Storage\Home;
 use OC\ForbiddenException;
 use OC\Hooks\PublicEmitter;
 use OC\Lock\DBLockingProvider;
@@ -211,13 +213,24 @@ class Scanner extends PublicEmitter {
 			}
 
 			// if the home storage isn't writable then the scanner is run as the wrong user
-			if ($storage->instanceOfStorage('\OC\Files\Storage\Home') and
-				(!$storage->isCreatable('') or !$storage->isCreatable('files'))
-			) {
-				if ($storage->is_dir('files')) {
-					throw new ForbiddenException();
-				} else {// if the root exists in neither the cache nor the storage the user isn't setup yet
-					break;
+			if ($storage->instanceOfStorage(Home::class)) {
+				/** @var Home $storage */
+				foreach (['', 'files'] as $path) {
+					if (!$storage->isCreatable($path)) {
+						$fullPath = $storage->getSourcePath($path);
+						if (!$storage->is_dir($path) && $storage->getCache()->inCache($path)) {
+							throw new NotFoundException("User folder $fullPath exists in cache but not on disk");
+						} elseif ($storage->is_dir($path)) {
+							$ownerUid = fileowner($fullPath);
+							$owner = posix_getpwuid($ownerUid);
+							$owner = $owner['name'] ?? $ownerUid;
+							$permissions = decoct(fileperms($fullPath));
+							throw new ForbiddenException("User folder $fullPath is not writable, folders is owned by $owner and has mode $permissions");
+						} else {
+							// if the root exists in neither the cache nor the storage the user isn't setup yet
+							break 2;
+						}
+					}
 				}
 			}