--- /dev/null
+<database>
+ <name>*dbname*</name>
+ <create>true</create>
+ <overwrite>false</overwrite>
+ <charset>utf8</charset>
+ <table>
+ <name>*dbprefix*external_mounts</name>
+ <declaration>
+ <field>
+ <name>mount_id</name>
+ <type>integer</type>
+ <default>0</default>
+ <notnull>true</notnull>
+ <autoincrement>1</autoincrement>
+ <length>6</length>
+ </field>
+ <field>
+ <name>mount_point</name>
+ <type>text</type>
+ <length>128</length>
+ <notnull>true</notnull>
+ </field>
+ <field>
+ <name>storage_backend</name>
+ <type>text</type>
+ <length>64</length>
+ <notnull>true</notnull>
+ </field>
+ <field>
+ <name>auth_backend</name>
+ <type>text</type>
+ <length>64</length>
+ <notnull>true</notnull>
+ </field>
+ <field>
+ <name>priority</name>
+ <type>integer</type>
+ <default>100</default>
+ <length>4</length>
+ <notnull>true</notnull>
+ </field>
+ <!-- admin = 1, personal = 2-->
+ <field>
+ <name>type</name>
+ <type>integer</type>
+ <length>4</length>
+ <notnull>true</notnull>
+ </field>
+ </declaration>
+ </table>
+ <table>
+ <name>*dbprefix*external_applicable</name>
+ <declaration>
+ <field>
+ <name>applicable_id</name>
+ <type>integer</type>
+ <default>0</default>
+ <notnull>true</notnull>
+ <autoincrement>1</autoincrement>
+ <length>6</length>
+ </field>
+ <field>
+ <!--foreign key: external_mounts.mount_id-->
+ <name>mount_id</name>
+ <type>integer</type>
+ <notnull>true</notnull>
+ <length>6</length>
+ </field>
+ <field>
+ <!-- possible mount types: global = 1, group = 2, user = 3 -->
+ <name>type</name>
+ <type>integer</type>
+ <length>4</length>
+ <notnull>true</notnull>
+ </field>
+ <field>
+ <!-- user_id, group_id or null for global mounts -->
+ <name>value</name>
+ <type>text</type>
+ <length>64</length>
+ </field>
+ <index>
+ <name>mount_id_app_index</name>
+ <field>
+ <name>mount_id</name>
+ <sorting>ascending</sorting>
+ </field>
+ </index>
+ <index>
+ <name>applicable_value_index</name>
+ <field>
+ <name>type</name>
+ <sorting>ascending</sorting>
+ </field>
+ <field>
+ <name>value</name>
+ <sorting>ascending</sorting>
+ </field>
+ </index>
+ <index>
+ <name>applicable_value_mount_index</name>
+ <unique>true</unique>
+ <field>
+ <name>type</name>
+ <sorting>ascending</sorting>
+ </field>
+ <field>
+ <name>value</name>
+ <sorting>ascending</sorting>
+ </field>
+ <field>
+ <name>mount_id</name>
+ <sorting>ascending</sorting>
+ </field>
+ </index>
+ </declaration>
+ </table>
+ <table>
+ <name>*dbprefix*external_config</name>
+ <declaration>
+ <field>
+ <name>config_id</name>
+ <type>integer</type>
+ <default>0</default>
+ <notnull>true</notnull>
+ <autoincrement>1</autoincrement>
+ <length>6</length>
+ </field>
+ <field>
+ <!--foreign key: external_mounts.mount_id-->
+ <name>mount_id</name>
+ <type>integer</type>
+ <notnull>true</notnull>
+ <length>6</length>
+ </field>
+ <field>
+ <name>key</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>64</length>
+ </field>
+ <field>
+ <name>value</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>4096</length>
+ </field>
+
+ <index>
+ <name>config_mount_id</name>
+ <field>
+ <name>mount_id</name>
+ <sorting>ascending</sorting>
+ </field>
+ </index>
+ <index>
+ <name>config_mount_key</name>
+ <unique>true</unique>
+ <field>
+ <name>mount_id</name>
+ <sorting>ascending</sorting>
+ </field>
+ <field>
+ <name>key</name>
+ <sorting>ascending</sorting>
+ </field>
+ </index>
+ </declaration>
+ </table>
+ <table>
+ <name>*dbprefix*external_options</name>
+ <declaration>
+ <field>
+ <name>option_id</name>
+ <type>integer</type>
+ <default>0</default>
+ <notnull>true</notnull>
+ <autoincrement>1</autoincrement>
+ <length>6</length>
+ </field>
+ <field>
+ <!--foreign key: external_mounts.mount_id-->
+ <name>mount_id</name>
+ <type>integer</type>
+ <notnull>true</notnull>
+ <length>6</length>
+ </field>
+ <field>
+ <name>key</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>64</length>
+ </field>
+ <field>
+ <name>value</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>256</length>
+ </field>
+
+ <index>
+ <name>option_mount_id</name>
+ <field>
+ <name>mount_id</name>
+ <sorting>ascending</sorting>
+ </field>
+ </index>
+ <index>
+ <name>option_mount_key</name>
+ <unique>true</unique>
+ <field>
+ <name>mount_id</name>
+ <sorting>ascending</sorting>
+ </field>
+ <field>
+ <name>key</name>
+ <sorting>ascending</sorting>
+ </field>
+ </index>
+ </declaration>
+ </table>
+</database>
<admin>admin-external-storage</admin>
</documentation>
<rememberlogin>false</rememberlogin>
- <version>0.4.0</version>
+ <version>0.5.0</version>
<types>
<filesystem/>
</types>
--- /dev/null
+<?php
+/**
+ * @author Robin Appelman <icewind@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/>
+ *
+ */
+
+$installedVersion = \OC::$server->getConfig()->getAppValue('files_external', 'installed_version');
+
+$app = new \OCA\Files_external\Appinfo\Application();
+
+// Migration to db config
+if (version_compare($installedVersion, '0.5.0', '<')) {
+ $migrator = $app->getContainer()->query('OCA\Files_external\Migration\StorageMigrator');
+ $migrator->migrateGlobal();
+}
namespace OCA\Files_External\Config;
+use OCA\Files_external\Migration\StorageMigrator;
use OCP\Files\Storage;
use OC\Files\Mount\MountPoint;
use OCP\Files\Storage\IStorageFactory;
/** @var UserGlobalStoragesService */
private $userGlobalStoragesService;
+ /** @var StorageMigrator */
+ private $migrator;
/**
* @param UserStoragesService $userStoragesService
* @param UserGlobalStoragesService $userGlobalStoragesService
+ * @param StorageMigrator $migrator
*/
public function __construct(
UserStoragesService $userStoragesService,
- UserGlobalStoragesService $userGlobalStoragesService
+ UserGlobalStoragesService $userGlobalStoragesService,
+ StorageMigrator $migrator
) {
$this->userStoragesService = $userStoragesService;
$this->userGlobalStoragesService = $userGlobalStoragesService;
+ $this->migrator = $migrator;
}
/**
* @return \OCP\Files\Mount\IMountPoint[]
*/
public function getMountsForUser(IUser $user, IStorageFactory $loader) {
+ $this->migrator->migrateUser();
+
$mounts = [];
$this->userStoragesService->setUser($user);
$mount = new MountPoint(
$impl,
- '/'.$user->getUID().'/files' . $storage->getMountPoint(),
+ '/' . $user->getUID() . '/files' . $storage->getMountPoint(),
null,
$loader,
$storage->getMountOptions()
$this->userStoragesService,
$storage->getId(),
$impl,
- '/'.$user->getUID().'/files' . $storage->getMountPoint(),
+ '/' . $user->getUID() . '/files' . $storage->getMountPoint(),
null,
$loader,
$storage->getMountOptions()
--- /dev/null
+<?php
+/**
+ * @author Robin Appelman <icewind@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\Migration;
+
+use OCA\Files_External\Service\BackendService;
+use OCA\Files_External\Service\DBConfigService;
+use OCA\Files_external\Service\GlobalLegacyStoragesService;
+use OCA\Files_external\Service\GlobalStoragesService;
+use OCA\Files_external\Service\LegacyStoragesService;
+use OCA\Files_external\Service\StoragesService;
+use OCA\Files_external\Service\UserLegacyStoragesService;
+use OCA\Files_external\Service\UserStoragesService;
+use OCP\IConfig;
+use OCP\IDBConnection;
+use OCP\ILogger;
+use OCP\IUserSession;
+
+/**
+ * Migrate mount config from mount.json to the database
+ */
+class StorageMigrator {
+ /**
+ * @var BackendService
+ */
+ private $backendService;
+
+ /**
+ * @var DBConfigService
+ */
+ private $dbConfig;
+
+ /**
+ * @var IUserSession
+ */
+ private $userSession;
+
+ /**
+ * @var IConfig
+ */
+ private $config;
+
+ /**
+ * @var IDBConnection
+ */
+ private $connection;
+
+ /**
+ * @var ILogger
+ */
+ private $logger;
+
+ /**
+ * StorageMigrator constructor.
+ *
+ * @param BackendService $backendService
+ * @param DBConfigService $dbConfig
+ * @param IUserSession $userSession
+ * @param IConfig $config
+ * @param IDBConnection $connection
+ * @param ILogger $logger
+ */
+ public function __construct(
+ BackendService $backendService,
+ DBConfigService $dbConfig,
+ IUserSession $userSession,
+ IConfig $config,
+ IDBConnection $connection,
+ ILogger $logger
+ ) {
+ $this->backendService = $backendService;
+ $this->dbConfig = $dbConfig;
+ $this->userSession = $userSession;
+ $this->config = $config;
+ $this->connection = $connection;
+ $this->logger = $logger;
+ }
+
+ private function migrate(LegacyStoragesService $legacyService, StoragesService $storageService) {
+ $existingStorage = $legacyService->getAllStorages();
+
+ $this->connection->beginTransaction();
+ try {
+ foreach ($existingStorage as $storage) {
+ $storageService->addStorage($storage);
+ }
+ $this->connection->commit();
+ } catch (\Exception $e) {
+ $this->logger->logException($e);
+ $this->connection->rollBack();
+ }
+ }
+
+ /**
+ * Migrate admin configured storages
+ */
+ public function migrateGlobal() {
+ $legacyService = new GlobalLegacyStoragesService($this->backendService);
+ $storageService = new GlobalStoragesService($this->backendService, $this->dbConfig);
+
+ $this->migrate($legacyService, $storageService);
+ }
+
+ /**
+ * Migrate personal storages configured by the current user
+ */
+ public function migrateUser() {
+ $userId = $this->userSession->getUser()->getUID();
+ $userVersion = $this->config->getUserValue($userId, 'files_external', 'config_version', '0.0.0');
+ if (version_compare($userVersion, '0.5.0', '<')) {
+ $this->config->setUserValue($userId, 'files_external', 'config_version', '0.5.0');
+ $legacyService = new UserLegacyStoragesService($this->backendService, $this->userSession);
+ $storageService = new UserStoragesService($this->backendService, $this->dbConfig, $this->userSession);
+
+ $this->migrate($legacyService, $storageService);
+ }
+ }
+}
--- /dev/null
+<?php
+/**
+ * @author Robin Appelman <icewind@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\DB\QueryBuilder\IQueryBuilder;
+use OCP\IDBConnection;
+
+/**
+ * Stores the mount config in the database
+ */
+class DBConfigService {
+ const MOUNT_TYPE_ADMIN = 1;
+ const MOUNT_TYPE_PERSONAl = 2;
+
+ const APPLICABLE_TYPE_GLOBAL = 1;
+ const APPLICABLE_TYPE_GROUP = 2;
+ const APPLICABLE_TYPE_USER = 3;
+
+ /**
+ * @var IDBConnection
+ */
+ private $connection;
+
+ /**
+ * DBConfigService constructor.
+ *
+ * @param IDBConnection $connection
+ */
+ public function __construct(IDBConnection $connection) {
+ $this->connection = $connection;
+ }
+
+ /**
+ * @param int $mountId
+ * @return array
+ */
+ public function getMountById($mountId) {
+ $builder = $this->connection->getQueryBuilder();
+ $query = $builder->select(['mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'type'])
+ ->from('external_mounts', 'm')
+ ->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, \PDO::PARAM_INT)));
+ $mounts = $this->getMountsFromQuery($query);
+ if (count($mounts) > 0) {
+ return $mounts[0];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get admin defined mounts
+ *
+ * @return array
+ */
+ public function getAdminMounts() {
+ $builder = $this->connection->getQueryBuilder();
+ $query = $builder->select(['mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'type'])
+ ->from('external_mounts')
+ ->where($builder->expr()->eq('type', $builder->expr()->literal(self::MOUNT_TYPE_ADMIN, \PDO::PARAM_INT)));
+ return $this->getMountsFromQuery($query);
+ }
+
+ protected function getForQuery(IQueryBuilder $builder, $type, $value) {
+ $query = $builder->select(['m.mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'm.type'])
+ ->from('external_mounts', 'm')
+ ->innerJoin('m', 'external_applicable', 'a', 'm.mount_id = a.mount_id')
+ ->where($builder->expr()->eq('a.type', $builder->createNamedParameter($type, \PDO::PARAM_INT)));
+
+ if (is_null($value)) {
+ $query = $query->andWhere($builder->expr()->isNull('a.value'));
+ } else {
+ $query = $query->andWhere($builder->expr()->eq('a.value', $builder->createNamedParameter($value)));
+ }
+
+ return $query;
+ }
+
+ /**
+ * Get mounts by applicable
+ *
+ * @param int $type any of the self::APPLICABLE_TYPE_ constants
+ * @param string|null $value user_id, group_id or null for global mounts
+ * @return array
+ */
+ public function getMountsFor($type, $value) {
+ $builder = $this->connection->getQueryBuilder();
+ $query = $this->getForQuery($builder, $type, $value);
+
+ return $this->getMountsFromQuery($query);
+ }
+
+ /**
+ * Get admin defined mounts by applicable
+ *
+ * @param int $type any of the self::APPLICABLE_TYPE_ constants
+ * @param string|null $value user_id, group_id or null for global mounts
+ * @return array
+ */
+ public function getAdminMountsFor($type, $value) {
+ $builder = $this->connection->getQueryBuilder();
+ $query = $this->getForQuery($builder, $type, $value);
+ $query->andWhere($builder->expr()->eq('m.type', $builder->expr()->literal(self::MOUNT_TYPE_ADMIN, \PDO::PARAM_INT)));
+
+ return $this->getMountsFromQuery($query);
+ }
+
+ /**
+ * Get admin defined mounts for multiple applicable
+ *
+ * @param int $type any of the self::APPLICABLE_TYPE_ constants
+ * @param string[] $values user_ids or group_ids
+ * @return array
+ */
+ public function getAdminMountsForMultiple($type, array $values) {
+ $builder = $this->connection->getQueryBuilder();
+ $params = array_map(function ($value) use ($builder) {
+ return $builder->createNamedParameter($value, \PDO::PARAM_STR);
+ }, $values);
+
+ $query = $builder->select(['m.mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'm.type'])
+ ->from('external_mounts', 'm')
+ ->innerJoin('m', 'external_applicable', 'a', 'm.mount_id = a.mount_id')
+ ->where($builder->expr()->eq('a.type', $builder->createNamedParameter($type, \PDO::PARAM_INT)))
+ ->andWhere($builder->expr()->in('a.value', $params));
+ $query->andWhere($builder->expr()->eq('m.type', $builder->expr()->literal(self::MOUNT_TYPE_ADMIN, \PDO::PARAM_INT)));
+
+ return $this->getMountsFromQuery($query);
+ }
+
+ /**
+ * Get user defined mounts by applicable
+ *
+ * @param int $type any of the self::APPLICABLE_TYPE_ constants
+ * @param string|null $value user_id, group_id or null for global mounts
+ * @return array
+ */
+ public function getUserMountsFor($type, $value) {
+ $builder = $this->connection->getQueryBuilder();
+ $query = $this->getForQuery($builder, $type, $value);
+ $query->andWhere($builder->expr()->eq('m.type', $builder->expr()->literal(self::MOUNT_TYPE_PERSONAl, \PDO::PARAM_INT)));
+
+ return $this->getMountsFromQuery($query);
+ }
+
+ /**
+ * Add a mount to the database
+ *
+ * @param string $mountPoint
+ * @param string $storageBackend
+ * @param string $authBackend
+ * @param int $priority
+ * @param int $type self::MOUNT_TYPE_ADMIN or self::MOUNT_TYPE_PERSONAL
+ * @return int the id of the new mount
+ */
+ public function addMount($mountPoint, $storageBackend, $authBackend, $priority, $type) {
+ if (!$priority) {
+ $priority = 100;
+ }
+ $builder = $this->connection->getQueryBuilder();
+ $query = $builder->insert('external_mounts')
+ ->values([
+ 'mount_point' => $builder->createNamedParameter($mountPoint, \PDO::PARAM_STR),
+ 'storage_backend' => $builder->createNamedParameter($storageBackend, \PDO::PARAM_STR),
+ 'auth_backend' => $builder->createNamedParameter($authBackend, \PDO::PARAM_STR),
+ 'priority' => $builder->createNamedParameter($priority, \PDO::PARAM_INT),
+ 'type' => $builder->createNamedParameter($type, \PDO::PARAM_INT)
+ ]);
+ $query->execute();
+ return (int)$this->connection->lastInsertId('external_mounts');
+ }
+
+ /**
+ * Remove a mount from the database
+ *
+ * @param int $mountId
+ */
+ public function removeMount($mountId) {
+ $builder = $this->connection->getQueryBuilder();
+ $query = $builder->delete('external_mounts')
+ ->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, \PDO::PARAM_INT)));
+ $query->execute();
+
+ $query = $builder->delete('external_applicable')
+ ->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, \PDO::PARAM_INT)));
+ $query->execute();
+
+ $query = $builder->delete('external_config')
+ ->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, \PDO::PARAM_INT)));
+ $query->execute();
+
+ $query = $builder->delete('external_options')
+ ->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, \PDO::PARAM_INT)));
+ $query->execute();
+ }
+
+ /**
+ * @param int $mountId
+ * @param string $key
+ * @param string $value
+ */
+ public function setConfig($mountId, $key, $value) {
+ $count = $this->connection->insertIfNotExist('*PREFIX*external_config', [
+ 'mount_id' => $mountId,
+ 'key' => $key,
+ 'value' => $value
+ ], ['mount_id', 'key']);
+ if ($count === 0) {
+ $builder = $this->connection->getQueryBuilder();
+ $query = $builder->update('external_config')
+ ->set('value', $builder->createNamedParameter($value, \PDO::PARAM_STR))
+ ->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, \PDO::PARAM_INT)))
+ ->andWhere($builder->expr()->eq('key', $builder->createNamedParameter($key, \PDO::PARAM_STR)));
+ $query->execute();
+ }
+ }
+
+ /**
+ * @param int $mountId
+ * @param string $key
+ * @param string $value
+ */
+ public function setOption($mountId, $key, $value) {
+ $count = $this->connection->insertIfNotExist('*PREFIX*external_options', [
+ 'mount_id' => $mountId,
+ 'key' => $key,
+ 'value' => json_encode($value)
+ ], ['mount_id', 'key']);
+ if ($count === 0) {
+ $builder = $this->connection->getQueryBuilder();
+ $query = $builder->update('external_options')
+ ->set('value', $builder->createNamedParameter(json_encode($value), \PDO::PARAM_STR))
+ ->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, \PDO::PARAM_INT)))
+ ->andWhere($builder->expr()->eq('key', $builder->createNamedParameter($key, \PDO::PARAM_STR)));
+ $query->execute();
+ }
+ }
+
+ public function addApplicable($mountId, $type, $value) {
+ $this->connection->insertIfNotExist('*PREFIX*external_applicable', [
+ 'mount_id' => $mountId,
+ 'type' => $type,
+ 'value' => $value
+ ], ['mount_id', 'type', 'value']);
+ }
+
+ public function removeApplicable($mountId, $type, $value) {
+ $builder = $this->connection->getQueryBuilder();
+ $query = $builder->delete('external_applicable')
+ ->where($builder->expr()->eq('mount_id', $builder->createNamedParameter($mountId, \PDO::PARAM_INT)))
+ ->andWhere($builder->expr()->eq('type', $builder->createNamedParameter($type, \PDO::PARAM_INT)))
+ ->andWhere($builder->expr()->eq('value', $builder->createNamedParameter($value, \PDO::PARAM_STR)));
+ $query->execute();
+ }
+
+ private function getMountsFromQuery(IQueryBuilder $query) {
+ $result = $query->execute();
+ $mounts = $result->fetchAll();
+
+ $mountIds = array_map(function ($mount) {
+ return $mount['mount_id'];
+ }, $mounts);
+
+ $applicable = $this->getApplicableForMounts($mountIds);
+ $config = $this->getConfigForMounts($mountIds);
+ $options = $this->getOptionsForMounts($mountIds);
+
+ return array_map(function ($mount, $applicable, $config, $options) {
+ $mount['type'] = (int)$mount['type'];
+ $mount['priority'] = (int)$mount['priority'];
+ $mount['applicable'] = $applicable;
+ $mount['config'] = $config;
+ $mount['options'] = $options;
+ return $mount;
+ }, $mounts, $applicable, $config, $options);
+ }
+
+ /**
+ * Get mount options from a table grouped by mount id
+ *
+ * @param string $table
+ * @param string[] $fields
+ * @param int[] $mountIds
+ * @return array [$mountId => [['field1' => $value1, ...], ...], ...]
+ */
+ private function selectForMounts($table, array $fields, array $mountIds) {
+ if (count($mountIds) === 0) {
+ return [];
+ }
+ $builder = $this->connection->getQueryBuilder();
+ $fields[] = 'mount_id';
+ $placeHolders = array_map(function ($id) use ($builder) {
+ return $builder->createPositionalParameter($id, \PDO::PARAM_INT);
+ }, $mountIds);
+ $query = $builder->select($fields)
+ ->from($table)
+ ->where($builder->expr()->in('mount_id', $placeHolders));
+ $rows = $query->execute()->fetchAll();
+
+ $result = [];
+ foreach ($mountIds as $mountId) {
+ $result[$mountId] = [];
+ }
+ foreach ($rows as $row) {
+ if (isset($row['type'])) {
+ $row['type'] = (int)$row['type'];
+ }
+ $result[$row['mount_id']][] = $row;
+ }
+ return $result;
+ }
+
+ /**
+ * @param int[] $mountIds
+ * @return array [$id => [['type' => $type, 'value' => $value], ...], ...]
+ */
+ public function getApplicableForMounts($mountIds) {
+ return $this->selectForMounts('external_applicable', ['type', 'value'], $mountIds);
+ }
+
+ /**
+ * @param int[] $mountIds
+ * @return array [$id => ['key1' => $value1, ...], ...]
+ */
+ public function getConfigForMounts($mountIds) {
+ $mountConfigs = $this->selectForMounts('external_config', ['key', 'value'], $mountIds);
+ return array_map([$this, 'createKeyValueMap'], $mountConfigs);
+ }
+
+ /**
+ * @param int[] $mountIds
+ * @return array [$id => ['key1' => $value1, ...], ...]
+ */
+ public function getOptionsForMounts($mountIds) {
+ $mountOptions = $this->selectForMounts('external_options', ['key', 'value'], $mountIds);
+ $optionsMap = array_map([$this, 'createKeyValueMap'], $mountOptions);
+ return array_map(function (array $options) {
+ return array_map(function ($option) {
+ return json_decode($option);
+ }, $options);
+ }, $optionsMap);
+ }
+
+ /**
+ * @param array $keyValuePairs [['key'=>$key, 'value=>$value], ...]
+ * @return array ['key1' => $value1, ...]
+ */
+ private function createKeyValueMap(array $keyValuePairs) {
+ $keys = array_map(function ($pair) {
+ return $pair['key'];
+ }, $keyValuePairs);
+ $values = array_map(function ($pair) {
+ return $pair['value'];
+ }, $keyValuePairs);
+
+ return array_combine($keys, $values);
+ }
+}
--- /dev/null
+<?php
+/**
+ * @author Robin Appelman <icewind@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;
+
+/**
+ * Read admin defined mounts from the legacy mount.json
+ */
+class GlobalLegacyStoragesService extends LegacyStoragesService {
+ /**
+ * @param BackendService $backendService
+ */
+ public function __construct(BackendService $backendService) {
+ $this->backendService = $backendService;
+ }
+
+ /**
+ * Read legacy config data
+ *
+ * @return array list of mount configs
+ */
+ protected function readLegacyConfig() {
+ // read global config
+ return \OC_Mount_Config::readData();
+ }
+}
* Service class to manage global external storages
*/
class GlobalStoragesService extends StoragesService {
-
- /**
- * Write the storages to the configuration.
- *
- * @param array $storages map of storage id to storage config
- */
- public function writeConfig($storages) {
- // let the horror begin
- $mountPoints = [];
- foreach ($storages as $storageConfig) {
- $mountPoint = $storageConfig->getMountPoint();
- $oldBackendOptions = $storageConfig->getBackendOptions();
- $storageConfig->setBackendOptions(
- \OC_Mount_Config::encryptPasswords(
- $oldBackendOptions
- )
- );
-
- // system mount
- $rootMountPoint = '/$user/files/' . ltrim($mountPoint, '/');
-
- $applicableUsers = $storageConfig->getApplicableUsers();
- $applicableGroups = $storageConfig->getApplicableGroups();
- foreach ($applicableUsers as $applicable) {
- $this->addMountPoint(
- $mountPoints,
- \OC_Mount_Config::MOUNT_TYPE_USER,
- $applicable,
- $rootMountPoint,
- $storageConfig
- );
- }
-
- foreach ($applicableGroups as $applicable) {
- $this->addMountPoint(
- $mountPoints,
- \OC_Mount_Config::MOUNT_TYPE_GROUP,
- $applicable,
- $rootMountPoint,
- $storageConfig
- );
- }
-
- // if neither "applicableGroups" or "applicableUsers" were set, use "all" user
- if (empty($applicableUsers) && empty($applicableGroups)) {
- $this->addMountPoint(
- $mountPoints,
- \OC_Mount_Config::MOUNT_TYPE_USER,
- 'all',
- $rootMountPoint,
- $storageConfig
- );
- }
-
- // restore old backend options where the password was not encrypted,
- // because we don't want to change the state of the original object
- $storageConfig->setBackendOptions($oldBackendOptions);
- }
-
- $this->writeLegacyConfig($mountPoints);
- }
-
/**
* Triggers $signal for all applicable users of the given
* storage
--- /dev/null
+<?php
+/**
+ * @author Robin Appelman <icewind@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\Lib\StorageConfig;
+
+/**
+ * Read mount config from legacy mount.json
+ */
+abstract class LegacyStoragesService {
+ /** @var BackendService */
+ protected $backendService;
+
+ /**
+ * Read legacy config data
+ *
+ * @return array list of mount configs
+ */
+ abstract protected function readLegacyConfig();
+
+ /**
+ * Copy legacy storage options into the given storage config object.
+ *
+ * @param StorageConfig $storageConfig storage config to populate
+ * @param string $mountType mount type
+ * @param string $applicable applicable user or group
+ * @param array $storageOptions legacy storage options
+ *
+ * @return StorageConfig populated storage config
+ */
+ protected function populateStorageConfigWithLegacyOptions(
+ &$storageConfig,
+ $mountType,
+ $applicable,
+ $storageOptions
+ ) {
+ $backend = $this->backendService->getBackend($storageOptions['backend']);
+ if (!$backend) {
+ throw new \UnexpectedValueException('Invalid backend ' . $storageOptions['backend']);
+ }
+ $storageConfig->setBackend($backend);
+ if (isset($storageOptions['authMechanism']) && $storageOptions['authMechanism'] !== 'builtin::builtin') {
+ $authMechanism = $this->backendService->getAuthMechanism($storageOptions['authMechanism']);
+ } else {
+ $authMechanism = $backend->getLegacyAuthMechanism($storageOptions);
+ $storageOptions['authMechanism'] = 'null'; // to make error handling easier
+ }
+ if (!$authMechanism) {
+ throw new \UnexpectedValueException('Invalid authentication mechanism ' . $storageOptions['authMechanism']);
+ }
+ $storageConfig->setAuthMechanism($authMechanism);
+ $storageConfig->setBackendOptions($storageOptions['options']);
+ if (isset($storageOptions['mountOptions'])) {
+ $storageConfig->setMountOptions($storageOptions['mountOptions']);
+ }
+ if (!isset($storageOptions['priority'])) {
+ $storageOptions['priority'] = $backend->getPriority();
+ }
+ $storageConfig->setPriority($storageOptions['priority']);
+ if ($mountType === \OC_Mount_Config::MOUNT_TYPE_USER) {
+ $applicableUsers = $storageConfig->getApplicableUsers();
+ if ($applicable !== 'all') {
+ $applicableUsers[] = $applicable;
+ $storageConfig->setApplicableUsers($applicableUsers);
+ }
+ } else if ($mountType === \OC_Mount_Config::MOUNT_TYPE_GROUP) {
+ $applicableGroups = $storageConfig->getApplicableGroups();
+ $applicableGroups[] = $applicable;
+ $storageConfig->setApplicableGroups($applicableGroups);
+ }
+ return $storageConfig;
+ }
+
+ /**
+ * Read the external storages config
+ *
+ * @return StorageConfig[] map of storage id to storage config
+ */
+ public function getAllStorages() {
+ $mountPoints = $this->readLegacyConfig();
+ /**
+ * Here is the how the horribly messy mount point array looks like
+ * from the mount.json file:
+ *
+ * $storageOptions = $mountPoints[$mountType][$applicable][$mountPath]
+ *
+ * - $mountType is either "user" or "group"
+ * - $applicable is the name of a user or group (or the current user for personal mounts)
+ * - $mountPath is the mount point path (where the storage must be mounted)
+ * - $storageOptions is a map of storage options:
+ * - "priority": storage priority
+ * - "backend": backend identifier
+ * - "class": LEGACY backend class name
+ * - "options": backend-specific options
+ * - "authMechanism": authentication mechanism identifier
+ * - "mountOptions": mount-specific options (ex: disable previews, scanner, etc)
+ */
+ // group by storage id
+ /** @var StorageConfig[] $storages */
+ $storages = [];
+ // for storages without id (legacy), group by config hash for
+ // later processing
+ $storagesWithConfigHash = [];
+ foreach ($mountPoints as $mountType => $applicables) {
+ foreach ($applicables as $applicable => $mountPaths) {
+ foreach ($mountPaths as $rootMountPath => $storageOptions) {
+ $currentStorage = null;
+ /**
+ * Flag whether the config that was read already has an id.
+ * If not, it will use a config hash instead and generate
+ * a proper id later
+ *
+ * @var boolean
+ */
+ $hasId = false;
+ // the root mount point is in the format "/$user/files/the/mount/point"
+ // we remove the "/$user/files" prefix
+ $parts = explode('/', ltrim($rootMountPath, '/'), 3);
+ if (count($parts) < 3) {
+ // something went wrong, skip
+ \OCP\Util::writeLog(
+ 'files_external',
+ 'Could not parse mount point "' . $rootMountPath . '"',
+ \OCP\Util::ERROR
+ );
+ continue;
+ }
+ $relativeMountPath = rtrim($parts[2], '/');
+ // note: we cannot do this after the loop because the decrypted config
+ // options might be needed for the config hash
+ $storageOptions['options'] = \OC_Mount_Config::decryptPasswords($storageOptions['options']);
+ if (!isset($storageOptions['backend'])) {
+ $storageOptions['backend'] = $storageOptions['class']; // legacy compat
+ }
+ if (!isset($storageOptions['authMechanism'])) {
+ $storageOptions['authMechanism'] = null; // ensure config hash works
+ }
+ if (isset($storageOptions['id'])) {
+ $configId = (int)$storageOptions['id'];
+ if (isset($storages[$configId])) {
+ $currentStorage = $storages[$configId];
+ }
+ $hasId = true;
+ } else {
+ // missing id in legacy config, need to generate
+ // but at this point we don't know the max-id, so use
+ // first group it by config hash
+ $storageOptions['mountpoint'] = $rootMountPath;
+ $configId = \OC_Mount_Config::makeConfigHash($storageOptions);
+ if (isset($storagesWithConfigHash[$configId])) {
+ $currentStorage = $storagesWithConfigHash[$configId];
+ }
+ }
+ if (is_null($currentStorage)) {
+ // create new
+ $currentStorage = new StorageConfig($configId);
+ $currentStorage->setMountPoint($relativeMountPath);
+ }
+ try {
+ $this->populateStorageConfigWithLegacyOptions(
+ $currentStorage,
+ $mountType,
+ $applicable,
+ $storageOptions
+ );
+ if ($hasId) {
+ $storages[$configId] = $currentStorage;
+ } else {
+ $storagesWithConfigHash[$configId] = $currentStorage;
+ }
+ } catch (\UnexpectedValueException $e) {
+ // dont die if a storage backend doesn't exist
+ \OCP\Util::writeLog(
+ 'files_external',
+ 'Could not load storage: "' . $e->getMessage() . '"',
+ \OCP\Util::ERROR
+ );
+ }
+ }
+ }
+ }
+
+ // convert parameter values
+ foreach ($storages as $storage) {
+ $storage->getBackend()->validateStorageDefinition($storage);
+ $storage->getAuthMechanism()->validateStorageDefinition($storage);
+ }
+ return $storages;
+ }
+}
protected $backendService;
/**
- * @param BackendService $backendService
+ * @var DBConfigService
*/
- public function __construct(BackendService $backendService) {
- $this->backendService = $backendService;
- }
+ protected $dbConfig;
/**
- * Read legacy config data
- *
- * @return array list of mount configs
+ * @param BackendService $backendService
+ * @param DBConfigService $dbConfigService
*/
- protected function readLegacyConfig() {
- // read global config
- return \OC_Mount_Config::readData();
+ public function __construct(BackendService $backendService, DBConfigService $dbConfigService) {
+ $this->backendService = $backendService;
+ $this->dbConfig = $dbConfigService;
}
- /**
- * Write legacy config data
- *
- * @param array $mountPoints
- */
- protected function writeLegacyConfig(array $mountPoints) {
- // write global config
- \OC_Mount_Config::writeData(null, $mountPoints);
+ protected function readDBConfig() {
+ return $this->dbConfig->getAdminMounts();
}
- /**
- * Copy legacy storage options into the given storage config object.
- *
- * @param StorageConfig $storageConfig storage config to populate
- * @param string $mountType mount type
- * @param string $applicable applicable user or group
- * @param array $storageOptions legacy storage options
- *
- * @return StorageConfig populated storage config
- */
- protected function populateStorageConfigWithLegacyOptions(
- &$storageConfig,
- $mountType,
- $applicable,
- $storageOptions
- ) {
- $backend = $this->backendService->getBackend($storageOptions['backend']);
- if (!$backend) {
- throw new \UnexpectedValueException('Invalid backend '.$storageOptions['backend']);
- }
- $storageConfig->setBackend($backend);
-
- if (isset($storageOptions['authMechanism']) && $storageOptions['authMechanism'] !== 'builtin::builtin') {
- $authMechanism = $this->backendService->getAuthMechanism($storageOptions['authMechanism']);
- } else {
- $authMechanism = $backend->getLegacyAuthMechanism($storageOptions);
- $storageOptions['authMechanism'] = 'null'; // to make error handling easier
- }
- if (!$authMechanism) {
- throw new \UnexpectedValueException('Invalid authentication mechanism '.$storageOptions['authMechanism']);
- }
- $storageConfig->setAuthMechanism($authMechanism);
-
- $storageConfig->setBackendOptions($storageOptions['options']);
- if (isset($storageOptions['mountOptions'])) {
- $storageConfig->setMountOptions($storageOptions['mountOptions']);
- }
- if (!isset($storageOptions['priority'])) {
- $storageOptions['priority'] = $backend->getPriority();
- }
- $storageConfig->setPriority($storageOptions['priority']);
+ protected function getStorageConfigFromDBMount(array $mount) {
+ $applicableUsers = array_filter($mount['applicable'], function ($applicable) {
+ return $applicable['type'] === DBConfigService::APPLICABLE_TYPE_USER;
+ });
+ $applicableUsers = array_map(function ($applicable) {
+ return $applicable['value'];
+ }, $applicableUsers);
+
+ $applicableGroups = array_filter($mount['applicable'], function ($applicable) {
+ return $applicable['type'] === DBConfigService::APPLICABLE_TYPE_GROUP;
+ });
+ $applicableGroups = array_map(function ($applicable) {
+ return $applicable['value'];
+ }, $applicableGroups);
- if ($mountType === \OC_Mount_Config::MOUNT_TYPE_USER) {
- $applicableUsers = $storageConfig->getApplicableUsers();
- if ($applicable !== 'all') {
- $applicableUsers[] = $applicable;
- $storageConfig->setApplicableUsers($applicableUsers);
- }
- } else if ($mountType === \OC_Mount_Config::MOUNT_TYPE_GROUP) {
- $applicableGroups = $storageConfig->getApplicableGroups();
- $applicableGroups[] = $applicable;
- $storageConfig->setApplicableGroups($applicableGroups);
+ try {
+ $config = $this->createStorage(
+ $mount['mount_point'],
+ $mount['storage_backend'],
+ $mount['auth_backend'],
+ $mount['config'],
+ $mount['options'],
+ array_values($applicableUsers),
+ array_values($applicableGroups),
+ $mount['priority']
+ );
+ $config->setId((int)$mount['mount_id']);
+ return $config;
+ } catch (\UnexpectedValueException $e) {
+ // dont die if a storage backend doesn't exist
+ \OCP\Util::writeLog(
+ 'files_external',
+ 'Could not load storage: "' . $e->getMessage() . '"',
+ \OCP\Util::ERROR
+ );
+ return null;
}
-
-
- return $storageConfig;
}
/**
* @return array map of storage id to storage config
*/
protected function readConfig() {
- $mountPoints = $this->readLegacyConfig();
-
- /**
- * Here is the how the horribly messy mount point array looks like
- * from the mount.json file:
- *
- * $storageOptions = $mountPoints[$mountType][$applicable][$mountPath]
- *
- * - $mountType is either "user" or "group"
- * - $applicable is the name of a user or group (or the current user for personal mounts)
- * - $mountPath is the mount point path (where the storage must be mounted)
- * - $storageOptions is a map of storage options:
- * - "priority": storage priority
- * - "backend": backend identifier
- * - "class": LEGACY backend class name
- * - "options": backend-specific options
- * - "authMechanism": authentication mechanism identifier
- * - "mountOptions": mount-specific options (ex: disable previews, scanner, etc)
- */
-
- // group by storage id
- $storages = [];
-
- // for storages without id (legacy), group by config hash for
- // later processing
- $storagesWithConfigHash = [];
-
- foreach ($mountPoints as $mountType => $applicables) {
- foreach ($applicables as $applicable => $mountPaths) {
- foreach ($mountPaths as $rootMountPath => $storageOptions) {
- $currentStorage = null;
-
- /**
- * Flag whether the config that was read already has an id.
- * If not, it will use a config hash instead and generate
- * a proper id later
- *
- * @var boolean
- */
- $hasId = false;
-
- // the root mount point is in the format "/$user/files/the/mount/point"
- // we remove the "/$user/files" prefix
- $parts = explode('/', ltrim($rootMountPath, '/'), 3);
- if (count($parts) < 3) {
- // something went wrong, skip
- \OCP\Util::writeLog(
- 'files_external',
- 'Could not parse mount point "' . $rootMountPath . '"',
- \OCP\Util::ERROR
- );
- continue;
- }
-
- $relativeMountPath = rtrim($parts[2], '/');
-
- // note: we cannot do this after the loop because the decrypted config
- // options might be needed for the config hash
- $storageOptions['options'] = \OC_Mount_Config::decryptPasswords($storageOptions['options']);
-
- if (!isset($storageOptions['backend'])) {
- $storageOptions['backend'] = $storageOptions['class']; // legacy compat
- }
- if (!isset($storageOptions['authMechanism'])) {
- $storageOptions['authMechanism'] = null; // ensure config hash works
- }
-
- if (isset($storageOptions['id'])) {
- $configId = (int)$storageOptions['id'];
- if (isset($storages[$configId])) {
- $currentStorage = $storages[$configId];
- }
- $hasId = true;
- } else {
- // missing id in legacy config, need to generate
- // but at this point we don't know the max-id, so use
- // first group it by config hash
- $storageOptions['mountpoint'] = $rootMountPath;
- $configId = \OC_Mount_Config::makeConfigHash($storageOptions);
- if (isset($storagesWithConfigHash[$configId])) {
- $currentStorage = $storagesWithConfigHash[$configId];
- }
- }
-
- if (is_null($currentStorage)) {
- // create new
- $currentStorage = new StorageConfig($configId);
- $currentStorage->setMountPoint($relativeMountPath);
- }
-
- try {
- $this->populateStorageConfigWithLegacyOptions(
- $currentStorage,
- $mountType,
- $applicable,
- $storageOptions
- );
-
- if ($hasId) {
- $storages[$configId] = $currentStorage;
- } else {
- $storagesWithConfigHash[$configId] = $currentStorage;
- }
- } catch (\UnexpectedValueException $e) {
- // dont die if a storage backend doesn't exist
- \OCP\Util::writeLog(
- 'files_external',
- 'Could not load storage: "' . $e->getMessage() . '"',
- \OCP\Util::ERROR
- );
- }
- }
- }
- }
-
- // process storages with config hash, they must get a real id
- if (!empty($storagesWithConfigHash)) {
- $this->setRealStorageIds($storages, $storagesWithConfigHash);
- }
+ $mounts = $this->readDBConfig();
+ $configs = array_map([$this, 'getStorageConfigFromDBMount'], $mounts);
+ $configs = array_filter($configs, function ($config) {
+ return $config instanceof StorageConfig;
+ });
- // convert parameter values
- foreach ($storages as $storage) {
- $storage->getBackend()->validateStorageDefinition($storage);
- $storage->getAuthMechanism()->validateStorageDefinition($storage);
- }
+ $keys = array_map(function (StorageConfig $config) {
+ return $config->getId();
+ }, $configs);
- return $storages;
+ return array_combine($keys, $configs);
}
- /**
- * 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
- * @param string $mountType mount type
- * @param string $applicable single applicable user or group
- * @param string $rootMountPoint root mount point to use
- * @param array $storageConfig storage config to set to the mount point
- */
- protected function addMountPoint(&$mountPoints, $mountType, $applicable, $rootMountPoint, $storageConfig) {
- if (!isset($mountPoints[$mountType])) {
- $mountPoints[$mountType] = [];
- }
-
- if (!isset($mountPoints[$mountType][$applicable])) {
- $mountPoints[$mountType][$applicable] = [];
- }
-
- $options = [
- 'id' => $storageConfig->getId(),
- 'backend' => $storageConfig->getBackend()->getIdentifier(),
- //'class' => $storageConfig->getBackend()->getClass(),
- 'authMechanism' => $storageConfig->getAuthMechanism()->getIdentifier(),
- 'options' => $storageConfig->getBackendOptions(),
- ];
-
- if (!is_null($storageConfig->getPriority())) {
- $options['priority'] = $storageConfig->getPriority();
- }
-
- $mountOptions = $storageConfig->getMountOptions();
- if (!empty($mountOptions)) {
- $options['mountOptions'] = $mountOptions;
- }
-
- $mountPoints[$mountType][$applicable][$rootMountPoint] = $options;
- }
-
- /**
- * Write the storages to the configuration.
- *
- * @param array $storages map of storage id to storage config
- */
- abstract protected function writeConfig($storages);
-
/**
* Get a storage with status
*
* @throws NotFoundException if the storage with the given id was not found
*/
public function getStorage($id) {
- $allStorages = $this->readConfig();
+ $mount = $this->dbConfig->getMountById($id);
- if (!isset($allStorages[$id])) {
+ if (!is_array($mount)) {
throw new NotFoundException('Storage with id "' . $id . '" not found');
}
- return $allStorages[$id];
+ return $this->getStorageConfigFromDBMount($mount);
}
/**
* Gets all storages, valid or not
*
- * @return array array of storage configs
+ * @return StorageConfig[] array of storage configs
*/
public function getAllStorages() {
return $this->readConfig();
/**
* Gets all valid storages
*
- * @return array
+ * @return StorageConfig[]
*/
public function getStorages() {
return array_filter($this->getAllStorages(), [$this, 'validateStorage']);
*/
abstract public function getVisibilityType();
+ protected function getType() {
+ return DBConfigService::MOUNT_TYPE_ADMIN;
+ }
+
/**
* Add new storage to the configuration
*
- * @param array $newStorage storage attributes
+ * @param StorageConfig $newStorage storage attributes
*
* @return StorageConfig storage config, with added id
*/
public function addStorage(StorageConfig $newStorage) {
$allStorages = $this->readConfig();
- $configId = $this->generateNextId($allStorages);
+ $configId = $this->dbConfig->addMount(
+ $newStorage->getMountPoint(),
+ $newStorage->getBackend()->getIdentifier(),
+ $newStorage->getAuthMechanism()->getIdentifier(),
+ $newStorage->getPriority(),
+ $this->getType()
+ );
+
$newStorage->setId($configId);
+ foreach ($newStorage->getApplicableUsers() as $user) {
+ $this->dbConfig->addApplicable($configId, DBConfigService::APPLICABLE_TYPE_USER, $user);
+ }
+ foreach ($newStorage->getApplicableGroups() as $group) {
+ $this->dbConfig->addApplicable($configId, DBConfigService::APPLICABLE_TYPE_GROUP, $group);
+ }
+ foreach ($newStorage->getBackendOptions() as $key => $value) {
+ $this->dbConfig->setConfig($configId, $key, $value);
+ }
+ foreach ($newStorage->getMountOptions() as $key => $value) {
+ $this->dbConfig->setOption($configId, $key, $value);
+ }
+
+ if (count($newStorage->getApplicableUsers()) === 0 && count($newStorage->getApplicableGroups()) === 0) {
+ $this->dbConfig->addApplicable($configId, DBConfigService::APPLICABLE_TYPE_GLOBAL, null);
+ }
+
// add new storage
$allStorages[$configId] = $newStorage;
- $this->writeConfig($allStorages);
-
$this->triggerHooks($newStorage, Filesystem::signal_create_mount);
$newStorage->setStatus(StorageNotAvailableException::STATUS_SUCCESS);
) {
$backend = $this->backendService->getBackend($backendIdentifier);
if (!$backend) {
- throw new \InvalidArgumentException('Unable to get backend for '.$backendIdentifier);
+ throw new \InvalidArgumentException('Unable to get backend for ' . $backendIdentifier);
}
$authMechanism = $this->backendService->getAuthMechanism($authMechanismIdentifier);
if (!$authMechanism) {
- throw new \InvalidArgumentException('Unable to get authentication mechanism for '.$authMechanismIdentifier);
+ throw new \InvalidArgumentException('Unable to get authentication mechanism for ' . $authMechanismIdentifier);
}
$newStorage = new StorageConfig();
$newStorage->setMountPoint($mountPoint);
* @throws NotFoundException if the given storage does not exist in the config
*/
public function updateStorage(StorageConfig $updatedStorage) {
- $allStorages = $this->readConfig();
-
$id = $updatedStorage->getId();
- if (!isset($allStorages[$id])) {
- throw new NotFoundException('Storage with id "' . $id . '" not found');
+
+ $existingMount = $this->dbConfig->getMountById($id);
+
+ if (!is_array($existingMount)) {
+ throw new NotFoundException('Storage with id "' . $id . '" not found while updating storage');
+ }
+
+ $oldStorage = $this->getStorageConfigFromDBMount($existingMount);
+
+ $removedUsers = array_diff($oldStorage->getApplicableUsers(), $updatedStorage->getApplicableUsers());
+ $removedGroups = array_diff($oldStorage->getApplicableGroups(), $updatedStorage->getApplicableGroups());
+ $addedUsers = array_diff($updatedStorage->getApplicableUsers(), $oldStorage->getApplicableUsers());
+ $addedGroups = array_diff($updatedStorage->getApplicableGroups(), $oldStorage->getApplicableGroups());
+
+ $oldUserCount = count($oldStorage->getApplicableUsers());
+ $oldGroupCount = count($oldStorage->getApplicableGroups());
+ $newUserCount = count($oldStorage->getApplicableUsers());
+ $newGroupCount = count($oldStorage->getApplicableGroups());
+ $wasGlobal = ($oldUserCount + $oldGroupCount) === 0;
+ $isGlobal = ($newUserCount + $newGroupCount) === 0;
+
+ foreach ($removedUsers as $user) {
+ $this->dbConfig->removeApplicable($id, DBConfigService::APPLICABLE_TYPE_USER, $user);
+ }
+ foreach ($removedGroups as $group) {
+ $this->dbConfig->removeApplicable($id, DBConfigService::APPLICABLE_TYPE_GROUP, $group);
+ }
+ foreach ($addedUsers as $user) {
+ $this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_USER, $user);
+ }
+ foreach ($addedGroups as $group) {
+ $this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_GROUP, $group);
}
- $oldStorage = $allStorages[$id];
- // ensure objectstore is persistent
- if ($objectstore = $oldStorage->getBackendOption('objectstore')) {
- $updatedStorage->setBackendOption('objectstore', $objectstore);
+ if ($wasGlobal && !$isGlobal) {
+ $this->dbConfig->removeApplicable($id, DBConfigService::APPLICABLE_TYPE_GLOBAL, null);
+ } else if (!$wasGlobal && $isGlobal) {
+ $this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_GLOBAL, null);
}
- $allStorages[$id] = $updatedStorage;
- $this->writeConfig($allStorages);
+ $changedConfig = array_diff_assoc($updatedStorage->getBackendOptions(), $oldStorage->getBackendOptions());
+ $changedOptions = array_diff_assoc($updatedStorage->getMountOptions(), $oldStorage->getMountOptions());
+
+ foreach ($changedConfig as $key => $value) {
+ $this->dbConfig->setConfig($id, $key, $value);
+ }
+ foreach ($changedOptions as $key => $value) {
+ $this->dbConfig->setOption($id, $key, $value);
+ }
$this->triggerChangeHooks($oldStorage, $updatedStorage);
* @throws NotFoundException if no storage was found with the given id
*/
public function removeStorage($id) {
- $allStorages = $this->readConfig();
+ $existingMount = $this->dbConfig->getMountById($id);
- if (!isset($allStorages[$id])) {
+ if (!is_array($existingMount)) {
throw new NotFoundException('Storage with id "' . $id . '" not found');
}
- $deletedStorage = $allStorages[$id];
- unset($allStorages[$id]);
-
- $this->writeConfig($allStorages);
+ $this->dbConfig->removeMount($id);
+ $deletedStorage = $this->getStorageConfigFromDBMount($existingMount);
$this->triggerHooks($deletedStorage, Filesystem::signal_delete_mount);
// delete oc_storages entries and oc_filecache
}
}
- /**
- * Generates a configuration id to use for a new configuration entry.
- *
- * @param array $allStorages array of all storage configs
- *
- * @return int id
- */
- protected function generateNextId($allStorages) {
- if (empty($allStorages)) {
- return 1;
- }
- // note: this will mess up with with concurrency,
- // but so did the mount.json. This horribly hack
- // will disappear once we move to DB tables to
- // store the config
- return (max(array_keys($allStorages)) + 1);
- }
-
/**
* Returns the rusty storage id from oc_storages from the given storage config.
*
/**
* @param BackendService $backendService
+ * @param DBConfigService $dbConfig
* @param IUserSession $userSession
* @param IGroupManager $groupManager
*/
public function __construct(
BackendService $backendService,
+ DBConfigService $dbConfig,
IUserSession $userSession,
IGroupManager $groupManager
) {
- parent::__construct($backendService);
+ parent::__construct($backendService, $dbConfig);
$this->userSession = $userSession;
$this->groupManager = $groupManager;
}
}
}
- /**
- * Read legacy config data
- *
- * @return array list of mount configs
- */
- protected function readLegacyConfig() {
- // read global config
- $data = parent::readLegacyConfig();
- $userId = $this->getUser()->getUID();
-
- // don't use array_filter() with ARRAY_FILTER_USE_KEY, it's PHP 5.6+
- if (isset($data[\OC_Mount_Config::MOUNT_TYPE_USER])) {
- $newData = [];
- foreach ($data[\OC_Mount_Config::MOUNT_TYPE_USER] as $key => $value) {
- if (strtolower($key) === strtolower($userId) || $key === 'all') {
- $newData[$key] = $value;
- }
- }
- $data[\OC_Mount_Config::MOUNT_TYPE_USER] = $newData;
+ protected function readDBConfig() {
+ $userMounts = $this->dbConfig->getAdminMountsFor(DBConfigService::APPLICABLE_TYPE_USER, $this->getUser()->getUID());
+ $globalMounts = $this->dbConfig->getAdminMountsFor(DBConfigService::APPLICABLE_TYPE_GLOBAL, null);
+ $groups = $this->groupManager->getUserGroupIds($this->getUser());
+ if (is_array($groups) && count($groups) !== 0) {
+ $groupMounts = $this->dbConfig->getAdminMountsForMultiple(DBConfigService::APPLICABLE_TYPE_GROUP, $groups);
+ } else {
+ $groupMounts = [];
}
+ return array_merge($userMounts, $groupMounts, $globalMounts);
+ }
- if (isset($data[\OC_Mount_Config::MOUNT_TYPE_GROUP])) {
- $newData = [];
- foreach ($data[\OC_Mount_Config::MOUNT_TYPE_GROUP] as $key => $value) {
- if ($this->groupManager->isInGroup($userId, $key)) {
- $newData[$key] = $value;
- }
- }
- $data[\OC_Mount_Config::MOUNT_TYPE_GROUP] = $newData;
- }
+ public function addStorage(StorageConfig $newStorage) {
+ throw new \DomainException('UserGlobalStoragesService writing disallowed');
+ }
- return $data;
+ public function updateStorage(StorageConfig $updatedStorage) {
+ throw new \DomainException('UserGlobalStoragesService writing disallowed');
}
- /**
- * Write legacy config data
- *
- * @param array $mountPoints
- */
- protected function writeLegacyConfig(array $mountPoints) {
+ public function removeStorage($id) {
throw new \DomainException('UserGlobalStoragesService writing disallowed');
}
$result = [];
foreach ($storagesByMountpoint as $storageList) {
- $storage = array_reduce($storageList, function($carry, $item) {
+ $storage = array_reduce($storageList, function ($carry, $item) {
if (isset($carry)) {
$carryPriorityType = $this->getPriorityType($carry);
$itemPriorityType = $this->getPriorityType($item);
--- /dev/null
+<?php
+/**
+ * @author Robin Appelman <icewind@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;
+
+/**
+ * Read user defined mounts from the legacy mount.json
+ */
+class UserLegacyStoragesService extends LegacyStoragesService {
+ /**
+ * @var IUserSession
+ */
+ private $userSession;
+
+ /**
+ * @param BackendService $backendService
+ * @param IUserSession $userSession
+ */
+ public function __construct(BackendService $backendService, IUserSession $userSession) {
+ $this->backendService = $backendService;
+ $this->userSession = $userSession;
+ }
+
+ /**
+ * Read legacy config data
+ *
+ * @return array list of storage configs
+ */
+ protected function readLegacyConfig() {
+ // read user config
+ $user = $this->userSession->getUser()->getUID();
+ return \OC_Mount_Config::readData($user);
+ }
+}
* (aka personal storages)
*/
class UserStoragesService extends StoragesService {
-
use UserTrait;
/**
* Create a user storages service
*
* @param BackendService $backendService
+ * @param DBConfigService $dbConfig
* @param IUserSession $userSession user session
*/
public function __construct(
BackendService $backendService,
+ DBConfigService $dbConfig,
IUserSession $userSession
) {
$this->userSession = $userSession;
- parent::__construct($backendService);
- }
-
- /**
- * Read legacy config data
- *
- * @return array list of storage configs
- */
- protected function readLegacyConfig() {
- // read user config
- $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->getUser()->getUID();
- // TODO: in the future don't rely on the global config reading code
- $storages = parent::readConfig();
-
- $filteredStorages = [];
- foreach ($storages as $configId => $storage) {
- // filter out all bogus storages that aren't for the current user
- if (!in_array($user, $storage->getApplicableUsers())) {
- continue;
- }
-
- // clear applicable users, should not be used
- $storage->setApplicableUsers([]);
-
- // strip out unneeded applicableUser fields
- $filteredStorages[$configId] = $storage;
- }
-
- return $filteredStorages;
+ parent::__construct($backendService, $dbConfig);
}
- /**
- * Write the storages to the user's configuration.
- *
- * @param array $storages map of storage id to storage config
- */
- public function writeConfig($storages) {
- $user = $this->getUser()->getUID();
-
- // let the horror begin
- $mountPoints = [];
- foreach ($storages as $storageConfig) {
- $mountPoint = $storageConfig->getMountPoint();
- $oldBackendOptions = $storageConfig->getBackendOptions();
- $storageConfig->setBackendOptions(
- \OC_Mount_Config::encryptPasswords(
- $oldBackendOptions
- )
- );
-
- $rootMountPoint = '/' . $user . '/files/' . ltrim($mountPoint, '/');
-
- $this->addMountPoint(
- $mountPoints,
- \OC_Mount_Config::MOUNT_TYPE_USER,
- $user,
- $rootMountPoint,
- $storageConfig
- );
-
- // restore old backend options where the password was not encrypted,
- // because we don't want to change the state of the original object
- $storageConfig->setBackendOptions($oldBackendOptions);
- }
-
- $this->writeLegacyConfig($mountPoints);
+ protected function readDBConfig() {
+ return $this->dbConfig->getUserMountsFor(DBConfigService::APPLICABLE_TYPE_USER, $this->getUser()->getUID());
}
/**
}
}
+ protected function getType() {
+ return DBConfigService::MOUNT_TYPE_PERSONAl;
+ }
+
+ /**
+ * Add new storage to the configuration
+ *
+ * @param StorageConfig $newStorage storage attributes
+ *
+ * @return StorageConfig storage config, with added id
+ */
+ public function addStorage(StorageConfig $newStorage) {
+ $config = parent::addStorage($newStorage);
+ $this->dbConfig->addApplicable($config->getId(), DBConfigService::APPLICABLE_TYPE_USER, $this->getUser()->getUID());
+ return $config;
+ }
+
/**
* Get the visibility type for this controller, used in validation
*
--- /dev/null
+<?php
+/**
+ * @author Robin Appelman <icewind@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\Tests\Service;
+
+
+use OCA\Files_External\Service\DBConfigService;
+use OCP\IDBConnection;
+use Test\TestCase;
+
+/**
+ * @group DB
+ */
+class DBConfigServiceTest extends TestCase {
+ /**
+ * @var DBConfigService
+ */
+ private $dbConfig;
+
+ /**
+ * @var IDBConnection
+ */
+ private $connection;
+
+ private $mounts = [];
+
+ public function setUp() {
+ parent::setUp();
+ $this->connection = \OC::$server->getDatabaseConnection();
+ $this->dbConfig = new DBConfigService($this->connection);
+ }
+
+ public function tearDown() {
+ foreach ($this->mounts as $mount) {
+ $this->dbConfig->removeMount($mount);
+ }
+ $this->mounts = [];
+ }
+
+ private function addMount($mountPoint, $storageBackend, $authBackend, $priority, $type) {
+ $id = $this->dbConfig->addMount($mountPoint, $storageBackend, $authBackend, $priority, $type);
+ $this->mounts[] = $id;
+ return $id;
+ }
+
+ public function testAddSimpleMount() {
+ $id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+
+ $mount = $this->dbConfig->getMountById($id);
+ $this->assertEquals('/test', $mount['mount_point']);
+ $this->assertEquals('foo', $mount['storage_backend']);
+ $this->assertEquals('bar', $mount['auth_backend']);
+ $this->assertEquals(100, $mount['priority']);
+ $this->assertEquals(DBConfigService::MOUNT_TYPE_ADMIN, $mount['type']);
+ $this->assertEquals([], $mount['applicable']);
+ $this->assertEquals([], $mount['config']);
+ $this->assertEquals([], $mount['options']);
+ }
+
+ public function testAddApplicable() {
+ $id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+ $this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+
+ $mount = $this->dbConfig->getMountById($id);
+ $this->assertEquals([
+ ['type' => DBConfigService::APPLICABLE_TYPE_USER, 'value' => 'test', 'mount_id' => $id]
+ ], $mount['applicable']);
+
+ $this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_GROUP, 'bar');
+ $this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_GLOBAL, null);
+
+ $mount = $this->dbConfig->getMountById($id);
+ $this->assertEquals([
+ ['type' => DBConfigService::APPLICABLE_TYPE_USER, 'value' => 'test', 'mount_id' => $id],
+ ['type' => DBConfigService::APPLICABLE_TYPE_GROUP, 'value' => 'bar', 'mount_id' => $id],
+ ['type' => DBConfigService::APPLICABLE_TYPE_GLOBAL, 'value' => null, 'mount_id' => $id]
+ ], $mount['applicable']);
+ }
+
+ public function testAddApplicableDouble() {
+ $id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+ $this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+ $this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+
+ $mount = $this->dbConfig->getMountById($id);
+ $this->assertEquals([
+ ['type' => DBConfigService::APPLICABLE_TYPE_USER, 'value' => 'test', 'mount_id' => $id]
+ ], $mount['applicable']);
+ }
+
+ public function testDeleteMount() {
+ $id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+
+ $this->dbConfig->removeMount($id);
+
+ $mount = $this->dbConfig->getMountById($id);
+ $this->assertEquals(null, $mount);
+ }
+
+ public function testRemoveApplicable() {
+ $id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+ $this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+ $this->dbConfig->removeApplicable($id, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+
+ $mount = $this->dbConfig->getMountById($id);
+ $this->assertEquals([], $mount['applicable']);
+ }
+
+ public function testSetConfig() {
+ $id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+ $this->dbConfig->setConfig($id, 'foo', 'bar');
+
+ $mount = $this->dbConfig->getMountById($id);
+ $this->assertEquals(['foo' => 'bar'], $mount['config']);
+
+ $this->dbConfig->setConfig($id, 'foo2', 'bar2');
+
+ $mount = $this->dbConfig->getMountById($id);
+ $this->assertEquals(['foo' => 'bar', 'foo2' => 'bar2'], $mount['config']);
+ }
+
+ public function testSetConfigOverwrite() {
+ $id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+ $this->dbConfig->setConfig($id, 'foo', 'bar');
+ $this->dbConfig->setConfig($id, 'asd', '1');
+ $this->dbConfig->setConfig($id, 'foo', 'qwerty');
+
+ $mount = $this->dbConfig->getMountById($id);
+ $this->assertEquals(['foo' => 'qwerty', 'asd' => '1'], $mount['config']);
+ }
+
+ public function testSetOption() {
+ $id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+ $this->dbConfig->setOption($id, 'foo', 'bar');
+
+ $mount = $this->dbConfig->getMountById($id);
+ $this->assertEquals(['foo' => 'bar'], $mount['options']);
+
+ $this->dbConfig->setOption($id, 'foo2', 'bar2');
+
+ $mount = $this->dbConfig->getMountById($id);
+ $this->assertEquals(['foo' => 'bar', 'foo2' => 'bar2'], $mount['options']);
+ }
+
+ public function testSetOptionOverwrite() {
+ $id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+ $this->dbConfig->setOption($id, 'foo', 'bar');
+ $this->dbConfig->setOption($id, 'asd', '1');
+ $this->dbConfig->setOption($id, 'foo', 'qwerty');
+
+ $mount = $this->dbConfig->getMountById($id);
+ $this->assertEquals(['foo' => 'qwerty', 'asd' => '1'], $mount['options']);
+ }
+
+ public function testGetMountsFor() {
+ $mounts = $this->dbConfig->getMountsFor(DBConfigService::APPLICABLE_TYPE_USER, 'test');
+ $this->assertEquals([], $mounts);
+
+ $id = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+ $this->dbConfig->addApplicable($id, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+
+ $mounts = $this->dbConfig->getMountsFor(DBConfigService::APPLICABLE_TYPE_USER, 'test');
+ $this->assertCount(1, $mounts);
+ $this->assertEquals($id, $mounts[0]['mount_id']);
+ $this->assertEquals([['type' => DBConfigService::APPLICABLE_TYPE_USER, 'value' => 'test', 'mount_id' => $id]], $mounts[0]['applicable']);
+ }
+
+ public function testGetAdminMounts() {
+ $id1 = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+ $this->addMount('/test2', 'foo2', 'bar2', 100, DBConfigService::MOUNT_TYPE_PERSONAl);
+
+ $mounts = $this->dbConfig->getAdminMounts();
+ $this->assertCount(1, $mounts);
+ $this->assertEquals($id1, $mounts[0]['mount_id']);
+ }
+
+ public function testGetAdminMountsFor() {
+ $id1 = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+ $this->addMount('/test2', 'foo2', 'bar2', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+ $id3 = $this->addMount('/test3', 'foo3', 'bar3', 100, DBConfigService::MOUNT_TYPE_PERSONAl);
+
+ $this->dbConfig->addApplicable($id1, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+ $this->dbConfig->addApplicable($id3, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+
+ $mounts = $this->dbConfig->getAdminMountsFor(DBConfigService::APPLICABLE_TYPE_USER, 'test');
+ $this->assertCount(1, $mounts);
+ $this->assertEquals($id1, $mounts[0]['mount_id']);
+ $this->assertEquals([['type' => DBConfigService::APPLICABLE_TYPE_USER, 'value' => 'test', 'mount_id' => $id1]], $mounts[0]['applicable']);
+ }
+
+ public function testGetUserMountsFor() {
+ $id1 = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+ $this->addMount('/test2', 'foo2', 'bar2', 100, DBConfigService::MOUNT_TYPE_PERSONAl);
+ $id3 = $this->addMount('/test3', 'foo3', 'bar3', 100, DBConfigService::MOUNT_TYPE_PERSONAl);
+
+ $this->dbConfig->addApplicable($id1, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+ $this->dbConfig->addApplicable($id3, DBConfigService::APPLICABLE_TYPE_USER, 'test');
+
+ $mounts = $this->dbConfig->getUserMountsFor(DBConfigService::APPLICABLE_TYPE_USER, 'test');
+ $this->assertCount(1, $mounts);
+ $this->assertEquals($id3, $mounts[0]['mount_id']);
+ $this->assertEquals([['type' => DBConfigService::APPLICABLE_TYPE_USER, 'value' => 'test', 'mount_id' => $id3]], $mounts[0]['applicable']);
+ }
+
+ public function testGetAdminMountsForGlobal() {
+ $id1 = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN);
+
+ $this->dbConfig->addApplicable($id1, DBConfigService::APPLICABLE_TYPE_GLOBAL, null);
+
+ $mounts = $this->dbConfig->getAdminMountsFor(DBConfigService::APPLICABLE_TYPE_GLOBAL, null);
+ $this->assertCount(1, $mounts);
+ $this->assertEquals($id1, $mounts[0]['mount_id']);
+ $this->assertEquals([['type' => DBConfigService::APPLICABLE_TYPE_GLOBAL, 'value' => null, 'mount_id' => $id1]], $mounts[0]['applicable']);
+ }
+}
use \OC\Files\Filesystem;
+use OCA\Files_External\Service\DBConfigService;
use \OCA\Files_external\Service\GlobalStoragesService;
use \OCA\Files_external\NotFoundException;
use \OCA\Files_external\Lib\StorageConfig;
+/**
+ * @group DB
+ */
class GlobalStoragesServiceTest extends StoragesServiceTest {
public function setUp() {
parent::setUp();
- $this->service = new GlobalStoragesService($this->backendService);
+ $this->service = new GlobalStoragesService($this->backendService, $this->dbConfig);
}
public function tearDown() {
}
protected function makeTestStorageData() {
- return $this->makeStorageConfig([
+ return $this->makeStorageConfig([
'mountPoint' => 'mountpoint',
'backendIdentifier' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
'authMechanismIdentifier' => 'identifier:\Auth\Mechanism',
$storage = $this->makeStorageConfig($storageParams);
$newStorage = $this->service->addStorage($storage);
- $this->assertEquals(1, $newStorage->getId());
-
+ $baseId = $newStorage->getId();
- $newStorage = $this->service->getStorage(1);
+ $newStorage = $this->service->getStorage($baseId);
$this->assertEquals($storage->getMountPoint(), $newStorage->getMountPoint());
$this->assertEquals($storage->getBackend(), $newStorage->getBackend());
$this->assertEquals($storage->getApplicableUsers(), $newStorage->getApplicableUsers());
$this->assertEquals($storage->getApplicableGroups(), $newStorage->getApplicableGroups());
$this->assertEquals($storage->getPriority(), $newStorage->getPriority());
- $this->assertEquals(1, $newStorage->getId());
$this->assertEquals(0, $newStorage->getStatus());
- // next one gets id 2
$nextStorage = $this->service->addStorage($storage);
- $this->assertEquals(2, $nextStorage->getId());
+ $this->assertEquals($baseId + 1, $nextStorage->getId());
}
/**
]);
$newStorage = $this->service->addStorage($storage);
- $this->assertEquals(1, $newStorage->getId());
+ $id = $newStorage->getId();
- $updatedStorage->setId(1);
+ $updatedStorage->setId($id);
$this->service->updateStorage($updatedStorage);
- $newStorage = $this->service->getStorage(1);
+ $newStorage = $this->service->getStorage($id);
$this->assertEquals($updatedStorage->getMountPoint(), $newStorage->getMountPoint());
$this->assertEquals($updatedStorage->getBackendOptions()['password'], $newStorage->getBackendOptions()['password']);
$this->assertEquals($updatedStorage->getApplicableUsers(), $newStorage->getApplicableUsers());
$this->assertEquals($updatedStorage->getApplicableGroups(), $newStorage->getApplicableGroups());
$this->assertEquals($updatedStorage->getPriority(), $newStorage->getPriority());
- $this->assertEquals(1, $newStorage->getId());
$this->assertEquals(0, $newStorage->getStatus());
}
$sourceApplicableGroups,
$updatedApplicableUsers,
$updatedApplicableGroups,
- $expectedCalls) {
+ $expectedCalls) {
$storage = $this->makeTestStorageData();
$storage->setApplicableUsers($sourceApplicableUsers);
public function testHooksDeleteStorage(
$sourceApplicableUsers,
$sourceApplicableGroups,
- $expectedCalls) {
+ $expectedCalls) {
$storage = $this->makeTestStorageData();
$storage->setApplicableUsers($sourceApplicableUsers);
}
}
- /**
- * Make sure it uses the correct format when reading/writing
- * the legacy config
- */
- public function testLegacyConfigConversionApplicableAll() {
- $configFile = $this->dataDir . '/mount.json';
-
- $storage = $this->makeTestStorageData();
- $storage = $this->service->addStorage($storage);
-
- $json = json_decode(file_get_contents($configFile), true);
-
- $this->assertCount(1, $json);
-
- $this->assertEquals([\OC_Mount_Config::MOUNT_TYPE_USER], array_keys($json));
- $this->assertEquals(['all'], array_keys($json[\OC_Mount_config::MOUNT_TYPE_USER]));
-
- $mountPointData = $json[\OC_Mount_config::MOUNT_TYPE_USER]['all'];
- $this->assertEquals(['/$user/files/mountpoint'], array_keys($mountPointData));
-
- $mountPointOptions = current($mountPointData);
- $this->assertEquals(1, $mountPointOptions['id']);
- $this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SMB', $mountPointOptions['backend']);
- $this->assertEquals('identifier:\Auth\Mechanism', $mountPointOptions['authMechanism']);
- $this->assertEquals(15, $mountPointOptions['priority']);
- $this->assertEquals(false, $mountPointOptions['mountOptions']['preview']);
-
- $backendOptions = $mountPointOptions['options'];
- $this->assertEquals('value1', $backendOptions['option1']);
- $this->assertEquals('value2', $backendOptions['option2']);
- $this->assertEquals('', $backendOptions['password']);
- $this->assertNotEmpty($backendOptions['password_encrypted']);
- }
-
- /**
- * Make sure it uses the correct format when reading/writing
- * the legacy config
- */
- public function testLegacyConfigConversionApplicableUserAndGroup() {
- $configFile = $this->dataDir . '/mount.json';
-
- $storage = $this->makeTestStorageData();
- $storage->setApplicableUsers(['user1', 'user2']);
- $storage->setApplicableGroups(['group1', 'group2']);
-
- $storage = $this->service->addStorage($storage);
-
- $json = json_decode(file_get_contents($configFile), true);
-
- $this->assertCount(2, $json);
-
- $this->assertTrue(isset($json[\OC_Mount_Config::MOUNT_TYPE_USER]));
- $this->assertTrue(isset($json[\OC_Mount_Config::MOUNT_TYPE_GROUP]));
- $this->assertEquals(['user1', 'user2'], array_keys($json[\OC_Mount_config::MOUNT_TYPE_USER]));
- $this->assertEquals(['group1', 'group2'], array_keys($json[\OC_Mount_config::MOUNT_TYPE_GROUP]));
-
- // check that all options are the same for both users and both groups
- foreach ($json[\OC_Mount_Config::MOUNT_TYPE_USER] as $mountPointData) {
- $this->assertEquals(['/$user/files/mountpoint'], array_keys($mountPointData));
-
- $mountPointOptions = current($mountPointData);
-
- $this->assertEquals(1, $mountPointOptions['id']);
- $this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SMB', $mountPointOptions['backend']);
- $this->assertEquals('identifier:\Auth\Mechanism', $mountPointOptions['authMechanism']);
- $this->assertEquals(15, $mountPointOptions['priority']);
- $this->assertEquals(false, $mountPointOptions['mountOptions']['preview']);
-
- $backendOptions = $mountPointOptions['options'];
- $this->assertEquals('value1', $backendOptions['option1']);
- $this->assertEquals('value2', $backendOptions['option2']);
- $this->assertEquals('', $backendOptions['password']);
- $this->assertNotEmpty($backendOptions['password_encrypted']);
- }
-
- foreach ($json[\OC_Mount_Config::MOUNT_TYPE_GROUP] as $mountPointData) {
- $this->assertEquals(['/$user/files/mountpoint'], array_keys($mountPointData));
-
- $mountPointOptions = current($mountPointData);
-
- $this->assertEquals(1, $mountPointOptions['id']);
- $this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SMB', $mountPointOptions['backend']);
- $this->assertEquals('identifier:\Auth\Mechanism', $mountPointOptions['authMechanism']);
- $this->assertEquals(15, $mountPointOptions['priority']);
- $this->assertEquals(false, $mountPointOptions['mountOptions']['preview']);
-
- $backendOptions = $mountPointOptions['options'];
- $this->assertEquals('value1', $backendOptions['option1']);
- $this->assertEquals('value2', $backendOptions['option2']);
- $this->assertEquals('', $backendOptions['password']);
- $this->assertNotEmpty($backendOptions['password_encrypted']);
- }
- }
-
- /**
- * Test reading in a legacy config and generating config ids.
- */
- public function testReadLegacyConfigAndGenerateConfigId() {
- $configFile = $this->dataDir . '/mount.json';
-
- $legacyBackendOptions = [
- 'user' => 'someuser',
- 'password' => 'somepassword',
- ];
- $legacyBackendOptions = \OC_Mount_Config::encryptPasswords($legacyBackendOptions);
-
- $legacyConfig = [
- 'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
- 'authMechanism' => 'identifier:\Auth\Mechanism',
- 'options' => $legacyBackendOptions,
- 'mountOptions' => ['preview' => false],
- ];
- // different mount options
- $legacyConfig2 = [
- 'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
- 'authMechanism' => 'identifier:\Auth\Mechanism',
- 'options' => $legacyBackendOptions,
- 'mountOptions' => ['preview' => true],
- ];
-
- $legacyBackendOptions2 = $legacyBackendOptions;
- $legacyBackendOptions2 = ['user' => 'someuser2', 'password' => 'somepassword2'];
- $legacyBackendOptions2 = \OC_Mount_Config::encryptPasswords($legacyBackendOptions2);
-
- // different config
- $legacyConfig3 = [
- 'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
- 'authMechanism' => 'identifier:\Auth\Mechanism',
- 'options' => $legacyBackendOptions2,
- 'mountOptions' => ['preview' => true],
- ];
-
- $json = [
- 'user' => [
- 'user1' => [
- '/$user/files/somemount' => $legacyConfig,
- ],
- // same config
- 'user2' => [
- '/$user/files/somemount' => $legacyConfig,
- ],
- // different mountOptions
- 'user3' => [
- '/$user/files/somemount' => $legacyConfig2,
- ],
- // different mount point
- 'user4' => [
- '/$user/files/anothermount' => $legacyConfig,
- ],
- // different storage config
- 'user5' => [
- '/$user/files/somemount' => $legacyConfig3,
- ],
- ],
- 'group' => [
- 'group1' => [
- // will get grouped with user configs
- '/$user/files/somemount' => $legacyConfig,
- ],
- ],
- ];
-
- file_put_contents($configFile, json_encode($json));
-
- $this->backendService->getBackend('identifier:\OCA\Files_External\Lib\Backend\SMB')
- ->expects($this->exactly(4))
- ->method('validateStorageDefinition');
- $this->backendService->getAuthMechanism('identifier:\Auth\Mechanism')
- ->expects($this->exactly(4))
- ->method('validateStorageDefinition');
-
- $allStorages = $this->service->getAllStorages();
-
- $this->assertCount(4, $allStorages);
-
- $storage1 = $allStorages[1];
- $storage2 = $allStorages[2];
- $storage3 = $allStorages[3];
- $storage4 = $allStorages[4];
-
- $this->assertEquals('/somemount', $storage1->getMountPoint());
- $this->assertEquals('someuser', $storage1->getBackendOptions()['user']);
- $this->assertEquals('somepassword', $storage1->getBackendOptions()['password']);
- $this->assertEquals(['user1', 'user2'], $storage1->getApplicableUsers());
- $this->assertEquals(['group1'], $storage1->getApplicableGroups());
- $this->assertEquals(['preview' => false], $storage1->getMountOptions());
-
- $this->assertEquals('/somemount', $storage2->getMountPoint());
- $this->assertEquals('someuser', $storage2->getBackendOptions()['user']);
- $this->assertEquals('somepassword', $storage2->getBackendOptions()['password']);
- $this->assertEquals(['user3'], $storage2->getApplicableUsers());
- $this->assertEquals([], $storage2->getApplicableGroups());
- $this->assertEquals(['preview' => true], $storage2->getMountOptions());
-
- $this->assertEquals('/anothermount', $storage3->getMountPoint());
- $this->assertEquals('someuser', $storage3->getBackendOptions()['user']);
- $this->assertEquals('somepassword', $storage3->getBackendOptions()['password']);
- $this->assertEquals(['user4'], $storage3->getApplicableUsers());
- $this->assertEquals([], $storage3->getApplicableGroups());
- $this->assertEquals(['preview' => false], $storage3->getMountOptions());
-
- $this->assertEquals('/somemount', $storage4->getMountPoint());
- $this->assertEquals('someuser2', $storage4->getBackendOptions()['user']);
- $this->assertEquals('somepassword2', $storage4->getBackendOptions()['password']);
- $this->assertEquals(['user5'], $storage4->getApplicableUsers());
- $this->assertEquals([], $storage4->getApplicableGroups());
- $this->assertEquals(['preview' => true], $storage4->getMountOptions());
- }
-
- public function testReadLegacyConfigNoAuthMechanism() {
- $configFile = $this->dataDir . '/mount.json';
-
- $json = [
- 'user' => [
- 'user1' => [
- '/$user/files/somemount' => [
- 'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SFTP',
- 'authMechanism' => 'identifier:\Auth\Mechanism',
- 'options' => [],
- 'mountOptions' => [],
- ],
- '/$user/files/othermount' => [
- 'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SFTP',
- // no authMechanism
- 'options' => [],
- 'mountOptions' => [],
- ],
- ]
- ]
- ];
-
- file_put_contents($configFile, json_encode($json));
-
- $allStorages = $this->service->getAllStorages();
-
- $this->assertCount(2, $allStorages);
-
- $storage1 = $allStorages[1];
- $storage2 = $allStorages[2];
-
- $this->assertEquals('/somemount', $storage1->getMountPoint());
- $this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SFTP', $storage1->getBackend()->getIdentifier());
- $this->assertEquals('identifier:\Auth\Mechanism', $storage1->getAuthMechanism()->getIdentifier());
-
- $this->assertEquals('/othermount', $storage2->getMountPoint());
- $this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SFTP', $storage2->getBackend()->getIdentifier());
- $this->assertEquals('identifier:\Other\Auth\Mechanism', $storage2->getAuthMechanism()->getIdentifier());
- }
-
- public function testReadLegacyConfigClass() {
- $configFile = $this->dataDir . '/mount.json';
-
- $json = [
- 'user' => [
- 'user1' => [
- '/$user/files/somemount' => [
- 'class' => 'identifier:\OCA\Files_External\Lib\Backend\SFTP',
- 'authMechanism' => 'identifier:\Auth\Mechanism',
- 'options' => [],
- 'mountOptions' => [],
- ],
- '/$user/files/othermount' => [
- 'class' => 'identifier:sftp_alias',
- 'authMechanism' => 'identifier:\Auth\Mechanism',
- 'options' => [],
- 'mountOptions' => [],
- ],
- ]
- ]
- ];
-
- file_put_contents($configFile, json_encode($json));
-
- $allStorages = $this->service->getAllStorages();
-
- $this->assertCount(2, $allStorages);
-
- $storage1 = $allStorages[1];
- $storage2 = $allStorages[2];
-
- $this->assertEquals('/somemount', $storage1->getMountPoint());
- $this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SFTP', $storage1->getBackend()->getIdentifier());
- $this->assertEquals('identifier:\Auth\Mechanism', $storage1->getAuthMechanism()->getIdentifier());
-
- $this->assertEquals('/othermount', $storage2->getMountPoint());
- $this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SFTP', $storage2->getBackend()->getIdentifier());
- $this->assertEquals('identifier:\Auth\Mechanism', $storage2->getAuthMechanism()->getIdentifier());
- }
-
- public function testReadEmptyMountPoint() {
- $configFile = $this->dataDir . '/mount.json';
-
- $json = [
- 'user' => [
- 'user1' => [
- '/$user/files/' => [
- 'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SFTP',
- 'authMechanism' => 'identifier:\Auth\Mechanism',
- 'options' => [],
- 'mountOptions' => [],
- ],
- ]
- ]
- ];
-
- file_put_contents($configFile, json_encode($json));
-
- $allStorages = $this->service->getAllStorages();
-
- $this->assertCount(1, $allStorages);
-
- $storage1 = $allStorages[1];
-
- $this->assertEquals('/', $storage1->getMountPoint());
- }
-
-
}
use \OCA\Files_external\NotFoundException;
use \OCA\Files_external\Lib\StorageConfig;
-use \OCA\Files_External\Lib\BackendService;
+use OCA\Files_External\Service\BackendService;
+use OCA\Files_External\Service\DBConfigService;
+use OCA\Files_external\Service\StoragesService;
+class CleaningDBConfig extends DBConfigService {
+ private $mountIds = [];
+
+ public function addMount($mountPoint, $storageBackend, $authBackend, $priority, $type) {
+ $id = parent::addMount($mountPoint, $storageBackend, $authBackend, $priority, $type); // TODO: Change the autogenerated stub
+ $this->mountIds[] = $id;
+ return $id;
+ }
+
+ public function clean() {
+ foreach ($this->mountIds as $id) {
+ $this->removeMount($id);
+ }
+ }
+}
+
+/**
+ * @group DB
+ */
abstract class StoragesServiceTest extends \Test\TestCase {
/**
*/
protected $dataDir;
+ /** @var CleaningDBConfig */
+ protected $dbConfig;
+
/**
* Hook calls
*
protected static $hookCalls;
public function setUp() {
+ parent::setUp();
+ $this->dbConfig = new CleaningDBConfig(\OC::$server->getDatabaseConnection());
self::$hookCalls = array();
$config = \OC::$server->getConfig();
$this->dataDir = $config->getSystemValue(
// prepare BackendService mock
$this->backendService =
$this->getMockBuilder('\OCA\Files_External\Service\BackendService')
- ->disableOriginalConstructor()
- ->getMock();
+ ->disableOriginalConstructor()
+ ->getMock();
$authMechanisms = [
'identifier:\Auth\Mechanism' => $this->getAuthMechMock('null', '\Auth\Mechanism'),
'identifier:\OCA\Files_External\Lib\Auth\NullMechanism' => $this->getAuthMechMock(),
];
$this->backendService->method('getAuthMechanism')
- ->will($this->returnCallback(function($class) use ($authMechanisms) {
+ ->will($this->returnCallback(function ($class) use ($authMechanisms) {
if (isset($authMechanisms[$class])) {
return $authMechanisms[$class];
}
return null;
}));
$this->backendService->method('getAuthMechanismsByScheme')
- ->will($this->returnCallback(function($schemes) use ($authMechanisms) {
+ ->will($this->returnCallback(function ($schemes) use ($authMechanisms) {
return array_filter($authMechanisms, function ($authMech) use ($schemes) {
return in_array($authMech->getScheme(), $schemes, true);
});
$backends['identifier:\OCA\Files_External\Lib\Backend\SFTP']->method('getLegacyAuthMechanism')
->willReturn($authMechanisms['identifier:\Other\Auth\Mechanism']);
$this->backendService->method('getBackend')
- ->will($this->returnCallback(function($backendClass) use ($backends) {
+ ->will($this->returnCallback(function ($backendClass) use ($backends) {
if (isset($backends[$backendClass])) {
return $backends[$backendClass];
}
$containerMock = $this->getMock('\OCP\AppFramework\IAppContainer');
$containerMock->method('query')
- ->will($this->returnCallback(function($name) {
+ ->will($this->returnCallback(function ($name) {
if ($name === 'OCA\Files_External\Service\BackendService') {
return $this->backendService;
}
public function tearDown() {
\OC_Mount_Config::$skipTest = false;
self::$hookCalls = array();
+ if ($this->dbConfig) {
+ $this->dbConfig->clean();
+ }
}
protected function getBackendMock($class = '\OCA\Files_External\Lib\Backend\SMB', $storageClass = '\OC\Files\Storage\SMB') {
$backend->method('getStorageClass')
->willReturn($storageClass);
$backend->method('getIdentifier')
- ->willReturn('identifier:'.$class);
+ ->willReturn('identifier:' . $class);
return $backend;
}
$authMech->method('getScheme')
->willReturn($scheme);
$authMech->method('getIdentifier')
- ->willReturn('identifier:'.$class);
+ ->willReturn('identifier:' . $class);
return $authMech;
}
$storage->setBackendOptions($backendOptions);
$newStorage = $this->service->addStorage($storage);
- $this->assertEquals(1, $newStorage->getId());
+ $id = $newStorage->getId();
// manually trigger storage entry because normally it happens on first
// access, which isn't possible within this test
// get numeric id for later check
$numericId = $storageCache->getNumericId();
- $newStorage = $this->service->removeStorage(1);
+ $this->service->removeStorage($id);
$caught = false;
try {
$priority
);
- $this->assertEquals('/'.$mountPoint, $storage->getMountPoint());
+ $this->assertEquals('/' . $mountPoint, $storage->getMountPoint());
$this->assertEquals($backend, $storage->getBackend());
$this->assertEquals($authMechanism, $storage->getAuthMechanism());
$this->assertEquals($backendOptions, $storage->getBackendOptions());
*/
namespace OCA\Files_External\Tests\Service;
+use OCA\Files_external\Service\StoragesService;
use \OCA\Files_External\Service\UserGlobalStoragesService;
use \OCP\IGroupManager;
use \OCA\Files_External\Lib\StorageConfig;
+use OCP\IUser;
+use Test\Traits\UserTrait;
+/**
+ * @group DB
+ */
class UserGlobalStoragesServiceTest extends GlobalStoragesServiceTest {
+ use UserTrait;
+ /** @var \OCP\IGroupManager|\PHPUnit_Framework_MockObject_MockObject groupManager */
protected $groupManager;
+ /**
+ * @var StoragesService
+ */
protected $globalStoragesService;
+ /**
+ * @var UserGlobalStoragesService
+ */
+ protected $service;
+
protected $user;
const USER_ID = 'test_user';
$this->globalStoragesService = $this->service;
$this->user = new \OC\User\User(self::USER_ID, null);
+ /** @var \OCP\IUserSession|\PHPUnit_Framework_MockObject_MockObject $userSession */
$userSession = $this->getMock('\OCP\IUserSession');
$userSession
->expects($this->any())
$this->groupManager = $this->getMock('\OCP\IGroupManager');
$this->groupManager->method('isInGroup')
- ->will($this->returnCallback(function($userId, $groupId) {
+ ->will($this->returnCallback(function ($userId, $groupId) {
if ($userId === self::USER_ID) {
switch ($groupId) {
- case self::GROUP_ID:
- case self::GROUP_ID2:
- return true;
+ case self::GROUP_ID:
+ case self::GROUP_ID2:
+ return true;
}
}
return false;
}));
+ $this->groupManager->method('getUserGroupIds')
+ ->will($this->returnCallback(function (IUser $user) {
+ if ($user->getUID() === self::USER_ID) {
+ return [self::GROUP_ID, self::GROUP_ID2];
+ } else {
+ return [];
+ }
+ }));
$this->service = new UserGlobalStoragesService(
$this->backendService,
+ $this->dbConfig,
$userSession,
$this->groupManager
);
$this->service->updateStorage($retrievedStorage);
}
+ /**
+ * @expectedException \DomainException
+ */
+ public function testNonExistingStorage() {
+ parent::testNonExistingStorage();
+ }
+
/**
* @expectedException \DomainException
* @dataProvider deleteStorageDataProvider
$storage->setBackendOptions($backendOptions);
$newStorage = $this->globalStoragesService->addStorage($storage);
- $this->assertEquals(1, $newStorage->getId());
+ $id = $newStorage->getId();
- $this->service->removeStorage(1);
+ $this->service->removeStorage($id);
+ }
+
+ /**
+ * @expectedException \DomainException
+ */
+ public function testDeleteUnexistingStorage() {
+ parent::testDeleteUnexistingStorage();
}
public function getUniqueStoragesProvider() {
use \OCA\Files_external\Service\UserStoragesService;
use \OCA\Files_external\NotFoundException;
use \OCA\Files_external\Lib\StorageConfig;
+use Test\Traits\UserTrait;
+/**
+ * @group DB
+ */
class UserStoragesServiceTest extends StoragesServiceTest {
+ use UserTrait;
+
+ private $user;
+
+ private $userId;
public function setUp() {
parent::setUp();
- $userManager = \OC::$server->getUserManager();
-
$this->userId = $this->getUniqueID('user_');
- $this->user = $userManager->createUser(
- $this->userId,
- $this->userId
- );
+ $this->createUser($this->userId, $this->userId);
+ $this->user = \OC::$server->getUserManager()->get($this->userId);
+ /** @var \OCP\IUserSession|\PHPUnit_Framework_MockObject_MockObject $userSession */
$userSession = $this->getMock('\OCP\IUserSession');
$userSession
->expects($this->any())
->method('getUser')
->will($this->returnValue($this->user));
- $this->service = new UserStoragesService($this->backendService, $userSession);
-
- // create home folder
- mkdir($this->dataDir . '/' . $this->userId . '/');
- }
-
- public function tearDown() {
- @unlink($this->dataDir . '/' . $this->userId . '/mount.json');
- $this->user->delete();
- parent::tearDown();
+ $this->service = new UserStoragesService($this->backendService, $this->dbConfig, $userSession);
}
private function makeTestStorageData() {
$newStorage = $this->service->addStorage($storage);
- $this->assertEquals(1, $newStorage->getId());
+ $id = $newStorage->getId();
- $newStorage = $this->service->getStorage(1);
+ $newStorage = $this->service->getStorage($id);
$this->assertEquals($storage->getMountPoint(), $newStorage->getMountPoint());
$this->assertEquals($storage->getBackend(), $newStorage->getBackend());
$this->assertEquals($storage->getAuthMechanism(), $newStorage->getAuthMechanism());
$this->assertEquals($storage->getBackendOptions(), $newStorage->getBackendOptions());
- $this->assertEquals(1, $newStorage->getId());
$this->assertEquals(0, $newStorage->getStatus());
// hook called once for user
$this->userId
);
- // next one gets id 2
$nextStorage = $this->service->addStorage($storage);
- $this->assertEquals(2, $nextStorage->getId());
+ $this->assertEquals($id + 1, $nextStorage->getId());
}
public function testUpdateStorage() {
]);
$newStorage = $this->service->addStorage($storage);
- $this->assertEquals(1, $newStorage->getId());
$backendOptions = $newStorage->getBackendOptions();
$backendOptions['password'] = 'anotherPassword';
// these attributes are unused for user storages
$this->assertEmpty($newStorage->getApplicableUsers());
$this->assertEmpty($newStorage->getApplicableGroups());
- $this->assertEquals(1, $newStorage->getId());
$this->assertEquals(0, $newStorage->getStatus());
// no hook calls
$this->userId
);
}
-
- /**
- * Make sure it uses the correct format when reading/writing
- * the legacy config
- */
- public function testLegacyConfigConversion() {
- $configFile = $this->dataDir . '/' . $this->userId . '/mount.json';
-
- $storage = $this->makeTestStorageData();
- $storage = $this->service->addStorage($storage);
-
- $json = json_decode(file_get_contents($configFile), true);
-
- $this->assertCount(1, $json);
-
- $this->assertEquals([\OC_Mount_Config::MOUNT_TYPE_USER], array_keys($json));
- $this->assertEquals([$this->userId], array_keys($json[\OC_Mount_config::MOUNT_TYPE_USER]));
-
- $mountPointData = $json[\OC_Mount_config::MOUNT_TYPE_USER][$this->userId];
- $this->assertEquals(['/' . $this->userId . '/files/mountpoint'], array_keys($mountPointData));
-
- $mountPointOptions = current($mountPointData);
- $this->assertEquals(1, $mountPointOptions['id']);
- $this->assertEquals('identifier:\OCA\Files_External\Lib\Backend\SMB', $mountPointOptions['backend']);
- $this->assertEquals('identifier:\Auth\Mechanism', $mountPointOptions['authMechanism']);
- $this->assertEquals(false, $mountPointOptions['mountOptions']['preview']);
-
- $backendOptions = $mountPointOptions['options'];
- $this->assertEquals('value1', $backendOptions['option1']);
- $this->assertEquals('value2', $backendOptions['option2']);
- $this->assertEquals('', $backendOptions['password']);
- $this->assertNotEmpty($backendOptions['password_encrypted']);
- }
-
- /**
- * Test reading in a legacy config and generating config ids.
- */
- public function testReadLegacyConfigAndGenerateConfigId() {
- $configFile = $this->dataDir . '/' . $this->userId . '/mount.json';
-
- $legacyBackendOptions = [
- 'user' => 'someuser',
- 'password' => 'somepassword',
- ];
- $legacyBackendOptions = \OC_Mount_Config::encryptPasswords($legacyBackendOptions);
-
- $legacyConfig = [
- 'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
- 'authMechanism' => 'identifier:\Auth\Mechanism',
- 'options' => $legacyBackendOptions,
- 'mountOptions' => ['preview' => false],
- ];
- // different mount options
- $legacyConfig2 = [
- 'backend' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
- 'authMechanism' => 'identifier:\Auth\Mechanism',
- 'options' => $legacyBackendOptions,
- 'mountOptions' => ['preview' => true],
- ];
-
- $json = ['user' => []];
- $json['user'][$this->userId] = [
- '/$user/files/somemount' => $legacyConfig,
- '/$user/files/anothermount' => $legacyConfig2,
- ];
-
- file_put_contents($configFile, json_encode($json));
-
- $allStorages = $this->service->getAllStorages();
-
- $this->assertCount(2, $allStorages);
-
- $storage1 = $allStorages[1];
- $storage2 = $allStorages[2];
-
- $this->assertEquals('/somemount', $storage1->getMountPoint());
- $this->assertEquals('someuser', $storage1->getBackendOptions()['user']);
- $this->assertEquals('somepassword', $storage1->getBackendOptions()['password']);
- $this->assertEquals(['preview' => false], $storage1->getMountOptions());
-
- $this->assertEquals('/anothermount', $storage2->getMountPoint());
- $this->assertEquals('someuser', $storage2->getBackendOptions()['user']);
- $this->assertEquals('somepassword', $storage2->getBackendOptions()['password']);
- $this->assertEquals(['preview' => true], $storage2->getMountOptions());
- }
}