diff options
Diffstat (limited to 'lib/private')
-rw-r--r-- | lib/private/Authentication/Token/DefaultToken.php | 33 | ||||
-rw-r--r-- | lib/private/Authentication/Token/DefaultTokenMapper.php | 31 | ||||
-rw-r--r-- | lib/private/Authentication/Token/DefaultTokenProvider.php | 17 | ||||
-rw-r--r-- | lib/private/Authentication/Token/IProvider.php | 11 | ||||
-rw-r--r-- | lib/private/Authentication/Token/IToken.php | 23 | ||||
-rw-r--r-- | lib/private/Files/Filesystem.php | 42 | ||||
-rw-r--r-- | lib/private/Lockdown/Filesystem/NullCache.php | 122 | ||||
-rw-r--r-- | lib/private/Lockdown/Filesystem/NullStorage.php | 177 | ||||
-rw-r--r-- | lib/private/Lockdown/LockdownManager.php | 46 | ||||
-rw-r--r-- | lib/private/Server.php | 11 | ||||
-rw-r--r-- | lib/private/Settings/Admin/ServerDevNotice.php | 62 | ||||
-rw-r--r-- | lib/private/Settings/Manager.php | 2 | ||||
-rw-r--r-- | lib/private/User/Session.php | 1 | ||||
-rw-r--r-- | lib/private/legacy/app.php | 2 |
14 files changed, 558 insertions, 22 deletions
diff --git a/lib/private/Authentication/Token/DefaultToken.php b/lib/private/Authentication/Token/DefaultToken.php index faef2f73b33..127430ea6cb 100644 --- a/lib/private/Authentication/Token/DefaultToken.php +++ b/lib/private/Authentication/Token/DefaultToken.php @@ -87,6 +87,17 @@ class DefaultToken extends Entity implements IToken { */ protected $lastCheck; + /** + * @var string + */ + protected $scope; + + public function __construct() { + $this->addType('type', 'int'); + $this->addType('lastActivity', 'int'); + $this->addType('lastCheck', 'int'); + } + public function getId() { return $this->id; } @@ -119,6 +130,7 @@ class DefaultToken extends Entity implements IToken { 'name' => $this->name, 'lastActivity' => $this->lastActivity, 'type' => $this->type, + 'scope' => $this->getScopeAsArray() ]; } @@ -140,4 +152,25 @@ class DefaultToken extends Entity implements IToken { return parent::setLastCheck($time); } + public function getScope() { + return parent::getScope(); + } + + public function getScopeAsArray() { + $scope = json_decode($this->getScope(), true); + if (!$scope) { + return [ + 'filesystem'=> true + ]; + } + return $scope; + } + + public function setScope($scope) { + if (is_array($scope)) { + parent::setScope(json_encode($scope)); + } else { + parent::setScope((string)$scope); + } + } } diff --git a/lib/private/Authentication/Token/DefaultTokenMapper.php b/lib/private/Authentication/Token/DefaultTokenMapper.php index 752974ff240..8848cd3ec56 100644 --- a/lib/private/Authentication/Token/DefaultTokenMapper.php +++ b/lib/private/Authentication/Token/DefaultTokenMapper.php @@ -72,10 +72,9 @@ class DefaultTokenMapper extends Mapper { public function getToken($token) { /* @var $qb IQueryBuilder */ $qb = $this->db->getQueryBuilder(); - $result = $qb->select('id', 'uid', 'login_name', 'password', 'name', 'type', 'remember', 'token', 'last_activity', 'last_check') + $result = $qb->select('id', 'uid', 'login_name', 'password', 'name', 'type', 'remember', 'token', 'last_activity', 'last_check', 'scope') ->from('authtoken') - ->where($qb->expr()->eq('token', $qb->createParameter('token'))) - ->setParameter('token', $token) + ->where($qb->expr()->eq('token', $qb->createNamedParameter($token))) ->execute(); $data = $result->fetch(); @@ -83,6 +82,30 @@ class DefaultTokenMapper extends Mapper { if ($data === false) { throw new DoesNotExistException('token does not exist'); } +; + return DefaultToken::fromRow($data); + } + + /** + * Get the token for $id + * + * @param string $id + * @throws DoesNotExistException + * @return DefaultToken + */ + public function getTokenById($id) { + /* @var $qb IQueryBuilder */ + $qb = $this->db->getQueryBuilder(); + $result = $qb->select('id', 'uid', 'login_name', 'password', 'name', 'type', 'token', 'last_activity', 'last_check', 'scope') + ->from('authtoken') + ->where($qb->expr()->eq('id', $qb->createNamedParameter($id))) + ->execute(); + + $data = $result->fetch(); + $result->closeCursor(); + if ($data === false) { + throw new DoesNotExistException('token does not exist'); + }; return DefaultToken::fromRow($data); } @@ -98,7 +121,7 @@ class DefaultTokenMapper extends Mapper { public function getTokenByUser(IUser $user) { /* @var $qb IQueryBuilder */ $qb = $this->db->getQueryBuilder(); - $qb->select('id', 'uid', 'login_name', 'password', 'name', 'type', 'remember', 'token', 'last_activity', 'last_check') + $qb->select('id', 'uid', 'login_name', 'password', 'name', 'type', 'remember', 'token', 'last_activity', 'last_check', 'scope') ->from('authtoken') ->where($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID()))) ->setMaxResults(1000); diff --git a/lib/private/Authentication/Token/DefaultTokenProvider.php b/lib/private/Authentication/Token/DefaultTokenProvider.php index 87f434c684c..0fdbc4a51dd 100644 --- a/lib/private/Authentication/Token/DefaultTokenProvider.php +++ b/lib/private/Authentication/Token/DefaultTokenProvider.php @@ -145,7 +145,7 @@ class DefaultTokenProvider implements IProvider { } /** - * Get a token by token id + * Get a token by token * * @param string $tokenId * @throws InvalidTokenException @@ -160,6 +160,21 @@ class DefaultTokenProvider implements IProvider { } /** + * Get a token by token id + * + * @param string $tokenId + * @throws InvalidTokenException + * @return DefaultToken + */ + public function getTokenById($tokenId) { + try { + return $this->mapper->getTokenById($tokenId); + } catch (DoesNotExistException $ex) { + throw new InvalidTokenException(); + } + } + + /** * @param string $oldSessionId * @param string $sessionId * @throws InvalidTokenException diff --git a/lib/private/Authentication/Token/IProvider.php b/lib/private/Authentication/Token/IProvider.php index ce14a5880c5..9f280263d76 100644 --- a/lib/private/Authentication/Token/IProvider.php +++ b/lib/private/Authentication/Token/IProvider.php @@ -50,7 +50,16 @@ interface IProvider { * @throws InvalidTokenException * @return IToken */ - public function getToken($tokenId) ; + public function getToken($tokenId); + + /** + * Get a token by token id + * + * @param string $tokenId + * @throws InvalidTokenException + * @return DefaultToken + */ + public function getTokenById($tokenId); /** * Duplicate an existing session token diff --git a/lib/private/Authentication/Token/IToken.php b/lib/private/Authentication/Token/IToken.php index 14811dd3201..49745b266c4 100644 --- a/lib/private/Authentication/Token/IToken.php +++ b/lib/private/Authentication/Token/IToken.php @@ -67,9 +67,30 @@ interface IToken extends JsonSerializable { public function getLastCheck(); /** - * Get the timestamp of the last password check + * Set the timestamp of the last password check * * @param int $time */ public function setLastCheck($time); + + /** + * Get the authentication scope for this token + * + * @return string + */ + public function getScope(); + + /** + * Get the authentication scope for this token + * + * @return array + */ + public function getScopeAsArray(); + + /** + * Set the authentication scope for this token + * + * @param array $scope + */ + public function setScope($scope); } diff --git a/lib/private/Files/Filesystem.php b/lib/private/Files/Filesystem.php index 55cf38bbdc9..ac0e66973d4 100644 --- a/lib/private/Files/Filesystem.php +++ b/lib/private/Files/Filesystem.php @@ -62,6 +62,7 @@ use OC\Cache\CappedMemoryCache; use OC\Files\Config\MountProviderCollection; use OC\Files\Mount\MountPoint; use OC\Files\Storage\StorageFactory; +use OC\Lockdown\Filesystem\NullStorage; use OCP\Files\Config\IMountProvider; use OCP\Files\Mount\IMountPoint; use OCP\Files\NotFoundException; @@ -216,7 +217,7 @@ class Filesystem { * @internal */ public static function logWarningWhenAddingStorageWrapper($shouldLog) { - self::$logWarningWhenAddingStorageWrapper = (bool) $shouldLog; + self::$logWarningWhenAddingStorageWrapper = (bool)$shouldLog; } /** @@ -426,25 +427,36 @@ class Filesystem { self::$usersSetup[$user] = true; } - /** @var \OC\Files\Config\MountProviderCollection $mountConfigManager */ - $mountConfigManager = \OC::$server->getMountProviderCollection(); + if (\OC::$server->getLockdownManager()->canAccessFilesystem()) { + /** @var \OC\Files\Config\MountProviderCollection $mountConfigManager */ + $mountConfigManager = \OC::$server->getMountProviderCollection(); - // home mounts are handled seperate since we need to ensure this is mounted before we call the other mount providers - $homeMount = $mountConfigManager->getHomeMountForUser($userObject); + // home mounts are handled seperate since we need to ensure this is mounted before we call the other mount providers + $homeMount = $mountConfigManager->getHomeMountForUser($userObject); - self::getMountManager()->addMount($homeMount); + self::getMountManager()->addMount($homeMount); - \OC\Files\Filesystem::getStorage($user); + \OC\Files\Filesystem::getStorage($user); - // Chance to mount for other storages - if ($userObject) { - $mounts = $mountConfigManager->getMountsForUser($userObject); - array_walk($mounts, array(self::$mounts, 'addMount')); - $mounts[] = $homeMount; - $mountConfigManager->registerMounts($userObject, $mounts); - } + // Chance to mount for other storages + if ($userObject) { + $mounts = $mountConfigManager->getMountsForUser($userObject); + array_walk($mounts, array(self::$mounts, 'addMount')); + $mounts[] = $homeMount; + $mountConfigManager->registerMounts($userObject, $mounts); + } - self::listenForNewMountProviders($mountConfigManager, $userManager); + self::listenForNewMountProviders($mountConfigManager, $userManager); + } else { + self::$mounts->addMount(new MountPoint( + new NullStorage([]), + '/' . $user + )); + self::$mounts->addMount(new MountPoint( + new NullStorage([]), + '/' . $user . '/files' + )); + } \OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user)); } diff --git a/lib/private/Lockdown/Filesystem/NullCache.php b/lib/private/Lockdown/Filesystem/NullCache.php new file mode 100644 index 00000000000..8c6b5258aa8 --- /dev/null +++ b/lib/private/Lockdown/Filesystem/NullCache.php @@ -0,0 +1,122 @@ +<?php + +/** + * @copyright Copyright (c) 2016, Robin Appelman <robin@icewind.nl> + * + * 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 OC\Lockdown\Filesystem; + +use OC\Files\Cache\CacheEntry; +use OCP\Constants; +use OCP\Files\Cache\ICache; +use OCP\Files\Cache\ICacheEntry; +use OCP\Files\FileInfo; + +class NullCache implements ICache { + public function getNumericStorageId() { + return -1; + } + + public function get($file) { + return $file !== '' ? null : + new CacheEntry([ + 'fileid' => -1, + 'parent' => -1, + 'name' => '', + 'path' => '', + 'size' => '0', + 'mtime' => time(), + 'storage_mtime' => time(), + 'etag' => '', + 'mimetype' => FileInfo::MIMETYPE_FOLDER, + 'mimepart' => 'httpd', + 'permissions' => Constants::PERMISSION_READ + ]); + } + + public function getFolderContents($folder) { + return []; + } + + public function getFolderContentsById($fileId) { + return []; + } + + public function put($file, array $data) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function insert($file, array $data) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function update($id, array $data) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function getId($file) { + return -1; + } + + public function getParentId($file) { + return -1; + } + + public function inCache($file) { + return $file === ''; + } + + public function remove($file) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function move($source, $target) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function getStatus($file) { + return ICache::COMPLETE; + } + + public function search($pattern) { + return []; + } + + public function searchByMime($mimetype) { + return []; + } + + public function searchByTag($tag, $userId) { + return []; + } + + public function getIncomplete() { + return []; + } + + public function getPathById($id) { + return ''; + } + + public function normalize($path) { + return $path; + } + +} diff --git a/lib/private/Lockdown/Filesystem/NullStorage.php b/lib/private/Lockdown/Filesystem/NullStorage.php new file mode 100644 index 00000000000..967b6d2c6e7 --- /dev/null +++ b/lib/private/Lockdown/Filesystem/NullStorage.php @@ -0,0 +1,177 @@ +<?php + +/** + * @copyright Copyright (c) 2016, Robin Appelman <robin@icewind.nl> + * + * 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 OC\Lockdown\Filesystem; + +use Icewind\Streams\IteratorDirectory; +use OC\Files\Storage\Common; + +class NullStorage extends Common { + public function __construct($parameters) { + parent::__construct($parameters); + } + + public function getId() { + return 'null'; + } + + public function mkdir($path) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function rmdir($path) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function opendir($path) { + return new IteratorDirectory([]); + } + + public function is_dir($path) { + return $path === ''; + } + + public function is_file($path) { + return false; + } + + public function stat($path) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function filetype($path) { + return ($path === '') ? 'dir' : false; + } + + public function filesize($path) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function isCreatable($path) { + return false; + } + + public function isReadable($path) { + return $path === ''; + } + + public function isUpdatable($path) { + return false; + } + + public function isDeletable($path) { + return false; + } + + public function isSharable($path) { + return false; + } + + public function getPermissions($path) { + return null; + } + + public function file_exists($path) { + return $path === ''; + } + + public function filemtime($path) { + return ($path === '') ? time() : false; + } + + public function file_get_contents($path) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function file_put_contents($path, $data) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function unlink($path) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function rename($path1, $path2) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function copy($path1, $path2) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function fopen($path, $mode) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function getMimeType($path) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function hash($type, $path, $raw = false) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function free_space($path) { + return 0; + } + + public function touch($path, $mtime = null) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function getLocalFile($path) { + return false; + } + + public function hasUpdated($path, $time) { + return false; + } + + public function getETag($path) { + return ''; + } + + public function isLocal() { + return false; + } + + public function getDirectDownload($path) { + return false; + } + + public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) { + throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); + } + + public function test() { + return true; + } + + public function getOwner($path) { + return null; + } + + public function getCache($path = '', $storage = null) { + return new NullCache(); + } +} diff --git a/lib/private/Lockdown/LockdownManager.php b/lib/private/Lockdown/LockdownManager.php new file mode 100644 index 00000000000..5ce52a03683 --- /dev/null +++ b/lib/private/Lockdown/LockdownManager.php @@ -0,0 +1,46 @@ +<?php + +/** + * @copyright Copyright (c) 2016, Robin Appelman <robin@icewind.nl> + * + * 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 OC\Lockdown; + +use OC\Authentication\Token\IToken; +use OCP\Lockdown\ILockdownManager; + +class LockdownManager implements ILockdownManager { + private $enabled = false; + + /** @var array|null */ + private $scope; + + public function enable() { + $this->enabled = true; + } + + public function setToken(IToken $token) { + $this->scope = $token->getScopeAsArray(); + $this->enable(); + } + + public function canAccessFilesystem() { + if (!$this->enabled) { + return true; + } + return !$this->scope || $this->scope['filesystem']; + } +} diff --git a/lib/private/Server.php b/lib/private/Server.php index abedf8230ed..c6755357a1d 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -69,6 +69,7 @@ use OC\IntegrityCheck\Helpers\FileAccessHelper; use OC\Lock\DBLockingProvider; use OC\Lock\MemcacheLockingProvider; use OC\Lock\NoopLockingProvider; +use OC\Lockdown\LockdownManager; use OC\Mail\Mailer; use OC\Memcache\ArrayCache; use OC\Notification\Manager; @@ -795,6 +796,9 @@ class Server extends ServerContainer implements IServerContainer { $c->getSystemConfig() ); }); + $this->registerService('LockdownManager', function (Server $c) { + return new LockdownManager(); + }); } /** @@ -1534,4 +1538,11 @@ class Server extends ServerContainer implements IServerContainer { $factory = $this->query(\OC\Files\AppData\Factory::class); return $factory->get($app); } + + /** + * @return \OCP\Lockdown\ILockdownManager + */ + public function getLockdownManager() { + return $this->query('LockdownManager'); + } } diff --git a/lib/private/Settings/Admin/ServerDevNotice.php b/lib/private/Settings/Admin/ServerDevNotice.php new file mode 100644 index 00000000000..1d7f34f782d --- /dev/null +++ b/lib/private/Settings/Admin/ServerDevNotice.php @@ -0,0 +1,62 @@ +<?php +/** + * @copyright 2016, Roeland Jago Douma <roeland@famdouma.nl> + * + * @author Roeland Jago Douma <roeland@famdouma.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OC\Settings\Admin; + +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Platforms\SqlitePlatform; +use OC\Lock\DBLockingProvider; +use OC\Lock\NoopLockingProvider; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IConfig; +use OCP\IDBConnection; +use OCP\IL10N; +use OCP\Lock\ILockingProvider; +use OCP\Settings\ISettings; + +class ServerDevNotice implements ISettings { + /** + * @return TemplateResponse + */ + public function getForm() { + return new TemplateResponse('settings', 'admin/server.development.notice'); + } + + /** + * @return string the section ID, e.g. 'sharing' + */ + public function getSection() { + return 'server'; + } + + /** + * @return int whether the form should be rather on the top or bottom of + * the admin section. The forms are arranged in ascending order of the + * priority values. It is required to return a value between 0 and 100. + * + * E.g.: 70 + */ + public function getPriority() { + return 1000; + } +} diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php index e7be3d4e77d..a6f9aacccb2 100644 --- a/lib/private/Settings/Manager.php +++ b/lib/private/Settings/Manager.php @@ -369,6 +369,8 @@ class Manager implements IManager { /** @var ISettings $form */ $form = new Admin\Server($this->dbc, $this->config, $this->lockingProvider, $this->l); $forms[$form->getPriority()] = [$form]; + $form = new Admin\ServerDevNotice(); + $forms[$form->getPriority()] = [$form]; } if($section === 'encryption') { /** @var ISettings $form */ diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php index ef408aa4077..6033f060504 100644 --- a/lib/private/User/Session.php +++ b/lib/private/User/Session.php @@ -525,6 +525,7 @@ class Session implements IUserSession, Emitter { //login $this->setUser($user); $this->setLoginName($dbToken->getLoginName()); + \OC::$server->getLockdownManager()->setToken($dbToken); $this->manager->emit('\OC\User', 'postLogin', array($user, $password)); if ($this->isLoggedIn()) { diff --git a/lib/private/legacy/app.php b/lib/private/legacy/app.php index c2ff9a5be3c..0d9adfa9d2b 100644 --- a/lib/private/legacy/app.php +++ b/lib/private/legacy/app.php @@ -376,6 +376,8 @@ class OC_App { $config, $l ); + $appPath = self::getAppPath($appId); + self::registerAutoloading($appId, $appPath); $installer->installApp($appId); } else { // check for required dependencies |