Merge pull request #13490 from owncloud/fix_reshare_s2s_share

use uid provided by setupfs hook to mount server2server shares
remotes/origin/create-share-target-reuse
Vincent Petry 12 years ago
commit bd888748bd
  1. 4
      apps/files_sharing/ajax/external.php
  2. 5
      apps/files_sharing/api/server2server.php
  3. 6
      apps/files_sharing/application.php
  4. 1
      apps/files_sharing/lib/controllers/sharecontroller.php
  5. 78
      apps/files_sharing/lib/external/manager.php
  6. 4
      apps/files_sharing/lib/hooks.php
  7. 5
      apps/files_sharing/tests/server2server.php
  8. 42
      lib/private/security/certificatemanager.php
  9. 13
      lib/private/server.php
  10. 8
      tests/lib/security/certificatemanager.php

@ -34,8 +34,8 @@ $externalManager = new \OCA\Files_Sharing\External\Manager(
\OC::$server->getDatabaseConnection(), \OC::$server->getDatabaseConnection(),
\OC\Files\Filesystem::getMountManager(), \OC\Files\Filesystem::getMountManager(),
\OC\Files\Filesystem::getLoader(), \OC\Files\Filesystem::getLoader(),
\OC::$server->getUserSession(), \OC::$server->getHTTPHelper(),
\OC::$server->getHTTPHelper() \OC::$server->getUserSession()->getUser()->getUID()
); );
$name = OCP\Files::buildNotExistingFileName('/', $name); $name = OCP\Files::buildNotExistingFileName('/', $name);

@ -60,8 +60,9 @@ class Server2Server {
\OC::$server->getDatabaseConnection(), \OC::$server->getDatabaseConnection(),
\OC\Files\Filesystem::getMountManager(), \OC\Files\Filesystem::getMountManager(),
\OC\Files\Filesystem::getLoader(), \OC\Files\Filesystem::getLoader(),
\OC::$server->getUserSession(), \OC::$server->getHTTPHelper(),
\OC::$server->getHTTPHelper()); $shareWith
);
$name = \OCP\Files::buildNotExistingFileName('/', $name); $name = \OCP\Files::buildNotExistingFileName('/', $name);

@ -69,12 +69,14 @@ class Application extends App {
return Helper::isIncomingServer2serverShareEnabled(); return Helper::isIncomingServer2serverShareEnabled();
}); });
$container->registerService('ExternalManager', function(SimpleContainer $c) use ($server){ $container->registerService('ExternalManager', function(SimpleContainer $c) use ($server){
$user = $server->getUserSession()->getUser();
$uid = $user ? $user->getUID() : null;
return new \OCA\Files_Sharing\External\Manager( return new \OCA\Files_Sharing\External\Manager(
$server->getDatabaseConnection(), $server->getDatabaseConnection(),
\OC\Files\Filesystem::getMountManager(), \OC\Files\Filesystem::getMountManager(),
\OC\Files\Filesystem::getLoader(), \OC\Files\Filesystem::getLoader(),
$server->getUserSession(), $server->getHTTPHelper(),
$server->getHTTPHelper() $uid
); );
}); });

@ -142,7 +142,6 @@ class ShareController extends Controller {
return new TemplateResponse('core', '404', array(), 'guest'); return new TemplateResponse('core', '404', array(), 'guest');
} }
$linkItem = OCP\Share::getShareByToken($token, false);
$shareOwner = $linkItem['uid_owner']; $shareOwner = $linkItem['uid_owner'];
$originalSharePath = null; $originalSharePath = null;
$rootLinkItem = OCP\Share::resolveReShare($linkItem); $rootLinkItem = OCP\Share::resolveReShare($linkItem);

@ -13,6 +13,11 @@ use OC\Files\Filesystem;
class Manager { class Manager {
const STORAGE = '\OCA\Files_Sharing\External\Storage'; const STORAGE = '\OCA\Files_Sharing\External\Storage';
/**
* @var string
*/
private $uid;
/** /**
* @var \OCP\IDBConnection * @var \OCP\IDBConnection
*/ */
@ -28,11 +33,6 @@ class Manager {
*/ */
private $storageLoader; private $storageLoader;
/**
* @var \OC\User\Session
*/
private $userSession;
/** /**
* @var \OC\HTTPHelper * @var \OC\HTTPHelper
*/ */
@ -41,21 +41,35 @@ class Manager {
/** /**
* @param \OCP\IDBConnection $connection * @param \OCP\IDBConnection $connection
* @param \OC\Files\Mount\Manager $mountManager * @param \OC\Files\Mount\Manager $mountManager
* @param \OC\User\Session $userSession
* @param \OC\Files\Storage\StorageFactory $storageLoader * @param \OC\Files\Storage\StorageFactory $storageLoader
* @param \OC\HTTPHelper $httpHelper
* @param string $uid
*/ */
public function __construct(\OCP\IDBConnection $connection, \OC\Files\Mount\Manager $mountManager, public function __construct(\OCP\IDBConnection $connection, \OC\Files\Mount\Manager $mountManager,
\OC\Files\Storage\StorageFactory $storageLoader, \OC\User\Session $userSession, \OC\HTTPHelper $httpHelper) { \OC\Files\Storage\StorageFactory $storageLoader, \OC\HTTPHelper $httpHelper, $uid) {
$this->connection = $connection; $this->connection = $connection;
$this->mountManager = $mountManager; $this->mountManager = $mountManager;
$this->userSession = $userSession;
$this->storageLoader = $storageLoader; $this->storageLoader = $storageLoader;
$this->httpHelper = $httpHelper; $this->httpHelper = $httpHelper;
$this->uid = $uid;
} }
/**
* add new server-to-server share
*
* @param string $remote
* @param string $token
* @param string $password
* @param string $name
* @param string $owner
* @param boolean $accepted
* @param string $user
* @param int $remoteId
* @return mixed
*/
public function addShare($remote, $token, $password, $name, $owner, $accepted=false, $user = null, $remoteId = -1) { public function addShare($remote, $token, $password, $name, $owner, $accepted=false, $user = null, $remoteId = -1) {
$user = $user ? $user: $this->userSession->getUser()->getUID(); $user = $user ? $user : $this->uid;
$accepted = $accepted ? 1 : 0; $accepted = $accepted ? 1 : 0;
$mountPoint = Filesystem::normalizePath('/' . $name); $mountPoint = Filesystem::normalizePath('/' . $name);
@ -86,14 +100,13 @@ class Manager {
return false; return false;
} }
$user = $this->userSession->getUser(); if (!is_null($this->uid)) {
if ($user) {
$query = $this->connection->prepare(' $query = $this->connection->prepare('
SELECT `remote`, `share_token`, `password`, `mountpoint`, `owner` SELECT `remote`, `share_token`, `password`, `mountpoint`, `owner`
FROM `*PREFIX*share_external` FROM `*PREFIX*share_external`
WHERE `user` = ? AND `accepted` = ? WHERE `user` = ? AND `accepted` = ?
'); ');
$query->execute(array($user->getUID(), 1)); $query->execute(array($this->uid, 1));
while ($row = $query->fetch()) { while ($row = $query->fetch()) {
$row['manager'] = $this; $row['manager'] = $this;
@ -114,7 +127,7 @@ class Manager {
SELECT `remote`, `share_token` SELECT `remote`, `share_token`
FROM `*PREFIX*share_external` FROM `*PREFIX*share_external`
WHERE `id` = ? AND `user` = ?'); WHERE `id` = ? AND `user` = ?');
$result = $getShare->execute(array($id, $this->userSession->getUser()->getUID())); $result = $getShare->execute(array($id, $this->uid));
return $result ? $getShare->fetch() : false; return $result ? $getShare->fetch() : false;
} }
@ -133,7 +146,7 @@ class Manager {
UPDATE `*PREFIX*share_external` UPDATE `*PREFIX*share_external`
SET `accepted` = ? SET `accepted` = ?
WHERE `id` = ? AND `user` = ?'); WHERE `id` = ? AND `user` = ?');
$acceptShare->execute(array(1, $id, $this->userSession->getUser()->getUID())); $acceptShare->execute(array(1, $id, $this->uid));
$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $id, 'accept'); $this->sendFeedbackToRemote($share['remote'], $share['share_token'], $id, 'accept');
} }
} }
@ -150,7 +163,7 @@ class Manager {
if ($share) { if ($share) {
$removeShare = $this->connection->prepare(' $removeShare = $this->connection->prepare('
DELETE FROM `*PREFIX*share_external` WHERE `id` = ? AND `user` = ?'); DELETE FROM `*PREFIX*share_external` WHERE `id` = ? AND `user` = ?');
$removeShare->execute(array($id, $this->userSession->getUser()->getUID())); $removeShare->execute(array($id, $this->uid));
$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $id, 'decline'); $this->sendFeedbackToRemote($share['remote'], $share['share_token'], $id, 'decline');
} }
} }
@ -175,19 +188,31 @@ class Manager {
return ($result['success'] && $status['ocs']['meta']['statuscode'] === 100); return ($result['success'] && $status['ocs']['meta']['statuscode'] === 100);
} }
public static function setup() { /**
* setup the server-to-server mounts
*
* @param array $params
*/
public static function setup(array $params) {
$externalManager = new \OCA\Files_Sharing\External\Manager( $externalManager = new \OCA\Files_Sharing\External\Manager(
\OC::$server->getDatabaseConnection(), \OC::$server->getDatabaseConnection(),
\OC\Files\Filesystem::getMountManager(), \OC\Files\Filesystem::getMountManager(),
\OC\Files\Filesystem::getLoader(), \OC\Files\Filesystem::getLoader(),
\OC::$server->getUserSession(), \OC::$server->getHTTPHelper(),
\OC::$server->getHTTPHelper() $params['user']
); );
$externalManager->setupMounts(); $externalManager->setupMounts();
} }
/**
* remove '/user/files' from the path and trailing slashes
*
* @param string $path
* @return string
*/
protected function stripPath($path) { protected function stripPath($path) {
$prefix = '/' . $this->userSession->getUser()->getUID() . '/files'; $prefix = '/' . $this->uid . '/files';
return rtrim(substr($path, strlen($prefix)), '/'); return rtrim(substr($path, strlen($prefix)), '/');
} }
@ -196,11 +221,10 @@ class Manager {
* @return Mount * @return Mount
*/ */
protected function mountShare($data) { protected function mountShare($data) {
$user = $this->userSession->getUser();
$data['manager'] = $this; $data['manager'] = $this;
$mountPoint = '/' . $user->getUID() . '/files' . $data['mountpoint']; $mountPoint = '/' . $this->uid . '/files' . $data['mountpoint'];
$data['mountpoint'] = $mountPoint; $data['mountpoint'] = $mountPoint;
$data['certificateManager'] = \OC::$server->getCertificateManager($user); $data['certificateManager'] = \OC::$server->getCertificateManager($this->uid);
$mount = new Mount(self::STORAGE, $mountPoint, $data, $this, $this->storageLoader); $mount = new Mount(self::STORAGE, $mountPoint, $data, $this, $this->storageLoader);
$this->mountManager->addMount($mount); $this->mountManager->addMount($mount);
return $mount; return $mount;
@ -219,7 +243,6 @@ class Manager {
* @return bool * @return bool
*/ */
public function setMountPoint($source, $target) { public function setMountPoint($source, $target) {
$user = $this->userSession->getUser();
$source = $this->stripPath($source); $source = $this->stripPath($source);
$target = $this->stripPath($target); $target = $this->stripPath($target);
$sourceHash = md5($source); $sourceHash = md5($source);
@ -231,13 +254,12 @@ class Manager {
WHERE `mountpoint_hash` = ? WHERE `mountpoint_hash` = ?
AND `user` = ? AND `user` = ?
'); ');
$result = (bool)$query->execute(array($target, $targetHash, $sourceHash, $user->getUID())); $result = (bool)$query->execute(array($target, $targetHash, $sourceHash, $this->uid));
return $result; return $result;
} }
public function removeShare($mountPoint) { public function removeShare($mountPoint) {
$user = $this->userSession->getUser();
$mountPoint = $this->stripPath($mountPoint); $mountPoint = $this->stripPath($mountPoint);
$hash = md5($mountPoint); $hash = md5($mountPoint);
@ -245,7 +267,7 @@ class Manager {
SELECT `remote`, `share_token`, `remote_id` SELECT `remote`, `share_token`, `remote_id`
FROM `*PREFIX*share_external` FROM `*PREFIX*share_external`
WHERE `mountpoint_hash` = ? AND `user` = ?'); WHERE `mountpoint_hash` = ? AND `user` = ?');
$result = $getShare->execute(array($hash, $user->getUID())); $result = $getShare->execute(array($hash, $this->uid));
if ($result) { if ($result) {
$share = $getShare->fetch(); $share = $getShare->fetch();
@ -257,7 +279,7 @@ class Manager {
WHERE `mountpoint_hash` = ? WHERE `mountpoint_hash` = ?
AND `user` = ? AND `user` = ?
'); ');
return (bool)$query->execute(array($hash, $user->getUID())); return (bool)$query->execute(array($hash, $this->uid));
} }
/** /**
@ -294,7 +316,7 @@ class Manager {
*/ */
public function getOpenShares() { public function getOpenShares() {
$openShares = $this->connection->prepare('SELECT * FROM `*PREFIX*share_external` WHERE `accepted` = ? AND `user` = ?'); $openShares = $this->connection->prepare('SELECT * FROM `*PREFIX*share_external` WHERE `accepted` = ? AND `user` = ?');
$result = $openShares->execute(array(0, $this->userSession->getUser()->getUID())); $result = $openShares->execute(array(0, $this->uid));
return $result ? $openShares->fetchAll() : array(); return $result ? $openShares->fetchAll() : array();

@ -30,8 +30,8 @@ class Hooks {
\OC::$server->getDatabaseConnection(), \OC::$server->getDatabaseConnection(),
\OC\Files\Filesystem::getMountManager(), \OC\Files\Filesystem::getMountManager(),
\OC\Files\Filesystem::getLoader(), \OC\Files\Filesystem::getLoader(),
\OC::$server->getUserSession(), \OC::$server->getHTTPHelper(),
\OC::$server->getHTTPHelper()); $params['uid']);
$manager->removeUserShares($params['uid']); $manager->removeUserShares($params['uid']);
} }

@ -153,8 +153,9 @@ class Test_Files_Sharing_S2S_OCS_API extends TestCase {
\OC::$server->getDatabaseConnection(), \OC::$server->getDatabaseConnection(),
\OC\Files\Filesystem::getMountManager(), \OC\Files\Filesystem::getMountManager(),
\OC\Files\Filesystem::getLoader(), \OC\Files\Filesystem::getLoader(),
\OC::$server->getUserSession(), \OC::$server->getHTTPHelper(),
\OC::$server->getHTTPHelper()); $toDelete
);
$manager->removeUserShares($toDelete); $manager->removeUserShares($toDelete);

@ -16,15 +16,22 @@ use OCP\ICertificateManager;
*/ */
class CertificateManager implements ICertificateManager { class CertificateManager implements ICertificateManager {
/** /**
* @var \OCP\IUser * @var string
*/ */
protected $user; protected $uid;
/** /**
* @param \OCP\IUser $user * @var \OC\Files\View
*/ */
public function __construct($user) { protected $view;
$this->user = $user;
/**
* @param string $uid
* @param \OC\Files\View $view relative zu data/
*/
public function __construct($uid, \OC\Files\View $view) {
$this->uid = $uid;
$this->view = $view;
} }
/** /**
@ -34,18 +41,18 @@ class CertificateManager implements ICertificateManager {
*/ */
public function listCertificates() { public function listCertificates() {
$path = $this->getPathToCertificates() . 'uploads/'; $path = $this->getPathToCertificates() . 'uploads/';
if (!is_dir($path)) { if (!$this->view->is_dir($path)) {
return array(); return array();
} }
$result = array(); $result = array();
$handle = opendir($path); $handle = $this->view->opendir($path);
if (!is_resource($handle)) { if (!is_resource($handle)) {
return array(); return array();
} }
while (false !== ($file = readdir($handle))) { while (false !== ($file = readdir($handle))) {
if ($file != '.' && $file != '..') { if ($file != '.' && $file != '..') {
try { try {
$result[] = new Certificate(file_get_contents($path . $file), $file); $result[] = new Certificate($this->view->file_get_contents($path . $file), $file);
} catch(\Exception $e) {} } catch(\Exception $e) {}
} }
} }
@ -60,10 +67,10 @@ class CertificateManager implements ICertificateManager {
$path = $this->getPathToCertificates(); $path = $this->getPathToCertificates();
$certs = $this->listCertificates(); $certs = $this->listCertificates();
$fh_certs = fopen($path . '/rootcerts.crt', 'w'); $fh_certs = $this->view->fopen($path . '/rootcerts.crt', 'w');
foreach ($certs as $cert) { foreach ($certs as $cert) {
$file = $path . '/uploads/' . $cert->getName(); $file = $path . '/uploads/' . $cert->getName();
$data = file_get_contents($file); $data = $this->view->file_get_contents($file);
if (strpos($data, 'BEGIN CERTIFICATE')) { if (strpos($data, 'BEGIN CERTIFICATE')) {
fwrite($fh_certs, $data); fwrite($fh_certs, $data);
fwrite($fh_certs, "\r\n"); fwrite($fh_certs, "\r\n");
@ -87,17 +94,14 @@ class CertificateManager implements ICertificateManager {
} }
$dir = $this->getPathToCertificates() . 'uploads/'; $dir = $this->getPathToCertificates() . 'uploads/';
if (!file_exists($dir)) { if (!$this->view->file_exists($dir)) {
//path might not exist (e.g. non-standard OC_User::getHome() value) $this->view->mkdir($dir);
//in this case create full path using 3rd (recursive=true) parameter.
//note that we use "normal" php filesystem functions here since the certs need to be local
mkdir($dir, 0700, true);
} }
try { try {
$file = $dir . $name; $file = $dir . $name;
$certificateObject = new Certificate($certificate, $name); $certificateObject = new Certificate($certificate, $name);
file_put_contents($file, $certificate); $this->view->file_put_contents($file, $certificate);
$this->createCertificateBundle(); $this->createCertificateBundle();
return $certificateObject; return $certificateObject;
} catch (\Exception $e) { } catch (\Exception $e) {
@ -117,8 +121,8 @@ class CertificateManager implements ICertificateManager {
return false; return false;
} }
$path = $this->getPathToCertificates() . 'uploads/'; $path = $this->getPathToCertificates() . 'uploads/';
if (file_exists($path . $name)) { if ($this->view->file_exists($path . $name)) {
unlink($path . $name); $this->view->unlink($path . $name);
$this->createCertificateBundle(); $this->createCertificateBundle();
} }
return true; return true;
@ -134,7 +138,7 @@ class CertificateManager implements ICertificateManager {
} }
private function getPathToCertificates() { private function getPathToCertificates() {
$path = $this->user ? $this->user->getHome() . '/files_external/' : '/files_external/'; $path = is_null($this->uid) ? '/files_external/' : '/' . $this->uid . '/files_external/';
return $path; return $path;
} }

@ -249,7 +249,9 @@ class Server extends SimpleContainer implements IServerContainer {
}); });
$this->registerService('HTTPHelper', function (Server $c) { $this->registerService('HTTPHelper', function (Server $c) {
$config = $c->getConfig(); $config = $c->getConfig();
return new HTTPHelper($config, new \OC\Security\CertificateManager($c->getUserSession()->getUser())); $user = $c->getUserSession()->getUser();
$uid = $user ? $user->getUID() : null;
return new HTTPHelper($config, new \OC\Security\CertificateManager($uid, new \OC\Files\View()));
}); });
$this->registerService('EventLogger', function (Server $c) { $this->registerService('EventLogger', function (Server $c) {
if (defined('DEBUG') and DEBUG) { if (defined('DEBUG') and DEBUG) {
@ -631,18 +633,19 @@ class Server extends SimpleContainer implements IServerContainer {
/** /**
* Get the certificate manager for the user * Get the certificate manager for the user
* *
* @param \OCP\IUser $user (optional) if not specified the current loggedin user is used * @param string $uid (optional) if not specified the current loggedin user is used
* @return \OCP\ICertificateManager * @return \OCP\ICertificateManager
*/ */
function getCertificateManager($user = null) { function getCertificateManager($uid = null) {
if (is_null($user)) { if (is_null($uid)) {
$userSession = $this->getUserSession(); $userSession = $this->getUserSession();
$user = $userSession->getUser(); $user = $userSession->getUser();
if (is_null($user)) { if (is_null($user)) {
return null; return null;
} }
$uid = $user->getUID();
} }
return new CertificateManager($user); return new CertificateManager($uid, new \OC\Files\View());
} }
/** /**

@ -28,9 +28,7 @@ class CertificateManagerTest extends \Test\TestCase {
\OC\Files\Filesystem::tearDown(); \OC\Files\Filesystem::tearDown();
\OC_Util::setupFS($this->username); \OC_Util::setupFS($this->username);
$this->user = \OC::$server->getUserManager()->get($this->username); $this->certificateManager = new CertificateManager($this->username, new \OC\Files\View());
$this->certificateManager = new CertificateManager($this->user);
} }
protected function tearDown() { protected function tearDown() {
@ -84,7 +82,7 @@ class CertificateManagerTest extends \Test\TestCase {
} }
function testGetCertificateBundle() { function testGetCertificateBundle() {
$this->assertSame($this->user->getHome().'/files_external/rootcerts.crt', $this->certificateManager->getCertificateBundle()); $this->assertSame('/' . $this->username . '/files_external/rootcerts.crt', $this->certificateManager->getCertificateBundle());
} }
} }

Loading…
Cancel
Save