Passed
Push — master ( 615cf6...cbbbbe )
by Morris
13:19 queued 12s
created
apps/files_external/lib/Config/ConfigAdapter.php 1 patch
Indentation   +138 added lines, -138 removed lines patch added patch discarded remove patch
@@ -48,142 +48,142 @@
 block discarded – undo
48 48
  */
49 49
 class ConfigAdapter implements IMountProvider {
50 50
 
51
-	/** @var UserStoragesService */
52
-	private $userStoragesService;
53
-
54
-	/** @var UserGlobalStoragesService */
55
-	private $userGlobalStoragesService;
56
-	/** @var StorageMigrator  */
57
-	private $migrator;
58
-
59
-	/**
60
-	 * @param UserStoragesService $userStoragesService
61
-	 * @param UserGlobalStoragesService $userGlobalStoragesService
62
-	 * @param StorageMigrator $migrator
63
-	 */
64
-	public function __construct(
65
-		UserStoragesService $userStoragesService,
66
-		UserGlobalStoragesService $userGlobalStoragesService,
67
-		StorageMigrator $migrator
68
-	) {
69
-		$this->userStoragesService = $userStoragesService;
70
-		$this->userGlobalStoragesService = $userGlobalStoragesService;
71
-		$this->migrator = $migrator;
72
-	}
73
-
74
-	/**
75
-	 * Process storage ready for mounting
76
-	 *
77
-	 * @param StorageConfig $storage
78
-	 * @param IUser $user
79
-	 * @throws \OCP\AppFramework\QueryException
80
-	 */
81
-	private function prepareStorageConfig(StorageConfig &$storage, IUser $user) {
82
-		foreach ($storage->getBackendOptions() as $option => $value) {
83
-			$storage->setBackendOption($option, \OCA\Files_External\MountConfig::substitutePlaceholdersInConfig($value, $user->getUID()));
84
-		}
85
-
86
-		$objectStore = $storage->getBackendOption('objectstore');
87
-		if ($objectStore) {
88
-			$objectClass = $objectStore['class'];
89
-			if (!is_subclass_of($objectClass, '\OCP\Files\ObjectStore\IObjectStore')) {
90
-				throw new \InvalidArgumentException('Invalid object store');
91
-			}
92
-			$storage->setBackendOption('objectstore', new $objectClass($objectStore));
93
-		}
94
-
95
-		$storage->getAuthMechanism()->manipulateStorageConfig($storage, $user);
96
-		$storage->getBackend()->manipulateStorageConfig($storage, $user);
97
-	}
98
-
99
-	/**
100
-	 * Construct the storage implementation
101
-	 *
102
-	 * @param StorageConfig $storageConfig
103
-	 * @return Storage
104
-	 */
105
-	private function constructStorage(StorageConfig $storageConfig) {
106
-		$class = $storageConfig->getBackend()->getStorageClass();
107
-		$storage = new $class($storageConfig->getBackendOptions());
108
-
109
-		// auth mechanism should fire first
110
-		$storage = $storageConfig->getBackend()->wrapStorage($storage);
111
-		$storage = $storageConfig->getAuthMechanism()->wrapStorage($storage);
112
-
113
-		return $storage;
114
-	}
115
-
116
-	/**
117
-	 * Get all mountpoints applicable for the user
118
-	 *
119
-	 * @param \OCP\IUser $user
120
-	 * @param \OCP\Files\Storage\IStorageFactory $loader
121
-	 * @return \OCP\Files\Mount\IMountPoint[]
122
-	 */
123
-	public function getMountsForUser(IUser $user, IStorageFactory $loader) {
124
-		$this->migrator->migrateUser($user);
125
-
126
-		$this->userStoragesService->setUser($user);
127
-		$this->userGlobalStoragesService->setUser($user);
128
-
129
-		$storageConfigs = $this->userGlobalStoragesService->getAllStoragesForUser();
130
-
131
-		$storages = array_map(function (StorageConfig $storageConfig) use ($user) {
132
-			try {
133
-				$this->prepareStorageConfig($storageConfig, $user);
134
-				return $this->constructStorage($storageConfig);
135
-			} catch (\Exception $e) {
136
-				// propagate exception into filesystem
137
-				return new FailedStorage(['exception' => $e]);
138
-			}
139
-		}, $storageConfigs);
140
-
141
-
142
-		\OC\Files\Cache\Storage::getGlobalCache()->loadForStorageIds(array_map(function (Storage\IStorage $storage) {
143
-			return $storage->getId();
144
-		}, $storages));
145
-
146
-		$availableStorages = array_map(function (Storage\IStorage $storage, StorageConfig $storageConfig) {
147
-			try {
148
-				$availability = $storage->getAvailability();
149
-				if (!$availability['available'] && !Availability::shouldRecheck($availability)) {
150
-					$storage = new FailedStorage([
151
-						'exception' => new StorageNotAvailableException('Storage with mount id ' . $storageConfig->getId() . ' is not available')
152
-					]);
153
-				}
154
-			} catch (\Exception $e) {
155
-				// propagate exception into filesystem
156
-				$storage = new FailedStorage(['exception' => $e]);
157
-			}
158
-			return $storage;
159
-		}, $storages, $storageConfigs);
160
-
161
-		$mounts = array_map(function (StorageConfig $storageConfig, Storage\IStorage $storage) use ($user, $loader) {
162
-			if ($storageConfig->getType() === StorageConfig::MOUNT_TYPE_PERSONAl) {
163
-				return new PersonalMount(
164
-					$this->userStoragesService,
165
-					$storageConfig->getId(),
166
-					$storage,
167
-					'/' . $user->getUID() . '/files' . $storageConfig->getMountPoint(),
168
-					null,
169
-					$loader,
170
-					$storageConfig->getMountOptions()
171
-				);
172
-			} else {
173
-				return new ExternalMountPoint(
174
-					$storage,
175
-					'/' . $user->getUID() . '/files' . $storageConfig->getMountPoint(),
176
-					null,
177
-					$loader,
178
-					$storageConfig->getMountOptions(),
179
-					$storageConfig->getId()
180
-				);
181
-			}
182
-		}, $storageConfigs, $availableStorages);
183
-
184
-		$this->userStoragesService->resetUser();
185
-		$this->userGlobalStoragesService->resetUser();
186
-
187
-		return $mounts;
188
-	}
51
+    /** @var UserStoragesService */
52
+    private $userStoragesService;
53
+
54
+    /** @var UserGlobalStoragesService */
55
+    private $userGlobalStoragesService;
56
+    /** @var StorageMigrator  */
57
+    private $migrator;
58
+
59
+    /**
60
+     * @param UserStoragesService $userStoragesService
61
+     * @param UserGlobalStoragesService $userGlobalStoragesService
62
+     * @param StorageMigrator $migrator
63
+     */
64
+    public function __construct(
65
+        UserStoragesService $userStoragesService,
66
+        UserGlobalStoragesService $userGlobalStoragesService,
67
+        StorageMigrator $migrator
68
+    ) {
69
+        $this->userStoragesService = $userStoragesService;
70
+        $this->userGlobalStoragesService = $userGlobalStoragesService;
71
+        $this->migrator = $migrator;
72
+    }
73
+
74
+    /**
75
+     * Process storage ready for mounting
76
+     *
77
+     * @param StorageConfig $storage
78
+     * @param IUser $user
79
+     * @throws \OCP\AppFramework\QueryException
80
+     */
81
+    private function prepareStorageConfig(StorageConfig &$storage, IUser $user) {
82
+        foreach ($storage->getBackendOptions() as $option => $value) {
83
+            $storage->setBackendOption($option, \OCA\Files_External\MountConfig::substitutePlaceholdersInConfig($value, $user->getUID()));
84
+        }
85
+
86
+        $objectStore = $storage->getBackendOption('objectstore');
87
+        if ($objectStore) {
88
+            $objectClass = $objectStore['class'];
89
+            if (!is_subclass_of($objectClass, '\OCP\Files\ObjectStore\IObjectStore')) {
90
+                throw new \InvalidArgumentException('Invalid object store');
91
+            }
92
+            $storage->setBackendOption('objectstore', new $objectClass($objectStore));
93
+        }
94
+
95
+        $storage->getAuthMechanism()->manipulateStorageConfig($storage, $user);
96
+        $storage->getBackend()->manipulateStorageConfig($storage, $user);
97
+    }
98
+
99
+    /**
100
+     * Construct the storage implementation
101
+     *
102
+     * @param StorageConfig $storageConfig
103
+     * @return Storage
104
+     */
105
+    private function constructStorage(StorageConfig $storageConfig) {
106
+        $class = $storageConfig->getBackend()->getStorageClass();
107
+        $storage = new $class($storageConfig->getBackendOptions());
108
+
109
+        // auth mechanism should fire first
110
+        $storage = $storageConfig->getBackend()->wrapStorage($storage);
111
+        $storage = $storageConfig->getAuthMechanism()->wrapStorage($storage);
112
+
113
+        return $storage;
114
+    }
115
+
116
+    /**
117
+     * Get all mountpoints applicable for the user
118
+     *
119
+     * @param \OCP\IUser $user
120
+     * @param \OCP\Files\Storage\IStorageFactory $loader
121
+     * @return \OCP\Files\Mount\IMountPoint[]
122
+     */
123
+    public function getMountsForUser(IUser $user, IStorageFactory $loader) {
124
+        $this->migrator->migrateUser($user);
125
+
126
+        $this->userStoragesService->setUser($user);
127
+        $this->userGlobalStoragesService->setUser($user);
128
+
129
+        $storageConfigs = $this->userGlobalStoragesService->getAllStoragesForUser();
130
+
131
+        $storages = array_map(function (StorageConfig $storageConfig) use ($user) {
132
+            try {
133
+                $this->prepareStorageConfig($storageConfig, $user);
134
+                return $this->constructStorage($storageConfig);
135
+            } catch (\Exception $e) {
136
+                // propagate exception into filesystem
137
+                return new FailedStorage(['exception' => $e]);
138
+            }
139
+        }, $storageConfigs);
140
+
141
+
142
+        \OC\Files\Cache\Storage::getGlobalCache()->loadForStorageIds(array_map(function (Storage\IStorage $storage) {
143
+            return $storage->getId();
144
+        }, $storages));
145
+
146
+        $availableStorages = array_map(function (Storage\IStorage $storage, StorageConfig $storageConfig) {
147
+            try {
148
+                $availability = $storage->getAvailability();
149
+                if (!$availability['available'] && !Availability::shouldRecheck($availability)) {
150
+                    $storage = new FailedStorage([
151
+                        'exception' => new StorageNotAvailableException('Storage with mount id ' . $storageConfig->getId() . ' is not available')
152
+                    ]);
153
+                }
154
+            } catch (\Exception $e) {
155
+                // propagate exception into filesystem
156
+                $storage = new FailedStorage(['exception' => $e]);
157
+            }
158
+            return $storage;
159
+        }, $storages, $storageConfigs);
160
+
161
+        $mounts = array_map(function (StorageConfig $storageConfig, Storage\IStorage $storage) use ($user, $loader) {
162
+            if ($storageConfig->getType() === StorageConfig::MOUNT_TYPE_PERSONAl) {
163
+                return new PersonalMount(
164
+                    $this->userStoragesService,
165
+                    $storageConfig->getId(),
166
+                    $storage,
167
+                    '/' . $user->getUID() . '/files' . $storageConfig->getMountPoint(),
168
+                    null,
169
+                    $loader,
170
+                    $storageConfig->getMountOptions()
171
+                );
172
+            } else {
173
+                return new ExternalMountPoint(
174
+                    $storage,
175
+                    '/' . $user->getUID() . '/files' . $storageConfig->getMountPoint(),
176
+                    null,
177
+                    $loader,
178
+                    $storageConfig->getMountOptions(),
179
+                    $storageConfig->getId()
180
+                );
181
+            }
182
+        }, $storageConfigs, $availableStorages);
183
+
184
+        $this->userStoragesService->resetUser();
185
+        $this->userGlobalStoragesService->resetUser();
186
+
187
+        return $mounts;
188
+    }
189 189
 }
Please login to merge, or discard this patch.
apps/files_external/lib/Lib/Backend/LegacyBackend.php 1 patch
Indentation   +63 added lines, -63 removed lines patch added patch discarded remove patch
@@ -32,72 +32,72 @@
 block discarded – undo
32 32
  * Legacy compatibility for OCA\Files_External\MountConfig::registerBackend()
33 33
  */
34 34
 class LegacyBackend extends Backend {
35
-	use LegacyDependencyCheckPolyfill {
36
-		LegacyDependencyCheckPolyfill::checkDependencies as doCheckDependencies;
37
-	}
35
+    use LegacyDependencyCheckPolyfill {
36
+        LegacyDependencyCheckPolyfill::checkDependencies as doCheckDependencies;
37
+    }
38 38
 
39
-	/** @var bool */
40
-	protected $hasDependencies = false;
39
+    /** @var bool */
40
+    protected $hasDependencies = false;
41 41
 
42
-	/**
43
-	 * @param string $class
44
-	 * @param array $definition
45
-	 * @param Builtin $authMechanism
46
-	 */
47
-	public function __construct($class, array $definition, Builtin $authMechanism) {
48
-		$this
49
-			->setIdentifier($class)
50
-			->setStorageClass($class)
51
-			->setText($definition['backend'])
52
-			->addAuthScheme(Builtin::SCHEME_BUILTIN)
53
-			->setLegacyAuthMechanism($authMechanism)
54
-		;
42
+    /**
43
+     * @param string $class
44
+     * @param array $definition
45
+     * @param Builtin $authMechanism
46
+     */
47
+    public function __construct($class, array $definition, Builtin $authMechanism) {
48
+        $this
49
+            ->setIdentifier($class)
50
+            ->setStorageClass($class)
51
+            ->setText($definition['backend'])
52
+            ->addAuthScheme(Builtin::SCHEME_BUILTIN)
53
+            ->setLegacyAuthMechanism($authMechanism)
54
+        ;
55 55
 
56
-		foreach ($definition['configuration'] as $name => $placeholder) {
57
-			$flags = DefinitionParameter::FLAG_NONE;
58
-			$type = DefinitionParameter::VALUE_TEXT;
59
-			if ($placeholder[0] === '&') {
60
-				$flags = DefinitionParameter::FLAG_OPTIONAL;
61
-				$placeholder = substr($placeholder, 1);
62
-			}
63
-			switch ($placeholder[0]) {
64
-			case '!':
65
-				$type = DefinitionParameter::VALUE_BOOLEAN;
66
-				$placeholder = substr($placeholder, 1);
67
-				break;
68
-			case '*':
69
-				$type = DefinitionParameter::VALUE_PASSWORD;
70
-				$placeholder = substr($placeholder, 1);
71
-				break;
72
-			case '#':
73
-				$type = DefinitionParameter::VALUE_HIDDEN;
74
-				$placeholder = substr($placeholder, 1);
75
-				break;
76
-			}
77
-			$this->addParameter((new DefinitionParameter($name, $placeholder))
78
-				->setType($type)
79
-				->setFlags($flags)
80
-			);
81
-		}
56
+        foreach ($definition['configuration'] as $name => $placeholder) {
57
+            $flags = DefinitionParameter::FLAG_NONE;
58
+            $type = DefinitionParameter::VALUE_TEXT;
59
+            if ($placeholder[0] === '&') {
60
+                $flags = DefinitionParameter::FLAG_OPTIONAL;
61
+                $placeholder = substr($placeholder, 1);
62
+            }
63
+            switch ($placeholder[0]) {
64
+            case '!':
65
+                $type = DefinitionParameter::VALUE_BOOLEAN;
66
+                $placeholder = substr($placeholder, 1);
67
+                break;
68
+            case '*':
69
+                $type = DefinitionParameter::VALUE_PASSWORD;
70
+                $placeholder = substr($placeholder, 1);
71
+                break;
72
+            case '#':
73
+                $type = DefinitionParameter::VALUE_HIDDEN;
74
+                $placeholder = substr($placeholder, 1);
75
+                break;
76
+            }
77
+            $this->addParameter((new DefinitionParameter($name, $placeholder))
78
+                ->setType($type)
79
+                ->setFlags($flags)
80
+            );
81
+        }
82 82
 
83
-		if (isset($definition['priority'])) {
84
-			$this->setPriority($definition['priority']);
85
-		}
86
-		if (isset($definition['custom'])) {
87
-			$this->addCustomJs($definition['custom']);
88
-		}
89
-		if (isset($definition['has_dependencies']) && $definition['has_dependencies']) {
90
-			$this->hasDependencies = true;
91
-		}
92
-	}
83
+        if (isset($definition['priority'])) {
84
+            $this->setPriority($definition['priority']);
85
+        }
86
+        if (isset($definition['custom'])) {
87
+            $this->addCustomJs($definition['custom']);
88
+        }
89
+        if (isset($definition['has_dependencies']) && $definition['has_dependencies']) {
90
+            $this->hasDependencies = true;
91
+        }
92
+    }
93 93
 
94
-	/**
95
-	 * @return MissingDependency[]
96
-	 */
97
-	public function checkDependencies() {
98
-		if ($this->hasDependencies) {
99
-			return $this->doCheckDependencies();
100
-		}
101
-		return [];
102
-	}
94
+    /**
95
+     * @return MissingDependency[]
96
+     */
97
+    public function checkDependencies() {
98
+        if ($this->hasDependencies) {
99
+            return $this->doCheckDependencies();
100
+        }
101
+        return [];
102
+    }
103 103
 }
Please login to merge, or discard this patch.
apps/files_external/lib/Command/Verify.php 1 patch
Indentation   +95 added lines, -95 removed lines patch added patch discarded remove patch
@@ -38,109 +38,109 @@
 block discarded – undo
38 38
 use Symfony\Component\Console\Output\OutputInterface;
39 39
 
40 40
 class Verify extends Base {
41
-	/**
42
-	 * @var GlobalStoragesService
43
-	 */
44
-	protected $globalService;
41
+    /**
42
+     * @var GlobalStoragesService
43
+     */
44
+    protected $globalService;
45 45
 
46
-	public function __construct(GlobalStoragesService $globalService) {
47
-		parent::__construct();
48
-		$this->globalService = $globalService;
49
-	}
46
+    public function __construct(GlobalStoragesService $globalService) {
47
+        parent::__construct();
48
+        $this->globalService = $globalService;
49
+    }
50 50
 
51
-	protected function configure() {
52
-		$this
53
-			->setName('files_external:verify')
54
-			->setDescription('Verify mount configuration')
55
-			->addArgument(
56
-				'mount_id',
57
-				InputArgument::REQUIRED,
58
-				'The id of the mount to check'
59
-			)->addOption(
60
-				'config',
61
-				'c',
62
-				InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
63
-				'Additional config option to set before checking in key=value pairs, required for certain auth backends such as login credentails'
64
-			);
65
-		parent::configure();
66
-	}
51
+    protected function configure() {
52
+        $this
53
+            ->setName('files_external:verify')
54
+            ->setDescription('Verify mount configuration')
55
+            ->addArgument(
56
+                'mount_id',
57
+                InputArgument::REQUIRED,
58
+                'The id of the mount to check'
59
+            )->addOption(
60
+                'config',
61
+                'c',
62
+                InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
63
+                'Additional config option to set before checking in key=value pairs, required for certain auth backends such as login credentails'
64
+            );
65
+        parent::configure();
66
+    }
67 67
 
68
-	protected function execute(InputInterface $input, OutputInterface $output): int {
69
-		$mountId = $input->getArgument('mount_id');
70
-		$configInput = $input->getOption('config');
68
+    protected function execute(InputInterface $input, OutputInterface $output): int {
69
+        $mountId = $input->getArgument('mount_id');
70
+        $configInput = $input->getOption('config');
71 71
 
72
-		try {
73
-			$mount = $this->globalService->getStorage($mountId);
74
-		} catch (NotFoundException $e) {
75
-			$output->writeln('<error>Mount with id "' . $mountId . ' not found, check "occ files_external:list" to get available mounts"</error>');
76
-			return 404;
77
-		}
72
+        try {
73
+            $mount = $this->globalService->getStorage($mountId);
74
+        } catch (NotFoundException $e) {
75
+            $output->writeln('<error>Mount with id "' . $mountId . ' not found, check "occ files_external:list" to get available mounts"</error>');
76
+            return 404;
77
+        }
78 78
 
79
-		$this->updateStorageStatus($mount, $configInput, $output);
79
+        $this->updateStorageStatus($mount, $configInput, $output);
80 80
 
81
-		$this->writeArrayInOutputFormat($input, $output, [
82
-			'status' => StorageNotAvailableException::getStateCodeName($mount->getStatus()),
83
-			'code' => $mount->getStatus(),
84
-			'message' => $mount->getStatusMessage()
85
-		]);
86
-		return 0;
87
-	}
81
+        $this->writeArrayInOutputFormat($input, $output, [
82
+            'status' => StorageNotAvailableException::getStateCodeName($mount->getStatus()),
83
+            'code' => $mount->getStatus(),
84
+            'message' => $mount->getStatusMessage()
85
+        ]);
86
+        return 0;
87
+    }
88 88
 
89
-	private function manipulateStorageConfig(StorageConfig $storage) {
90
-		/** @var AuthMechanism */
91
-		$authMechanism = $storage->getAuthMechanism();
92
-		$authMechanism->manipulateStorageConfig($storage);
93
-		/** @var Backend */
94
-		$backend = $storage->getBackend();
95
-		$backend->manipulateStorageConfig($storage);
96
-	}
89
+    private function manipulateStorageConfig(StorageConfig $storage) {
90
+        /** @var AuthMechanism */
91
+        $authMechanism = $storage->getAuthMechanism();
92
+        $authMechanism->manipulateStorageConfig($storage);
93
+        /** @var Backend */
94
+        $backend = $storage->getBackend();
95
+        $backend->manipulateStorageConfig($storage);
96
+    }
97 97
 
98
-	private function updateStorageStatus(StorageConfig &$storage, $configInput, OutputInterface $output) {
99
-		try {
100
-			try {
101
-				$this->manipulateStorageConfig($storage);
102
-			} catch (InsufficientDataForMeaningfulAnswerException $e) {
103
-				if (count($configInput) === 0) { // extra config options might solve the error
104
-					throw $e;
105
-				}
106
-			}
98
+    private function updateStorageStatus(StorageConfig &$storage, $configInput, OutputInterface $output) {
99
+        try {
100
+            try {
101
+                $this->manipulateStorageConfig($storage);
102
+            } catch (InsufficientDataForMeaningfulAnswerException $e) {
103
+                if (count($configInput) === 0) { // extra config options might solve the error
104
+                    throw $e;
105
+                }
106
+            }
107 107
 
108
-			foreach ($configInput as $configOption) {
109
-				if (!strpos($configOption, '=')) {
110
-					$output->writeln('<error>Invalid mount configuration option "' . $configOption . '"</error>');
111
-					return;
112
-				}
113
-				list($key, $value) = explode('=', $configOption, 2);
114
-				$storage->setBackendOption($key, $value);
115
-			}
108
+            foreach ($configInput as $configOption) {
109
+                if (!strpos($configOption, '=')) {
110
+                    $output->writeln('<error>Invalid mount configuration option "' . $configOption . '"</error>');
111
+                    return;
112
+                }
113
+                list($key, $value) = explode('=', $configOption, 2);
114
+                $storage->setBackendOption($key, $value);
115
+            }
116 116
 
117
-			/** @var Backend */
118
-			$backend = $storage->getBackend();
119
-			// update status (can be time-consuming)
120
-			$storage->setStatus(
121
-				\OCA\Files_External\MountConfig::getBackendStatus(
122
-					$backend->getStorageClass(),
123
-					$storage->getBackendOptions(),
124
-					false
125
-				)
126
-			);
127
-		} catch (InsufficientDataForMeaningfulAnswerException $e) {
128
-			$status = $e->getCode() ? $e->getCode() : StorageNotAvailableException::STATUS_INDETERMINATE;
129
-			$storage->setStatus(
130
-				$status,
131
-				$e->getMessage()
132
-			);
133
-		} catch (StorageNotAvailableException $e) {
134
-			$storage->setStatus(
135
-				$e->getCode(),
136
-				$e->getMessage()
137
-			);
138
-		} catch (\Exception $e) {
139
-			// FIXME: convert storage exceptions to StorageNotAvailableException
140
-			$storage->setStatus(
141
-				StorageNotAvailableException::STATUS_ERROR,
142
-				get_class($e) . ': ' . $e->getMessage()
143
-			);
144
-		}
145
-	}
117
+            /** @var Backend */
118
+            $backend = $storage->getBackend();
119
+            // update status (can be time-consuming)
120
+            $storage->setStatus(
121
+                \OCA\Files_External\MountConfig::getBackendStatus(
122
+                    $backend->getStorageClass(),
123
+                    $storage->getBackendOptions(),
124
+                    false
125
+                )
126
+            );
127
+        } catch (InsufficientDataForMeaningfulAnswerException $e) {
128
+            $status = $e->getCode() ? $e->getCode() : StorageNotAvailableException::STATUS_INDETERMINATE;
129
+            $storage->setStatus(
130
+                $status,
131
+                $e->getMessage()
132
+            );
133
+        } catch (StorageNotAvailableException $e) {
134
+            $storage->setStatus(
135
+                $e->getCode(),
136
+                $e->getMessage()
137
+            );
138
+        } catch (\Exception $e) {
139
+            // FIXME: convert storage exceptions to StorageNotAvailableException
140
+            $storage->setStatus(
141
+                StorageNotAvailableException::STATUS_ERROR,
142
+                get_class($e) . ': ' . $e->getMessage()
143
+            );
144
+        }
145
+    }
146 146
 }
Please login to merge, or discard this patch.
apps/files_external/lib/MountConfig.php 2 patches
Indentation   +383 added lines, -383 removed lines patch added patch discarded remove patch
@@ -60,387 +60,387 @@
 block discarded – undo
60 60
  * Class to configure mount.json globally and for users
61 61
  */
62 62
 class MountConfig {
63
-	// TODO: make this class non-static and give it a proper namespace
64
-
65
-	public const MOUNT_TYPE_GLOBAL = 'global';
66
-	public const MOUNT_TYPE_GROUP = 'group';
67
-	public const MOUNT_TYPE_USER = 'user';
68
-	public const MOUNT_TYPE_PERSONAL = 'personal';
69
-
70
-	// whether to skip backend test (for unit tests, as this static class is not mockable)
71
-	public static $skipTest = false;
72
-
73
-	/** @var Application */
74
-	public static $app;
75
-
76
-	/**
77
-	 * @param string $class
78
-	 * @param array $definition
79
-	 * @return bool
80
-	 * @deprecated 8.2.0 use \OCA\Files_External\Service\BackendService::registerBackend()
81
-	 */
82
-	public static function registerBackend($class, $definition) {
83
-		$backendService = self::$app->getContainer()->query(BackendService::class);
84
-		$auth = self::$app->getContainer()->query(Builtin::class);
85
-
86
-		$backendService->registerBackend(new LegacyBackend($class, $definition, $auth));
87
-
88
-		return true;
89
-	}
90
-
91
-	/**
92
-	 * Returns the mount points for the given user.
93
-	 * The mount point is relative to the data directory.
94
-	 *
95
-	 * @param string $uid user
96
-	 * @return array of mount point string as key, mountpoint config as value
97
-	 *
98
-	 * @deprecated 8.2.0 use UserGlobalStoragesService::getStorages() and UserStoragesService::getStorages()
99
-	 */
100
-	public static function getAbsoluteMountPoints($uid) {
101
-		$mountPoints = [];
102
-
103
-		$userGlobalStoragesService = self::$app->getContainer()->query(UserGlobalStoragesService::class);
104
-		$userStoragesService = self::$app->getContainer()->query(UserStoragesService::class);
105
-		$user = self::$app->getContainer()->query(IUserManager::class)->get($uid);
106
-
107
-		$userGlobalStoragesService->setUser($user);
108
-		$userStoragesService->setUser($user);
109
-
110
-		foreach ($userGlobalStoragesService->getStorages() as $storage) {
111
-			/** @var \OCA\Files_External\Lib\StorageConfig $storage */
112
-			$mountPoint = '/'.$uid.'/files'.$storage->getMountPoint();
113
-			$mountEntry = self::prepareMountPointEntry($storage, false);
114
-			foreach ($mountEntry['options'] as &$option) {
115
-				$option = self::substitutePlaceholdersInConfig($option, $uid);
116
-			}
117
-			$mountPoints[$mountPoint] = $mountEntry;
118
-		}
119
-
120
-		foreach ($userStoragesService->getStorages() as $storage) {
121
-			$mountPoint = '/'.$uid.'/files'.$storage->getMountPoint();
122
-			$mountEntry = self::prepareMountPointEntry($storage, true);
123
-			foreach ($mountEntry['options'] as &$option) {
124
-				$option = self::substitutePlaceholdersInConfig($option, $uid);
125
-			}
126
-			$mountPoints[$mountPoint] = $mountEntry;
127
-		}
128
-
129
-		$userGlobalStoragesService->resetUser();
130
-		$userStoragesService->resetUser();
131
-
132
-		return $mountPoints;
133
-	}
134
-
135
-	/**
136
-	 * Get the system mount points
137
-	 *
138
-	 * @return array
139
-	 *
140
-	 * @deprecated 8.2.0 use GlobalStoragesService::getStorages()
141
-	 */
142
-	public static function getSystemMountPoints() {
143
-		$mountPoints = [];
144
-		$service = self::$app->getContainer()->query(GlobalStoragesService::class);
145
-
146
-		foreach ($service->getStorages() as $storage) {
147
-			$mountPoints[] = self::prepareMountPointEntry($storage, false);
148
-		}
149
-
150
-		return $mountPoints;
151
-	}
152
-
153
-	/**
154
-	 * Get the personal mount points of the current user
155
-	 *
156
-	 * @return array
157
-	 *
158
-	 * @deprecated 8.2.0 use UserStoragesService::getStorages()
159
-	 */
160
-	public static function getPersonalMountPoints() {
161
-		$mountPoints = [];
162
-		$service = self::$app->getContainer()->query(UserStoragesService::class);
163
-
164
-		foreach ($service->getStorages() as $storage) {
165
-			$mountPoints[] = self::prepareMountPointEntry($storage, true);
166
-		}
167
-
168
-		return $mountPoints;
169
-	}
170
-
171
-	/**
172
-	 * Convert a StorageConfig to the legacy mountPoints array format
173
-	 * There's a lot of extra information in here, to satisfy all of the legacy functions
174
-	 *
175
-	 * @param StorageConfig $storage
176
-	 * @param bool $isPersonal
177
-	 * @return array
178
-	 */
179
-	private static function prepareMountPointEntry(StorageConfig $storage, $isPersonal) {
180
-		$mountEntry = [];
181
-
182
-		$mountEntry['mountpoint'] = substr($storage->getMountPoint(), 1); // remove leading slash
183
-		$mountEntry['class'] = $storage->getBackend()->getIdentifier();
184
-		$mountEntry['backend'] = $storage->getBackend()->getText();
185
-		$mountEntry['authMechanism'] = $storage->getAuthMechanism()->getIdentifier();
186
-		$mountEntry['personal'] = $isPersonal;
187
-		$mountEntry['options'] = self::decryptPasswords($storage->getBackendOptions());
188
-		$mountEntry['mountOptions'] = $storage->getMountOptions();
189
-		$mountEntry['priority'] = $storage->getPriority();
190
-		$mountEntry['applicable'] = [
191
-			'groups' => $storage->getApplicableGroups(),
192
-			'users' => $storage->getApplicableUsers(),
193
-		];
194
-		// if mountpoint is applicable to all users the old API expects ['all']
195
-		if (empty($mountEntry['applicable']['groups']) && empty($mountEntry['applicable']['users'])) {
196
-			$mountEntry['applicable']['users'] = ['all'];
197
-		}
198
-
199
-		$mountEntry['id'] = $storage->getId();
200
-
201
-		return $mountEntry;
202
-	}
203
-
204
-	/**
205
-	 * fill in the correct values for $user
206
-	 *
207
-	 * @param string $user user value
208
-	 * @param string|array $input
209
-	 * @return string
210
-	 * @deprecated use self::substitutePlaceholdersInConfig($input)
211
-	 */
212
-	public static function setUserVars($user, $input) {
213
-		$handler = self::$app->getContainer()->query(UserPlaceholderHandler::class);
214
-		return $handler->handle($input);
215
-	}
216
-
217
-	/**
218
-	 * @param mixed $input
219
-	 * @param string|null $userId
220
-	 * @return mixed
221
-	 * @throws \OCP\AppFramework\QueryException
222
-	 * @since 16.0.0
223
-	 */
224
-	public static function substitutePlaceholdersInConfig($input, string $userId = null) {
225
-		/** @var BackendService $backendService */
226
-		$backendService = self::$app->getContainer()->query(BackendService::class);
227
-		/** @var IConfigHandler[] $handlers */
228
-		$handlers = $backendService->getConfigHandlers();
229
-		foreach ($handlers as $handler) {
230
-			if ($handler instanceof UserContext && $userId !== null) {
231
-				$handler->setUserId($userId);
232
-			}
233
-			$input = $handler->handle($input);
234
-		}
235
-		return $input;
236
-	}
237
-
238
-	/**
239
-	 * Test connecting using the given backend configuration
240
-	 *
241
-	 * @param string $class backend class name
242
-	 * @param array $options backend configuration options
243
-	 * @param boolean $isPersonal
244
-	 * @return int see self::STATUS_*
245
-	 * @throws Exception
246
-	 */
247
-	public static function getBackendStatus($class, $options, $isPersonal, $testOnly = true) {
248
-		if (self::$skipTest) {
249
-			return StorageNotAvailableException::STATUS_SUCCESS;
250
-		}
251
-		foreach ($options as $key => &$option) {
252
-			if ($key === 'password') {
253
-				// no replacements in passwords
254
-				continue;
255
-			}
256
-			$option = self::substitutePlaceholdersInConfig($option);
257
-		}
258
-		if (class_exists($class)) {
259
-			try {
260
-				/** @var \OC\Files\Storage\Common $storage */
261
-				$storage = new $class($options);
262
-
263
-				try {
264
-					$result = $storage->test($isPersonal, $testOnly);
265
-					$storage->setAvailability($result);
266
-					if ($result) {
267
-						return StorageNotAvailableException::STATUS_SUCCESS;
268
-					}
269
-				} catch (\Exception $e) {
270
-					$storage->setAvailability(false);
271
-					throw $e;
272
-				}
273
-			} catch (Exception $exception) {
274
-				\OC::$server->getLogger()->logException($exception, ['app' => 'files_external']);
275
-				throw $exception;
276
-			}
277
-		}
278
-		return StorageNotAvailableException::STATUS_ERROR;
279
-	}
280
-
281
-	/**
282
-	 * Read the mount points in the config file into an array
283
-	 *
284
-	 * @param string|null $user If not null, personal for $user, otherwise system
285
-	 * @return array
286
-	 */
287
-	public static function readData($user = null) {
288
-		if (isset($user)) {
289
-			$jsonFile = \OC::$server->getUserManager()->get($user)->getHome() . '/mount.json';
290
-		} else {
291
-			$config = \OC::$server->getConfig();
292
-			$datadir = $config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data/');
293
-			$jsonFile = $config->getSystemValue('mount_file', $datadir . '/mount.json');
294
-		}
295
-		if (is_file($jsonFile)) {
296
-			$mountPoints = json_decode(file_get_contents($jsonFile), true);
297
-			if (is_array($mountPoints)) {
298
-				return $mountPoints;
299
-			}
300
-		}
301
-		return [];
302
-	}
303
-
304
-	/**
305
-	 * Get backend dependency message
306
-	 * TODO: move into AppFramework along with templates
307
-	 *
308
-	 * @param Backend[] $backends
309
-	 * @return string
310
-	 */
311
-	public static function dependencyMessage($backends) {
312
-		$l = \OC::$server->getL10N('files_external');
313
-		$message = '';
314
-		$dependencyGroups = [];
315
-
316
-		foreach ($backends as $backend) {
317
-			foreach ($backend->checkDependencies() as $dependency) {
318
-				if ($message = $dependency->getMessage()) {
319
-					$message .= '<p>' . $message . '</p>';
320
-				} else {
321
-					$dependencyGroups[$dependency->getDependency()][] = $backend;
322
-				}
323
-			}
324
-		}
325
-
326
-		foreach ($dependencyGroups as $module => $dependants) {
327
-			$backends = implode(', ', array_map(function ($backend) {
328
-				return '"' . $backend->getText() . '"';
329
-			}, $dependants));
330
-			$message .= '<p>' . MountConfig::getSingleDependencyMessage($l, $module, $backends) . '</p>';
331
-		}
332
-
333
-		return $message;
334
-	}
335
-
336
-	/**
337
-	 * Returns a dependency missing message
338
-	 *
339
-	 * @param \OCP\IL10N $l
340
-	 * @param string $module
341
-	 * @param string $backend
342
-	 * @return string
343
-	 */
344
-	private static function getSingleDependencyMessage(\OCP\IL10N $l, $module, $backend) {
345
-		switch (strtolower($module)) {
346
-			case 'curl':
347
-				return (string)$l->t('The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it.', [$backend]);
348
-			case 'ftp':
349
-				return (string)$l->t('The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it.', [$backend]);
350
-			default:
351
-				return (string)$l->t('"%1$s" is not installed. Mounting of %2$s is not possible. Please ask your system administrator to install it.', [$module, $backend]);
352
-		}
353
-	}
354
-
355
-	/**
356
-	 * Encrypt passwords in the given config options
357
-	 *
358
-	 * @param array $options mount options
359
-	 * @return array updated options
360
-	 */
361
-	public static function encryptPasswords($options) {
362
-		if (isset($options['password'])) {
363
-			$options['password_encrypted'] = self::encryptPassword($options['password']);
364
-			// do not unset the password, we want to keep the keys order
365
-			// on load... because that's how the UI currently works
366
-			$options['password'] = '';
367
-		}
368
-		return $options;
369
-	}
370
-
371
-	/**
372
-	 * Decrypt passwords in the given config options
373
-	 *
374
-	 * @param array $options mount options
375
-	 * @return array updated options
376
-	 */
377
-	public static function decryptPasswords($options) {
378
-		// note: legacy options might still have the unencrypted password in the "password" field
379
-		if (isset($options['password_encrypted'])) {
380
-			$options['password'] = self::decryptPassword($options['password_encrypted']);
381
-			unset($options['password_encrypted']);
382
-		}
383
-		return $options;
384
-	}
385
-
386
-	/**
387
-	 * Encrypt a single password
388
-	 *
389
-	 * @param string $password plain text password
390
-	 * @return string encrypted password
391
-	 */
392
-	private static function encryptPassword($password) {
393
-		$cipher = self::getCipher();
394
-		$iv = \OC::$server->getSecureRandom()->generate(16);
395
-		$cipher->setIV($iv);
396
-		return base64_encode($iv . $cipher->encrypt($password));
397
-	}
398
-
399
-	/**
400
-	 * Decrypts a single password
401
-	 *
402
-	 * @param string $encryptedPassword encrypted password
403
-	 * @return string plain text password
404
-	 */
405
-	private static function decryptPassword($encryptedPassword) {
406
-		$cipher = self::getCipher();
407
-		$binaryPassword = base64_decode($encryptedPassword);
408
-		$iv = substr($binaryPassword, 0, 16);
409
-		$cipher->setIV($iv);
410
-		$binaryPassword = substr($binaryPassword, 16);
411
-		return $cipher->decrypt($binaryPassword);
412
-	}
413
-
414
-	/**
415
-	 * Returns the encryption cipher
416
-	 *
417
-	 * @return AES
418
-	 */
419
-	private static function getCipher() {
420
-		$cipher = new AES(AES::MODE_CBC);
421
-		$cipher->setKey(\OC::$server->getConfig()->getSystemValue('passwordsalt', null));
422
-		return $cipher;
423
-	}
424
-
425
-	/**
426
-	 * Computes a hash based on the given configuration.
427
-	 * This is mostly used to find out whether configurations
428
-	 * are the same.
429
-	 *
430
-	 * @param array $config
431
-	 * @return string
432
-	 */
433
-	public static function makeConfigHash($config) {
434
-		$data = json_encode(
435
-			[
436
-				'c' => $config['backend'],
437
-				'a' => $config['authMechanism'],
438
-				'm' => $config['mountpoint'],
439
-				'o' => $config['options'],
440
-				'p' => isset($config['priority']) ? $config['priority'] : -1,
441
-				'mo' => isset($config['mountOptions']) ? $config['mountOptions'] : [],
442
-			]
443
-		);
444
-		return hash('md5', $data);
445
-	}
63
+    // TODO: make this class non-static and give it a proper namespace
64
+
65
+    public const MOUNT_TYPE_GLOBAL = 'global';
66
+    public const MOUNT_TYPE_GROUP = 'group';
67
+    public const MOUNT_TYPE_USER = 'user';
68
+    public const MOUNT_TYPE_PERSONAL = 'personal';
69
+
70
+    // whether to skip backend test (for unit tests, as this static class is not mockable)
71
+    public static $skipTest = false;
72
+
73
+    /** @var Application */
74
+    public static $app;
75
+
76
+    /**
77
+     * @param string $class
78
+     * @param array $definition
79
+     * @return bool
80
+     * @deprecated 8.2.0 use \OCA\Files_External\Service\BackendService::registerBackend()
81
+     */
82
+    public static function registerBackend($class, $definition) {
83
+        $backendService = self::$app->getContainer()->query(BackendService::class);
84
+        $auth = self::$app->getContainer()->query(Builtin::class);
85
+
86
+        $backendService->registerBackend(new LegacyBackend($class, $definition, $auth));
87
+
88
+        return true;
89
+    }
90
+
91
+    /**
92
+     * Returns the mount points for the given user.
93
+     * The mount point is relative to the data directory.
94
+     *
95
+     * @param string $uid user
96
+     * @return array of mount point string as key, mountpoint config as value
97
+     *
98
+     * @deprecated 8.2.0 use UserGlobalStoragesService::getStorages() and UserStoragesService::getStorages()
99
+     */
100
+    public static function getAbsoluteMountPoints($uid) {
101
+        $mountPoints = [];
102
+
103
+        $userGlobalStoragesService = self::$app->getContainer()->query(UserGlobalStoragesService::class);
104
+        $userStoragesService = self::$app->getContainer()->query(UserStoragesService::class);
105
+        $user = self::$app->getContainer()->query(IUserManager::class)->get($uid);
106
+
107
+        $userGlobalStoragesService->setUser($user);
108
+        $userStoragesService->setUser($user);
109
+
110
+        foreach ($userGlobalStoragesService->getStorages() as $storage) {
111
+            /** @var \OCA\Files_External\Lib\StorageConfig $storage */
112
+            $mountPoint = '/'.$uid.'/files'.$storage->getMountPoint();
113
+            $mountEntry = self::prepareMountPointEntry($storage, false);
114
+            foreach ($mountEntry['options'] as &$option) {
115
+                $option = self::substitutePlaceholdersInConfig($option, $uid);
116
+            }
117
+            $mountPoints[$mountPoint] = $mountEntry;
118
+        }
119
+
120
+        foreach ($userStoragesService->getStorages() as $storage) {
121
+            $mountPoint = '/'.$uid.'/files'.$storage->getMountPoint();
122
+            $mountEntry = self::prepareMountPointEntry($storage, true);
123
+            foreach ($mountEntry['options'] as &$option) {
124
+                $option = self::substitutePlaceholdersInConfig($option, $uid);
125
+            }
126
+            $mountPoints[$mountPoint] = $mountEntry;
127
+        }
128
+
129
+        $userGlobalStoragesService->resetUser();
130
+        $userStoragesService->resetUser();
131
+
132
+        return $mountPoints;
133
+    }
134
+
135
+    /**
136
+     * Get the system mount points
137
+     *
138
+     * @return array
139
+     *
140
+     * @deprecated 8.2.0 use GlobalStoragesService::getStorages()
141
+     */
142
+    public static function getSystemMountPoints() {
143
+        $mountPoints = [];
144
+        $service = self::$app->getContainer()->query(GlobalStoragesService::class);
145
+
146
+        foreach ($service->getStorages() as $storage) {
147
+            $mountPoints[] = self::prepareMountPointEntry($storage, false);
148
+        }
149
+
150
+        return $mountPoints;
151
+    }
152
+
153
+    /**
154
+     * Get the personal mount points of the current user
155
+     *
156
+     * @return array
157
+     *
158
+     * @deprecated 8.2.0 use UserStoragesService::getStorages()
159
+     */
160
+    public static function getPersonalMountPoints() {
161
+        $mountPoints = [];
162
+        $service = self::$app->getContainer()->query(UserStoragesService::class);
163
+
164
+        foreach ($service->getStorages() as $storage) {
165
+            $mountPoints[] = self::prepareMountPointEntry($storage, true);
166
+        }
167
+
168
+        return $mountPoints;
169
+    }
170
+
171
+    /**
172
+     * Convert a StorageConfig to the legacy mountPoints array format
173
+     * There's a lot of extra information in here, to satisfy all of the legacy functions
174
+     *
175
+     * @param StorageConfig $storage
176
+     * @param bool $isPersonal
177
+     * @return array
178
+     */
179
+    private static function prepareMountPointEntry(StorageConfig $storage, $isPersonal) {
180
+        $mountEntry = [];
181
+
182
+        $mountEntry['mountpoint'] = substr($storage->getMountPoint(), 1); // remove leading slash
183
+        $mountEntry['class'] = $storage->getBackend()->getIdentifier();
184
+        $mountEntry['backend'] = $storage->getBackend()->getText();
185
+        $mountEntry['authMechanism'] = $storage->getAuthMechanism()->getIdentifier();
186
+        $mountEntry['personal'] = $isPersonal;
187
+        $mountEntry['options'] = self::decryptPasswords($storage->getBackendOptions());
188
+        $mountEntry['mountOptions'] = $storage->getMountOptions();
189
+        $mountEntry['priority'] = $storage->getPriority();
190
+        $mountEntry['applicable'] = [
191
+            'groups' => $storage->getApplicableGroups(),
192
+            'users' => $storage->getApplicableUsers(),
193
+        ];
194
+        // if mountpoint is applicable to all users the old API expects ['all']
195
+        if (empty($mountEntry['applicable']['groups']) && empty($mountEntry['applicable']['users'])) {
196
+            $mountEntry['applicable']['users'] = ['all'];
197
+        }
198
+
199
+        $mountEntry['id'] = $storage->getId();
200
+
201
+        return $mountEntry;
202
+    }
203
+
204
+    /**
205
+     * fill in the correct values for $user
206
+     *
207
+     * @param string $user user value
208
+     * @param string|array $input
209
+     * @return string
210
+     * @deprecated use self::substitutePlaceholdersInConfig($input)
211
+     */
212
+    public static function setUserVars($user, $input) {
213
+        $handler = self::$app->getContainer()->query(UserPlaceholderHandler::class);
214
+        return $handler->handle($input);
215
+    }
216
+
217
+    /**
218
+     * @param mixed $input
219
+     * @param string|null $userId
220
+     * @return mixed
221
+     * @throws \OCP\AppFramework\QueryException
222
+     * @since 16.0.0
223
+     */
224
+    public static function substitutePlaceholdersInConfig($input, string $userId = null) {
225
+        /** @var BackendService $backendService */
226
+        $backendService = self::$app->getContainer()->query(BackendService::class);
227
+        /** @var IConfigHandler[] $handlers */
228
+        $handlers = $backendService->getConfigHandlers();
229
+        foreach ($handlers as $handler) {
230
+            if ($handler instanceof UserContext && $userId !== null) {
231
+                $handler->setUserId($userId);
232
+            }
233
+            $input = $handler->handle($input);
234
+        }
235
+        return $input;
236
+    }
237
+
238
+    /**
239
+     * Test connecting using the given backend configuration
240
+     *
241
+     * @param string $class backend class name
242
+     * @param array $options backend configuration options
243
+     * @param boolean $isPersonal
244
+     * @return int see self::STATUS_*
245
+     * @throws Exception
246
+     */
247
+    public static function getBackendStatus($class, $options, $isPersonal, $testOnly = true) {
248
+        if (self::$skipTest) {
249
+            return StorageNotAvailableException::STATUS_SUCCESS;
250
+        }
251
+        foreach ($options as $key => &$option) {
252
+            if ($key === 'password') {
253
+                // no replacements in passwords
254
+                continue;
255
+            }
256
+            $option = self::substitutePlaceholdersInConfig($option);
257
+        }
258
+        if (class_exists($class)) {
259
+            try {
260
+                /** @var \OC\Files\Storage\Common $storage */
261
+                $storage = new $class($options);
262
+
263
+                try {
264
+                    $result = $storage->test($isPersonal, $testOnly);
265
+                    $storage->setAvailability($result);
266
+                    if ($result) {
267
+                        return StorageNotAvailableException::STATUS_SUCCESS;
268
+                    }
269
+                } catch (\Exception $e) {
270
+                    $storage->setAvailability(false);
271
+                    throw $e;
272
+                }
273
+            } catch (Exception $exception) {
274
+                \OC::$server->getLogger()->logException($exception, ['app' => 'files_external']);
275
+                throw $exception;
276
+            }
277
+        }
278
+        return StorageNotAvailableException::STATUS_ERROR;
279
+    }
280
+
281
+    /**
282
+     * Read the mount points in the config file into an array
283
+     *
284
+     * @param string|null $user If not null, personal for $user, otherwise system
285
+     * @return array
286
+     */
287
+    public static function readData($user = null) {
288
+        if (isset($user)) {
289
+            $jsonFile = \OC::$server->getUserManager()->get($user)->getHome() . '/mount.json';
290
+        } else {
291
+            $config = \OC::$server->getConfig();
292
+            $datadir = $config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data/');
293
+            $jsonFile = $config->getSystemValue('mount_file', $datadir . '/mount.json');
294
+        }
295
+        if (is_file($jsonFile)) {
296
+            $mountPoints = json_decode(file_get_contents($jsonFile), true);
297
+            if (is_array($mountPoints)) {
298
+                return $mountPoints;
299
+            }
300
+        }
301
+        return [];
302
+    }
303
+
304
+    /**
305
+     * Get backend dependency message
306
+     * TODO: move into AppFramework along with templates
307
+     *
308
+     * @param Backend[] $backends
309
+     * @return string
310
+     */
311
+    public static function dependencyMessage($backends) {
312
+        $l = \OC::$server->getL10N('files_external');
313
+        $message = '';
314
+        $dependencyGroups = [];
315
+
316
+        foreach ($backends as $backend) {
317
+            foreach ($backend->checkDependencies() as $dependency) {
318
+                if ($message = $dependency->getMessage()) {
319
+                    $message .= '<p>' . $message . '</p>';
320
+                } else {
321
+                    $dependencyGroups[$dependency->getDependency()][] = $backend;
322
+                }
323
+            }
324
+        }
325
+
326
+        foreach ($dependencyGroups as $module => $dependants) {
327
+            $backends = implode(', ', array_map(function ($backend) {
328
+                return '"' . $backend->getText() . '"';
329
+            }, $dependants));
330
+            $message .= '<p>' . MountConfig::getSingleDependencyMessage($l, $module, $backends) . '</p>';
331
+        }
332
+
333
+        return $message;
334
+    }
335
+
336
+    /**
337
+     * Returns a dependency missing message
338
+     *
339
+     * @param \OCP\IL10N $l
340
+     * @param string $module
341
+     * @param string $backend
342
+     * @return string
343
+     */
344
+    private static function getSingleDependencyMessage(\OCP\IL10N $l, $module, $backend) {
345
+        switch (strtolower($module)) {
346
+            case 'curl':
347
+                return (string)$l->t('The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it.', [$backend]);
348
+            case 'ftp':
349
+                return (string)$l->t('The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it.', [$backend]);
350
+            default:
351
+                return (string)$l->t('"%1$s" is not installed. Mounting of %2$s is not possible. Please ask your system administrator to install it.', [$module, $backend]);
352
+        }
353
+    }
354
+
355
+    /**
356
+     * Encrypt passwords in the given config options
357
+     *
358
+     * @param array $options mount options
359
+     * @return array updated options
360
+     */
361
+    public static function encryptPasswords($options) {
362
+        if (isset($options['password'])) {
363
+            $options['password_encrypted'] = self::encryptPassword($options['password']);
364
+            // do not unset the password, we want to keep the keys order
365
+            // on load... because that's how the UI currently works
366
+            $options['password'] = '';
367
+        }
368
+        return $options;
369
+    }
370
+
371
+    /**
372
+     * Decrypt passwords in the given config options
373
+     *
374
+     * @param array $options mount options
375
+     * @return array updated options
376
+     */
377
+    public static function decryptPasswords($options) {
378
+        // note: legacy options might still have the unencrypted password in the "password" field
379
+        if (isset($options['password_encrypted'])) {
380
+            $options['password'] = self::decryptPassword($options['password_encrypted']);
381
+            unset($options['password_encrypted']);
382
+        }
383
+        return $options;
384
+    }
385
+
386
+    /**
387
+     * Encrypt a single password
388
+     *
389
+     * @param string $password plain text password
390
+     * @return string encrypted password
391
+     */
392
+    private static function encryptPassword($password) {
393
+        $cipher = self::getCipher();
394
+        $iv = \OC::$server->getSecureRandom()->generate(16);
395
+        $cipher->setIV($iv);
396
+        return base64_encode($iv . $cipher->encrypt($password));
397
+    }
398
+
399
+    /**
400
+     * Decrypts a single password
401
+     *
402
+     * @param string $encryptedPassword encrypted password
403
+     * @return string plain text password
404
+     */
405
+    private static function decryptPassword($encryptedPassword) {
406
+        $cipher = self::getCipher();
407
+        $binaryPassword = base64_decode($encryptedPassword);
408
+        $iv = substr($binaryPassword, 0, 16);
409
+        $cipher->setIV($iv);
410
+        $binaryPassword = substr($binaryPassword, 16);
411
+        return $cipher->decrypt($binaryPassword);
412
+    }
413
+
414
+    /**
415
+     * Returns the encryption cipher
416
+     *
417
+     * @return AES
418
+     */
419
+    private static function getCipher() {
420
+        $cipher = new AES(AES::MODE_CBC);
421
+        $cipher->setKey(\OC::$server->getConfig()->getSystemValue('passwordsalt', null));
422
+        return $cipher;
423
+    }
424
+
425
+    /**
426
+     * Computes a hash based on the given configuration.
427
+     * This is mostly used to find out whether configurations
428
+     * are the same.
429
+     *
430
+     * @param array $config
431
+     * @return string
432
+     */
433
+    public static function makeConfigHash($config) {
434
+        $data = json_encode(
435
+            [
436
+                'c' => $config['backend'],
437
+                'a' => $config['authMechanism'],
438
+                'm' => $config['mountpoint'],
439
+                'o' => $config['options'],
440
+                'p' => isset($config['priority']) ? $config['priority'] : -1,
441
+                'mo' => isset($config['mountOptions']) ? $config['mountOptions'] : [],
442
+            ]
443
+        );
444
+        return hash('md5', $data);
445
+    }
446 446
 }
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -286,11 +286,11 @@  discard block
 block discarded – undo
286 286
 	 */
287 287
 	public static function readData($user = null) {
288 288
 		if (isset($user)) {
289
-			$jsonFile = \OC::$server->getUserManager()->get($user)->getHome() . '/mount.json';
289
+			$jsonFile = \OC::$server->getUserManager()->get($user)->getHome().'/mount.json';
290 290
 		} else {
291 291
 			$config = \OC::$server->getConfig();
292
-			$datadir = $config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data/');
293
-			$jsonFile = $config->getSystemValue('mount_file', $datadir . '/mount.json');
292
+			$datadir = $config->getSystemValue('datadirectory', \OC::$SERVERROOT.'/data/');
293
+			$jsonFile = $config->getSystemValue('mount_file', $datadir.'/mount.json');
294 294
 		}
295 295
 		if (is_file($jsonFile)) {
296 296
 			$mountPoints = json_decode(file_get_contents($jsonFile), true);
@@ -316,7 +316,7 @@  discard block
 block discarded – undo
316 316
 		foreach ($backends as $backend) {
317 317
 			foreach ($backend->checkDependencies() as $dependency) {
318 318
 				if ($message = $dependency->getMessage()) {
319
-					$message .= '<p>' . $message . '</p>';
319
+					$message .= '<p>'.$message.'</p>';
320 320
 				} else {
321 321
 					$dependencyGroups[$dependency->getDependency()][] = $backend;
322 322
 				}
@@ -324,10 +324,10 @@  discard block
 block discarded – undo
324 324
 		}
325 325
 
326 326
 		foreach ($dependencyGroups as $module => $dependants) {
327
-			$backends = implode(', ', array_map(function ($backend) {
328
-				return '"' . $backend->getText() . '"';
327
+			$backends = implode(', ', array_map(function($backend) {
328
+				return '"'.$backend->getText().'"';
329 329
 			}, $dependants));
330
-			$message .= '<p>' . MountConfig::getSingleDependencyMessage($l, $module, $backends) . '</p>';
330
+			$message .= '<p>'.MountConfig::getSingleDependencyMessage($l, $module, $backends).'</p>';
331 331
 		}
332 332
 
333 333
 		return $message;
@@ -344,11 +344,11 @@  discard block
 block discarded – undo
344 344
 	private static function getSingleDependencyMessage(\OCP\IL10N $l, $module, $backend) {
345 345
 		switch (strtolower($module)) {
346 346
 			case 'curl':
347
-				return (string)$l->t('The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it.', [$backend]);
347
+				return (string) $l->t('The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it.', [$backend]);
348 348
 			case 'ftp':
349
-				return (string)$l->t('The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it.', [$backend]);
349
+				return (string) $l->t('The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it.', [$backend]);
350 350
 			default:
351
-				return (string)$l->t('"%1$s" is not installed. Mounting of %2$s is not possible. Please ask your system administrator to install it.', [$module, $backend]);
351
+				return (string) $l->t('"%1$s" is not installed. Mounting of %2$s is not possible. Please ask your system administrator to install it.', [$module, $backend]);
352 352
 		}
353 353
 	}
354 354
 
@@ -393,7 +393,7 @@  discard block
 block discarded – undo
393 393
 		$cipher = self::getCipher();
394 394
 		$iv = \OC::$server->getSecureRandom()->generate(16);
395 395
 		$cipher->setIV($iv);
396
-		return base64_encode($iv . $cipher->encrypt($password));
396
+		return base64_encode($iv.$cipher->encrypt($password));
397 397
 	}
398 398
 
399 399
 	/**
Please login to merge, or discard this patch.
lib/private/Encryption/File.php 1 patch
Indentation   +90 added lines, -90 removed lines patch added patch discarded remove patch
@@ -34,94 +34,94 @@
 block discarded – undo
34 34
 
35 35
 class File implements \OCP\Encryption\IFile {
36 36
 
37
-	/** @var Util */
38
-	protected $util;
39
-
40
-	/** @var IRootFolder */
41
-	private $rootFolder;
42
-
43
-	/** @var IManager */
44
-	private $shareManager;
45
-
46
-	/**
47
-	 * cache results of already checked folders
48
-	 *
49
-	 * @var array
50
-	 */
51
-	protected $cache;
52
-
53
-	public function __construct(Util $util,
54
-								IRootFolder $rootFolder,
55
-								IManager $shareManager) {
56
-		$this->util = $util;
57
-		$this->cache = new CappedMemoryCache();
58
-		$this->rootFolder = $rootFolder;
59
-		$this->shareManager = $shareManager;
60
-	}
61
-
62
-
63
-	/**
64
-	 * get list of users with access to the file
65
-	 *
66
-	 * @param string $path to the file
67
-	 * @return array  ['users' => $uniqueUserIds, 'public' => $public]
68
-	 */
69
-	public function getAccessList($path) {
70
-
71
-		// Make sure that a share key is generated for the owner too
72
-		list($owner, $ownerPath) = $this->util->getUidAndFilename($path);
73
-
74
-		// always add owner to the list of users with access to the file
75
-		$userIds = [$owner];
76
-
77
-		if (!$this->util->isFile($owner . '/' . $ownerPath)) {
78
-			return ['users' => $userIds, 'public' => false];
79
-		}
80
-
81
-		$ownerPath = substr($ownerPath, strlen('/files'));
82
-		$userFolder = $this->rootFolder->getUserFolder($owner);
83
-		try {
84
-			$file = $userFolder->get($ownerPath);
85
-		} catch (NotFoundException $e) {
86
-			$file = null;
87
-		}
88
-		$ownerPath = $this->util->stripPartialFileExtension($ownerPath);
89
-
90
-		// first get the shares for the parent and cache the result so that we don't
91
-		// need to check all parents for every file
92
-		$parent = dirname($ownerPath);
93
-		$parentNode = $userFolder->get($parent);
94
-		if (isset($this->cache[$parent])) {
95
-			$resultForParents = $this->cache[$parent];
96
-		} else {
97
-			$resultForParents = $this->shareManager->getAccessList($parentNode);
98
-			$this->cache[$parent] = $resultForParents;
99
-		}
100
-		$userIds = array_merge($userIds, $resultForParents['users']);
101
-		$public = $resultForParents['public'] || $resultForParents['remote'];
102
-
103
-
104
-		// Find out who, if anyone, is sharing the file
105
-		if ($file !== null) {
106
-			$resultForFile = $this->shareManager->getAccessList($file, false);
107
-			$userIds = array_merge($userIds, $resultForFile['users']);
108
-			$public = $resultForFile['public'] || $resultForFile['remote'] || $public;
109
-		}
110
-
111
-		// check if it is a group mount
112
-		if (\OCP\App::isEnabled("files_external")) {
113
-			$mounts = \OCA\Files_External\MountConfig::getSystemMountPoints();
114
-			foreach ($mounts as $mount) {
115
-				if ($mount['mountpoint'] == substr($ownerPath, 1, strlen($mount['mountpoint']))) {
116
-					$mountedFor = $this->util->getUserWithAccessToMountPoint($mount['applicable']['users'], $mount['applicable']['groups']);
117
-					$userIds = array_merge($userIds, $mountedFor);
118
-				}
119
-			}
120
-		}
121
-
122
-		// Remove duplicate UIDs
123
-		$uniqueUserIds = array_unique($userIds);
124
-
125
-		return ['users' => $uniqueUserIds, 'public' => $public];
126
-	}
37
+    /** @var Util */
38
+    protected $util;
39
+
40
+    /** @var IRootFolder */
41
+    private $rootFolder;
42
+
43
+    /** @var IManager */
44
+    private $shareManager;
45
+
46
+    /**
47
+     * cache results of already checked folders
48
+     *
49
+     * @var array
50
+     */
51
+    protected $cache;
52
+
53
+    public function __construct(Util $util,
54
+                                IRootFolder $rootFolder,
55
+                                IManager $shareManager) {
56
+        $this->util = $util;
57
+        $this->cache = new CappedMemoryCache();
58
+        $this->rootFolder = $rootFolder;
59
+        $this->shareManager = $shareManager;
60
+    }
61
+
62
+
63
+    /**
64
+     * get list of users with access to the file
65
+     *
66
+     * @param string $path to the file
67
+     * @return array  ['users' => $uniqueUserIds, 'public' => $public]
68
+     */
69
+    public function getAccessList($path) {
70
+
71
+        // Make sure that a share key is generated for the owner too
72
+        list($owner, $ownerPath) = $this->util->getUidAndFilename($path);
73
+
74
+        // always add owner to the list of users with access to the file
75
+        $userIds = [$owner];
76
+
77
+        if (!$this->util->isFile($owner . '/' . $ownerPath)) {
78
+            return ['users' => $userIds, 'public' => false];
79
+        }
80
+
81
+        $ownerPath = substr($ownerPath, strlen('/files'));
82
+        $userFolder = $this->rootFolder->getUserFolder($owner);
83
+        try {
84
+            $file = $userFolder->get($ownerPath);
85
+        } catch (NotFoundException $e) {
86
+            $file = null;
87
+        }
88
+        $ownerPath = $this->util->stripPartialFileExtension($ownerPath);
89
+
90
+        // first get the shares for the parent and cache the result so that we don't
91
+        // need to check all parents for every file
92
+        $parent = dirname($ownerPath);
93
+        $parentNode = $userFolder->get($parent);
94
+        if (isset($this->cache[$parent])) {
95
+            $resultForParents = $this->cache[$parent];
96
+        } else {
97
+            $resultForParents = $this->shareManager->getAccessList($parentNode);
98
+            $this->cache[$parent] = $resultForParents;
99
+        }
100
+        $userIds = array_merge($userIds, $resultForParents['users']);
101
+        $public = $resultForParents['public'] || $resultForParents['remote'];
102
+
103
+
104
+        // Find out who, if anyone, is sharing the file
105
+        if ($file !== null) {
106
+            $resultForFile = $this->shareManager->getAccessList($file, false);
107
+            $userIds = array_merge($userIds, $resultForFile['users']);
108
+            $public = $resultForFile['public'] || $resultForFile['remote'] || $public;
109
+        }
110
+
111
+        // check if it is a group mount
112
+        if (\OCP\App::isEnabled("files_external")) {
113
+            $mounts = \OCA\Files_External\MountConfig::getSystemMountPoints();
114
+            foreach ($mounts as $mount) {
115
+                if ($mount['mountpoint'] == substr($ownerPath, 1, strlen($mount['mountpoint']))) {
116
+                    $mountedFor = $this->util->getUserWithAccessToMountPoint($mount['applicable']['users'], $mount['applicable']['groups']);
117
+                    $userIds = array_merge($userIds, $mountedFor);
118
+                }
119
+            }
120
+        }
121
+
122
+        // Remove duplicate UIDs
123
+        $uniqueUserIds = array_unique($userIds);
124
+
125
+        return ['users' => $uniqueUserIds, 'public' => $public];
126
+    }
127 127
 }
Please login to merge, or discard this patch.
lib/private/Encryption/Util.php 2 patches
Indentation   +362 added lines, -362 removed lines patch added patch discarded remove patch
@@ -38,366 +38,366 @@
 block discarded – undo
38 38
 use OCP\IUser;
39 39
 
40 40
 class Util {
41
-	public const HEADER_START = 'HBEGIN';
42
-	public const HEADER_END = 'HEND';
43
-	public const HEADER_PADDING_CHAR = '-';
44
-
45
-	public const HEADER_ENCRYPTION_MODULE_KEY = 'oc_encryption_module';
46
-
47
-	/**
48
-	 * block size will always be 8192 for a PHP stream
49
-	 * @see https://bugs.php.net/bug.php?id=21641
50
-	 * @var integer
51
-	 */
52
-	protected $headerSize = 8192;
53
-
54
-	/**
55
-	 * block size will always be 8192 for a PHP stream
56
-	 * @see https://bugs.php.net/bug.php?id=21641
57
-	 * @var integer
58
-	 */
59
-	protected $blockSize = 8192;
60
-
61
-	/** @var View */
62
-	protected $rootView;
63
-
64
-	/** @var array */
65
-	protected $ocHeaderKeys;
66
-
67
-	/** @var \OC\User\Manager */
68
-	protected $userManager;
69
-
70
-	/** @var IConfig */
71
-	protected $config;
72
-
73
-	/** @var array paths excluded from encryption */
74
-	protected $excludedPaths;
75
-
76
-	/** @var \OC\Group\Manager $manager */
77
-	protected $groupManager;
78
-
79
-	/**
80
-	 *
81
-	 * @param View $rootView
82
-	 * @param \OC\User\Manager $userManager
83
-	 * @param \OC\Group\Manager $groupManager
84
-	 * @param IConfig $config
85
-	 */
86
-	public function __construct(
87
-		View $rootView,
88
-		\OC\User\Manager $userManager,
89
-		\OC\Group\Manager $groupManager,
90
-		IConfig $config) {
91
-		$this->ocHeaderKeys = [
92
-			self::HEADER_ENCRYPTION_MODULE_KEY
93
-		];
94
-
95
-		$this->rootView = $rootView;
96
-		$this->userManager = $userManager;
97
-		$this->groupManager = $groupManager;
98
-		$this->config = $config;
99
-
100
-		$this->excludedPaths[] = 'files_encryption';
101
-		$this->excludedPaths[] = 'appdata_' . $config->getSystemValue('instanceid', null);
102
-		$this->excludedPaths[] = 'files_external';
103
-	}
104
-
105
-	/**
106
-	 * read encryption module ID from header
107
-	 *
108
-	 * @param array $header
109
-	 * @return string
110
-	 * @throws ModuleDoesNotExistsException
111
-	 */
112
-	public function getEncryptionModuleId(array $header = null) {
113
-		$id = '';
114
-		$encryptionModuleKey = self::HEADER_ENCRYPTION_MODULE_KEY;
115
-
116
-		if (isset($header[$encryptionModuleKey])) {
117
-			$id = $header[$encryptionModuleKey];
118
-		} elseif (isset($header['cipher'])) {
119
-			if (class_exists('\OCA\Encryption\Crypto\Encryption')) {
120
-				// fall back to default encryption if the user migrated from
121
-				// ownCloud <= 8.0 with the old encryption
122
-				$id = \OCA\Encryption\Crypto\Encryption::ID;
123
-			} else {
124
-				throw new ModuleDoesNotExistsException('Default encryption module missing');
125
-			}
126
-		}
127
-
128
-		return $id;
129
-	}
130
-
131
-	/**
132
-	 * create header for encrypted file
133
-	 *
134
-	 * @param array $headerData
135
-	 * @param IEncryptionModule $encryptionModule
136
-	 * @return string
137
-	 * @throws EncryptionHeaderToLargeException if header has to many arguments
138
-	 * @throws EncryptionHeaderKeyExistsException if header key is already in use
139
-	 */
140
-	public function createHeader(array $headerData, IEncryptionModule $encryptionModule) {
141
-		$header = self::HEADER_START . ':' . self::HEADER_ENCRYPTION_MODULE_KEY . ':' . $encryptionModule->getId() . ':';
142
-		foreach ($headerData as $key => $value) {
143
-			if (in_array($key, $this->ocHeaderKeys)) {
144
-				throw new EncryptionHeaderKeyExistsException($key);
145
-			}
146
-			$header .= $key . ':' . $value . ':';
147
-		}
148
-		$header .= self::HEADER_END;
149
-
150
-		if (strlen($header) > $this->getHeaderSize()) {
151
-			throw new EncryptionHeaderToLargeException();
152
-		}
153
-
154
-		$paddedHeader = str_pad($header, $this->headerSize, self::HEADER_PADDING_CHAR, STR_PAD_RIGHT);
155
-
156
-		return $paddedHeader;
157
-	}
158
-
159
-	/**
160
-	 * go recursively through a dir and collect all files and sub files.
161
-	 *
162
-	 * @param string $dir relative to the users files folder
163
-	 * @return array with list of files relative to the users files folder
164
-	 */
165
-	public function getAllFiles($dir) {
166
-		$result = [];
167
-		$dirList = [$dir];
168
-
169
-		while ($dirList) {
170
-			$dir = array_pop($dirList);
171
-			$content = $this->rootView->getDirectoryContent($dir);
172
-
173
-			foreach ($content as $c) {
174
-				if ($c->getType() === 'dir') {
175
-					$dirList[] = $c->getPath();
176
-				} else {
177
-					$result[] =  $c->getPath();
178
-				}
179
-			}
180
-		}
181
-
182
-		return $result;
183
-	}
184
-
185
-	/**
186
-	 * check if it is a file uploaded by the user stored in data/user/files
187
-	 * or a metadata file
188
-	 *
189
-	 * @param string $path relative to the data/ folder
190
-	 * @return boolean
191
-	 */
192
-	public function isFile($path) {
193
-		$parts = explode('/', Filesystem::normalizePath($path), 4);
194
-		if (isset($parts[2]) && $parts[2] === 'files') {
195
-			return true;
196
-		}
197
-		return false;
198
-	}
199
-
200
-	/**
201
-	 * return size of encryption header
202
-	 *
203
-	 * @return integer
204
-	 */
205
-	public function getHeaderSize() {
206
-		return $this->headerSize;
207
-	}
208
-
209
-	/**
210
-	 * return size of block read by a PHP stream
211
-	 *
212
-	 * @return integer
213
-	 */
214
-	public function getBlockSize() {
215
-		return $this->blockSize;
216
-	}
217
-
218
-	/**
219
-	 * get the owner and the path for the file relative to the owners files folder
220
-	 *
221
-	 * @param string $path
222
-	 * @return array
223
-	 * @throws \BadMethodCallException
224
-	 */
225
-	public function getUidAndFilename($path) {
226
-		$parts = explode('/', $path);
227
-		$uid = '';
228
-		if (count($parts) > 2) {
229
-			$uid = $parts[1];
230
-		}
231
-		if (!$this->userManager->userExists($uid)) {
232
-			throw new \BadMethodCallException(
233
-				'path needs to be relative to the system wide data folder and point to a user specific file'
234
-			);
235
-		}
236
-
237
-		$ownerPath = implode('/', array_slice($parts, 2));
238
-
239
-		return [$uid, Filesystem::normalizePath($ownerPath)];
240
-	}
241
-
242
-	/**
243
-	 * Remove .path extension from a file path
244
-	 * @param string $path Path that may identify a .part file
245
-	 * @return string File path without .part extension
246
-	 * @note this is needed for reusing keys
247
-	 */
248
-	public function stripPartialFileExtension($path) {
249
-		$extension = pathinfo($path, PATHINFO_EXTENSION);
250
-
251
-		if ($extension === 'part') {
252
-			$newLength = strlen($path) - 5; // 5 = strlen(".part")
253
-			$fPath = substr($path, 0, $newLength);
254
-
255
-			// if path also contains a transaction id, we remove it too
256
-			$extension = pathinfo($fPath, PATHINFO_EXTENSION);
257
-			if (substr($extension, 0, 12) === 'ocTransferId') { // 12 = strlen("ocTransferId")
258
-				$newLength = strlen($fPath) - strlen($extension) -1;
259
-				$fPath = substr($fPath, 0, $newLength);
260
-			}
261
-			return $fPath;
262
-		} else {
263
-			return $path;
264
-		}
265
-	}
266
-
267
-	public function getUserWithAccessToMountPoint($users, $groups) {
268
-		$result = [];
269
-		if (in_array('all', $users)) {
270
-			$users = $this->userManager->search('', null, null);
271
-			$result = array_map(function (IUser $user) {
272
-				return $user->getUID();
273
-			}, $users);
274
-		} else {
275
-			$result = array_merge($result, $users);
276
-
277
-			$groupManager = \OC::$server->getGroupManager();
278
-			foreach ($groups as $group) {
279
-				$groupObject = $groupManager->get($group);
280
-				if ($groupObject) {
281
-					$foundUsers = $groupObject->searchUsers('', -1, 0);
282
-					$userIds = [];
283
-					foreach ($foundUsers as $user) {
284
-						$userIds[] = $user->getUID();
285
-					}
286
-					$result = array_merge($result, $userIds);
287
-				}
288
-			}
289
-		}
290
-
291
-		return $result;
292
-	}
293
-
294
-	/**
295
-	 * check if the file is stored on a system wide mount point
296
-	 * @param string $path relative to /data/user with leading '/'
297
-	 * @param string $uid
298
-	 * @return boolean
299
-	 */
300
-	public function isSystemWideMountPoint($path, $uid) {
301
-		if (\OCP\App::isEnabled("files_external")) {
302
-			$mounts = \OCA\Files_External\MountConfig::getSystemMountPoints();
303
-			foreach ($mounts as $mount) {
304
-				if (strpos($path, '/files/' . $mount['mountpoint']) === 0) {
305
-					if ($this->isMountPointApplicableToUser($mount, $uid)) {
306
-						return true;
307
-					}
308
-				}
309
-			}
310
-		}
311
-		return false;
312
-	}
313
-
314
-	/**
315
-	 * check if mount point is applicable to user
316
-	 *
317
-	 * @param array $mount contains $mount['applicable']['users'], $mount['applicable']['groups']
318
-	 * @param string $uid
319
-	 * @return boolean
320
-	 */
321
-	private function isMountPointApplicableToUser($mount, $uid) {
322
-		$acceptedUids = ['all', $uid];
323
-		// check if mount point is applicable for the user
324
-		$intersection = array_intersect($acceptedUids, $mount['applicable']['users']);
325
-		if (!empty($intersection)) {
326
-			return true;
327
-		}
328
-		// check if mount point is applicable for group where the user is a member
329
-		foreach ($mount['applicable']['groups'] as $gid) {
330
-			if ($this->groupManager->isInGroup($uid, $gid)) {
331
-				return true;
332
-			}
333
-		}
334
-		return false;
335
-	}
336
-
337
-	/**
338
-	 * check if it is a path which is excluded by ownCloud from encryption
339
-	 *
340
-	 * @param string $path
341
-	 * @return boolean
342
-	 */
343
-	public function isExcluded($path) {
344
-		$normalizedPath = Filesystem::normalizePath($path);
345
-		$root = explode('/', $normalizedPath, 4);
346
-		if (count($root) > 1) {
347
-
348
-			// detect alternative key storage root
349
-			$rootDir = $this->getKeyStorageRoot();
350
-			if ($rootDir !== '' &&
351
-				0 === strpos(
352
-					Filesystem::normalizePath($path),
353
-					Filesystem::normalizePath($rootDir)
354
-				)
355
-			) {
356
-				return true;
357
-			}
358
-
359
-
360
-			//detect system wide folders
361
-			if (in_array($root[1], $this->excludedPaths)) {
362
-				return true;
363
-			}
364
-
365
-			// detect user specific folders
366
-			if ($this->userManager->userExists($root[1])
367
-				&& in_array($root[2], $this->excludedPaths)) {
368
-				return true;
369
-			}
370
-		}
371
-		return false;
372
-	}
373
-
374
-	/**
375
-	 * check if recovery key is enabled for user
376
-	 *
377
-	 * @param string $uid
378
-	 * @return boolean
379
-	 */
380
-	public function recoveryEnabled($uid) {
381
-		$enabled = $this->config->getUserValue($uid, 'encryption', 'recovery_enabled', '0');
382
-
383
-		return $enabled === '1';
384
-	}
385
-
386
-	/**
387
-	 * set new key storage root
388
-	 *
389
-	 * @param string $root new key store root relative to the data folder
390
-	 */
391
-	public function setKeyStorageRoot($root) {
392
-		$this->config->setAppValue('core', 'encryption_key_storage_root', $root);
393
-	}
394
-
395
-	/**
396
-	 * get key storage root
397
-	 *
398
-	 * @return string key storage root
399
-	 */
400
-	public function getKeyStorageRoot() {
401
-		return $this->config->getAppValue('core', 'encryption_key_storage_root', '');
402
-	}
41
+    public const HEADER_START = 'HBEGIN';
42
+    public const HEADER_END = 'HEND';
43
+    public const HEADER_PADDING_CHAR = '-';
44
+
45
+    public const HEADER_ENCRYPTION_MODULE_KEY = 'oc_encryption_module';
46
+
47
+    /**
48
+     * block size will always be 8192 for a PHP stream
49
+     * @see https://bugs.php.net/bug.php?id=21641
50
+     * @var integer
51
+     */
52
+    protected $headerSize = 8192;
53
+
54
+    /**
55
+     * block size will always be 8192 for a PHP stream
56
+     * @see https://bugs.php.net/bug.php?id=21641
57
+     * @var integer
58
+     */
59
+    protected $blockSize = 8192;
60
+
61
+    /** @var View */
62
+    protected $rootView;
63
+
64
+    /** @var array */
65
+    protected $ocHeaderKeys;
66
+
67
+    /** @var \OC\User\Manager */
68
+    protected $userManager;
69
+
70
+    /** @var IConfig */
71
+    protected $config;
72
+
73
+    /** @var array paths excluded from encryption */
74
+    protected $excludedPaths;
75
+
76
+    /** @var \OC\Group\Manager $manager */
77
+    protected $groupManager;
78
+
79
+    /**
80
+     *
81
+     * @param View $rootView
82
+     * @param \OC\User\Manager $userManager
83
+     * @param \OC\Group\Manager $groupManager
84
+     * @param IConfig $config
85
+     */
86
+    public function __construct(
87
+        View $rootView,
88
+        \OC\User\Manager $userManager,
89
+        \OC\Group\Manager $groupManager,
90
+        IConfig $config) {
91
+        $this->ocHeaderKeys = [
92
+            self::HEADER_ENCRYPTION_MODULE_KEY
93
+        ];
94
+
95
+        $this->rootView = $rootView;
96
+        $this->userManager = $userManager;
97
+        $this->groupManager = $groupManager;
98
+        $this->config = $config;
99
+
100
+        $this->excludedPaths[] = 'files_encryption';
101
+        $this->excludedPaths[] = 'appdata_' . $config->getSystemValue('instanceid', null);
102
+        $this->excludedPaths[] = 'files_external';
103
+    }
104
+
105
+    /**
106
+     * read encryption module ID from header
107
+     *
108
+     * @param array $header
109
+     * @return string
110
+     * @throws ModuleDoesNotExistsException
111
+     */
112
+    public function getEncryptionModuleId(array $header = null) {
113
+        $id = '';
114
+        $encryptionModuleKey = self::HEADER_ENCRYPTION_MODULE_KEY;
115
+
116
+        if (isset($header[$encryptionModuleKey])) {
117
+            $id = $header[$encryptionModuleKey];
118
+        } elseif (isset($header['cipher'])) {
119
+            if (class_exists('\OCA\Encryption\Crypto\Encryption')) {
120
+                // fall back to default encryption if the user migrated from
121
+                // ownCloud <= 8.0 with the old encryption
122
+                $id = \OCA\Encryption\Crypto\Encryption::ID;
123
+            } else {
124
+                throw new ModuleDoesNotExistsException('Default encryption module missing');
125
+            }
126
+        }
127
+
128
+        return $id;
129
+    }
130
+
131
+    /**
132
+     * create header for encrypted file
133
+     *
134
+     * @param array $headerData
135
+     * @param IEncryptionModule $encryptionModule
136
+     * @return string
137
+     * @throws EncryptionHeaderToLargeException if header has to many arguments
138
+     * @throws EncryptionHeaderKeyExistsException if header key is already in use
139
+     */
140
+    public function createHeader(array $headerData, IEncryptionModule $encryptionModule) {
141
+        $header = self::HEADER_START . ':' . self::HEADER_ENCRYPTION_MODULE_KEY . ':' . $encryptionModule->getId() . ':';
142
+        foreach ($headerData as $key => $value) {
143
+            if (in_array($key, $this->ocHeaderKeys)) {
144
+                throw new EncryptionHeaderKeyExistsException($key);
145
+            }
146
+            $header .= $key . ':' . $value . ':';
147
+        }
148
+        $header .= self::HEADER_END;
149
+
150
+        if (strlen($header) > $this->getHeaderSize()) {
151
+            throw new EncryptionHeaderToLargeException();
152
+        }
153
+
154
+        $paddedHeader = str_pad($header, $this->headerSize, self::HEADER_PADDING_CHAR, STR_PAD_RIGHT);
155
+
156
+        return $paddedHeader;
157
+    }
158
+
159
+    /**
160
+     * go recursively through a dir and collect all files and sub files.
161
+     *
162
+     * @param string $dir relative to the users files folder
163
+     * @return array with list of files relative to the users files folder
164
+     */
165
+    public function getAllFiles($dir) {
166
+        $result = [];
167
+        $dirList = [$dir];
168
+
169
+        while ($dirList) {
170
+            $dir = array_pop($dirList);
171
+            $content = $this->rootView->getDirectoryContent($dir);
172
+
173
+            foreach ($content as $c) {
174
+                if ($c->getType() === 'dir') {
175
+                    $dirList[] = $c->getPath();
176
+                } else {
177
+                    $result[] =  $c->getPath();
178
+                }
179
+            }
180
+        }
181
+
182
+        return $result;
183
+    }
184
+
185
+    /**
186
+     * check if it is a file uploaded by the user stored in data/user/files
187
+     * or a metadata file
188
+     *
189
+     * @param string $path relative to the data/ folder
190
+     * @return boolean
191
+     */
192
+    public function isFile($path) {
193
+        $parts = explode('/', Filesystem::normalizePath($path), 4);
194
+        if (isset($parts[2]) && $parts[2] === 'files') {
195
+            return true;
196
+        }
197
+        return false;
198
+    }
199
+
200
+    /**
201
+     * return size of encryption header
202
+     *
203
+     * @return integer
204
+     */
205
+    public function getHeaderSize() {
206
+        return $this->headerSize;
207
+    }
208
+
209
+    /**
210
+     * return size of block read by a PHP stream
211
+     *
212
+     * @return integer
213
+     */
214
+    public function getBlockSize() {
215
+        return $this->blockSize;
216
+    }
217
+
218
+    /**
219
+     * get the owner and the path for the file relative to the owners files folder
220
+     *
221
+     * @param string $path
222
+     * @return array
223
+     * @throws \BadMethodCallException
224
+     */
225
+    public function getUidAndFilename($path) {
226
+        $parts = explode('/', $path);
227
+        $uid = '';
228
+        if (count($parts) > 2) {
229
+            $uid = $parts[1];
230
+        }
231
+        if (!$this->userManager->userExists($uid)) {
232
+            throw new \BadMethodCallException(
233
+                'path needs to be relative to the system wide data folder and point to a user specific file'
234
+            );
235
+        }
236
+
237
+        $ownerPath = implode('/', array_slice($parts, 2));
238
+
239
+        return [$uid, Filesystem::normalizePath($ownerPath)];
240
+    }
241
+
242
+    /**
243
+     * Remove .path extension from a file path
244
+     * @param string $path Path that may identify a .part file
245
+     * @return string File path without .part extension
246
+     * @note this is needed for reusing keys
247
+     */
248
+    public function stripPartialFileExtension($path) {
249
+        $extension = pathinfo($path, PATHINFO_EXTENSION);
250
+
251
+        if ($extension === 'part') {
252
+            $newLength = strlen($path) - 5; // 5 = strlen(".part")
253
+            $fPath = substr($path, 0, $newLength);
254
+
255
+            // if path also contains a transaction id, we remove it too
256
+            $extension = pathinfo($fPath, PATHINFO_EXTENSION);
257
+            if (substr($extension, 0, 12) === 'ocTransferId') { // 12 = strlen("ocTransferId")
258
+                $newLength = strlen($fPath) - strlen($extension) -1;
259
+                $fPath = substr($fPath, 0, $newLength);
260
+            }
261
+            return $fPath;
262
+        } else {
263
+            return $path;
264
+        }
265
+    }
266
+
267
+    public function getUserWithAccessToMountPoint($users, $groups) {
268
+        $result = [];
269
+        if (in_array('all', $users)) {
270
+            $users = $this->userManager->search('', null, null);
271
+            $result = array_map(function (IUser $user) {
272
+                return $user->getUID();
273
+            }, $users);
274
+        } else {
275
+            $result = array_merge($result, $users);
276
+
277
+            $groupManager = \OC::$server->getGroupManager();
278
+            foreach ($groups as $group) {
279
+                $groupObject = $groupManager->get($group);
280
+                if ($groupObject) {
281
+                    $foundUsers = $groupObject->searchUsers('', -1, 0);
282
+                    $userIds = [];
283
+                    foreach ($foundUsers as $user) {
284
+                        $userIds[] = $user->getUID();
285
+                    }
286
+                    $result = array_merge($result, $userIds);
287
+                }
288
+            }
289
+        }
290
+
291
+        return $result;
292
+    }
293
+
294
+    /**
295
+     * check if the file is stored on a system wide mount point
296
+     * @param string $path relative to /data/user with leading '/'
297
+     * @param string $uid
298
+     * @return boolean
299
+     */
300
+    public function isSystemWideMountPoint($path, $uid) {
301
+        if (\OCP\App::isEnabled("files_external")) {
302
+            $mounts = \OCA\Files_External\MountConfig::getSystemMountPoints();
303
+            foreach ($mounts as $mount) {
304
+                if (strpos($path, '/files/' . $mount['mountpoint']) === 0) {
305
+                    if ($this->isMountPointApplicableToUser($mount, $uid)) {
306
+                        return true;
307
+                    }
308
+                }
309
+            }
310
+        }
311
+        return false;
312
+    }
313
+
314
+    /**
315
+     * check if mount point is applicable to user
316
+     *
317
+     * @param array $mount contains $mount['applicable']['users'], $mount['applicable']['groups']
318
+     * @param string $uid
319
+     * @return boolean
320
+     */
321
+    private function isMountPointApplicableToUser($mount, $uid) {
322
+        $acceptedUids = ['all', $uid];
323
+        // check if mount point is applicable for the user
324
+        $intersection = array_intersect($acceptedUids, $mount['applicable']['users']);
325
+        if (!empty($intersection)) {
326
+            return true;
327
+        }
328
+        // check if mount point is applicable for group where the user is a member
329
+        foreach ($mount['applicable']['groups'] as $gid) {
330
+            if ($this->groupManager->isInGroup($uid, $gid)) {
331
+                return true;
332
+            }
333
+        }
334
+        return false;
335
+    }
336
+
337
+    /**
338
+     * check if it is a path which is excluded by ownCloud from encryption
339
+     *
340
+     * @param string $path
341
+     * @return boolean
342
+     */
343
+    public function isExcluded($path) {
344
+        $normalizedPath = Filesystem::normalizePath($path);
345
+        $root = explode('/', $normalizedPath, 4);
346
+        if (count($root) > 1) {
347
+
348
+            // detect alternative key storage root
349
+            $rootDir = $this->getKeyStorageRoot();
350
+            if ($rootDir !== '' &&
351
+                0 === strpos(
352
+                    Filesystem::normalizePath($path),
353
+                    Filesystem::normalizePath($rootDir)
354
+                )
355
+            ) {
356
+                return true;
357
+            }
358
+
359
+
360
+            //detect system wide folders
361
+            if (in_array($root[1], $this->excludedPaths)) {
362
+                return true;
363
+            }
364
+
365
+            // detect user specific folders
366
+            if ($this->userManager->userExists($root[1])
367
+                && in_array($root[2], $this->excludedPaths)) {
368
+                return true;
369
+            }
370
+        }
371
+        return false;
372
+    }
373
+
374
+    /**
375
+     * check if recovery key is enabled for user
376
+     *
377
+     * @param string $uid
378
+     * @return boolean
379
+     */
380
+    public function recoveryEnabled($uid) {
381
+        $enabled = $this->config->getUserValue($uid, 'encryption', 'recovery_enabled', '0');
382
+
383
+        return $enabled === '1';
384
+    }
385
+
386
+    /**
387
+     * set new key storage root
388
+     *
389
+     * @param string $root new key store root relative to the data folder
390
+     */
391
+    public function setKeyStorageRoot($root) {
392
+        $this->config->setAppValue('core', 'encryption_key_storage_root', $root);
393
+    }
394
+
395
+    /**
396
+     * get key storage root
397
+     *
398
+     * @return string key storage root
399
+     */
400
+    public function getKeyStorageRoot() {
401
+        return $this->config->getAppValue('core', 'encryption_key_storage_root', '');
402
+    }
403 403
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -98,7 +98,7 @@  discard block
 block discarded – undo
98 98
 		$this->config = $config;
99 99
 
100 100
 		$this->excludedPaths[] = 'files_encryption';
101
-		$this->excludedPaths[] = 'appdata_' . $config->getSystemValue('instanceid', null);
101
+		$this->excludedPaths[] = 'appdata_'.$config->getSystemValue('instanceid', null);
102 102
 		$this->excludedPaths[] = 'files_external';
103 103
 	}
104 104
 
@@ -138,12 +138,12 @@  discard block
 block discarded – undo
138 138
 	 * @throws EncryptionHeaderKeyExistsException if header key is already in use
139 139
 	 */
140 140
 	public function createHeader(array $headerData, IEncryptionModule $encryptionModule) {
141
-		$header = self::HEADER_START . ':' . self::HEADER_ENCRYPTION_MODULE_KEY . ':' . $encryptionModule->getId() . ':';
141
+		$header = self::HEADER_START.':'.self::HEADER_ENCRYPTION_MODULE_KEY.':'.$encryptionModule->getId().':';
142 142
 		foreach ($headerData as $key => $value) {
143 143
 			if (in_array($key, $this->ocHeaderKeys)) {
144 144
 				throw new EncryptionHeaderKeyExistsException($key);
145 145
 			}
146
-			$header .= $key . ':' . $value . ':';
146
+			$header .= $key.':'.$value.':';
147 147
 		}
148 148
 		$header .= self::HEADER_END;
149 149
 
@@ -174,7 +174,7 @@  discard block
 block discarded – undo
174 174
 				if ($c->getType() === 'dir') {
175 175
 					$dirList[] = $c->getPath();
176 176
 				} else {
177
-					$result[] =  $c->getPath();
177
+					$result[] = $c->getPath();
178 178
 				}
179 179
 			}
180 180
 		}
@@ -255,7 +255,7 @@  discard block
 block discarded – undo
255 255
 			// if path also contains a transaction id, we remove it too
256 256
 			$extension = pathinfo($fPath, PATHINFO_EXTENSION);
257 257
 			if (substr($extension, 0, 12) === 'ocTransferId') { // 12 = strlen("ocTransferId")
258
-				$newLength = strlen($fPath) - strlen($extension) -1;
258
+				$newLength = strlen($fPath) - strlen($extension) - 1;
259 259
 				$fPath = substr($fPath, 0, $newLength);
260 260
 			}
261 261
 			return $fPath;
@@ -268,7 +268,7 @@  discard block
 block discarded – undo
268 268
 		$result = [];
269 269
 		if (in_array('all', $users)) {
270 270
 			$users = $this->userManager->search('', null, null);
271
-			$result = array_map(function (IUser $user) {
271
+			$result = array_map(function(IUser $user) {
272 272
 				return $user->getUID();
273 273
 			}, $users);
274 274
 		} else {
@@ -301,7 +301,7 @@  discard block
 block discarded – undo
301 301
 		if (\OCP\App::isEnabled("files_external")) {
302 302
 			$mounts = \OCA\Files_External\MountConfig::getSystemMountPoints();
303 303
 			foreach ($mounts as $mount) {
304
-				if (strpos($path, '/files/' . $mount['mountpoint']) === 0) {
304
+				if (strpos($path, '/files/'.$mount['mountpoint']) === 0) {
305 305
 					if ($this->isMountPointApplicableToUser($mount, $uid)) {
306 306
 						return true;
307 307
 					}
Please login to merge, or discard this patch.
lib/private/Log/ExceptionSerializer.php 1 patch
Indentation   +152 added lines, -152 removed lines patch added patch discarded remove patch
@@ -34,156 +34,156 @@
 block discarded – undo
34 34
 use OC\Setup;
35 35
 
36 36
 class ExceptionSerializer {
37
-	public const methodsWithSensitiveParameters = [
38
-		// Session/User
39
-		'completeLogin',
40
-		'login',
41
-		'checkPassword',
42
-		'checkPasswordNoLogging',
43
-		'loginWithPassword',
44
-		'updatePrivateKeyPassword',
45
-		'validateUserPass',
46
-		'loginWithToken',
47
-		'{closure}',
48
-		'createSessionToken',
49
-
50
-		// Provisioning
51
-		'addUser',
52
-
53
-		// TokenProvider
54
-		'getToken',
55
-		'isTokenPassword',
56
-		'getPassword',
57
-		'decryptPassword',
58
-		'logClientIn',
59
-		'generateToken',
60
-		'validateToken',
61
-
62
-		// TwoFactorAuth
63
-		'solveChallenge',
64
-		'verifyChallenge',
65
-
66
-		// ICrypto
67
-		'calculateHMAC',
68
-		'encrypt',
69
-		'decrypt',
70
-
71
-		// LoginController
72
-		'tryLogin',
73
-		'confirmPassword',
74
-
75
-		// LDAP
76
-		'bind',
77
-		'areCredentialsValid',
78
-		'invokeLDAPMethod',
79
-
80
-		// Encryption
81
-		'storeKeyPair',
82
-		'setupUser',
83
-
84
-		// files_external: OCA\Files_External\MountConfig
85
-		'getBackendStatus',
86
-
87
-		// files_external: UserStoragesController
88
-		'update',
89
-	];
90
-
91
-	public const methodsWithSensitiveParametersByClass = [
92
-		SetupController::class => [
93
-			'run',
94
-			'display',
95
-			'loadAutoConfig',
96
-		],
97
-		Setup::class => [
98
-			'install'
99
-		],
100
-		Key::class => [
101
-			'__construct'
102
-		],
103
-	];
104
-
105
-	private function editTrace(array &$sensitiveValues, array $traceLine): array {
106
-		if (isset($traceLine['args'])) {
107
-			$sensitiveValues = array_merge($sensitiveValues, $traceLine['args']);
108
-		}
109
-		$traceLine['args'] = ['*** sensitive parameters replaced ***'];
110
-		return $traceLine;
111
-	}
112
-
113
-	private function filterTrace(array $trace) {
114
-		$sensitiveValues = [];
115
-		$trace = array_map(function (array $traceLine) use (&$sensitiveValues) {
116
-			$className = $traceLine['class'] ?? '';
117
-			if ($className && isset(self::methodsWithSensitiveParametersByClass[$className])
118
-				&& in_array($traceLine['function'], self::methodsWithSensitiveParametersByClass[$className], true)) {
119
-				return $this->editTrace($sensitiveValues, $traceLine);
120
-			}
121
-			foreach (self::methodsWithSensitiveParameters as $sensitiveMethod) {
122
-				if (strpos($traceLine['function'], $sensitiveMethod) !== false) {
123
-					return $this->editTrace($sensitiveValues, $traceLine);
124
-				}
125
-			}
126
-			return $traceLine;
127
-		}, $trace);
128
-		return array_map(function (array $traceLine) use ($sensitiveValues) {
129
-			if (isset($traceLine['args'])) {
130
-				$traceLine['args'] = $this->removeValuesFromArgs($traceLine['args'], $sensitiveValues);
131
-			}
132
-			return $traceLine;
133
-		}, $trace);
134
-	}
135
-
136
-	private function removeValuesFromArgs($args, $values) {
137
-		foreach ($args as &$arg) {
138
-			if (in_array($arg, $values, true)) {
139
-				$arg = '*** sensitive parameter replaced ***';
140
-			} elseif (is_array($arg)) {
141
-				$arg = $this->removeValuesFromArgs($arg, $values);
142
-			}
143
-		}
144
-		return $args;
145
-	}
146
-
147
-	private function encodeTrace($trace) {
148
-		$filteredTrace = $this->filterTrace($trace);
149
-		return array_map(function (array $line) {
150
-			if (isset($line['args'])) {
151
-				$line['args'] = array_map([$this, 'encodeArg'], $line['args']);
152
-			}
153
-			return $line;
154
-		}, $filteredTrace);
155
-	}
156
-
157
-	private function encodeArg($arg) {
158
-		if (is_object($arg)) {
159
-			$data = get_object_vars($arg);
160
-			$data['__class__'] = get_class($arg);
161
-			return array_map([$this, 'encodeArg'], $data);
162
-		} elseif (is_array($arg)) {
163
-			return array_map([$this, 'encodeArg'], $arg);
164
-		} else {
165
-			return $arg;
166
-		}
167
-	}
168
-
169
-	public function serializeException(\Throwable $exception) {
170
-		$data = [
171
-			'Exception' => get_class($exception),
172
-			'Message' => $exception->getMessage(),
173
-			'Code' => $exception->getCode(),
174
-			'Trace' => $this->encodeTrace($exception->getTrace()),
175
-			'File' => $exception->getFile(),
176
-			'Line' => $exception->getLine(),
177
-		];
178
-
179
-		if ($exception instanceof HintException) {
180
-			$data['Hint'] = $exception->getHint();
181
-		}
182
-
183
-		if ($exception->getPrevious()) {
184
-			$data['Previous'] = $this->serializeException($exception->getPrevious());
185
-		}
186
-
187
-		return $data;
188
-	}
37
+    public const methodsWithSensitiveParameters = [
38
+        // Session/User
39
+        'completeLogin',
40
+        'login',
41
+        'checkPassword',
42
+        'checkPasswordNoLogging',
43
+        'loginWithPassword',
44
+        'updatePrivateKeyPassword',
45
+        'validateUserPass',
46
+        'loginWithToken',
47
+        '{closure}',
48
+        'createSessionToken',
49
+
50
+        // Provisioning
51
+        'addUser',
52
+
53
+        // TokenProvider
54
+        'getToken',
55
+        'isTokenPassword',
56
+        'getPassword',
57
+        'decryptPassword',
58
+        'logClientIn',
59
+        'generateToken',
60
+        'validateToken',
61
+
62
+        // TwoFactorAuth
63
+        'solveChallenge',
64
+        'verifyChallenge',
65
+
66
+        // ICrypto
67
+        'calculateHMAC',
68
+        'encrypt',
69
+        'decrypt',
70
+
71
+        // LoginController
72
+        'tryLogin',
73
+        'confirmPassword',
74
+
75
+        // LDAP
76
+        'bind',
77
+        'areCredentialsValid',
78
+        'invokeLDAPMethod',
79
+
80
+        // Encryption
81
+        'storeKeyPair',
82
+        'setupUser',
83
+
84
+        // files_external: OCA\Files_External\MountConfig
85
+        'getBackendStatus',
86
+
87
+        // files_external: UserStoragesController
88
+        'update',
89
+    ];
90
+
91
+    public const methodsWithSensitiveParametersByClass = [
92
+        SetupController::class => [
93
+            'run',
94
+            'display',
95
+            'loadAutoConfig',
96
+        ],
97
+        Setup::class => [
98
+            'install'
99
+        ],
100
+        Key::class => [
101
+            '__construct'
102
+        ],
103
+    ];
104
+
105
+    private function editTrace(array &$sensitiveValues, array $traceLine): array {
106
+        if (isset($traceLine['args'])) {
107
+            $sensitiveValues = array_merge($sensitiveValues, $traceLine['args']);
108
+        }
109
+        $traceLine['args'] = ['*** sensitive parameters replaced ***'];
110
+        return $traceLine;
111
+    }
112
+
113
+    private function filterTrace(array $trace) {
114
+        $sensitiveValues = [];
115
+        $trace = array_map(function (array $traceLine) use (&$sensitiveValues) {
116
+            $className = $traceLine['class'] ?? '';
117
+            if ($className && isset(self::methodsWithSensitiveParametersByClass[$className])
118
+                && in_array($traceLine['function'], self::methodsWithSensitiveParametersByClass[$className], true)) {
119
+                return $this->editTrace($sensitiveValues, $traceLine);
120
+            }
121
+            foreach (self::methodsWithSensitiveParameters as $sensitiveMethod) {
122
+                if (strpos($traceLine['function'], $sensitiveMethod) !== false) {
123
+                    return $this->editTrace($sensitiveValues, $traceLine);
124
+                }
125
+            }
126
+            return $traceLine;
127
+        }, $trace);
128
+        return array_map(function (array $traceLine) use ($sensitiveValues) {
129
+            if (isset($traceLine['args'])) {
130
+                $traceLine['args'] = $this->removeValuesFromArgs($traceLine['args'], $sensitiveValues);
131
+            }
132
+            return $traceLine;
133
+        }, $trace);
134
+    }
135
+
136
+    private function removeValuesFromArgs($args, $values) {
137
+        foreach ($args as &$arg) {
138
+            if (in_array($arg, $values, true)) {
139
+                $arg = '*** sensitive parameter replaced ***';
140
+            } elseif (is_array($arg)) {
141
+                $arg = $this->removeValuesFromArgs($arg, $values);
142
+            }
143
+        }
144
+        return $args;
145
+    }
146
+
147
+    private function encodeTrace($trace) {
148
+        $filteredTrace = $this->filterTrace($trace);
149
+        return array_map(function (array $line) {
150
+            if (isset($line['args'])) {
151
+                $line['args'] = array_map([$this, 'encodeArg'], $line['args']);
152
+            }
153
+            return $line;
154
+        }, $filteredTrace);
155
+    }
156
+
157
+    private function encodeArg($arg) {
158
+        if (is_object($arg)) {
159
+            $data = get_object_vars($arg);
160
+            $data['__class__'] = get_class($arg);
161
+            return array_map([$this, 'encodeArg'], $data);
162
+        } elseif (is_array($arg)) {
163
+            return array_map([$this, 'encodeArg'], $arg);
164
+        } else {
165
+            return $arg;
166
+        }
167
+    }
168
+
169
+    public function serializeException(\Throwable $exception) {
170
+        $data = [
171
+            'Exception' => get_class($exception),
172
+            'Message' => $exception->getMessage(),
173
+            'Code' => $exception->getCode(),
174
+            'Trace' => $this->encodeTrace($exception->getTrace()),
175
+            'File' => $exception->getFile(),
176
+            'Line' => $exception->getLine(),
177
+        ];
178
+
179
+        if ($exception instanceof HintException) {
180
+            $data['Hint'] = $exception->getHint();
181
+        }
182
+
183
+        if ($exception->getPrevious()) {
184
+            $data['Previous'] = $this->serializeException($exception->getPrevious());
185
+        }
186
+
187
+        return $data;
188
+    }
189 189
 }
Please login to merge, or discard this patch.