|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* @copyright Copyright (c) 2016, ownCloud, Inc. |
|
4
|
|
|
* |
|
5
|
|
|
* @author Christoph Wurst <[email protected]> |
|
6
|
|
|
* @author Morris Jobke <[email protected]> |
|
7
|
|
|
* @author Robin Appelman <[email protected]> |
|
8
|
|
|
* @author Roeland Jago Douma <[email protected]> |
|
9
|
|
|
* |
|
10
|
|
|
* @license AGPL-3.0 |
|
11
|
|
|
* |
|
12
|
|
|
* This code is free software: you can redistribute it and/or modify |
|
13
|
|
|
* it under the terms of the GNU Affero General Public License, version 3, |
|
14
|
|
|
* as published by the Free Software Foundation. |
|
15
|
|
|
* |
|
16
|
|
|
* This program is distributed in the hope that it will be useful, |
|
17
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
18
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
19
|
|
|
* GNU Affero General Public License for more details. |
|
20
|
|
|
* |
|
21
|
|
|
* You should have received a copy of the GNU Affero General Public License, version 3, |
|
22
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|
23
|
|
|
* |
|
24
|
|
|
*/ |
|
25
|
|
|
namespace OC\Files\Config; |
|
26
|
|
|
|
|
27
|
|
|
use OC\Hooks\Emitter; |
|
28
|
|
|
use OC\Hooks\EmitterTrait; |
|
29
|
|
|
use OCP\Diagnostics\IEventLogger; |
|
30
|
|
|
use OCP\Files\Config\IHomeMountProvider; |
|
31
|
|
|
use OCP\Files\Config\IMountProvider; |
|
32
|
|
|
use OCP\Files\Config\IMountProviderCollection; |
|
33
|
|
|
use OCP\Files\Config\IRootMountProvider; |
|
34
|
|
|
use OCP\Files\Config\IUserMountCache; |
|
35
|
|
|
use OCP\Files\Mount\IMountManager; |
|
36
|
|
|
use OCP\Files\Mount\IMountPoint; |
|
37
|
|
|
use OCP\Files\Storage\IStorageFactory; |
|
38
|
|
|
use OCP\IUser; |
|
39
|
|
|
|
|
40
|
|
|
class MountProviderCollection implements IMountProviderCollection, Emitter { |
|
|
|
|
|
|
41
|
|
|
use EmitterTrait; |
|
|
|
|
|
|
42
|
|
|
|
|
43
|
|
|
/** |
|
44
|
|
|
* @var \OCP\Files\Config\IHomeMountProvider[] |
|
45
|
|
|
*/ |
|
46
|
|
|
private $homeProviders = []; |
|
47
|
|
|
|
|
48
|
|
|
/** |
|
49
|
|
|
* @var \OCP\Files\Config\IMountProvider[] |
|
50
|
|
|
*/ |
|
51
|
|
|
private $providers = []; |
|
52
|
|
|
|
|
53
|
|
|
/** @var \OCP\Files\Config\IRootMountProvider[] */ |
|
54
|
|
|
private $rootProviders = []; |
|
55
|
|
|
|
|
56
|
|
|
/** |
|
57
|
|
|
* @var \OCP\Files\Storage\IStorageFactory |
|
58
|
|
|
*/ |
|
59
|
|
|
private $loader; |
|
60
|
|
|
|
|
61
|
|
|
/** |
|
62
|
|
|
* @var \OCP\Files\Config\IUserMountCache |
|
63
|
|
|
*/ |
|
64
|
|
|
private $mountCache; |
|
65
|
|
|
|
|
66
|
|
|
/** @var callable[] */ |
|
67
|
|
|
private $mountFilters = []; |
|
68
|
|
|
|
|
69
|
|
|
private IEventLogger $eventLogger; |
|
70
|
|
|
|
|
71
|
|
|
/** |
|
72
|
|
|
* @param \OCP\Files\Storage\IStorageFactory $loader |
|
73
|
|
|
* @param IUserMountCache $mountCache |
|
74
|
|
|
*/ |
|
75
|
|
|
public function __construct( |
|
76
|
|
|
IStorageFactory $loader, |
|
77
|
|
|
IUserMountCache $mountCache, |
|
78
|
|
|
IEventLogger $eventLogger |
|
79
|
|
|
) { |
|
80
|
|
|
$this->loader = $loader; |
|
81
|
|
|
$this->mountCache = $mountCache; |
|
82
|
|
|
$this->eventLogger = $eventLogger; |
|
83
|
|
|
} |
|
84
|
|
|
|
|
85
|
|
|
private function getMountsFromProvider(IMountProvider $provider, IUser $user, IStorageFactory $loader): array { |
|
86
|
|
|
$class = str_replace('\\', '_', get_class($provider)); |
|
87
|
|
|
$uid = $user->getUID(); |
|
88
|
|
|
$this->eventLogger->start('fs:setup:provider:' . $class, "Getting mounts from $class for $uid"); |
|
89
|
|
|
$mounts = $provider->getMountsForUser($user, $loader) ?? []; |
|
90
|
|
|
$this->eventLogger->end('fs:setup:provider:' . $class); |
|
91
|
|
|
return $mounts; |
|
92
|
|
|
} |
|
93
|
|
|
|
|
94
|
|
|
/** |
|
95
|
|
|
* @param IUser $user |
|
96
|
|
|
* @param IMountProvider[] $providers |
|
97
|
|
|
* @return IMountPoint[] |
|
98
|
|
|
*/ |
|
99
|
|
|
private function getUserMountsForProviders(IUser $user, array $providers): array { |
|
100
|
|
|
$loader = $this->loader; |
|
101
|
|
|
$mounts = array_map(function (IMountProvider $provider) use ($user, $loader) { |
|
102
|
|
|
return $this->getMountsFromProvider($provider, $user, $loader); |
|
103
|
|
|
}, $providers); |
|
104
|
|
|
$mounts = array_reduce($mounts, function (array $mounts, array $providerMounts) { |
|
105
|
|
|
return array_merge($mounts, $providerMounts); |
|
106
|
|
|
}, []); |
|
107
|
|
|
return $this->filterMounts($user, $mounts); |
|
108
|
|
|
} |
|
109
|
|
|
|
|
110
|
|
|
public function getMountsForUser(IUser $user): array { |
|
111
|
|
|
return $this->getUserMountsForProviders($user, $this->providers); |
|
112
|
|
|
} |
|
113
|
|
|
|
|
114
|
|
|
public function getUserMountsForProviderClasses(IUser $user, array $mountProviderClasses): array { |
|
115
|
|
|
$providers = array_filter( |
|
116
|
|
|
$this->providers, |
|
117
|
|
|
fn (IMountProvider $mountProvider) => (in_array(get_class($mountProvider), $mountProviderClasses)) |
|
118
|
|
|
); |
|
119
|
|
|
return $this->getUserMountsForProviders($user, $providers); |
|
120
|
|
|
} |
|
121
|
|
|
|
|
122
|
|
|
public function addMountForUser(IUser $user, IMountManager $mountManager, callable $providerFilter = null) { |
|
123
|
|
|
// shared mount provider gets to go last since it needs to know existing files |
|
124
|
|
|
// to check for name collisions |
|
125
|
|
|
$firstMounts = []; |
|
126
|
|
|
if ($providerFilter) { |
|
127
|
|
|
$providers = array_filter($this->providers, $providerFilter); |
|
128
|
|
|
} else { |
|
129
|
|
|
$providers = $this->providers; |
|
130
|
|
|
} |
|
131
|
|
|
$firstProviders = array_filter($providers, function (IMountProvider $provider) { |
|
132
|
|
|
return (get_class($provider) !== 'OCA\Files_Sharing\MountProvider'); |
|
133
|
|
|
}); |
|
134
|
|
|
$lastProviders = array_filter($providers, function (IMountProvider $provider) { |
|
135
|
|
|
return (get_class($provider) === 'OCA\Files_Sharing\MountProvider'); |
|
136
|
|
|
}); |
|
137
|
|
|
foreach ($firstProviders as $provider) { |
|
138
|
|
|
$mounts = $this->getMountsFromProvider($provider, $user, $this->loader); |
|
139
|
|
|
$firstMounts = array_merge($firstMounts, $mounts); |
|
140
|
|
|
} |
|
141
|
|
|
$firstMounts = $this->filterMounts($user, $firstMounts); |
|
142
|
|
|
array_walk($firstMounts, [$mountManager, 'addMount']); |
|
143
|
|
|
|
|
144
|
|
|
$lateMounts = []; |
|
145
|
|
|
foreach ($lastProviders as $provider) { |
|
146
|
|
|
$mounts = $this->getMountsFromProvider($provider, $user, $this->loader); |
|
147
|
|
|
$lateMounts = array_merge($lateMounts, $mounts); |
|
148
|
|
|
} |
|
149
|
|
|
|
|
150
|
|
|
$lateMounts = $this->filterMounts($user, $lateMounts); |
|
151
|
|
|
$this->eventLogger->start("fs:setup:add-mounts", "Add mounts to the filesystem"); |
|
152
|
|
|
array_walk($lateMounts, [$mountManager, 'addMount']); |
|
153
|
|
|
$this->eventLogger->end("fs:setup:add-mounts"); |
|
154
|
|
|
|
|
155
|
|
|
return array_merge($lateMounts, $firstMounts); |
|
156
|
|
|
} |
|
157
|
|
|
|
|
158
|
|
|
/** |
|
159
|
|
|
* Get the configured home mount for this user |
|
160
|
|
|
* |
|
161
|
|
|
* @param \OCP\IUser $user |
|
162
|
|
|
* @return \OCP\Files\Mount\IMountPoint |
|
163
|
|
|
* @since 9.1.0 |
|
164
|
|
|
*/ |
|
165
|
|
|
public function getHomeMountForUser(IUser $user) { |
|
166
|
|
|
/** @var \OCP\Files\Config\IHomeMountProvider[] $providers */ |
|
167
|
|
|
$providers = array_reverse($this->homeProviders); // call the latest registered provider first to give apps an opportunity to overwrite builtin |
|
168
|
|
|
foreach ($providers as $homeProvider) { |
|
169
|
|
|
if ($mount = $homeProvider->getHomeMountForUser($user, $this->loader)) { |
|
170
|
|
|
$mount->setMountPoint('/' . $user->getUID()); //make sure the mountpoint is what we expect |
|
171
|
|
|
return $mount; |
|
172
|
|
|
} |
|
173
|
|
|
} |
|
174
|
|
|
throw new \Exception('No home storage configured for user ' . $user); |
|
|
|
|
|
|
175
|
|
|
} |
|
176
|
|
|
|
|
177
|
|
|
/** |
|
178
|
|
|
* Add a provider for mount points |
|
179
|
|
|
* |
|
180
|
|
|
* @param \OCP\Files\Config\IMountProvider $provider |
|
181
|
|
|
*/ |
|
182
|
|
|
public function registerProvider(IMountProvider $provider) { |
|
183
|
|
|
$this->providers[] = $provider; |
|
184
|
|
|
|
|
185
|
|
|
$this->emit('\OC\Files\Config', 'registerMountProvider', [$provider]); |
|
186
|
|
|
} |
|
187
|
|
|
|
|
188
|
|
|
public function registerMountFilter(callable $filter) { |
|
189
|
|
|
$this->mountFilters[] = $filter; |
|
190
|
|
|
} |
|
191
|
|
|
|
|
192
|
|
|
private function filterMounts(IUser $user, array $mountPoints) { |
|
193
|
|
|
return array_filter($mountPoints, function (IMountPoint $mountPoint) use ($user) { |
|
194
|
|
|
foreach ($this->mountFilters as $filter) { |
|
195
|
|
|
if ($filter($mountPoint, $user) === false) { |
|
196
|
|
|
return false; |
|
197
|
|
|
} |
|
198
|
|
|
} |
|
199
|
|
|
return true; |
|
200
|
|
|
}); |
|
201
|
|
|
} |
|
202
|
|
|
|
|
203
|
|
|
/** |
|
204
|
|
|
* Add a provider for home mount points |
|
205
|
|
|
* |
|
206
|
|
|
* @param \OCP\Files\Config\IHomeMountProvider $provider |
|
207
|
|
|
* @since 9.1.0 |
|
208
|
|
|
*/ |
|
209
|
|
|
public function registerHomeProvider(IHomeMountProvider $provider) { |
|
210
|
|
|
$this->homeProviders[] = $provider; |
|
211
|
|
|
$this->emit('\OC\Files\Config', 'registerHomeMountProvider', [$provider]); |
|
212
|
|
|
} |
|
213
|
|
|
|
|
214
|
|
|
/** |
|
215
|
|
|
* Get the mount cache which can be used to search for mounts without setting up the filesystem |
|
216
|
|
|
* |
|
217
|
|
|
* @return IUserMountCache |
|
218
|
|
|
*/ |
|
219
|
|
|
public function getMountCache() { |
|
220
|
|
|
return $this->mountCache; |
|
221
|
|
|
} |
|
222
|
|
|
|
|
223
|
|
|
public function registerRootProvider(IRootMountProvider $provider) { |
|
224
|
|
|
$this->rootProviders[] = $provider; |
|
225
|
|
|
} |
|
226
|
|
|
|
|
227
|
|
|
/** |
|
228
|
|
|
* Get all root mountpoints |
|
229
|
|
|
* |
|
230
|
|
|
* @return \OCP\Files\Mount\IMountPoint[] |
|
231
|
|
|
* @since 20.0.0 |
|
232
|
|
|
*/ |
|
233
|
|
|
public function getRootMounts(): array { |
|
234
|
|
|
$loader = $this->loader; |
|
235
|
|
|
$mounts = array_map(function (IRootMountProvider $provider) use ($loader) { |
|
236
|
|
|
return $provider->getRootMounts($loader); |
|
237
|
|
|
}, $this->rootProviders); |
|
238
|
|
|
$mounts = array_reduce($mounts, function (array $mounts, array $providerMounts) { |
|
239
|
|
|
return array_merge($mounts, $providerMounts); |
|
240
|
|
|
}, []); |
|
241
|
|
|
return $mounts; |
|
242
|
|
|
} |
|
243
|
|
|
|
|
244
|
|
|
public function clearProviders() { |
|
245
|
|
|
$this->providers = []; |
|
246
|
|
|
$this->homeProviders = []; |
|
247
|
|
|
$this->rootProviders = []; |
|
248
|
|
|
} |
|
249
|
|
|
|
|
250
|
|
|
public function getProviders(): array { |
|
251
|
|
|
return $this->providers; |
|
252
|
|
|
} |
|
253
|
|
|
} |
|
254
|
|
|
|
This interface has been deprecated. The supplier of the interface has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the interface will be removed and what other interface to use instead.