Skip to content

Commit 45ffc86

Browse files
committed
fix: visibility for local storage for the admin based on flag
Without the visibility, the admin won't be able to create local storages, and the previously created local mounts will be hidden and inaccessible
1 parent 88fcb18 commit 45ffc86

3 files changed

Lines changed: 111 additions & 2 deletions

File tree

lib/private/Files/External/StoragesBackendChecker.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function __construct(IConfig $config) {
2424
* Checks if the regular users are allowed to mount external storages
2525
* @return bool
2626
*/
27-
public function isUserMountingAllowed() {
27+
public function isUserMountingAllowed(): bool {
2828
if ($this->allowUserMounting === null) {
2929
$this->allowUserMounting = $this->config->getAppValue('files_external', 'allow_user_mounting', 'no') === 'yes';
3030
// if no backend is in the list an empty string is in the array and user mounting is disabled
@@ -49,9 +49,10 @@ private function allowedBackendsForUsers() {
4949
/**
5050
* Checks if the regular users are allowed to mount the specified backend.
5151
* Note that the admin might still mount the backend.
52+
* @param Backend $backend
5253
* @return bool
5354
*/
54-
public function isAllowedUserBackend(Backend $backend) {
55+
public function isAllowedUserBackend(Backend $backend): bool {
5556
$blacklistedBackendsForUsers = ['\OC\Files\Storage\Local'];
5657
if (\in_array($backend->getStorageClass(), $blacklistedBackendsForUsers, true)) {
5758
return false;
@@ -62,4 +63,17 @@ public function isAllowedUserBackend(Backend $backend) {
6263
}
6364
return false;
6465
}
66+
67+
/**
68+
* Checks if the admin is allowed to mount the specified backend.
69+
* @param Backend $backend
70+
* @return bool
71+
*/
72+
public function isAllowedAdminBackend(Backend $backend): bool {
73+
$canCreateNewLocalStorage = $this->config->getSystemValue('files_external_allow_create_new_local', false);
74+
if ($backend->getStorageClass() === '\OC\Files\Storage\Local' && !$canCreateNewLocalStorage) {
75+
return false;
76+
}
77+
return true;
78+
}
6579
}

lib/private/Files/External/StoragesBackendService.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ public function registerBackend(Backend $backend) {
104104
if (!$this->isAllowedUserBackend($backend)) {
105105
$backend->removeVisibility(IStoragesBackendService::VISIBILITY_PERSONAL);
106106
}
107+
if (!$this->isAllowedAdminBackend($backend)) {
108+
$backend->removeVisibility(IStoragesBackendService::VISIBILITY_ADMIN);
109+
}
107110
foreach ($backend->getIdentifierAliases() as $alias) {
108111
$this->backends[$alias] = $backend;
109112
}
@@ -237,6 +240,15 @@ protected function isAllowedUserBackend(Backend $backend) {
237240
return $this->storagesBackendChecker->isAllowedUserBackend($backend);
238241
}
239242

243+
/**
244+
* Checks if the admin is allowed to mount the backend
245+
* @param Backend $backend
246+
* @return bool
247+
*/
248+
protected function isAllowedAdminBackend(Backend $backend) {
249+
return $this->storagesBackendChecker->isAllowedAdminBackend($backend);
250+
}
251+
240252
/**
241253
* Check an authentication mechanism if a user is allowed to use it
242254
*

tests/lib/Files/External/StoragesBackendServiceTest.php

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ protected function setUp(): void {
3535
$this->storagesBackendChecker = $this->createMock(StoragesBackendChecker::class);
3636
$this->storagesBackendChecker->method('isUserMountingAllowed')->willReturn(false);
3737
$this->storagesBackendChecker->method('isAllowedUserBackend')->willReturn(false);
38+
$this->storagesBackendChecker->method('isAllowedAdminBackend')->willReturn(true);
3839
}
3940

4041
/**
@@ -157,6 +158,7 @@ public function testMultipleBackendProviders() {
157158
public function testUserMountingBackends() {
158159
$storagesBackendChecker = $this->createMock(StoragesBackendChecker::class);
159160
$storagesBackendChecker->method('isUserMountingAllowed')->willReturn(true);
161+
$storagesBackendChecker->method('isAllowedAdminBackend')->willReturn(true);
160162
$storagesBackendChecker->method('isAllowedUserBackend')->willReturnCallback(function (Backend $backend) {
161163
$backendAliases = $backend->getIdentifierAliases();
162164
if (\in_array('identifier:\User\Mount\Allowed', $backendAliases, true) || \in_array('identifier_alias', $backendAliases, true)) {
@@ -188,6 +190,87 @@ public function testUserMountingBackends() {
188190
$service->registerBackend($backendAlias);
189191
}
190192

193+
public function testAdminMountingBackends() {
194+
$storagesBackendChecker = $this->createMock(StoragesBackendChecker::class);
195+
$storagesBackendChecker->method('isUserMountingAllowed')->willReturn(true);
196+
$storagesBackendChecker->method('isAllowedUserBackend')->willReturn(true);
197+
$storagesBackendChecker->method('isAllowedAdminBackend')->willReturnCallback(function (Backend $backend) {
198+
$backendAliases = $backend->getIdentifierAliases();
199+
if (\in_array('identifier:\User\Mount\Allowed', $backendAliases, true) || \in_array('identifier_alias', $backendAliases, true)) {
200+
return true;
201+
}
202+
return false;
203+
});
204+
205+
$service = new StoragesBackendService($storagesBackendChecker);
206+
207+
$backendAllowed = $this->getBackendMock('\User\Mount\Allowed');
208+
$backendAllowed->expects($this->never())
209+
->method('removeVisibility');
210+
$backendNotAllowed = $this->getBackendMock('\User\Mount\NotAllowed');
211+
$backendNotAllowed->expects($this->once())
212+
->method('removeVisibility')
213+
->with(IStoragesBackendService::VISIBILITY_ADMIN);
214+
215+
$backendAlias = $this->getMockBuilder('\OCP\Files\External\Backend\Backend')
216+
->disableOriginalConstructor()
217+
->getMock();
218+
$backendAlias->method('getIdentifierAliases')
219+
->willReturn(['identifier_real', 'identifier_alias']);
220+
$backendAlias->expects($this->never())
221+
->method('removeVisibility');
222+
223+
$service->registerBackend($backendAllowed);
224+
$service->registerBackend($backendNotAllowed);
225+
$service->registerBackend($backendAlias);
226+
}
227+
228+
public function testAdminAndUserMountingBackends() {
229+
$storagesBackendChecker = $this->createMock(StoragesBackendChecker::class);
230+
$storagesBackendChecker->method('isUserMountingAllowed')->willReturn(true);
231+
$storagesBackendChecker->method('isAllowedUserBackend')->willReturnCallback(function (Backend $backend) {
232+
$backendAliases = $backend->getIdentifierAliases();
233+
if (\in_array('identifier:\User\Mount\Allowed', $backendAliases, true) || \in_array('identifier_alias', $backendAliases, true)) {
234+
return true;
235+
}
236+
return false;
237+
});
238+
$storagesBackendChecker->method('isAllowedAdminBackend')->willReturnCallback(function (Backend $backend) {
239+
$backendAliases = $backend->getIdentifierAliases();
240+
if (\in_array('identifier:\User\Mount\Allowed', $backendAliases, true) || \in_array('identifier_alias', $backendAliases, true)) {
241+
return true;
242+
}
243+
return false;
244+
});
245+
246+
$service = new StoragesBackendService($storagesBackendChecker);
247+
248+
$backendAllowed = $this->getBackendMock('\User\Mount\Allowed');
249+
$backendAllowed->expects($this->never())
250+
->method('removeVisibility');
251+
$backendNotAllowed = $this->getBackendMock('\User\Mount\NotAllowed');
252+
$backendNotAllowed->expects($this->exactly(2))
253+
->method('removeVisibility')
254+
->with(
255+
$this->logicalOr(
256+
$this->identicalTo(IStoragesBackendService::VISIBILITY_ADMIN),
257+
$this->identicalTo(IStoragesBackendService::VISIBILITY_PERSONAL)
258+
)
259+
);
260+
261+
$backendAlias = $this->getMockBuilder('\OCP\Files\External\Backend\Backend')
262+
->disableOriginalConstructor()
263+
->getMock();
264+
$backendAlias->method('getIdentifierAliases')
265+
->willReturn(['identifier_real', 'identifier_alias']);
266+
$backendAlias->expects($this->never())
267+
->method('removeVisibility');
268+
269+
$service->registerBackend($backendAllowed);
270+
$service->registerBackend($backendNotAllowed);
271+
$service->registerBackend($backendAlias);
272+
}
273+
191274
public function testGetAvailableBackends() {
192275
$service = new StoragesBackendService($this->storagesBackendChecker);
193276

0 commit comments

Comments
 (0)