summaryrefslogtreecommitdiffstats
path: root/apps/files_external
diff options
context:
space:
mode:
authorRobin McCorkell <rmccorkell@owncloud.com>2015-08-12 14:22:27 +0100
committerRobin McCorkell <rmccorkell@owncloud.com>2015-08-19 10:05:11 +0100
commita6a69ef1dfe1545e1362953803219ed6f28f71a5 (patch)
tree9c3c76b5c66f1fc83d843699c1878a825c18e52d /apps/files_external
parent37beb58c6f395523d8e2934870c5f52a8c6f6df0 (diff)
downloadnextcloud-server-a6a69ef1dfe1545e1362953803219ed6f28f71a5.tar.gz
nextcloud-server-a6a69ef1dfe1545e1362953803219ed6f28f71a5.zip
Introduce UserGlobalStoragesService
UserGlobalStoragesService reads the global storage configuration, cherry-picking storages applicable to a user. Writing storages through this service is forbidden, on punishment of throwing an exception. Storage IDs may also be config hashes when retrieved from this service, as it is unable to update the storages with real IDs. As UserGlobalStoragesService and UserStoragesService share a bit of code relating to users, that has been split into UserTrait. UserTrait also allows for the user set to be overridden, rather than using the user from IUserSession. Config\ConfigAdapter has been reworked to use UserStoragesService and UserGlobalStoragesService instead of OC_Mount_Config::getAbsoluteMountPoints(), further reducing dependance on that horrible static class.
Diffstat (limited to 'apps/files_external')
-rw-r--r--apps/files_external/lib/config/configadapter.php98
-rw-r--r--apps/files_external/service/globalstoragesservice.php2
-rw-r--r--apps/files_external/service/storagesservice.php38
-rw-r--r--apps/files_external/service/userglobalstoragesservice.php107
-rw-r--r--apps/files_external/service/userstoragesservice.php29
-rw-r--r--apps/files_external/service/usertrait.php74
6 files changed, 312 insertions, 36 deletions
diff --git a/apps/files_external/lib/config/configadapter.php b/apps/files_external/lib/config/configadapter.php
index 6956de1e748..63615e716ae 100644
--- a/apps/files_external/lib/config/configadapter.php
+++ b/apps/files_external/lib/config/configadapter.php
@@ -2,6 +2,7 @@
/**
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin Appelman <icewind@owncloud.com>
+ * @author Robin McCorkell <rmccorkell@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
@@ -22,23 +23,67 @@
namespace OCA\Files_External\Config;
+use OCP\Files\Storage;
use OC\Files\Mount\MountPoint;
use OCP\Files\Storage\IStorageFactory;
use OCA\Files_External\Lib\PersonalMount;
use OCP\Files\Config\IMountProvider;
use OCP\IUser;
use OCA\Files_external\Service\UserStoragesService;
+use OCA\Files_External\Service\UserGlobalStoragesService;
+use OCA\Files_External\Lib\StorageConfig;
/**
* Make the old files_external config work with the new public mount config api
*/
class ConfigAdapter implements IMountProvider {
+ /** @var UserStoragesService */
+ private $userStoragesService;
+
+ /** @var UserGlobalStoragesService */
+ private $userGlobalStoragesService;
+
/**
* @param UserStoragesService $userStoragesService
+ * @param UserGlobalStoragesService $userGlobalStoragesService
*/
- public function __construct(UserStoragesService $userStoragesService) {
+ public function __construct(
+ UserStoragesService $userStoragesService,
+ UserGlobalStoragesService $userGlobalStoragesService
+ ) {
$this->userStoragesService = $userStoragesService;
+ $this->userGlobalStoragesService = $userGlobalStoragesService;
+ }
+
+ /**
+ * Process storage ready for mounting
+ *
+ * @param StorageConfig $storage
+ */
+ private function prepareStorageConfig(StorageConfig &$storage) {
+ $objectStore = $storage->getBackendOption('objectstore');
+ if ($objectStore) {
+ $objectClass = $objectStore['class'];
+ $storage->setBackendOption('objectstore', new $objectClass($objectStore));
+ }
+
+ $storage->getBackend()->manipulateStorageConfig($storage);
+ }
+
+ /**
+ * Construct the storage implementation
+ *
+ * @param StorageConfig $storageConfig
+ * @return Storage
+ */
+ private function constructStorage(StorageConfig $storageConfig) {
+ $class = $storageConfig->getBackend()->getStorageClass();
+ $storage = new $class($storageConfig->getBackendOptions());
+
+ $storage = $storageConfig->getBackend()->wrapStorage($storage);
+
+ return $storage;
}
/**
@@ -49,21 +94,44 @@ class ConfigAdapter implements IMountProvider {
* @return \OCP\Files\Mount\IMountPoint[]
*/
public function getMountsForUser(IUser $user, IStorageFactory $loader) {
- $mountPoints = \OC_Mount_Config::getAbsoluteMountPoints($user->getUID());
- $mounts = array();
- foreach ($mountPoints as $mountPoint => $options) {
- if (isset($options['options']['objectstore'])) {
- $objectClass = $options['options']['objectstore']['class'];
- $options['options']['objectstore'] = new $objectClass($options['options']['objectstore']);
- }
- $mountOptions = isset($options['mountOptions']) ? $options['mountOptions'] : [];
- if (isset($options['personal']) && $options['personal']) {
- $mount = new PersonalMount($this->userStoragesService, $options['id'], $options['class'], $mountPoint, $options['options'], $loader, $mountOptions);
- $mounts[] = $mount;
- } else {
- $mounts[] = new MountPoint($options['class'], $mountPoint, $options['options'], $loader, $mountOptions);
- }
+ $mounts = [];
+
+ $this->userStoragesService->setUser($user);
+ $this->userGlobalStoragesService->setUser($user);
+
+ foreach ($this->userGlobalStoragesService->getAllStorages() as $storage) {
+ $this->prepareStorageConfig($storage);
+ $impl = $this->constructStorage($storage);
+
+ $mount = new MountPoint(
+ $impl,
+ '/'.$user->getUID().'/files' . $storage->getMountPoint(),
+ null,
+ $loader,
+ $storage->getMountOptions()
+ );
+ $mounts[$storage->getMountPoint()] = $mount;
+ }
+
+ foreach ($this->userStoragesService->getAllStorages() as $storage) {
+ $this->prepareStorageConfig($storage);
+ $impl = $this->constructStorage($storage);
+
+ $mount = new PersonalMount(
+ $this->userStoragesService,
+ $storage->getId(),
+ $impl,
+ '/'.$user->getUID().'/files' . $storage->getMountPoint(),
+ null,
+ $loader,
+ $storage->getMountOptions()
+ );
+ $mounts[$storage->getMountPoint()] = $mount;
}
+
+ $this->userStoragesService->resetUser();
+ $this->userGlobalStoragesService->resetUser();
+
return $mounts;
}
}
diff --git a/apps/files_external/service/globalstoragesservice.php b/apps/files_external/service/globalstoragesservice.php
index 04445127b34..0e2d3f2b9c1 100644
--- a/apps/files_external/service/globalstoragesservice.php
+++ b/apps/files_external/service/globalstoragesservice.php
@@ -92,7 +92,7 @@ class GlobalStoragesService extends StoragesService {
$storageConfig->setBackendOptions($oldBackendOptions);
}
- \OC_Mount_Config::writeData(null, $mountPoints);
+ $this->writeLegacyConfig($mountPoints);
}
/**
diff --git a/apps/files_external/service/storagesservice.php b/apps/files_external/service/storagesservice.php
index 5f11d9ace68..d3bde0ae96c 100644
--- a/apps/files_external/service/storagesservice.php
+++ b/apps/files_external/service/storagesservice.php
@@ -56,6 +56,16 @@ abstract class StoragesService {
}
/**
+ * Write legacy config data
+ *
+ * @param array $mountPoints
+ */
+ protected function writeLegacyConfig(array $mountPoints) {
+ // write global config
+ \OC_Mount_Config::writeData(null, $mountPoints);
+ }
+
+ /**
* Copy legacy storage options into the given storage config object.
*
* @param StorageConfig $storageConfig storage config to populate
@@ -202,21 +212,31 @@ abstract class StoragesService {
// process storages with config hash, they must get a real id
if (!empty($storagesWithConfigHash)) {
- $nextId = $this->generateNextId($storages);
- foreach ($storagesWithConfigHash as $storage) {
- $storage->setId($nextId);
- $storages[$nextId] = $storage;
- $nextId++;
- }
-
- // re-save the config with the generated ids
- $this->writeConfig($storages);
+ $this->setRealStorageIds($storages, $storagesWithConfigHash);
}
return $storages;
}
/**
+ * Replace config hash ID with real IDs, for migrating legacy storages
+ *
+ * @param StorageConfig[] $storages Storages with real IDs
+ * @param StorageConfig[] $storagesWithConfigHash Storages with config hash IDs
+ */
+ protected function setRealStorageIds(array &$storages, array $storagesWithConfigHash) {
+ $nextId = $this->generateNextId($storages);
+ foreach ($storagesWithConfigHash as $storage) {
+ $storage->setId($nextId);
+ $storages[$nextId] = $storage;
+ $nextId++;
+ }
+
+ // re-save the config with the generated ids
+ $this->writeConfig($storages);
+ }
+
+ /**
* Add mount point into the messy mount point structure
*
* @param array $mountPoints messy array of mount points
diff --git a/apps/files_external/service/userglobalstoragesservice.php b/apps/files_external/service/userglobalstoragesservice.php
new file mode 100644
index 00000000000..78520419556
--- /dev/null
+++ b/apps/files_external/service/userglobalstoragesservice.php
@@ -0,0 +1,107 @@
+<?php
+/**
+ * @author Robin McCorkell <rmccorkell@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files_External\Service;
+
+use \OCA\Files_external\Service\GlobalStoragesService;
+use \OCA\Files_External\Service\BackendService;
+use \OCP\IUserSession;
+use \OCP\IGroupManager;
+use \OCA\Files_External\Service\UserTrait;
+
+/**
+ * Service class to read global storages applicable to the user
+ * Read-only access available, attempting to write will throw DomainException
+ */
+class UserGlobalStoragesService extends GlobalStoragesService {
+
+ use UserTrait;
+
+ /** @var IGroupManager */
+ protected $groupManager;
+
+ /**
+ * @param BackendService $backendService
+ * @param IUserSession $userSession
+ * @param IGroupManager $groupManager
+ */
+ public function __construct(
+ BackendService $backendService,
+ IUserSession $userSession,
+ IGroupManager $groupManager
+ ) {
+ parent::__construct($backendService);
+ $this->userSession = $userSession;
+ $this->groupManager = $groupManager;
+ }
+
+ /**
+ * Replace config hash ID with real IDs, for migrating legacy storages
+ *
+ * @param StorageConfig[] $storages Storages with real IDs
+ * @param StorageConfig[] $storagesWithConfigHash Storages with config hash IDs
+ */
+ protected function setRealStorageIds(array &$storages, array $storagesWithConfigHash) {
+ // as a read-only view, storage IDs don't need to be real
+ foreach ($storagesWithConfigHash as $storage) {
+ $storages[$storage->getId()] = $storage;
+ }
+ }
+
+ /**
+ * Read legacy config data
+ *
+ * @return array list of mount configs
+ */
+ protected function readLegacyConfig() {
+ // read global config
+ $data = parent::readLegacyConfig();
+ $userId = $this->getUser()->getUID();
+
+ if (isset($data[\OC_Mount_Config::MOUNT_TYPE_USER])) {
+ $data[\OC_Mount_Config::MOUNT_TYPE_USER] = array_filter(
+ $data[\OC_Mount_Config::MOUNT_TYPE_USER], function($key) use ($userId) {
+ return (strtolower($key) === strtolower($userId) || $key === 'all');
+ }, ARRAY_FILTER_USE_KEY
+ );
+ }
+
+ if (isset($data[\OC_Mount_Config::MOUNT_TYPE_GROUP])) {
+ $data[\OC_Mount_Config::MOUNT_TYPE_GROUP] = array_filter(
+ $data[\OC_Mount_Config::MOUNT_TYPE_GROUP], function($key) use ($userId) {
+ return ($this->groupManager->isInGroup($userId, $key));
+ }, ARRAY_FILTER_USE_KEY
+ );
+ }
+
+ return $data;
+ }
+
+ /**
+ * Write legacy config data
+ *
+ * @param array $mountPoints
+ */
+ protected function writeLegacyConfig(array $mountPoints) {
+ throw new \DomainException('UserGlobalStoragesService writing disallowed');
+ }
+
+}
diff --git a/apps/files_external/service/userstoragesservice.php b/apps/files_external/service/userstoragesservice.php
index 7ca911d45fb..c69b8d4f51e 100644
--- a/apps/files_external/service/userstoragesservice.php
+++ b/apps/files_external/service/userstoragesservice.php
@@ -27,6 +27,7 @@ use \OC\Files\Filesystem;
use \OCA\Files_external\Lib\StorageConfig;
use \OCA\Files_external\NotFoundException;
use \OCA\Files_External\Service\BackendService;
+use \OCA\Files_External\Service\UserTrait;
/**
* Service class to manage user external storages
@@ -34,12 +35,7 @@ use \OCA\Files_External\Service\BackendService;
*/
class UserStoragesService extends StoragesService {
- /**
- * User session
- *
- * @var IUserSession
- */
- private $userSession;
+ use UserTrait;
/**
* Create a user storages service
@@ -62,17 +58,28 @@ class UserStoragesService extends StoragesService {
*/
protected function readLegacyConfig() {
// read user config
- $user = $this->userSession->getUser()->getUID();
+ $user = $this->getUser()->getUID();
return \OC_Mount_Config::readData($user);
}
/**
+ * Write legacy config data
+ *
+ * @param array $mountPoints
+ */
+ protected function writeLegacyConfig(array $mountPoints) {
+ // write user config
+ $user = $this->getUser()->getUID();
+ \OC_Mount_Config::writeData($user, $mountPoints);
+ }
+
+ /**
* Read the external storages config
*
* @return array map of storage id to storage config
*/
protected function readConfig() {
- $user = $this->userSession->getUser()->getUID();
+ $user = $this->getUser()->getUID();
// TODO: in the future don't rely on the global config reading code
$storages = parent::readConfig();
@@ -99,7 +106,7 @@ class UserStoragesService extends StoragesService {
* @param array $storages map of storage id to storage config
*/
public function writeConfig($storages) {
- $user = $this->userSession->getUser()->getUID();
+ $user = $this->getUser()->getUID();
// let the horror begin
$mountPoints = [];
@@ -127,7 +134,7 @@ class UserStoragesService extends StoragesService {
$storageConfig->setBackendOptions($oldBackendOptions);
}
- \OC_Mount_Config::writeData($user, $mountPoints);
+ $this->writeLegacyConfig($mountPoints);
}
/**
@@ -138,7 +145,7 @@ class UserStoragesService extends StoragesService {
* @param string $signal signal to trigger
*/
protected function triggerHooks(StorageConfig $storage, $signal) {
- $user = $this->userSession->getUser()->getUID();
+ $user = $this->getUser()->getUID();
// trigger hook for the current user
$this->triggerApplicableHooks(
diff --git a/apps/files_external/service/usertrait.php b/apps/files_external/service/usertrait.php
new file mode 100644
index 00000000000..4f84543565c
--- /dev/null
+++ b/apps/files_external/service/usertrait.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * @author Robin McCorkell <rmccorkell@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files_External\Service;
+
+use \OCP\IUserSession;
+use \OCP\IUser;
+
+/**
+ * Trait for getting user information in a service
+ */
+trait UserTrait {
+
+ /** @var IUserSession */
+ protected $userSession;
+
+ /**
+ * User override
+ *
+ * @var IUser|null
+ */
+ private $user = null;
+
+ /**
+ * @return IUser|null
+ */
+ protected function getUser() {
+ if ($this->user) {
+ return $this->user;
+ }
+ return $this->userSession->getUser();
+ }
+
+ /**
+ * Override the user from the session
+ * Unset with ->resetUser() when finished!
+ *
+ * @param IUser
+ * @return self
+ */
+ public function setUser(IUser $user) {
+ $this->user = $user;
+ return $this;
+ }
+
+ /**
+ * Reset the user override
+ *
+ * @return self
+ */
+ public function resetUser() {
+ $this->user = null;
+ return $this;
+ }
+}
+