1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @author Lukas Reschke <[email protected]> |
4
|
|
|
* @author Robin Appelman <[email protected]> |
5
|
|
|
* @author Robin McCorkell <[email protected]> |
6
|
|
|
* @author Stefan Weil <[email protected]> |
7
|
|
|
* @author Vincent Petry <[email protected]> |
8
|
|
|
* |
9
|
|
|
* @copyright Copyright (c) 2018, ownCloud GmbH |
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
|
|
|
|
26
|
|
|
namespace OC\Files\External\Service; |
27
|
|
|
|
28
|
|
|
use OC\Files\Filesystem; |
29
|
|
|
|
30
|
|
|
use OCP\Files\External\IStorageConfig; |
31
|
|
|
use OCP\Files\External\IStoragesBackendService; |
32
|
|
|
use OCP\Files\External\Service\IGlobalStoragesService; |
33
|
|
|
use OCP\IUser; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* Service class to manage global external storages |
37
|
|
|
*/ |
38
|
|
|
class GlobalStoragesService extends StoragesService implements IGlobalStoragesService { |
39
|
|
|
/** |
40
|
|
|
* Triggers $signal for all applicable users of the given |
41
|
|
|
* storage |
42
|
|
|
* |
43
|
|
|
* @param IStorageConfig $storage storage data |
44
|
|
|
* @param string $signal signal to trigger |
45
|
|
|
*/ |
46
|
|
|
protected function triggerHooks(IStorageConfig $storage, $signal) { |
47
|
|
|
// FIXME: Use as expression in empty once PHP 5.4 support is dropped |
48
|
|
|
$applicableUsers = $storage->getApplicableUsers(); |
49
|
|
|
$applicableGroups = $storage->getApplicableGroups(); |
50
|
|
|
if (empty($applicableUsers) && empty($applicableGroups)) { |
51
|
|
|
// raise for user "all" |
52
|
|
|
$this->triggerApplicableHooks( |
53
|
|
|
$signal, |
54
|
|
|
$storage->getMountPoint(), |
55
|
|
|
IStorageConfig::MOUNT_TYPE_USER, |
56
|
|
|
['all'] |
57
|
|
|
); |
58
|
|
|
return; |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
$this->triggerApplicableHooks( |
62
|
|
|
$signal, |
63
|
|
|
$storage->getMountPoint(), |
64
|
|
|
IStorageConfig::MOUNT_TYPE_USER, |
65
|
|
|
$applicableUsers |
66
|
|
|
); |
67
|
|
|
$this->triggerApplicableHooks( |
68
|
|
|
$signal, |
69
|
|
|
$storage->getMountPoint(), |
70
|
|
|
IStorageConfig::MOUNT_TYPE_GROUP, |
71
|
|
|
$applicableGroups |
72
|
|
|
); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Triggers signal_create_mount or signal_delete_mount to |
77
|
|
|
* accommodate for additions/deletions in applicableUsers |
78
|
|
|
* and applicableGroups fields. |
79
|
|
|
* |
80
|
|
|
* @param IStorageConfig $oldStorage old storage config |
81
|
|
|
* @param IStorageConfig $newStorage new storage config |
82
|
|
|
*/ |
83
|
|
|
protected function triggerChangeHooks(IStorageConfig $oldStorage, IStorageConfig $newStorage) { |
84
|
|
|
// if mount point changed, it's like a deletion + creation |
85
|
|
View Code Duplication |
if ($oldStorage->getMountPoint() !== $newStorage->getMountPoint()) { |
|
|
|
|
86
|
|
|
$this->triggerHooks($oldStorage, Filesystem::signal_delete_mount); |
87
|
|
|
$this->triggerHooks($newStorage, Filesystem::signal_create_mount); |
88
|
|
|
return; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
$userAdditions = \array_diff($newStorage->getApplicableUsers(), $oldStorage->getApplicableUsers()); |
92
|
|
|
$userDeletions = \array_diff($oldStorage->getApplicableUsers(), $newStorage->getApplicableUsers()); |
93
|
|
|
$groupAdditions = \array_diff($newStorage->getApplicableGroups(), $oldStorage->getApplicableGroups()); |
94
|
|
|
$groupDeletions = \array_diff($oldStorage->getApplicableGroups(), $newStorage->getApplicableGroups()); |
95
|
|
|
|
96
|
|
|
// FIXME: Use as expression in empty once PHP 5.4 support is dropped |
97
|
|
|
// if no applicable were set, raise a signal for "all" |
98
|
|
|
$oldApplicableUsers = $oldStorage->getApplicableUsers(); |
99
|
|
|
$oldApplicableGroups = $oldStorage->getApplicableGroups(); |
100
|
|
View Code Duplication |
if (empty($oldApplicableUsers) && empty($oldApplicableGroups)) { |
|
|
|
|
101
|
|
|
$this->triggerApplicableHooks( |
102
|
|
|
Filesystem::signal_delete_mount, |
103
|
|
|
$oldStorage->getMountPoint(), |
104
|
|
|
IStorageConfig::MOUNT_TYPE_USER, |
105
|
|
|
['all'] |
106
|
|
|
); |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
// trigger delete for removed users |
110
|
|
|
$this->triggerApplicableHooks( |
111
|
|
|
Filesystem::signal_delete_mount, |
112
|
|
|
$oldStorage->getMountPoint(), |
113
|
|
|
IStorageConfig::MOUNT_TYPE_USER, |
114
|
|
|
$userDeletions |
115
|
|
|
); |
116
|
|
|
|
117
|
|
|
// trigger delete for removed groups |
118
|
|
|
$this->triggerApplicableHooks( |
119
|
|
|
Filesystem::signal_delete_mount, |
120
|
|
|
$oldStorage->getMountPoint(), |
121
|
|
|
IStorageConfig::MOUNT_TYPE_GROUP, |
122
|
|
|
$groupDeletions |
123
|
|
|
); |
124
|
|
|
|
125
|
|
|
// and now add the new users |
126
|
|
|
$this->triggerApplicableHooks( |
127
|
|
|
Filesystem::signal_create_mount, |
128
|
|
|
$newStorage->getMountPoint(), |
129
|
|
|
IStorageConfig::MOUNT_TYPE_USER, |
130
|
|
|
$userAdditions |
131
|
|
|
); |
132
|
|
|
|
133
|
|
|
// and now add the new groups |
134
|
|
|
$this->triggerApplicableHooks( |
135
|
|
|
Filesystem::signal_create_mount, |
136
|
|
|
$newStorage->getMountPoint(), |
137
|
|
|
IStorageConfig::MOUNT_TYPE_GROUP, |
138
|
|
|
$groupAdditions |
139
|
|
|
); |
140
|
|
|
|
141
|
|
|
// FIXME: Use as expression in empty once PHP 5.4 support is dropped |
142
|
|
|
// if no applicable, raise a signal for "all" |
143
|
|
|
$newApplicableUsers = $newStorage->getApplicableUsers(); |
144
|
|
|
$newApplicableGroups = $newStorage->getApplicableGroups(); |
145
|
|
View Code Duplication |
if (empty($newApplicableUsers) && empty($newApplicableGroups)) { |
|
|
|
|
146
|
|
|
$this->triggerApplicableHooks( |
147
|
|
|
Filesystem::signal_create_mount, |
148
|
|
|
$newStorage->getMountPoint(), |
149
|
|
|
IStorageConfig::MOUNT_TYPE_USER, |
150
|
|
|
['all'] |
151
|
|
|
); |
152
|
|
|
} |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* Get the visibility type for this controller, used in validation |
157
|
|
|
* |
158
|
|
|
* @return string IStoragesBackendService::VISIBILITY_* constants |
159
|
|
|
*/ |
160
|
|
|
public function getVisibilityType() { |
161
|
|
|
return IStoragesBackendService::VISIBILITY_ADMIN; |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
protected function isApplicable(IStorageConfig $config) { |
165
|
|
|
return true; |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* Get all configured admin and personal mounts |
170
|
|
|
* |
171
|
|
|
* @return array map of storage id to storage config |
172
|
|
|
*/ |
173
|
|
View Code Duplication |
public function getStorageForAllUsers() { |
174
|
|
|
$mounts = $this->dbConfig->getAllMounts(); |
175
|
|
|
$configs = \array_map([$this, 'getStorageConfigFromDBMount'], $mounts); |
176
|
|
|
$configs = \array_filter($configs, function ($config) { |
177
|
|
|
return $config instanceof IStorageConfig; |
178
|
|
|
}); |
179
|
|
|
|
180
|
|
|
$keys = \array_map(function (IStorageConfig $config) { |
181
|
|
|
return $config->getId(); |
182
|
|
|
}, $configs); |
183
|
|
|
|
184
|
|
|
return \array_combine($keys, $configs); |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
/** |
188
|
|
|
* Deletes the external storages mounted to the user |
189
|
|
|
* |
190
|
|
|
* @param IUser $user |
191
|
|
|
* @return bool |
192
|
|
|
*/ |
193
|
|
|
public function deleteAllForUser($user) { |
194
|
|
|
$userId = $user->getUID(); |
195
|
|
|
$result = false; |
196
|
|
|
//Get all valid storages |
197
|
|
|
$mounts = $this->getStorages(); |
198
|
|
|
foreach ($mounts as $mount) { |
199
|
|
|
$applicableUsers = $mount->getApplicableUsers(); |
200
|
|
|
$id = $mount->getId(); |
201
|
|
|
if (\in_array($userId, $applicableUsers, true)) { |
202
|
|
|
if (\count($applicableUsers) === 1) { |
203
|
|
|
//As this storage is associated only with this user. |
204
|
|
|
$this->removeStorage($id); |
205
|
|
|
$result = true; |
206
|
|
|
} else { |
207
|
|
|
$storage = $this->getStorage($id); |
208
|
|
|
$userIndex = \array_search($userId, $applicableUsers, true); |
209
|
|
|
unset($applicableUsers[$userIndex]); |
210
|
|
|
$storage->setApplicableUsers($applicableUsers); |
211
|
|
|
$this->updateStorage($storage); |
|
|
|
|
212
|
|
|
$result = true; |
213
|
|
|
} |
214
|
|
|
} |
215
|
|
|
} |
216
|
|
|
return $result; |
217
|
|
|
} |
218
|
|
|
} |
219
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.