From 08a46e30806434bcd854f7868c3c9c6553d4ac11 Mon Sep 17 00:00:00 2001 From: adrien Date: Thu, 6 Mar 2014 17:57:09 +0100 Subject: add cache for single users --- lib/private/user/database.php | 78 +++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 33 deletions(-) (limited to 'lib/private') diff --git a/lib/private/user/database.php b/lib/private/user/database.php index 15e6643dfb3..911073c133e 100644 --- a/lib/private/user/database.php +++ b/lib/private/user/database.php @@ -42,7 +42,9 @@ class OC_User_Database extends OC_User_Backend { /** * @var PasswordHash */ - static private $hasher = null; + private static $hasher = null; + + protected static $cache = array(); private function getHasher() { if (!self::$hasher) { @@ -135,11 +137,9 @@ class OC_User_Database extends OC_User_Backend { * @return string display name */ public function getDisplayName($uid) { - $query = OC_DB::prepare('SELECT `displayname` FROM `*PREFIX*users` WHERE `uid` = ?'); - $result = $query->execute(array($uid))->fetchAll(); - $displayName = trim($result[0]['displayname'], ' '); - if (!empty($displayName)) { - return $displayName; + $this->loadUser($uid); + if (!empty(self::$cache['uid']['displayname'])) { + return self::$cache['uid']['displayname']; } else { return $uid; } @@ -183,23 +183,41 @@ class OC_User_Database extends OC_User_Backend { $storedHash = $row['password']; if ($storedHash[0] == '$') { //the new phpass based hashing $hasher = $this->getHasher(); - if ($hasher->CheckPassword($password . OC_Config::getValue('passwordsalt', ''), $storedHash)) { - return $row['uid']; - } else { - return false; - } - } else { //old sha1 based hashing - if (sha1($password) == $storedHash) { - //upgrade to new hashing - $this->setPassword($row['uid'], $password); + if ($hasher->CheckPassword($password . OC_Config::getValue('passwordsalt', ''), $storedHash)) return $row['uid']; - } else { - return false; - } + + //old sha1 based hashing + } elseif (sha1($password) == $storedHash) { + //upgrade to new hashing + $this->setPassword($row['uid'], $password); + return $row['uid']; + } + } + + return false; + } + + /** + * @brief Load an user in the cache + * @returns boolean + */ + protected function loadUser($uid) { + if (empty(self::$cache[$uid])) { + $query = OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users` WHERE LOWER(`uid`) = LOWER(?)'); + $result = $query->execute(array($uid)); + + if (OC_DB::isError($result)) { + OC_Log::write('core', OC_DB::getErrorMessage($result), OC_Log::ERROR); + return false; + } + + while ($row = $result->fetchRow()) { + self::$cache[$uid]['uid'] = $row['uid']; + self::$cache[$uid]['displayname'] = $row['displayname']; } - } else { - return false; } + + return true; } /** @@ -224,26 +242,20 @@ class OC_User_Database extends OC_User_Backend { * @return boolean */ public function userExists($uid) { - $query = OC_DB::prepare('SELECT COUNT(*) FROM `*PREFIX*users` WHERE LOWER(`uid`) = LOWER(?)'); - $result = $query->execute(array($uid)); - if (OC_DB::isError($result)) { - OC_Log::write('core', OC_DB::getErrorMessage($result), OC_Log::ERROR); - return false; - } - return $result->fetchOne() > 0; + $this->loadUser($uid); + return empty(self::$cache[$uid]) ? false : true; } /** * @brief get the user's home directory * @param string $uid the username - * @return string|false + * @return boolean */ public function getHome($uid) { - if ($this->userExists($uid)) { + if ($this->userExists($uid)) return OC_Config::getValue("datadirectory", OC::$SERVERROOT . "/data") . '/' . $uid; - } else { - return false; - } + + return false; } /** @@ -256,7 +268,7 @@ class OC_User_Database extends OC_User_Backend { /** * counts the users in the database * - * @return false|string | bool + * @return int | bool */ public function countUsers() { $query = OC_DB::prepare('SELECT COUNT(*) FROM `*PREFIX*users`'); -- cgit v1.2.3 From dde4f2f91720a5eb4ad7db4fdb15dfc115f0e8c0 Mon Sep 17 00:00:00 2001 From: adrien Date: Thu, 6 Mar 2014 22:23:17 +0100 Subject: upgrade the cache user --- lib/private/user/database.php | 52 +++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 14 deletions(-) (limited to 'lib/private') diff --git a/lib/private/user/database.php b/lib/private/user/database.php index 911073c133e..1e3d457eb50 100644 --- a/lib/private/user/database.php +++ b/lib/private/user/database.php @@ -39,13 +39,15 @@ require_once 'phpass/PasswordHash.php'; * Class for user management in a SQL Database (e.g. MySQL, SQLite) */ class OC_User_Database extends OC_User_Backend { + + protected static $cache = array(); + protected static $cache_complete = true; + /** * @var PasswordHash */ private static $hasher = null; - protected static $cache = array(); - private function getHasher() { if (!self::$hasher) { //we don't want to use DES based crypt(), since it doesn't return a hash with a recognisable prefix @@ -199,6 +201,7 @@ class OC_User_Database extends OC_User_Backend { /** * @brief Load an user in the cache + * @param string $uid the username * @returns boolean */ protected function loadUser($uid) { @@ -220,6 +223,32 @@ class OC_User_Database extends OC_User_Backend { return true; } + /** + * @brief Load an user in the cache + * @param string $uid the username + * @returns boolean + */ + protected function loadUsers() { + if (!self::$cache_complete) { + $query = OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users` ORDER BY `uid`'); + $result = $query->execute(array($uid)); + + if (OC_DB::isError($result)) { + OC_Log::write('core', OC_DB::getErrorMessage($result), OC_Log::ERROR); + return false; + } + + while ($row = $result->fetchRow()) { + self::$cache[$uid]['uid'] = $row['uid']; + self::$cache[$uid]['displayname'] = $row['displayname']; + } + + self::$cache_complete = true; + } + + return true; + } + /** * @brief Get a list of all users * @returns array with all uids @@ -227,12 +256,12 @@ class OC_User_Database extends OC_User_Backend { * Get a list of all users. */ public function getUsers($search = '', $limit = null, $offset = null) { - $query = OC_DB::prepare('SELECT `uid` FROM `*PREFIX*users` WHERE LOWER(`uid`) LIKE LOWER(?)', $limit, $offset); - $result = $query->execute(array($search . '%')); + $this->loadUsers(); + $users = array(); - while ($row = $result->fetchRow()) { - $users[] = $row['uid']; - } + foreach (self::$cache as $uid => $value) + $users[] = $uid; + return $users; } @@ -271,13 +300,8 @@ class OC_User_Database extends OC_User_Backend { * @return int | bool */ public function countUsers() { - $query = OC_DB::prepare('SELECT COUNT(*) FROM `*PREFIX*users`'); - $result = $query->execute(); - if (OC_DB::isError($result)) { - OC_Log::write('core', OC_DB::getErrorMessage($result), OC_Log::ERROR); - return false; - } - return $result->fetchOne(); + $this->loadUsers(); + return count(self::$cache); } } -- cgit v1.2.3 From 5cdfc56867d0fe8dc5be9e2112c53e3ddf212104 Mon Sep 17 00:00:00 2001 From: adrien Date: Thu, 6 Mar 2014 22:34:43 +0100 Subject: update the cache when add user --- lib/private/user/database.php | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'lib/private') diff --git a/lib/private/user/database.php b/lib/private/user/database.php index 1e3d457eb50..bbd72fc65e7 100644 --- a/lib/private/user/database.php +++ b/lib/private/user/database.php @@ -39,15 +39,14 @@ require_once 'phpass/PasswordHash.php'; * Class for user management in a SQL Database (e.g. MySQL, SQLite) */ class OC_User_Database extends OC_User_Backend { - - protected static $cache = array(); - protected static $cache_complete = true; - /** * @var PasswordHash */ private static $hasher = null; + protected static $cache = array(); + protected static $cache_complete = false; + private function getHasher() { if (!self::$hasher) { //we don't want to use DES based crypt(), since it doesn't return a hash with a recognisable prefix @@ -68,16 +67,19 @@ class OC_User_Database extends OC_User_Backend { * itself, not in its subclasses. */ public function createUser($uid, $password) { - if ($this->userExists($uid)) { - return false; - } else { + if (!$this->userExists($uid)) { $hasher = $this->getHasher(); $hash = $hasher->HashPassword($password . OC_Config::getValue('passwordsalt', '')); $query = OC_DB::prepare('INSERT INTO `*PREFIX*users` ( `uid`, `password` ) VALUES( ?, ? )'); $result = $query->execute(array($uid, $hash)); - - return $result ? true : false; + + if ($result) { + self::$cache[$uid]['uid'] = $uid; + return true; + } } + + return false; } /** @@ -127,10 +129,11 @@ class OC_User_Database extends OC_User_Backend { if ($this->userExists($uid)) { $query = OC_DB::prepare('UPDATE `*PREFIX*users` SET `displayname` = ? WHERE LOWER(`uid`) = ?'); $query->execute(array($displayName, $uid)); + self::$cache[$uid]['displayname'] = $displayName; return true; - } else { - return false; } + + return false; } /** @@ -140,8 +143,8 @@ class OC_User_Database extends OC_User_Backend { */ public function getDisplayName($uid) { $this->loadUser($uid); - if (!empty(self::$cache['uid']['displayname'])) { - return self::$cache['uid']['displayname']; + if (!empty(self::$cache[$uid]['displayname'])) { + return self::$cache[$uid]['displayname']; } else { return $uid; } -- cgit v1.2.3 From fbde24c89ae61294bb6327ccc2b5b150b2ec4928 Mon Sep 17 00:00:00 2001 From: adrien Date: Fri, 7 Mar 2014 08:46:34 +0100 Subject: fix undefined in loadUsers --- lib/private/user/database.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'lib/private') diff --git a/lib/private/user/database.php b/lib/private/user/database.php index bbd72fc65e7..80d52feffc8 100644 --- a/lib/private/user/database.php +++ b/lib/private/user/database.php @@ -54,7 +54,6 @@ class OC_User_Database extends OC_User_Backend { self::$hasher = new PasswordHash(8, $forcePortable); } return self::$hasher; - } /** @@ -112,9 +111,9 @@ class OC_User_Database extends OC_User_Backend { $query->execute(array($hash, $uid)); return true; - } else { - return false; } + + return false; } /** @@ -188,8 +187,9 @@ class OC_User_Database extends OC_User_Backend { $storedHash = $row['password']; if ($storedHash[0] == '$') { //the new phpass based hashing $hasher = $this->getHasher(); - if ($hasher->CheckPassword($password . OC_Config::getValue('passwordsalt', ''), $storedHash)) + if ($hasher->CheckPassword($password . OC_Config::getValue('passwordsalt', ''), $storedHash)) { return $row['uid']; + } //old sha1 based hashing } elseif (sha1($password) == $storedHash) { @@ -234,7 +234,7 @@ class OC_User_Database extends OC_User_Backend { protected function loadUsers() { if (!self::$cache_complete) { $query = OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users` ORDER BY `uid`'); - $result = $query->execute(array($uid)); + $result = $query->execute(); if (OC_DB::isError($result)) { OC_Log::write('core', OC_DB::getErrorMessage($result), OC_Log::ERROR); @@ -262,8 +262,9 @@ class OC_User_Database extends OC_User_Backend { $this->loadUsers(); $users = array(); - foreach (self::$cache as $uid => $value) + foreach (self::$cache as $uid => $value) { $users[] = $uid; + } return $users; } @@ -281,11 +282,12 @@ class OC_User_Database extends OC_User_Backend { /** * @brief get the user's home directory * @param string $uid the username - * @return boolean + * @return string|false */ public function getHome($uid) { - if ($this->userExists($uid)) + if ($this->userExists($uid)) { return OC_Config::getValue("datadirectory", OC::$SERVERROOT . "/data") . '/' . $uid; + } return false; } -- cgit v1.2.3 From d8843f6cd3b37bc7e95b5baa437d7087b09fc6fd Mon Sep 17 00:00:00 2001 From: nishiki Date: Sun, 9 Mar 2014 12:01:35 +0100 Subject: minor clean code --- lib/private/user/database.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/private') diff --git a/lib/private/user/database.php b/lib/private/user/database.php index 80d52feffc8..c472c5445b7 100644 --- a/lib/private/user/database.php +++ b/lib/private/user/database.php @@ -276,7 +276,7 @@ class OC_User_Database extends OC_User_Backend { */ public function userExists($uid) { $this->loadUser($uid); - return empty(self::$cache[$uid]) ? false : true; + return !empty(self::$cache[$uid]); } /** -- cgit v1.2.3 From 75011c2e09e2ee7e9c76a86e938c4d8656225352 Mon Sep 17 00:00:00 2001 From: nishiki Date: Sun, 9 Mar 2014 12:22:47 +0100 Subject: add query result (boolean) for update or delete --- lib/private/user/database.php | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'lib/private') diff --git a/lib/private/user/database.php b/lib/private/user/database.php index c472c5445b7..57ecdda9dad 100644 --- a/lib/private/user/database.php +++ b/lib/private/user/database.php @@ -91,8 +91,9 @@ class OC_User_Database extends OC_User_Backend { public function deleteUser($uid) { // Delete user-group-relation $query = OC_DB::prepare('DELETE FROM `*PREFIX*users` WHERE `uid` = ?'); - $query->execute(array($uid)); - return true; + $result = $query->execute(array($uid)); + + return $result ? true : false; } /** @@ -108,9 +109,9 @@ class OC_User_Database extends OC_User_Backend { $hasher = $this->getHasher(); $hash = $hasher->HashPassword($password . OC_Config::getValue('passwordsalt', '')); $query = OC_DB::prepare('UPDATE `*PREFIX*users` SET `password` = ? WHERE `uid` = ?'); - $query->execute(array($hash, $uid)); + $result = $query->execute(array($hash, $uid)); - return true; + return $result ? true : false; } return false; @@ -142,11 +143,7 @@ class OC_User_Database extends OC_User_Backend { */ public function getDisplayName($uid) { $this->loadUser($uid); - if (!empty(self::$cache[$uid]['displayname'])) { - return self::$cache[$uid]['displayname']; - } else { - return $uid; - } + return empty(self::$cache[$uid]['displayname']) ? $uid : self::$cache[$uid]['displayname']; } /** -- cgit v1.2.3 From ba9d8f7c1a448e0a769ee31d20ee75c1616b22e7 Mon Sep 17 00:00:00 2001 From: nishiki Date: Sun, 9 Mar 2014 12:47:19 +0100 Subject: fix undifined uid --- lib/private/user/database.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/private') diff --git a/lib/private/user/database.php b/lib/private/user/database.php index 57ecdda9dad..591ea2a5c98 100644 --- a/lib/private/user/database.php +++ b/lib/private/user/database.php @@ -239,7 +239,8 @@ class OC_User_Database extends OC_User_Backend { } while ($row = $result->fetchRow()) { - self::$cache[$uid]['uid'] = $row['uid']; + $uid = $row['uid']; + self::$cache[$uid]['uid'] = $uid; self::$cache[$uid]['displayname'] = $row['displayname']; } -- cgit v1.2.3 From 415b1d03bca12c082ff70e44d3b7b8b3fbc8f347 Mon Sep 17 00:00:00 2001 From: adrien Date: Mon, 10 Mar 2014 17:27:51 +0100 Subject: fix cache when remove an user --- lib/private/user/database.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'lib/private') diff --git a/lib/private/user/database.php b/lib/private/user/database.php index 591ea2a5c98..4a9ad1b825e 100644 --- a/lib/private/user/database.php +++ b/lib/private/user/database.php @@ -93,7 +93,14 @@ class OC_User_Database extends OC_User_Backend { $query = OC_DB::prepare('DELETE FROM `*PREFIX*users` WHERE `uid` = ?'); $result = $query->execute(array($uid)); - return $result ? true : false; + if ($result) { + if (isset(self::$cache[$uid])) { + unset(self::$cache[$uid]); + } + return true; + } + + return false; } /** -- cgit v1.2.3 From f827761e7111d4f3b082074facef31efd74939e7 Mon Sep 17 00:00:00 2001 From: adrien Date: Tue, 11 Mar 2014 11:56:46 +0100 Subject: remove static variable, add limit and offset --- lib/private/user/database.php | 80 +++++++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 29 deletions(-) (limited to 'lib/private') diff --git a/lib/private/user/database.php b/lib/private/user/database.php index 4a9ad1b825e..5df9c9e2b42 100644 --- a/lib/private/user/database.php +++ b/lib/private/user/database.php @@ -44,8 +44,8 @@ class OC_User_Database extends OC_User_Backend { */ private static $hasher = null; - protected static $cache = array(); - protected static $cache_complete = false; + private $cache = array(); + private $cache_complete = false; private function getHasher() { if (!self::$hasher) { @@ -73,7 +73,7 @@ class OC_User_Database extends OC_User_Backend { $result = $query->execute(array($uid, $hash)); if ($result) { - self::$cache[$uid]['uid'] = $uid; + $this->cache[$uid]['uid'] = $uid; return true; } } @@ -94,8 +94,8 @@ class OC_User_Database extends OC_User_Backend { $result = $query->execute(array($uid)); if ($result) { - if (isset(self::$cache[$uid])) { - unset(self::$cache[$uid]); + if (isset($this->cache[$uid])) { + unset($this->cache[$uid]); } return true; } @@ -136,7 +136,8 @@ class OC_User_Database extends OC_User_Backend { if ($this->userExists($uid)) { $query = OC_DB::prepare('UPDATE `*PREFIX*users` SET `displayname` = ? WHERE LOWER(`uid`) = ?'); $query->execute(array($displayName, $uid)); - self::$cache[$uid]['displayname'] = $displayName; + $this->cache[$uid]['displayname'] = $displayName; + return true; } @@ -150,7 +151,7 @@ class OC_User_Database extends OC_User_Backend { */ public function getDisplayName($uid) { $this->loadUser($uid); - return empty(self::$cache[$uid]['displayname']) ? $uid : self::$cache[$uid]['displayname']; + return empty($this->cache[$uid]['displayname']) ? $uid : $this->cache[$uid]['displayname']; } /** @@ -159,15 +160,24 @@ class OC_User_Database extends OC_User_Backend { * * Get a list of all display names and user ids. */ - public function getDisplayNames($search = '', $limit = null, $offset = null) { + public function getDisplayNames($search = '', $limit = null, $offset = 0) { + $this->loadUsers(); + + $search = strtolower($search); + $i = 0; + $displayNames = array(); - $query = OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users`' - . ' WHERE LOWER(`displayname`) LIKE LOWER(?) OR ' - . 'LOWER(`uid`) LIKE LOWER(?)', $limit, $offset); - $result = $query->execute(array($search . '%', $search . '%')); - $users = array(); - while ($row = $result->fetchRow()) { - $displayNames[$row['uid']] = $row['displayname']; + foreach ($this->cache as $uid => $value) { + if ((preg_match('/^.*'.$search.'.*/', strtolower($uid)) || preg_match('/^.*'.$search.'.*/', strtolower($value['displayname']))) && $offset <= $i) { + $displayNames[$uid] = $value['displayname']; + if (!is_null($limit)) { + $limit--; + if ($limit <= 0) { + break; + } + } + } + $i++; } return $displayNames; @@ -211,8 +221,8 @@ class OC_User_Database extends OC_User_Backend { * @param string $uid the username * @returns boolean */ - protected function loadUser($uid) { - if (empty(self::$cache[$uid])) { + private function loadUser($uid) { + if (empty($this->cache[$uid])) { $query = OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users` WHERE LOWER(`uid`) = LOWER(?)'); $result = $query->execute(array($uid)); @@ -222,8 +232,8 @@ class OC_User_Database extends OC_User_Backend { } while ($row = $result->fetchRow()) { - self::$cache[$uid]['uid'] = $row['uid']; - self::$cache[$uid]['displayname'] = $row['displayname']; + $this->cache[$uid]['uid'] = $row['uid']; + $this->cache[$uid]['displayname'] = $row['displayname']; } } @@ -235,8 +245,8 @@ class OC_User_Database extends OC_User_Backend { * @param string $uid the username * @returns boolean */ - protected function loadUsers() { - if (!self::$cache_complete) { + private function loadUsers() { + if (!$this->cache_complete) { $query = OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users` ORDER BY `uid`'); $result = $query->execute(); @@ -247,11 +257,11 @@ class OC_User_Database extends OC_User_Backend { while ($row = $result->fetchRow()) { $uid = $row['uid']; - self::$cache[$uid]['uid'] = $uid; - self::$cache[$uid]['displayname'] = $row['displayname']; + $this->cache[$uid]['uid'] = $uid; + $this->cache[$uid]['displayname'] = $row['displayname']; } - self::$cache_complete = true; + $this->cache_complete = true; } return true; @@ -263,12 +273,24 @@ class OC_User_Database extends OC_User_Backend { * * Get a list of all users. */ - public function getUsers($search = '', $limit = null, $offset = null) { + public function getUsers($search = '', $limit = null, $offset = 0) { $this->loadUsers(); + $search = strtolower($search); + $i = 0; + $users = array(); - foreach (self::$cache as $uid => $value) { - $users[] = $uid; + foreach ($this->cache as $uid => $value) { + if (preg_match('/^'.$search.'.*/', strtolower($uid)) && $offset <= $i) { + $users[] = $uid; + if (!is_null($limit)) { + $limit--; + if ($limit <= 0) { + break; + } + } + } + $i++; } return $users; @@ -281,7 +303,7 @@ class OC_User_Database extends OC_User_Backend { */ public function userExists($uid) { $this->loadUser($uid); - return !empty(self::$cache[$uid]); + return !empty($this->cache[$uid]); } /** @@ -311,7 +333,7 @@ class OC_User_Database extends OC_User_Backend { */ public function countUsers() { $this->loadUsers(); - return count(self::$cache); + return count($this->cache); } } -- cgit v1.2.3 From ea6f8ba352ac7b3c9069407d6f64664ddee81c4d Mon Sep 17 00:00:00 2001 From: adrien Date: Tue, 11 Mar 2014 16:58:10 +0100 Subject: fix remove cache when delete --- lib/private/user/database.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'lib/private') diff --git a/lib/private/user/database.php b/lib/private/user/database.php index 5df9c9e2b42..683ba90e558 100644 --- a/lib/private/user/database.php +++ b/lib/private/user/database.php @@ -93,14 +93,11 @@ class OC_User_Database extends OC_User_Backend { $query = OC_DB::prepare('DELETE FROM `*PREFIX*users` WHERE `uid` = ?'); $result = $query->execute(array($uid)); - if ($result) { - if (isset($this->cache[$uid])) { - unset($this->cache[$uid]); - } - return true; + if (isset($this->cache[$uid])) { + unset($this->cache[$uid]); } - return false; + return $result ? true : false; } /** -- cgit v1.2.3 From 0da61a26ee842e611f33d32109572c70bbc170b1 Mon Sep 17 00:00:00 2001 From: adrien Date: Fri, 21 Mar 2014 15:50:25 +0100 Subject: remove cache all user --- lib/private/user/database.php | 92 +++++++++++-------------------------------- 1 file changed, 22 insertions(+), 70 deletions(-) (limited to 'lib/private') diff --git a/lib/private/user/database.php b/lib/private/user/database.php index 683ba90e558..706982bb75d 100644 --- a/lib/private/user/database.php +++ b/lib/private/user/database.php @@ -45,7 +45,6 @@ class OC_User_Database extends OC_User_Backend { private static $hasher = null; private $cache = array(); - private $cache_complete = false; private function getHasher() { if (!self::$hasher) { @@ -71,11 +70,8 @@ class OC_User_Database extends OC_User_Backend { $hash = $hasher->HashPassword($password . OC_Config::getValue('passwordsalt', '')); $query = OC_DB::prepare('INSERT INTO `*PREFIX*users` ( `uid`, `password` ) VALUES( ?, ? )'); $result = $query->execute(array($uid, $hash)); - - if ($result) { - $this->cache[$uid]['uid'] = $uid; - return true; - } + + return $result ? true : false; } return false; @@ -157,24 +153,15 @@ class OC_User_Database extends OC_User_Backend { * * Get a list of all display names and user ids. */ - public function getDisplayNames($search = '', $limit = null, $offset = 0) { - $this->loadUsers(); - - $search = strtolower($search); - $i = 0; - + public function getDisplayNames($search = '', $limit = null, $offset = null) { $displayNames = array(); - foreach ($this->cache as $uid => $value) { - if ((preg_match('/^.*'.$search.'.*/', strtolower($uid)) || preg_match('/^.*'.$search.'.*/', strtolower($value['displayname']))) && $offset <= $i) { - $displayNames[$uid] = $value['displayname']; - if (!is_null($limit)) { - $limit--; - if ($limit <= 0) { - break; - } - } - } - $i++; + $query = OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users`' + . ' WHERE LOWER(`displayname`) LIKE LOWER(?) OR ' + . 'LOWER(`uid`) LIKE LOWER(?)', $limit, $offset); + $result = $query->execute(array($search . '%', $search . '%')); + $users = array(); + while ($row = $result->fetchRow()) { + $displayNames[$row['uid']] = $row['displayname']; } return $displayNames; @@ -237,59 +224,19 @@ class OC_User_Database extends OC_User_Backend { return true; } - /** - * @brief Load an user in the cache - * @param string $uid the username - * @returns boolean - */ - private function loadUsers() { - if (!$this->cache_complete) { - $query = OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users` ORDER BY `uid`'); - $result = $query->execute(); - - if (OC_DB::isError($result)) { - OC_Log::write('core', OC_DB::getErrorMessage($result), OC_Log::ERROR); - return false; - } - - while ($row = $result->fetchRow()) { - $uid = $row['uid']; - $this->cache[$uid]['uid'] = $uid; - $this->cache[$uid]['displayname'] = $row['displayname']; - } - - $this->cache_complete = true; - } - - return true; - } - /** * @brief Get a list of all users * @returns array with all uids * * Get a list of all users. */ - public function getUsers($search = '', $limit = null, $offset = 0) { - $this->loadUsers(); - - $search = strtolower($search); - $i = 0; - + public function getUsers($search = '', $limit = null, $offset = null) { + $query = OC_DB::prepare('SELECT `uid` FROM `*PREFIX*users` WHERE LOWER(`uid`) LIKE LOWER(?)', $limit, $offset); + $result = $query->execute(array($search . '%')); $users = array(); - foreach ($this->cache as $uid => $value) { - if (preg_match('/^'.$search.'.*/', strtolower($uid)) && $offset <= $i) { - $users[] = $uid; - if (!is_null($limit)) { - $limit--; - if ($limit <= 0) { - break; - } - } - } - $i++; + while ($row = $result->fetchRow()) { + $users[] = $row['uid']; } - return $users; } @@ -329,8 +276,13 @@ class OC_User_Database extends OC_User_Backend { * @return int | bool */ public function countUsers() { - $this->loadUsers(); - return count($this->cache); + $query = OC_DB::prepare('SELECT COUNT(*) FROM `*PREFIX*users`'); + $result = $query->execute(); + if (OC_DB::isError($result)) { + OC_Log::write('core', OC_DB::getErrorMessage($result), OC_Log::ERROR); + return false; + } + return $result->fetchOne(); } } -- cgit v1.2.3 From 015b9b1dac1e7f90e4e28d2b19697bedf83e56fe Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 2 Apr 2014 12:54:41 +0200 Subject: Add option to getUsersSharingFile() to get the paths for the shared users --- lib/private/share/share.php | 61 +++++++++++++++++++++++++++++++++++++-------- lib/public/share.php | 7 +++--- 2 files changed, 54 insertions(+), 14 deletions(-) (limited to 'lib/private') diff --git a/lib/private/share/share.php b/lib/private/share/share.php index 7bab98b00bf..3d22f6fd450 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -91,23 +91,25 @@ class Share extends \OC\Share\Constants { /** * Find which users can access a shared item - * @param $path to the file - * @param $user owner of the file - * @param include owner to the list of users with access to the file + * @param string $path to the file + * @param string $ownerUser owner of the file + * @param bool $includeOwner include owner to the list of users with access to the file + * @param bool $returnUserPaths Return an array with the user => path map * @return array * @note $path needs to be relative to user data dir, e.g. 'file.txt' * not '/admin/data/file.txt' */ - public static function getUsersSharingFile($path, $user, $includeOwner = false) { + public static function getUsersSharingFile($path, $ownerUser, $includeOwner = false, $returnUserPaths = false) { - $shares = array(); + $shares = $sharePaths = $fileTargets = array(); $publicShare = false; $source = -1; $cache = false; - $view = new \OC\Files\View('/' . $user . '/files'); + $view = new \OC\Files\View('/' . $ownerUser . '/files'); if ($view->file_exists($path)) { $meta = $view->getFileInfo($path); + $path = substr($meta->getPath(), strlen('/' . $ownerUser . '/files')); } else { // if the file doesn't exists yet we start with the parent folder $meta = $view->getFileInfo(dirname($path)); @@ -119,10 +121,9 @@ class Share extends \OC\Share\Constants { } while ($source !== -1) { - // Fetch all shares with another user $query = \OC_DB::prepare( - 'SELECT `share_with` + 'SELECT `share_with`, `file_source`, `file_target` FROM `*PREFIX*share` WHERE @@ -136,12 +137,15 @@ class Share extends \OC\Share\Constants { } else { while ($row = $result->fetchRow()) { $shares[] = $row['share_with']; + if ($returnUserPaths) { + $fileTargets[(int) $row['file_source']][$row['share_with']] = $row; + } } } - // We also need to take group shares into account + // We also need to take group shares into account $query = \OC_DB::prepare( - 'SELECT `share_with` + 'SELECT `share_with`, `file_source`, `file_target` FROM `*PREFIX*share` WHERE @@ -156,6 +160,11 @@ class Share extends \OC\Share\Constants { while ($row = $result->fetchRow()) { $usersInGroup = \OC_Group::usersInGroup($row['share_with']); $shares = array_merge($shares, $usersInGroup); + if ($returnUserPaths) { + foreach ($usersInGroup as $user) { + $fileTargets[(int) $row['file_source']][$user] = $row; + } + } } } @@ -188,9 +197,39 @@ class Share extends \OC\Share\Constants { $source = -1; } } + // Include owner in list of users, if requested if ($includeOwner) { - $shares[] = $user; + $shares[] = $ownerUser; + if ($returnUserPaths) { + $sharePaths[$ownerUser] = $path; + } + } + + if ($returnUserPaths) { + $fileTargetIDs = array_keys($fileTargets); + $fileTargetIDs = array_unique($fileTargetIDs); + + $query = \OC_DB::prepare( + 'SELECT `fileid`, `path` + FROM `*PREFIX*filecache` + WHERE `fileid` IN (' . implode(',', $fileTargetIDs) . ')' + ); + $result = $query->execute(); + + if (\OCP\DB::isError($result)) { + \OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage($result), \OC_Log::ERROR); + } else { + while ($row = $result->fetchRow()) { + foreach ($fileTargets[$row['fileid']] as $uid => $shareData) { + $sharedPath = '/Shared' . $shareData['file_target']; + $sharedPath .= substr($path, strlen($row['path']) -5); + $sharePaths[$uid] = $sharedPath; + } + } + } + + return $sharePaths; } return array("users" => array_unique($shares), "public" => $publicShare); diff --git a/lib/public/share.php b/lib/public/share.php index 564839e86b6..c694314ad08 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -64,14 +64,15 @@ class Share extends \OC\Share\Constants { /** * Find which users can access a shared item * @param string $path to the file - * @param string $user owner of the file + * @param string $ownerUser owner of the file * @param bool $includeOwner include owner to the list of users with access to the file + * @param bool $returnUserPaths Return an array with the user => path map * @return array * @note $path needs to be relative to user data dir, e.g. 'file.txt' * not '/admin/data/file.txt' */ - public static function getUsersSharingFile($path, $user, $includeOwner = false) { - return \OC\Share\Share::getUsersSharingFile($path, $user, $includeOwner); + public static function getUsersSharingFile($path, $ownerUser, $includeOwner = false, $returnUserPaths = false) { + return \OC\Share\Share::getUsersSharingFile($path, $ownerUser, $includeOwner, $returnUserPaths); } /** -- cgit v1.2.3 From d418e176ce4ce3ee07a5b9e632150470c0387f87 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 9 Apr 2014 15:01:39 +0200 Subject: Do not query when the list is empty --- lib/private/share/share.php | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'lib/private') diff --git a/lib/private/share/share.php b/lib/private/share/share.php index 3d22f6fd450..59826d03039 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -210,21 +210,23 @@ class Share extends \OC\Share\Constants { $fileTargetIDs = array_keys($fileTargets); $fileTargetIDs = array_unique($fileTargetIDs); - $query = \OC_DB::prepare( - 'SELECT `fileid`, `path` - FROM `*PREFIX*filecache` - WHERE `fileid` IN (' . implode(',', $fileTargetIDs) . ')' - ); - $result = $query->execute(); + if (!empty($fileTargetIDs)) { + $query = \OC_DB::prepare( + 'SELECT `fileid`, `path` + FROM `*PREFIX*filecache` + WHERE `fileid` IN (' . implode(',', $fileTargetIDs) . ')' + ); + $result = $query->execute(); - if (\OCP\DB::isError($result)) { - \OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage($result), \OC_Log::ERROR); - } else { - while ($row = $result->fetchRow()) { - foreach ($fileTargets[$row['fileid']] as $uid => $shareData) { - $sharedPath = '/Shared' . $shareData['file_target']; - $sharedPath .= substr($path, strlen($row['path']) -5); - $sharePaths[$uid] = $sharedPath; + if (\OCP\DB::isError($result)) { + \OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage($result), \OC_Log::ERROR); + } else { + while ($row = $result->fetchRow()) { + foreach ($fileTargets[$row['fileid']] as $uid => $shareData) { + $sharedPath = '/Shared' . $shareData['file_target']; + $sharedPath .= substr($path, strlen($row['path']) -5); + $sharePaths[$uid] = $sharedPath; + } } } } -- cgit v1.2.3 From b78c1373b681102f2904a4270c45b3030ffe22a5 Mon Sep 17 00:00:00 2001 From: LEDfan Date: Fri, 18 Apr 2014 14:30:44 +0200 Subject: Add key to every contact --- lib/private/contactsmanager.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'lib/private') diff --git a/lib/private/contactsmanager.php b/lib/private/contactsmanager.php index 1cb3da7098f..47ade48dcf0 100644 --- a/lib/private/contactsmanager.php +++ b/lib/private/contactsmanager.php @@ -37,7 +37,12 @@ namespace OC { $result = array(); foreach($this->address_books as $address_book) { $r = $address_book->search($pattern, $searchProperties, $options); - $result = array_merge($result, $r); + $contacts = array(); + foreach($r as $c){ + $c['key'] = $address_book->getKey(); + $contacts[] = $c; + } + $result = array_merge($result, $contacts); } return $result; -- cgit v1.2.3 From efff7dd2a43b604bd883e4e0aca9a74e4bb81222 Mon Sep 17 00:00:00 2001 From: Tobia De Koninck Date: Tue, 22 Apr 2014 12:46:09 +0200 Subject: Change key to addressbook-key --- lib/private/contactsmanager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/private') diff --git a/lib/private/contactsmanager.php b/lib/private/contactsmanager.php index 47ade48dcf0..4299d88017a 100644 --- a/lib/private/contactsmanager.php +++ b/lib/private/contactsmanager.php @@ -39,7 +39,7 @@ namespace OC { $r = $address_book->search($pattern, $searchProperties, $options); $contacts = array(); foreach($r as $c){ - $c['key'] = $address_book->getKey(); + $c['addressbook-key'] = $address_book->getKey(); $contacts[] = $c; } $result = array_merge($result, $contacts); -- cgit v1.2.3 From 6e857de6b71f92f3c23b5dab10d2372316f92ad7 Mon Sep 17 00:00:00 2001 From: Volkan Gezer Date: Sat, 5 Apr 2014 19:23:12 +0200 Subject: Make lib/** share.php strings extractable for translation They were not ready for translation as they had no placeholders and/nor wrapper function to be translated This should fix: #8011 --- lib/private/share/share.php | 152 ++++++++++++++++++++++++++------------------ 1 file changed, 89 insertions(+), 63 deletions(-) (limited to 'lib/private') diff --git a/lib/private/share/share.php b/lib/private/share/share.php index 7bab98b00bf..bea0588271b 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -426,6 +426,7 @@ class Share extends \OC\Share\Constants { public static function shareItem($itemType, $itemSource, $shareType, $shareWith, $permissions, $itemSourceName = null) { $uidOwner = \OC_User::getUser(); $sharingPolicy = \OC_Appconfig::getValue('core', 'shareapi_share_policy', 'global'); + $l = \OC_L10N::get('lib'); if (is_null($itemSourceName)) { $itemSourceName = $itemSource; @@ -434,22 +435,25 @@ class Share extends \OC\Share\Constants { // Verify share type and sharing conditions are met if ($shareType === self::SHARE_TYPE_USER) { if ($shareWith == $uidOwner) { - $message = 'Sharing '.$itemSourceName.' failed, because the user '.$shareWith.' is the item owner'; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Sharing %s failed, because the user %s is the item owner'; + $message_t = $l->t('Sharing %s failed, because the user %s is the item owner', array($itemSourceName, $shareWith)); + \OC_Log::write('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OC_Log::ERROR); + throw new \Exception($message_t); } if (!\OC_User::userExists($shareWith)) { - $message = 'Sharing '.$itemSourceName.' failed, because the user '.$shareWith.' does not exist'; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Sharing %s failed, because the user %s does not exist'; + $message_t = $l->t('Sharing %s failed, because the user %s does not exist', array($itemSourceName, $shareWith)); + \OC_Log::write('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OC_Log::ERROR); + throw new \Exception($message_t); } if ($sharingPolicy == 'groups_only') { $inGroup = array_intersect(\OC_Group::getUserGroups($uidOwner), \OC_Group::getUserGroups($shareWith)); if (empty($inGroup)) { - $message = 'Sharing '.$itemSourceName.' failed, because the user ' - .$shareWith.' is not a member of any groups that '.$uidOwner.' is a member of'; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Sharing %s failed, because the user ' + .'%s is not a member of any groups that %s is a member of'; + $message_t = $l->t('Sharing %s failed, because the user %s is not a member of any groups that %s is a member of', array($itemSourceName, $shareWith, $uidOwner)); + \OC_Log::write('OCP\Share', sprintf($message, $itemSourceName, $shareWith, $uidOwner), \OC_Log::ERROR); + throw new \Exception($message_t); } } // Check if the item source is already shared with the user, either from the same owner or a different user @@ -459,22 +463,25 @@ class Share extends \OC\Share\Constants { // owner and is not a user share, this use case is for increasing // permissions for a specific user if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) { - $message = 'Sharing '.$itemSourceName.' failed, because this item is already shared with '.$shareWith; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Sharing %s failed, because this item is already shared with %s'; + $message_t = $l->t('Sharing %s failed, because this item is already shared with %s', array($itemSourceName, $shareWith)); + \OC_Log::write('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OC_Log::ERROR); + throw new \Exception($message_t); } } } else if ($shareType === self::SHARE_TYPE_GROUP) { if (!\OC_Group::groupExists($shareWith)) { - $message = 'Sharing '.$itemSourceName.' failed, because the group '.$shareWith.' does not exist'; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Sharing %s failed, because the group %s does not exist'; + $message_t = $l->t('Sharing %s failed, because the group %s does not exist', array($itemSourceName, $shareWith)); + \OC_Log::write('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OC_Log::ERROR); + throw new \Exception($message_t); } if ($sharingPolicy == 'groups_only' && !\OC_Group::inGroup($uidOwner, $shareWith)) { - $message = 'Sharing '.$itemSourceName.' failed, because ' - .$uidOwner.' is not a member of the group '.$shareWith; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Sharing %s failed, because ' + .'%s is not a member of the group %s'; + $message_t = $l->t('Sharing %s failed, because %s is not a member of the group %s', array($itemSourceName, $uidOwner, $shareWith)); + \OC_Log::write('OCP\Share', sprintf($message, $itemSourceName, $uidOwner, $shareWith), \OC_Log::ERROR); + throw new \Exception($message_t); } // Check if the item source is already shared with the group, either from the same owner or a different user // The check for each user in the group is done inside the put() function @@ -484,9 +491,10 @@ class Share extends \OC\Share\Constants { // owner and is not a group share, this use case is for increasing // permissions for a specific user if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) { - $message = 'Sharing '.$itemSourceName.' failed, because this item is already shared with '.$shareWith; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Sharing %s failed, because this item is already shared with %s'; + $message_t = $l->t('Sharing %s failed, because this item is already shared with %s', array($itemSourceName, $shareWith)); + \OC_Log::write('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OC_Log::ERROR); + throw new \Exception($message_t); } } // Convert share with into an array with the keys group and users @@ -533,15 +541,17 @@ class Share extends \OC\Share\Constants { return false; } } - $message = 'Sharing '.$itemSourceName.' failed, because sharing with links is not allowed'; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Sharing %s failed, because sharing with links is not allowed'; + $message_t = $l->t('Sharing %s failed, because sharing with links is not allowed', array($itemSourceName)); + \OC_Log::write('OCP\Share', sprintf($message, $itemSourceName), \OC_Log::ERROR); + throw new \Exception($message_t); return false; } else { // Future share types need to include their own conditions - $message = 'Share type '.$shareType.' is not valid for '.$itemSource; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Share type %s is not valid for %s'; + $message_t = $l->t('Share type %s is not valid for %s', array($shareType, $itemSource)); + \OC_Log::write('OCP\Share', sprintf($message, $shareType, $itemSource), \OC_Log::ERROR); + throw new \Exception($message_t); } // Put the item into the database return self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, null, $itemSourceName); @@ -665,6 +675,7 @@ class Share extends \OC\Share\Constants { * @return Returns true on success or false on failure */ public static function setPermissions($itemType, $itemSource, $shareType, $shareWith, $permissions) { + $l = \OC_L10N::get('lib'); if ($item = self::getItems($itemType, $itemSource, $shareType, $shareWith, \OC_User::getUser(), self::FORMAT_NONE, null, 1, false)) { // Check if this item is a reshare and verify that the permissions @@ -673,10 +684,11 @@ class Share extends \OC\Share\Constants { $query = \OC_DB::prepare('SELECT `permissions` FROM `*PREFIX*share` WHERE `id` = ?', 1); $result = $query->execute(array($item['parent']))->fetchRow(); if (~(int)$result['permissions'] & $permissions) { - $message = 'Setting permissions for '.$itemSource.' failed,' - .' because the permissions exceed permissions granted to '.\OC_User::getUser(); - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Setting permissions for %s failed,' + .' because the permissions exceed permissions granted to %s'; + $message_t = $l->t('Setting permissions for %s failed, because the permissions exceed permissions granted to %s', array($itemSource, \OC_User::getUser())); + \OC_Log::write('OCP\Share', sprintf($message, $itemSource, \OC_User::getUser()), \OC_Log::ERROR); + throw new \Exception($message_t); } } $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = ? WHERE `id` = ?'); @@ -734,9 +746,11 @@ class Share extends \OC\Share\Constants { } return true; } - $message = 'Setting permissions for '.$itemSource.' failed, because the item was not found'; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Setting permissions for %s failed, because the item was not found'; + $message_t = $l->t('Setting permissions for %s failed, because the item was not found', array($itemSource)); + + \OC_Log::write('OCP\Share', sprintf($message, $itemSource), \OC_Log::ERROR); + throw new \Exception($message_t); } /** @@ -818,6 +832,7 @@ class Share extends \OC\Share\Constants { * @return \OCP\Share_Backend */ public static function getBackend($itemType) { + $l = \OC_L10N::get('lib'); if (isset(self::$backends[$itemType])) { return self::$backends[$itemType]; } else if (isset(self::$backendTypes[$itemType]['class'])) { @@ -825,20 +840,23 @@ class Share extends \OC\Share\Constants { if (class_exists($class)) { self::$backends[$itemType] = new $class; if (!(self::$backends[$itemType] instanceof \OCP\Share_Backend)) { - $message = 'Sharing backend '.$class.' must implement the interface OCP\Share_Backend'; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Sharing backend %s must implement the interface OCP\Share_Backend'; + $message_t = $l->t('Sharing backend %s must implement the interface OCP\Share_Backend', array($class)); + \OC_Log::write('OCP\Share', sprintf($message, $class), \OC_Log::ERROR); + throw new \Exception($message_t); } return self::$backends[$itemType]; } else { - $message = 'Sharing backend '.$class.' not found'; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Sharing backend %s not found'; + $message_t = $l->t('Sharing backend %s not found', array($class)); + \OC_Log::write('OCP\Share', sprintf($message, $class), \OC_Log::ERROR); + throw new \Exception($message_t); } } - $message = 'Sharing backend for '.$itemType.' not found'; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Sharing backend for %s not found'; + $message_t = $l->t('Sharing backend for %s not found', array($itemType)); + \OC_Log::write('OCP\Share', sprintf($message, $itemType), \OC_Log::ERROR); + throw new \Exception($message_t); } /** @@ -1246,23 +1264,26 @@ class Share extends \OC\Share\Constants { private static function put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, $parentFolder = null, $token = null, $itemSourceName = null) { $backend = self::getBackend($itemType); - + $l = \OC_L10N::get('lib'); // Check if this is a reshare if ($checkReshare = self::getItemSharedWithBySource($itemType, $itemSource, self::FORMAT_NONE, null, true)) { // Check if attempting to share back to owner if ($checkReshare['uid_owner'] == $shareWith && $shareType == self::SHARE_TYPE_USER) { - $message = 'Sharing '.$itemSourceName.' failed, because the user '.$shareWith.' is the original sharer'; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Sharing %s failed, because the user %s is the original sharer'; + $message_t = $l->t('Sharing %s failed, because the user %s is the original sharer', array($itemSourceName, $shareWith)); + + \OC_Log::write('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OC_Log::ERROR); + throw new \Exception($message_t); } // Check if share permissions is granted if (self::isResharingAllowed() && (int)$checkReshare['permissions'] & \OCP\PERMISSION_SHARE) { if (~(int)$checkReshare['permissions'] & $permissions) { - $message = 'Sharing '.$itemSourceName - .' failed, because the permissions exceed permissions granted to '.$uidOwner; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Sharing %s failed, because the permissions exceed permissions granted to %s'; + $message_t = $l->t('Sharing %s failed, because the permissions exceed permissions granted to %s', array($itemSourceName, $uidOwner)); + + \OC_Log::write('OCP\Share', sprintf($message, $itemSourceName, $uidOwner), \OC_Log::ERROR); + throw new \Exception($message_t); } else { // TODO Don't check if inside folder $parent = $checkReshare['id']; @@ -1273,19 +1294,22 @@ class Share extends \OC\Share\Constants { $filePath = $checkReshare['file_target']; } } else { - $message = 'Sharing '.$itemSourceName.' failed, because resharing is not allowed'; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Sharing %s failed, because resharing is not allowed'; + $message_t = $l->t('Sharing %s failed, because resharing is not allowed', array($itemSourceName)); + + \OC_Log::write('OCP\Share', sprintf($message, $itemSourceName), \OC_Log::ERROR); + throw new \Exception($message_t); } } else { $parent = null; $suggestedItemTarget = null; $suggestedFileTarget = null; if (!$backend->isValidSource($itemSource, $uidOwner)) { - $message = 'Sharing '.$itemSource.' failed, because the sharing backend for ' - .$itemType.' could not find its source'; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Sharing %s failed, because the sharing backend for ' + .'%s could not find its source'; + $message_t = $l->t('Sharing %s failed, because the sharing backend for %s could not find its source', array($itemSource, $itemType)); + \OC_Log::write('OCP\Share', sprintf($message, $itemSource, $itemType), \OC_Log::ERROR); + throw new \Exception($message_t); } if ($backend instanceof \OCP\Share_Backend_File_Dependent) { $filePath = $backend->getFilePath($itemSource, $uidOwner); @@ -1296,9 +1320,11 @@ class Share extends \OC\Share\Constants { $fileSource = $meta['fileid']; } if ($fileSource == -1) { - $message = 'Sharing '.$itemSource.' failed, because the file could not be found in the file cache'; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Sharing %s failed, because the file could not be found in the file cache'; + $message_t = $l->t('Sharing %s failed, because the file could not be found in the file cache', array($itemSource)); + + \OC_Log::write('OCP\Share', sprintf($message, $itemSource), \OC_Log::ERROR); + throw new \Exception($message_t); } } else { $filePath = null; -- cgit v1.2.3 From 3d0661a1e79d48ff68a1302126a30e78a9732fa4 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 23 Apr 2014 12:54:18 +0200 Subject: Fix error when viewing expired link --- lib/private/files/filesystem.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/private') diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php index 7e27650c557..434ee495870 100644 --- a/lib/private/files/filesystem.php +++ b/lib/private/files/filesystem.php @@ -374,6 +374,9 @@ class Filesystem { * Returns path like /admin/files */ static public function getRoot() { + if (!self::$defaultInstance) { + return null; + } return self::$defaultInstance->getRoot(); } -- cgit v1.2.3 From cfc52ccc3d3e7e233912adc58bdc95618d941a30 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 28 Mar 2014 15:24:13 +0100 Subject: add some action items --- lib/private/share/constants.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/private') diff --git a/lib/private/share/constants.php b/lib/private/share/constants.php index 7e4223d10fa..4c398c43c2d 100644 --- a/lib/private/share/constants.php +++ b/lib/private/share/constants.php @@ -26,13 +26,13 @@ class Constants { const SHARE_TYPE_USER = 0; const SHARE_TYPE_GROUP = 1; const SHARE_TYPE_LINK = 3; - const SHARE_TYPE_EMAIL = 4; - const SHARE_TYPE_CONTACT = 5; - const SHARE_TYPE_REMOTE = 6; + const SHARE_TYPE_EMAIL = 4; // ToDo Check if it is still in use otherwise remove it + const SHARE_TYPE_CONTACT = 5; // ToDo Check if it is still in use otherwise remove it + const SHARE_TYPE_REMOTE = 6; // ToDo Check if it is still in use otherwise remove it const FORMAT_NONE = -1; const FORMAT_STATUSES = -2; - const FORMAT_SOURCES = -3; + const FORMAT_SOURCES = -3; // ToDo Check if it is still in use otherwise remove it const TOKEN_LENGTH = 32; // see db_structure.xml -- cgit v1.2.3 From 72bbb9ca20498eba18d6b6a31ed1de2306f90faf Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 7 Apr 2014 19:00:03 +0200 Subject: allow to remove and change mount points --- lib/private/files/mount/manager.php | 7 +++++++ lib/private/files/mount/mount.php | 7 +++++++ 2 files changed, 14 insertions(+) (limited to 'lib/private') diff --git a/lib/private/files/mount/manager.php b/lib/private/files/mount/manager.php index ff4a336f347..91460b72730 100644 --- a/lib/private/files/mount/manager.php +++ b/lib/private/files/mount/manager.php @@ -23,6 +23,13 @@ class Manager { $this->mounts[$mount->getMountPoint()] = $mount; } + /** + * @param string $mountPoint + */ + public function removeMount($mountPoint) { + unset($this->mounts[$mountPoint]); + } + /** * Find the mount for $path * diff --git a/lib/private/files/mount/mount.php b/lib/private/files/mount/mount.php index 0ce2f5975c7..08d5ddf348b 100644 --- a/lib/private/files/mount/mount.php +++ b/lib/private/files/mount/mount.php @@ -65,6 +65,13 @@ class Mount { return $this->mountPoint; } + /** + * @param string $mountPoint new mount point + */ + public function setMountPoint($mountPoint) { + $this->mountPoint = $mountPoint; + } + /** * create the storage that is mounted * -- cgit v1.2.3 From a02fb3722bae6655ffdd5b0e6c522331612c255b Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 4 Apr 2014 18:32:49 +0200 Subject: user should be able to rename/delete shared files if the owner allowed it --- apps/files_sharing/lib/cache.php | 9 +++ apps/files_sharing/lib/sharedstorage.php | 102 ++++++++++++++++++++++++++++++- lib/private/files/view.php | 29 ++++++--- 3 files changed, 129 insertions(+), 11 deletions(-) (limited to 'lib/private') diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index becd436f798..4017b7ad64a 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -89,6 +89,12 @@ class Shared_Cache extends Cache { return $cache->get($this->files[$file]); } } else { + // if we are at the root of the mount point we want to return the + // cache information for the source item + if (!is_int($file) || $file === 0) { + $file = $this->storage->getSourceId(); + $mountPoint = $this->storage->getMountPoint(); + } $query = \OC_DB::prepare( 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`,' . ' `size`, `mtime`, `encrypted`, `unencrypted_size`' @@ -110,6 +116,9 @@ class Shared_Cache extends Cache { } else { $data['size'] = (int)$data['size']; } + if (isset($mountPoint)) { + $data['path'] = 'files/' . $mountPoint; + } return $data; } return false; diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 25a05a0d1f2..d09a4a22564 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -30,17 +30,33 @@ class Shared extends \OC\Files\Storage\Common { private $mountPoint; // mount point relative to data/user/files private $type; // can be "file" or "folder" + private $shareId; // share Id to identify the share in the database + private $fileSource; // file cache ID of the shared item private $files = array(); public function __construct($arguments) { $this->mountPoint = $arguments['shareTarget']; $this->type = $arguments['shareType']; + $this->shareId = $arguments['shareId']; + $this->fileSource = $arguments['fileSource']; } + /** + * @breif get id of the mount point + * @return string + */ public function getId() { return 'shared::' . $this->mountPoint; } + /** + * @breif get file cache of the shared item source + * @return string + */ + public function getSourceId() { + return $this->fileSource; + } + /** * @brief Get the source file path, permissions, and owner for a shared file * @param string Shared target file path @@ -289,11 +305,89 @@ class Shared extends \OC\Files\Storage\Common { return false; } + /** + * @brief Format a path to be relative to the /user/files/ directory + * @param string $path the absolute path + * @return string e.g. turns '/admin/files/test.txt' into '/test.txt' + */ + private static function stripUserFilesPath($path) { + $trimmed = ltrim($path, '/'); + $split = explode('/', $trimmed); + + // it is not a file relative to data/user/files + if (count($split) < 3 || $split[1] !== 'files') { + \OCP\Util::writeLog('file sharing', + 'Can not strip userid and "files/" from path: ' . $path, + \OCP\Util::DEBUG); + return false; + } + + // skip 'user' and 'files' + $sliced = array_slice($split, 2); + $relPath = implode('/', $sliced); + + return '/' . $relPath; + } + + /** + * @brief rename a shared foder/file + * @param string $sourcePath + * @param string $targetPath + * @return bool + */ + private function renameMountPoint($sourcePath, $targetPath) { + + // it shoulbn't be possible to move a Shared storage into another one + list($targetStorage, ) = \OC\Files\Filesystem::resolvePath($targetPath); + if ($targetStorage instanceof \OC\Files\Storage\Shared) { + \OCP\Util::writeLog('file sharing', + 'It is not allowed to move one mount point into another one', + \OCP\Util::DEBUG); + return false; + } + + $relTargetPath = $this->stripUserFilesPath($targetPath); + + // rename mount point + $query = \OC_DB::prepare( + 'Update `*PREFIX*share` + SET `file_target` = ? + WHERE `id` = ?' + ); + + $result = $query->execute(array($relTargetPath, $this->shareId)); + + if ($result) { + // update the mount manager with the new paths + $mountManager = \OC\Files\Filesystem::getMountManager(); + $mount = $mountManager->find($sourcePath); + $mount->setMountPoint($targetPath . '/'); + $mountManager->addMount($mount); + $mountManager->removeMount($sourcePath . '/'); + + } else { + \OCP\Util::writeLog('file sharing', + 'Could not rename mount point for shared folder "' . $sourcePath . '" to "' . $targetPath . '"', + \OCP\Util::ERROR); + } + + return $result; + } + + public function rename($path1, $path2) { + + $sourceMountPoint = \OC\Files\Filesystem::getMountPoint($path1); + + // if we renamed the mount point we need to adjust the file_target in the + // database + if (strlen($sourceMountPoint) >= strlen($path1)) { + return $this->renameMountPoint($path1, $path2); + } + // Renaming/moving is only allowed within shared folders - $pos1 = strpos($path1, '/', 1); - $pos2 = strpos($path2, '/', 1); - if ($pos1 !== false && $pos2 !== false && ($oldSource = $this->getSourcePath($path1))) { + $oldSource = $this->getSourcePath($path1); + if ($oldSource) { $newSource = $this->getSourcePath(dirname($path2)) . '/' . basename($path2); // Within the same folder, we only need UPDATE permissions if (dirname($path1) == dirname($path2) and $this->isUpdatable($path1)) { @@ -405,6 +499,8 @@ class Shared extends \OC\Files\Storage\Common { array( 'shareTarget' => $share['file_target'], 'shareType' => $share['item_type'], + 'shareId' => $share['id'], + 'fileSource' => $share['file_source'], ), $options['user_dir'] . '/' . $share['file_target']); } diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 519ed250b1f..6d630f978ba 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -404,11 +404,21 @@ class View { if ($run) { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); + list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); + list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2); + // if source and target are on the same storage we can call the rename operation from the + // storage. If it is a "Shared" file/folder we call always the rename operation of the + // shared storage to handle mount point renaming, etc correctly if ($mp1 == $mp2) { - list($storage, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); - list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2); - if ($storage) { - $result = $storage->rename($internalPath1, $internalPath2); + if ($storage1) { + $result = $storage1->rename($internalPath1, $internalPath2); + \OC_FileProxy::runPostProxies('rename', $absolutePath1, $absolutePath2); + } else { + $result = false; + } + } elseif ($storage1 instanceof \OC\Files\Storage\Shared) { + if ($storage1) { + $result = $storage1->rename($absolutePath1, $absolutePath2); \OC_FileProxy::runPostProxies('rename', $absolutePath1, $absolutePath2); } else { $result = false; @@ -417,7 +427,6 @@ class View { if ($this->is_dir($path1)) { $result = $this->copy($path1, $path2); if ($result === true) { - list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); $result = $storage1->unlink($internalPath1); } } else { @@ -431,7 +440,6 @@ class View { fclose($target); if ($result !== false) { - list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); $storage1->unlink($internalPath1); } } @@ -972,8 +980,13 @@ class View { $permissions = $subStorage->getPermissions($rootEntry['path']); $subPermissionsCache->set($rootEntry['fileid'], $user, $permissions); } - // do not allow renaming/deleting the mount point - $rootEntry['permissions'] = $permissions & (\OCP\PERMISSION_ALL - (\OCP\PERMISSION_UPDATE | \OCP\PERMISSION_DELETE)); + // do not allow renaming/deleting the mount point if they are not shared files/folders + // for shared files/folders we use the permissions given by the owner + if ($subStorage instanceof \OC\Files\Storage\Shared) { + $rootEntry['permissions'] = $permissions; + } else { + $rootEntry['permissions'] = $permissions & (\OCP\PERMISSION_ALL - (\OCP\PERMISSION_UPDATE | \OCP\PERMISSION_DELETE)); + } //remove any existing entry with the same name foreach ($files as $i => $file) { -- cgit v1.2.3 From c4e0fb75a4e8c9cb133ce79b6a737b2ba7b161df Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 8 Apr 2014 14:42:15 +0200 Subject: add api to get shares from a specific user --- lib/private/share/share.php | 16 ++++++++++++++++ lib/public/share.php | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) (limited to 'lib/private') diff --git a/lib/private/share/share.php b/lib/private/share/share.php index 3751b035bd4..ff56b9a48f1 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -252,6 +252,22 @@ class Share extends \OC\Share\Constants { $parameters, $limit, $includeCollections); } + /** + * Get the items of item type shared with a user + * @param string Item type + * @param sting user id for which user we want the shares + * @param int Format (optional) Format type must be defined by the backend + * @param mixed Parameters (optional) + * @param int Number of items to return (optional) Returns all by default + * @param bool include collections (optional) + * @return Return depends on format + */ + public static function getItemsSharedWithUser($itemType, $user, $format = self::FORMAT_NONE, + $parameters = null, $limit = -1, $includeCollections = false) { + return self::getItems($itemType, null, self::$shareTypeUserAndGroups, $user, null, $format, + $parameters, $limit, $includeCollections); + } + /** * Get the item of item type shared with the current user * @param string $itemType diff --git a/lib/public/share.php b/lib/public/share.php index c694314ad08..230a517b5ee 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -90,6 +90,22 @@ class Share extends \OC\Share\Constants { return \OC\Share\Share::getItemsSharedWith($itemType, $format, $parameters, $limit, $includeCollections); } + /** + * Get the items of item type shared with a user + * @param string Item type + * @param sting user id for which user we want the shares + * @param int Format (optional) Format type must be defined by the backend + * @param mixed Parameters (optional) + * @param int Number of items to return (optional) Returns all by default + * @param bool include collections (optional) + * @return Return depends on format + */ + public static function getItemsSharedWithUser($itemType, $user, $format = self::FORMAT_NONE, + $parameters = null, $limit = -1, $includeCollections = false) { + + return \OC\Share\Share::getItemsSharedWithUser($itemType, $user, $format, $parameters, $limit, $includeCollections); + } + /** * Get the item of item type shared with the current user * @param string $itemType -- cgit v1.2.3 From 27c5a978f91e7aa447a2acca040fd173baba53b9 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 8 Apr 2014 17:17:48 +0200 Subject: we no longer need to handle the Shared folder different from any other folder --- apps/files/js/file-upload.js | 4 +- apps/files/js/fileactions.js | 8 +-- apps/files/js/filelist.js | 2 +- apps/files/js/files.js | 6 +-- apps/files/lib/app.php | 11 +--- apps/files/tests/ajax_rename.php | 82 ------------------------------ apps/files/tests/js/filesSpec.js | 35 ------------- lib/private/connector/sabre/directory.php | 12 ----- lib/private/connector/sabre/file.php | 11 ---- lib/private/connector/sabre/objecttree.php | 3 -- 10 files changed, 8 insertions(+), 166 deletions(-) (limited to 'lib/private') diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index 3879aa65888..03ebdccb32d 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -235,7 +235,7 @@ OC.Upload = { var file = data.files[0]; try { // FIXME: not so elegant... need to refactor that method to return a value - Files.isFileNameValid(file.name, FileList.getCurrentDirectory()); + Files.isFileNameValid(file.name); } catch (errorMessage) { data.textStatus = 'invalidcharacters'; @@ -555,8 +555,6 @@ OC.Upload = { throw t('files', 'URL cannot be empty'); } else if (type !== 'web' && !Files.isFileNameValid(filename)) { // Files.isFileNameValid(filename) throws an exception itself - } else if (FileList.getCurrentDirectory() === '/' && filename.toLowerCase() === 'shared') { - throw t('files', 'In the home folder \'Shared\' is a reserved filename'); } else if (FileList.inList(filename)) { throw t('files', '{new_name} already exists', {new_name: filename}); } else { diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js index 631aebea954..ecdfa72a477 100644 --- a/apps/files/js/fileactions.js +++ b/apps/files/js/fileactions.js @@ -118,10 +118,6 @@ var FileActions = { }; var addAction = function (name, action, displayName) { - // NOTE: Temporary fix to prevent rename action in root of Shared directory - if (name === 'Rename' && $('#dir').val() === '/Shared') { - return true; - } if ((name === 'Download' || action !== defaultAction) && name !== 'Delete') { @@ -160,7 +156,7 @@ var FileActions = { addAction(name, ah, displayName); } }); - if(actions.Share && !($('#dir').val() === '/' && file === 'Shared')){ + if(actions.Share){ displayName = t('files', 'Share'); addAction('Share', actions.Share, displayName); } @@ -223,7 +219,7 @@ $(document).ready(function () { $('#fileList tr').each(function () { FileActions.display($(this).children('td.filename')); }); - + $('#fileList').trigger(jQuery.Event("fileActionsReady")); }); diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 9c749bb8f34..343da217416 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -580,7 +580,7 @@ window.FileList = { var filename = input.val(); if (filename !== oldname) { // Files.isFileNameValid(filename) throws an exception itself - Files.isFileNameValid(filename, FileList.getCurrentDirectory()); + Files.isFileNameValid(filename); if (FileList.inList(filename)) { throw t('files', '{new_name} already exists', {new_name: filename}); } diff --git a/apps/files/js/files.js b/apps/files/js/files.js index 9f38263bef3..5e669a796a9 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -87,11 +87,9 @@ var Files = { * Throws a string exception with an error message if * the file name is not valid */ - isFileNameValid: function (name, root) { + isFileNameValid: function (name) { var trimmedName = name.trim(); - if (trimmedName === '.' - || trimmedName === '..' - || (root === '/' && trimmedName.toLowerCase() === 'shared')) + if (trimmedName === '.' || trimmedName === '..') { throw t('files', '"{name}" is an invalid file name.', {name: name}); } else if (trimmedName.length === 0) { diff --git a/apps/files/lib/app.php b/apps/files/lib/app.php index adfca669577..ed4aa32c662 100644 --- a/apps/files/lib/app.php +++ b/apps/files/lib/app.php @@ -54,13 +54,8 @@ class App { 'data' => NULL ); - // rename to "/Shared" is denied - if( $dir === '/' and $newname === 'Shared' ) { - $result['data'] = array( - 'message' => $this->l10n->t("Invalid folder name. Usage of 'Shared' is reserved.") - ); // rename to non-existing folder is denied - } else if (!$this->view->file_exists($dir)) { + if (!$this->view->file_exists($dir)) { $result['data'] = array('message' => (string)$this->l10n->t( 'The target folder has been moved or deleted.', array($dir)), @@ -68,7 +63,7 @@ class App { ); // rename to existing file is denied } else if ($this->view->file_exists($dir . '/' . $newname)) { - + $result['data'] = array( 'message' => $this->l10n->t( "The name %s is already used in the folder %s. Please choose a different name.", @@ -77,8 +72,6 @@ class App { } else if ( // rename to "." is denied $newname !== '.' and - // rename of "/Shared" is denied - !($dir === '/' and $oldname === 'Shared') and // THEN try to rename $this->view->rename($dir . '/' . $oldname, $dir . '/' . $newname) ) { diff --git a/apps/files/tests/ajax_rename.php b/apps/files/tests/ajax_rename.php index cb62d22a7e2..74ca1e4495d 100644 --- a/apps/files/tests/ajax_rename.php +++ b/apps/files/tests/ajax_rename.php @@ -55,88 +55,6 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { \OC\Files\Filesystem::tearDown(); } - /** - * @brief test rename of file/folder named "Shared" - */ - function testRenameSharedFolder() { - $dir = '/'; - $oldname = 'Shared'; - $newname = 'new_name'; - - $this->viewMock->expects($this->at(0)) - ->method('file_exists') - ->with('/') - ->will($this->returnValue(true)); - - $result = $this->files->rename($dir, $oldname, $newname); - $expected = array( - 'success' => false, - 'data' => array('message' => '%s could not be renamed') - ); - - $this->assertEquals($expected, $result); - } - - /** - * @brief test rename of file/folder named "Shared" - */ - function testRenameSharedFolderInSubdirectory() { - $dir = '/test'; - $oldname = 'Shared'; - $newname = 'new_name'; - - $this->viewMock->expects($this->at(0)) - ->method('file_exists') - ->with('/test') - ->will($this->returnValue(true)); - - $this->viewMock->expects($this->any()) - ->method('getFileInfo') - ->will($this->returnValue(new \OC\Files\FileInfo( - '/test', - null, - '/test', - array( - 'fileid' => 123, - 'type' => 'dir', - 'mimetype' => 'httpd/unix-directory', - 'mtime' => 0, - 'permissions' => 31, - 'size' => 18, - 'etag' => 'abcdef', - 'directory' => '/', - 'name' => 'new_name', - )))); - - $result = $this->files->rename($dir, $oldname, $newname); - - $this->assertTrue($result['success']); - $this->assertEquals(123, $result['data']['id']); - $this->assertEquals('new_name', $result['data']['name']); - $this->assertEquals(18, $result['data']['size']); - $this->assertEquals('httpd/unix-directory', $result['data']['mimetype']); - $icon = \OC_Helper::mimetypeIcon('dir'); - $icon = substr($icon, 0, -3) . 'svg'; - $this->assertEquals($icon, $result['data']['icon']); - } - - /** - * @brief test rename of file/folder to "Shared" - */ - function testRenameFolderToShared() { - $dir = '/'; - $oldname = 'oldname'; - $newname = 'Shared'; - - $result = $this->files->rename($dir, $oldname, $newname); - $expected = array( - 'success' => false, - 'data' => array('message' => "Invalid folder name. Usage of 'Shared' is reserved.") - ); - - $this->assertEquals($expected, $result); - } - /** * @brief test rename of file/folder */ diff --git a/apps/files/tests/js/filesSpec.js b/apps/files/tests/js/filesSpec.js index 95bf87e03ec..018c8ef0f3c 100644 --- a/apps/files/tests/js/filesSpec.js +++ b/apps/files/tests/js/filesSpec.js @@ -48,41 +48,6 @@ describe('Files tests', function() { expect(error).toEqual(false); } }); - it('Validates correct file names do not create Shared folder in root', function() { - // create shared file in subfolder - var error = false; - try { - expect(Files.isFileNameValid('shared', '/foo')).toEqual(true); - expect(Files.isFileNameValid('Shared', '/foo')).toEqual(true); - } - catch (e) { - error = e; - } - expect(error).toEqual(false); - - // create shared file in root - var threwException = false; - try { - Files.isFileNameValid('Shared', '/'); - console.error('Invalid file name not detected'); - } - catch (e) { - threwException = true; - } - expect(threwException).toEqual(true); - - // create shared file in root - var threwException = false; - try { - Files.isFileNameValid('shared', '/'); - console.error('Invalid file name not detected'); - } - catch (e) { - threwException = true; - } - expect(threwException).toEqual(true); - - }); it('Detects invalid file names', function() { var fileNames = [ '', diff --git a/lib/private/connector/sabre/directory.php b/lib/private/connector/sabre/directory.php index 70f45aa1e7f..5d386a772a7 100644 --- a/lib/private/connector/sabre/directory.php +++ b/lib/private/connector/sabre/directory.php @@ -50,10 +50,6 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa */ public function createFile($name, $data = null) { - if (strtolower($name) === 'shared' && empty($this->path)) { - throw new \Sabre_DAV_Exception_Forbidden(); - } - // for chunked upload also updating a existing file is a "createFile" // because we create all the chunks before reasamble them to the existing file. if (isset($_SERVER['HTTP_OC_CHUNKED'])) { @@ -86,10 +82,6 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa */ public function createDirectory($name) { - if (strtolower($name) === 'shared' && empty($this->path)) { - throw new \Sabre_DAV_Exception_Forbidden(); - } - if (!\OC\Files\Filesystem::isCreatable($this->path)) { throw new \Sabre_DAV_Exception_Forbidden(); } @@ -196,10 +188,6 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa */ public function delete() { - if ($this->path === 'Shared') { - throw new \Sabre_DAV_Exception_Forbidden(); - } - if (!\OC\Files\Filesystem::isDeletable($this->path)) { throw new \Sabre_DAV_Exception_Forbidden(); } diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php index 750d646a8f5..433b4d805c9 100644 --- a/lib/private/connector/sabre/file.php +++ b/lib/private/connector/sabre/file.php @@ -71,13 +71,6 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D // mark file as partial while uploading (ignored by the scanner) $partpath = $this->path . '.ocTransferId' . rand() . '.part'; - // if file is located in /Shared we write the part file to the users - // root folder because we can't create new files in /shared - // we extend the name with a random number to avoid overwriting a existing file - if (dirname($partpath) === 'Shared') { - $partpath = pathinfo($partpath, PATHINFO_FILENAME) . rand() . '.part'; - } - try { $putOkay = $fs->file_put_contents($partpath, $data); if ($putOkay === false) { @@ -149,10 +142,6 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D public function delete() { $fs = $this->getFS(); - if ($this->path === 'Shared') { - throw new \Sabre_DAV_Exception_Forbidden(); - } - if (!$fs->isDeletable($this->path)) { throw new \Sabre_DAV_Exception_Forbidden(); } diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php index accf020daa2..d2fa425b22c 100644 --- a/lib/private/connector/sabre/objecttree.php +++ b/lib/private/connector/sabre/objecttree.php @@ -94,9 +94,6 @@ class ObjectTree extends \Sabre_DAV_ObjectTree { } if ($sourceDir !== $destinationDir) { // for a full move we need update privileges on sourcePath and sourceDir as well as destinationDir - if (ltrim($destinationDir, '/') === '' && strtolower($sourceNode->getName()) === 'shared') { - throw new \Sabre_DAV_Exception_Forbidden(); - } if (!$fs->isUpdatable($sourceDir)) { throw new \Sabre_DAV_Exception_Forbidden(); } -- cgit v1.2.3 From ed981294f11bd59733e0d121cbf737e16275b666 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 8 Apr 2014 19:57:07 +0200 Subject: fix share api tests --- apps/files_sharing/lib/api.php | 12 ------ apps/files_sharing/lib/cache.php | 21 ++++++---- apps/files_sharing/lib/share/file.php | 2 +- apps/files_sharing/lib/sharedstorage.php | 39 ++++-------------- apps/files_sharing/lib/watcher.php | 2 +- apps/files_sharing/tests/api.php | 70 +++++++------------------------- apps/files_sharing/tests/base.php | 12 +++--- apps/files_sharing/tests/cache.php | 60 ++++++++++++--------------- apps/files_sharing/tests/permissions.php | 15 ++++--- apps/files_sharing/tests/watcher.php | 33 +++++---------- lib/private/share/share.php | 6 +-- 11 files changed, 91 insertions(+), 181 deletions(-) (limited to 'lib/private') diff --git a/apps/files_sharing/lib/api.php b/apps/files_sharing/lib/api.php index de3c1cd2630..438d3cc4ba3 100644 --- a/apps/files_sharing/lib/api.php +++ b/apps/files_sharing/lib/api.php @@ -184,7 +184,6 @@ class Api { $receivedFrom = \OCP\Share::getItemSharedWithBySource($itemType, $file['fileid']); reset($share); $key = key($share); - $share[$key]['path'] = self::correctPath($share[$key]['path'], $path); if ($receivedFrom) { $share[$key]['received_from'] = $receivedFrom['uid_owner']; $share[$key]['received_from_displayname'] = \OCP\User::getDisplayName($receivedFrom['uid_owner']); @@ -531,15 +530,4 @@ class Api { } - /** - * @brief make sure that the path has the correct root - * - * @param string $path path returned from the share API - * @param string $folder current root folder - * @return string the correct path - */ - protected static function correctPath($path, $folder) { - return \OC_Filesystem::normalizePath('/' . $folder . '/' . basename($path)); - } - } diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 250c1e872e3..e91c15cc62a 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -47,7 +47,7 @@ class Shared_Cache extends Cache { * @return \OC\Files\Cache\Cache */ private function getSourceCache($target) { - if ($target === false) { + if ($target === false || $target === $this->storage->getMountPoint()) { $target = ''; } $source = \OC_Share_Backend_File::getSource($target, $this->storage->getMountPoint(), $this->storage->getShareType()); @@ -86,8 +86,11 @@ class Shared_Cache extends Cache { public function get($file) { if (is_string($file)) { if ($cache = $this->getSourceCache($file)) { + $path = 'files/' . $this->storage->getMountPoint(); + $path .= ($file !== '') ? '/' . $file : ''; $data = $cache->get($this->files[$file]); $data['displayname_owner'] = \OC_User::getDisplayName($this->storage->getSharedFrom()); + $data['path'] = $path; return $data; } } else { @@ -99,7 +102,7 @@ class Shared_Cache extends Cache { } $query = \OC_DB::prepare( 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`,' - . ' `size`, `mtime`, `encrypted`, `unencrypted_size`' + . ' `size`, `mtime`, `encrypted`, `unencrypted_size`, `storage_mtime`' . ' FROM `*PREFIX*filecache` WHERE `fileid` = ?'); $result = $query->execute(array($file)); $data = $result->fetchRow(); @@ -138,12 +141,15 @@ class Shared_Cache extends Cache { $folder = ''; } + $dir = 'files/' . $this->storage->getMountPoint(); + $dir .= ($folder !== '') ? '/' . $folder : ''; + $cache = $this->getSourceCache($folder); if ($cache) { $parent = $this->storage->getFile($folder); $sourceFolderContent = $cache->getFolderContents($this->files[$folder]); foreach ($sourceFolderContent as $key => $c) { - $sourceFolderContent[$key]['usersPath'] = 'files/' . $folder . '/' . $c['name']; + $sourceFolderContent[$key]['path'] = $dir . '/' . $c['name']; $sourceFolderContent[$key]['uid_owner'] = $parent['uid_owner']; $sourceFolderContent[$key]['displayname_owner'] = $parent['uid_owner']; } @@ -178,7 +184,11 @@ class Shared_Cache extends Cache { * @return int */ public function getId($file) { - if ($cache = $this->getSourceCache($file)) { + if ($file === false) { + return $this->storage->getSourceId(); + } + $cache = $this->getSourceCache($file); + if ($cache) { return $cache->getId($this->files[$file]); } return -1; @@ -292,9 +302,6 @@ class Shared_Cache extends Cache { if ($file['mimetype'] === 'httpd/unix-directory') { $exploreDirs[] = ltrim($dir . '/' . $file['name'], '/'); } else if (($mimepart && $file['mimepart'] === $mimepart) || ($mimetype && $file['mimetype'] === $mimetype)) { - // usersPath not reliable - //$file['path'] = $file['usersPath']; - $file['path'] = ltrim($dir . '/' . $file['name'], '/'); $result[] = $file; } } diff --git a/apps/files_sharing/lib/share/file.php b/apps/files_sharing/lib/share/file.php index c628b11589d..e1d0b49706b 100644 --- a/apps/files_sharing/lib/share/file.php +++ b/apps/files_sharing/lib/share/file.php @@ -87,7 +87,7 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent { 'path' => $items[key($items)]['path'], 'storage' => $items[key($items)]['storage'], 'permissions' => $items[key($items)]['permissions'], - 'uid_owner' => $items[key($items)]['uid_owner'] + 'uid_owner' => $items[key($items)]['uid_owner'], ); } else if ($format == self::FORMAT_GET_FOLDER_CONTENTS) { $files = array(); diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index f38f29635a2..565c3e7af8e 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -138,15 +138,9 @@ class Shared extends \OC\Files\Storage\Common { } public function opendir($path) { - if ($path == '' || $path == '/') { - $files = \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_Folder::FORMAT_OPENDIR); - \OC\Files\Stream\Dir::register($this->mountPoint, $files); - return opendir('fakedir://' . $this->mountPoint); - } else if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); - return $storage->opendir($internalPath); - } - return false; + $source = $this->getSourcePath($path); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); + return $storage->opendir($internalPath); } public function is_dir($path) { @@ -242,25 +236,9 @@ class Shared extends \OC\Files\Storage\Common { } public function filemtime($path) { - if ($path == '' || $path == '/') { - $mtime = 0; - $dh = $this->opendir($path); - if (is_resource($dh)) { - while (($filename = readdir($dh)) !== false) { - $tempmtime = $this->filemtime($filename); - if ($tempmtime > $mtime) { - $mtime = $tempmtime; - } - } - } - return $mtime; - } else { - $source = $this->getSourcePath($path); - if ($source) { - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); - return $storage->filemtime($internalPath); - } - } + $source = $this->getSourcePath($path); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); + return $storage->filemtime($internalPath); } public function file_get_contents($path) { @@ -285,7 +263,7 @@ class Shared extends \OC\Files\Storage\Common { return false; } $info = array( - 'target' => $this->mountPoint . $path, + 'target' => $this->mountPoint . '/' . $path, 'source' => $source, ); \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info); @@ -532,9 +510,6 @@ class Shared extends \OC\Files\Storage\Common { } public function hasUpdated($path, $time) { - if ($path == '') { - return false; - } return $this->filemtime($path) > $time; } diff --git a/apps/files_sharing/lib/watcher.php b/apps/files_sharing/lib/watcher.php index 285b1a58c6e..11d3ce1cabd 100644 --- a/apps/files_sharing/lib/watcher.php +++ b/apps/files_sharing/lib/watcher.php @@ -32,7 +32,7 @@ class Shared_Watcher extends Watcher { * @param string $path */ public function checkUpdate($path) { - if ($path != '' && parent::checkUpdate($path) === true) { + if (parent::checkUpdate($path) === true) { // since checkUpdate() has already updated the size of the subdirs, // only apply the update to the owner's parent dirs diff --git a/apps/files_sharing/tests/api.php b/apps/files_sharing/tests/api.php index c7a848315ac..6354d1099bb 100644 --- a/apps/files_sharing/tests/api.php +++ b/apps/files_sharing/tests/api.php @@ -324,10 +324,10 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { $this->assertTrue(is_string($result)); $testValues=array( - array('query' => 'Shared/' . $this->folder, - 'expectedResult' => '/Shared' . $this->folder . $this->filename), - array('query' => 'Shared/' . $this->folder . $this->subfolder, - 'expectedResult' => '/Shared' . $this->folder . $this->subfolder . $this->filename), + array('query' => $this->folder, + 'expectedResult' => $this->folder . $this->filename), + array('query' => $this->folder . $this->subfolder, + 'expectedResult' => $this->folder . $this->subfolder . $this->filename), ); foreach ($testValues as $value) { @@ -382,7 +382,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { // share was successful? $this->assertTrue(is_string($result)); - $_GET['path'] = '/Shared'; + $_GET['path'] = '/'; $_GET['subfiles'] = 'true'; $result = Share\Api::getAllShares(array()); @@ -395,7 +395,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { // we should get exactly one result $this->assertEquals(1, count($data)); - $expectedPath = '/Shared' . $this->subfolder; + $expectedPath = $this->subfolder; $this->assertEquals($expectedPath, $data[0]['path']); // cleanup @@ -444,7 +444,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { $this->assertTrue(is_string($result)); - $_GET['path'] = '/Shared'; + $_GET['path'] = '/'; $_GET['subfiles'] = 'true'; $result = Share\Api::getAllShares(array()); @@ -457,7 +457,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { // we should get exactly one result $this->assertEquals(1, count($data)); - $expectedPath = '/Shared' . $this->subsubfolder; + $expectedPath = $this->subsubfolder; $this->assertEquals($expectedPath, $data[0]['path']); @@ -512,8 +512,8 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { $this->assertTrue(is_string($result)); - // ask for shared/subfolder - $expectedPath1 = '/Shared' . $this->subfolder; + // ask for subfolder + $expectedPath1 = $this->subfolder; $_GET['path'] = $expectedPath1; $result1 = Share\Api::getAllShares(array()); @@ -524,8 +524,8 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { $data1 = $result1->getData(); $share1 = reset($data1); - // ask for shared/folder/subfolder - $expectedPath2 = '/Shared' . $this->folder . $this->subfolder; + // ask for folder/subfolder + $expectedPath2 = $this->folder . $this->subfolder; $_GET['path'] = $expectedPath2; $result2 = Share\Api::getAllShares(array()); @@ -595,7 +595,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { $this->assertTrue(is_string($result)); - $_GET['path'] = '/Shared'; + $_GET['path'] = '/'; $_GET['subfiles'] = 'true'; $result = Share\Api::getAllShares(array()); @@ -608,7 +608,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { // we should get exactly one result $this->assertEquals(1, count($data)); - $expectedPath = '/Shared' . $this->filename; + $expectedPath = $this->filename; $this->assertEquals($expectedPath, $data[0]['path']); @@ -868,46 +868,4 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { } - function testCorrectPath() { - $path = "/foo/bar/test.txt"; - $folder = "/correct/path"; - $expectedResult = "/correct/path/test.txt"; - - $shareApiDummy = new TestShareApi(); - - $this->assertSame($expectedResult, $shareApiDummy->correctPathTest($path, $folder)); - } - - /** - * @expectedException \Exception - */ - public function testShareNonExisting() { - \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); - - $id = PHP_INT_MAX - 1; - \OCP\Share::shareItem('file', $id, \OCP\Share::SHARE_TYPE_LINK, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31); - } - - /** - * @expectedException \Exception - */ - public function testShareNotOwner() { - \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); - \OC\Files\Filesystem::file_put_contents('foo.txt', 'bar'); - $info = \OC\Files\Filesystem::getFileInfo('foo.txt'); - - \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); - - \OCP\Share::shareItem('file', $info->getId(), \OCP\Share::SHARE_TYPE_LINK, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31); - } - -} - -/** - * @brief dumnmy class to test protected methods - */ -class TestShareApi extends \OCA\Files\Share\Api { - public function correctPathTest($path, $folder) { - return self::correctPath($path, $folder); - } } diff --git a/apps/files_sharing/tests/base.php b/apps/files_sharing/tests/base.php index d44972d01f1..495dca072c7 100644 --- a/apps/files_sharing/tests/base.php +++ b/apps/files_sharing/tests/base.php @@ -102,22 +102,20 @@ abstract class Test_Files_Sharing_Base extends \PHPUnit_Framework_TestCase { * @param bool $password */ protected static function loginHelper($user, $create = false, $password = false) { - if ($create) { - \OC_User::createUser($user, $user); - } if ($password === false) { $password = $user; } + if ($create) { + \OC_User::createUser($user, $password); + } + \OC_Util::tearDownFS(); \OC_User::setUserId(''); \OC\Files\Filesystem::tearDown(); - \OC_Util::setupFS($user); \OC_User::setUserId($user); - - $params['uid'] = $user; - $params['password'] = $password; + \OC_Util::setupFS($user); } /** diff --git a/apps/files_sharing/tests/cache.php b/apps/files_sharing/tests/cache.php index 47969833ab5..7a52f403d8e 100644 --- a/apps/files_sharing/tests/cache.php +++ b/apps/files_sharing/tests/cache.php @@ -68,7 +68,7 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { // retrieve the shared storage $secondView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2); - list($this->sharedStorage, $internalPath) = $secondView->resolvePath('files/Shared/shareddir'); + list($this->sharedStorage, $internalPath) = $secondView->resolvePath('files/shareddir'); $this->sharedCache = $this->sharedStorage->getCache(); } @@ -98,46 +98,46 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { function testSearchByMime() { $results = $this->sharedStorage->getCache()->searchByMime('text'); $check = array( - array( - 'name' => 'shared single file.txt', - 'path' => 'shared single file.txt' - ), array( 'name' => 'bar.txt', - 'path' => 'shareddir/bar.txt' + 'path' => 'files/shareddir/bar.txt' ), array( 'name' => 'another too.txt', - 'path' => 'shareddir/subdir/another too.txt' + 'path' => 'files/shareddir/subdir/another too.txt' ), array( 'name' => 'another.txt', - 'path' => 'shareddir/subdir/another.txt' + 'path' => 'files/shareddir/subdir/another.txt' ), ); $this->verifyFiles($check, $results); - $results2 = $this->sharedStorage->getCache()->searchByMime('text/plain'); - $this->verifyFiles($check, $results); } function testGetFolderContentsInRoot() { - $results = $this->user2View->getDirectoryContent('/Shared/'); + $results = $this->user2View->getDirectoryContent('/'); + // we should get the shared items "shareddir" and "shared single file.txt" + // additional root will always contain the example file "welcome.txt", + // so this will be part of the result $this->verifyFiles( array( + array( + 'name' => 'welcome.txt', + 'path' => 'files/welcome.txt', + 'mimetype' => 'text/plain', + ), array( 'name' => 'shareddir', - 'path' => '/shareddir', + 'path' => 'files/shareddir', 'mimetype' => 'httpd/unix-directory', - 'usersPath' => 'files/Shared/shareddir' ), array( 'name' => 'shared single file.txt', - 'path' => '/shared single file.txt', + 'path' => 'files/shared single file.txt', 'mimetype' => 'text/plain', - 'usersPath' => 'files/Shared/shared single file.txt' ), ), $results @@ -145,27 +145,24 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { } function testGetFolderContentsInSubdir() { - $results = $this->user2View->getDirectoryContent('/Shared/shareddir'); + $results = $this->user2View->getDirectoryContent('/shareddir'); $this->verifyFiles( array( array( 'name' => 'bar.txt', - 'path' => 'files/container/shareddir/bar.txt', + 'path' => 'files/shareddir/bar.txt', 'mimetype' => 'text/plain', - 'usersPath' => 'files/Shared/shareddir/bar.txt' ), array( 'name' => 'emptydir', - 'path' => 'files/container/shareddir/emptydir', + 'path' => 'files/shareddir/emptydir', 'mimetype' => 'httpd/unix-directory', - 'usersPath' => 'files/Shared/shareddir/emptydir' ), array( 'name' => 'subdir', - 'path' => 'files/container/shareddir/subdir', + 'path' => 'files/shareddir/subdir', 'mimetype' => 'httpd/unix-directory', - 'usersPath' => 'files/Shared/shareddir/subdir' ), ), $results @@ -182,27 +179,24 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { self::loginHelper(self::TEST_FILES_SHARING_API_USER3); $thirdView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER3 . '/files'); - $results = $thirdView->getDirectoryContent('/Shared/subdir'); + $results = $thirdView->getDirectoryContent('/subdir'); $this->verifyFiles( array( array( 'name' => 'another too.txt', - 'path' => 'files/container/shareddir/subdir/another too.txt', + 'path' => 'files/subdir/another too.txt', 'mimetype' => 'text/plain', - 'usersPath' => 'files/Shared/subdir/another too.txt' ), array( 'name' => 'another.txt', - 'path' => 'files/container/shareddir/subdir/another.txt', + 'path' => 'files/subdir/another.txt', 'mimetype' => 'text/plain', - 'usersPath' => 'files/Shared/subdir/another.txt' ), array( 'name' => 'not a text file.xml', - 'path' => 'files/container/shareddir/subdir/not a text file.xml', + 'path' => 'files/subdir/not a text file.xml', 'mimetype' => 'application/xml', - 'usersPath' => 'files/Shared/subdir/not a text file.xml' ), ), $results @@ -254,8 +248,8 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { \OC_Util::tearDownFS(); self::loginHelper(self::TEST_FILES_SHARING_API_USER2); - $this->assertTrue(\OC\Files\Filesystem::file_exists('/Shared/test.txt')); - list($sharedStorage) = \OC\Files\Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/Shared/test.txt'); + $this->assertTrue(\OC\Files\Filesystem::file_exists('/test.txt')); + list($sharedStorage) = \OC\Files\Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/test.txt'); /** * @var \OC\Files\Storage\Shared $sharedStorage */ @@ -275,8 +269,8 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { \OC_Util::tearDownFS(); self::loginHelper(self::TEST_FILES_SHARING_API_USER2); - $this->assertTrue(\OC\Files\Filesystem::file_exists('/Shared/foo')); - list($sharedStorage) = \OC\Files\Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/Shared/foo'); + $this->assertTrue(\OC\Files\Filesystem::file_exists('/foo')); + list($sharedStorage) = \OC\Files\Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/foo'); /** * @var \OC\Files\Storage\Shared $sharedStorage */ diff --git a/apps/files_sharing/tests/permissions.php b/apps/files_sharing/tests/permissions.php index e301d384a49..5ac251b0527 100644 --- a/apps/files_sharing/tests/permissions.php +++ b/apps/files_sharing/tests/permissions.php @@ -23,6 +23,9 @@ require_once __DIR__ . '/base.php'; class Test_Files_Sharing_Permissions extends Test_Files_Sharing_Base { + private $sharedStorageRestrictedShare; + private $sharedCacheRestrictedShare; + function setUp() { parent::setUp(); @@ -55,8 +58,10 @@ class Test_Files_Sharing_Permissions extends Test_Files_Sharing_Base { // retrieve the shared storage $this->secondView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2); - list($this->sharedStorage, $internalPath) = $this->secondView->resolvePath('files/Shared/shareddir'); + list($this->sharedStorage, $internalPath) = $this->secondView->resolvePath('files/shareddir'); + list($this->sharedStorageRestrictedShare, $internalPath) = $this->secondView->resolvePath('files/shareddirrestricted'); $this->sharedCache = $this->sharedStorage->getCache(); + $this->sharedCacheRestrictedShare = $this->sharedStorageRestrictedShare->getCache(); } function tearDown() { @@ -86,9 +91,9 @@ class Test_Files_Sharing_Permissions extends Test_Files_Sharing_Base { $this->assertEquals(31, $sharedDirPerms); $sharedDirPerms = $this->sharedStorage->getPermissions('shareddir/textfile.txt'); $this->assertEquals(31, $sharedDirPerms); - $sharedDirRestrictedPerms = $this->sharedStorage->getPermissions('shareddirrestricted'); + $sharedDirRestrictedPerms = $this->sharedStorageRestrictedShare->getPermissions('shareddirrestricted'); $this->assertEquals(7, $sharedDirRestrictedPerms); - $sharedDirRestrictedPerms = $this->sharedStorage->getPermissions('shareddirrestricted/textfile.txt'); + $sharedDirRestrictedPerms = $this->sharedStorageRestrictedShare->getPermissions('shareddirrestricted/textfile.txt'); $this->assertEquals(7, $sharedDirRestrictedPerms); } @@ -96,12 +101,12 @@ class Test_Files_Sharing_Permissions extends Test_Files_Sharing_Base { * Test that the permissions of shared directory are returned correctly */ function testGetDirectoryPermissions() { - $contents = $this->secondView->getDirectoryContent('files/Shared/shareddir'); + $contents = $this->secondView->getDirectoryContent('files/shareddir'); $this->assertEquals('subdir', $contents[0]['name']); $this->assertEquals(31, $contents[0]['permissions']); $this->assertEquals('textfile.txt', $contents[1]['name']); $this->assertEquals(31, $contents[1]['permissions']); - $contents = $this->secondView->getDirectoryContent('files/Shared/shareddirrestricted'); + $contents = $this->secondView->getDirectoryContent('files/shareddirrestricted'); $this->assertEquals('subdir', $contents[0]['name']); $this->assertEquals(7, $contents[0]['permissions']); $this->assertEquals('textfile1.txt', $contents[1]['name']); diff --git a/apps/files_sharing/tests/watcher.php b/apps/files_sharing/tests/watcher.php index 5ab716e829f..bce93c80a6c 100644 --- a/apps/files_sharing/tests/watcher.php +++ b/apps/files_sharing/tests/watcher.php @@ -48,7 +48,7 @@ class Test_Files_Sharing_Watcher extends Test_Files_Sharing_Base { // retrieve the shared storage $secondView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2); - list($this->sharedStorage, $internalPath) = $secondView->resolvePath('files/Shared/shareddir'); + list($this->sharedStorage, $internalPath) = $secondView->resolvePath('files/shareddir'); $this->sharedCache = $this->sharedStorage->getCache(); } @@ -77,12 +77,12 @@ class Test_Files_Sharing_Watcher extends Test_Files_Sharing_Base { $textData = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $dataLen = strlen($textData); - $this->sharedCache->put('shareddir/bar.txt', array('storage_mtime' => 10)); - $this->sharedStorage->file_put_contents('shareddir/bar.txt', $textData); - $this->sharedCache->put('shareddir', array('storage_mtime' => 10)); + $this->sharedCache->put('bar.txt', array('mtime' => 10, 'storage_mtime' => 10, 'size' => $dataLen, 'mimetype' => 'text/plain')); + $this->sharedStorage->file_put_contents('bar.txt', $textData); + $this->sharedCache->put('', array('mtime' => 10, 'storage_mtime' => 10, 'size' => '-1', 'mimetype' => 'httpd/unix-directory')); // run the propagation code - $result = $this->sharedStorage->getWatcher()->checkUpdate('shareddir'); + $result = $this->sharedStorage->getWatcher()->checkUpdate(''); $this->assertTrue($result); @@ -94,7 +94,7 @@ class Test_Files_Sharing_Watcher extends Test_Files_Sharing_Base { $this->assertEquals($initialSizes['files/container/shareddir'] + $dataLen, $newSizes['files/container/shareddir']); // no more updates - $result = $this->sharedStorage->getWatcher()->checkUpdate('shareddir'); + $result = $this->sharedStorage->getWatcher()->checkUpdate(''); $this->assertFalse($result); } @@ -108,12 +108,12 @@ class Test_Files_Sharing_Watcher extends Test_Files_Sharing_Base { $textData = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $dataLen = strlen($textData); - $this->sharedCache->put('shareddir/subdir/bar.txt', array('storage_mtime' => 10)); - $this->sharedStorage->file_put_contents('shareddir/subdir/bar.txt', $textData); - $this->sharedCache->put('shareddir/subdir', array('storage_mtime' => 10)); + $this->sharedCache->put('subdir/bar.txt', array('mtime' => 10, 'storage_mtime' => 10, 'size' => $dataLen, 'mimetype' => 'text/plain')); + $this->sharedStorage->file_put_contents('subdir/bar.txt', $textData); + $this->sharedCache->put('subdir', array('mtime' => 10, 'storage_mtime' => 10, 'size' => $dataLen, 'mimetype' => 'text/plain')); // run the propagation code - $result = $this->sharedStorage->getWatcher()->checkUpdate('shareddir/subdir'); + $result = $this->sharedStorage->getWatcher()->checkUpdate('subdir'); $this->assertTrue($result); @@ -126,20 +126,9 @@ class Test_Files_Sharing_Watcher extends Test_Files_Sharing_Base { $this->assertEquals($initialSizes['files/container/shareddir/subdir'] + $dataLen, $newSizes['files/container/shareddir/subdir']); // no more updates - $result = $this->sharedStorage->getWatcher()->checkUpdate('shareddir/subdir'); - - $this->assertFalse($result); - } - - function testNoUpdateOnRoot() { - // no updates when called for root path - $result = $this->sharedStorage->getWatcher()->checkUpdate(''); + $result = $this->sharedStorage->getWatcher()->checkUpdate('subdir'); $this->assertFalse($result); - - // FIXME: for some reason when running this "naked" test, - // there will be remaining nonsensical entries in the - // database with a path "test-share-user1/container/..." } /** diff --git a/lib/private/share/share.php b/lib/private/share/share.php index ff56b9a48f1..24e2a150640 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -1177,10 +1177,6 @@ class Share extends \OC\Share\Constants { // Remove root from file source paths if retrieving own shared items if (isset($uidOwner) && isset($row['path'])) { if (isset($row['parent'])) { - // FIXME: Doesn't always construct the correct path, example: - // Folder '/a/b', share '/a' and '/a/b' to user2 - // user2 reshares /Shared/b and ask for share status of /Shared/a/b - // expected result: path=/Shared/a/b; actual result /Shared/b because of the parent $query = \OC_DB::prepare('SELECT `file_target` FROM `*PREFIX*share` WHERE `id` = ?'); $parentResult = $query->execute(array($row['parent'])); if (\OC_DB::isError($result)) { @@ -1189,7 +1185,7 @@ class Share extends \OC\Share\Constants { \OC_Log::ERROR); } else { $parentRow = $parentResult->fetchRow(); - $tmpPath = '/Shared' . $parentRow['file_target']; + $tmpPath = $parentRow['file_target']; // find the right position where the row path continues from the target path $pos = strrpos($row['path'], $parentRow['file_target']); $subPath = substr($row['path'], $pos); -- cgit v1.2.3 From 4c840cb61d560ae567e3e9aaa7bd411cac917e48 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 9 Apr 2014 17:51:54 +0200 Subject: fix target generation for group shares --- lib/private/share/share.php | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'lib/private') diff --git a/lib/private/share/share.php b/lib/private/share/share.php index 24e2a150640..7af68d1b253 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -1395,8 +1395,8 @@ class Share extends \OC\Share\Constants { } } $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`, `item_target`,' - .' `parent`, `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,' - .' `file_target`, `token`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)'); + .' `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,' + .' `file_target`, `token`, `parent`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)'); // Share with a group if ($shareType == self::SHARE_TYPE_GROUP) { $groupItemTarget = Helper::generateTarget($itemType, $itemSource, $shareType, $shareWith['group'], @@ -1440,10 +1440,9 @@ class Share extends \OC\Share\Constants { } else { $groupFileTarget = null; } - $query->execute(array($itemType, $itemSource, $groupItemTarget, $parent, $shareType, - $shareWith['group'], $uidOwner, $permissions, time(), $fileSource, $groupFileTarget, $token)); - // Save this id, any extra rows for this group share will need to reference it - $parent = \OC_DB::insertid('*PREFIX*share'); + $queriesToExecute = array(); + $queriesToExecute['groupShare'] = array($itemType, $itemSource, $groupItemTarget, $shareType, + $shareWith['group'], $uidOwner, $permissions, time(), $fileSource, $groupFileTarget, $token, $parent); // Loop through all users of this group in case we need to add an extra row foreach ($shareWith['users'] as $uid) { $itemTarget = Helper::generateTarget($itemType, $itemSource, self::SHARE_TYPE_USER, $uid, @@ -1469,12 +1468,21 @@ class Share extends \OC\Share\Constants { } // Insert an extra row for the group share if the item or file target is unique for this user if ($itemTarget != $groupItemTarget || (isset($fileSource) && $fileTarget != $groupFileTarget)) { - $query->execute(array($itemType, $itemSource, $itemTarget, $parent, + $queriesToExecute[] = array($itemType, $itemSource, $itemTarget, self::$shareTypeGroupUserUnique, $uid, $uidOwner, $permissions, time(), - $fileSource, $fileTarget, $token)); + $fileSource, $fileTarget, $token); $id = \OC_DB::insertid('*PREFIX*share'); } } + $query->execute($queriesToExecute['groupShare']); + // Save this id, any extra rows for this group share will need to reference it + $parent = \OC_DB::insertid('*PREFIX*share'); + unset($queriesToExecute['groupShare']); + foreach ($queriesToExecute as $qe) { + $qe[] = $parent; + $query->execute($qe); + } + \OC_Hook::emit('OCP\Share', 'post_shared', array( 'itemType' => $itemType, 'itemSource' => $itemSource, @@ -1534,8 +1542,8 @@ class Share extends \OC\Share\Constants { } else { $fileTarget = null; } - $query->execute(array($itemType, $itemSource, $itemTarget, $parent, $shareType, $shareWith, $uidOwner, - $permissions, time(), $fileSource, $fileTarget, $token)); + $query->execute(array($itemType, $itemSource, $itemTarget, $shareType, $shareWith, $uidOwner, + $permissions, time(), $fileSource, $fileTarget, $token, $parent)); $id = \OC_DB::insertid('*PREFIX*share'); \OC_Hook::emit('OCP\Share', 'post_shared', array( 'itemType' => $itemType, -- cgit v1.2.3 From dfb69e9418704d8553193676f3a2ae85697c0fa9 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 11 Apr 2014 11:40:14 +0200 Subject: allow user to delete shared files/folders --- lib/private/files/view.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/private') diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 6d630f978ba..3f73632be13 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -348,7 +348,8 @@ class View { $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); - if (!$internalPath || $internalPath === '' || $internalPath === '/') { + if (!($storage instanceof \OC\Files\Storage\Shared) && + (!$internalPath || $internalPath === '' || $internalPath === '/')) { // do not allow deleting the storage's root / the mount point // because for some storages it might delete the whole contents // but isn't supposed to work that way -- cgit v1.2.3 From bffcbac7a78c8b88b581489cca9bb44795cf81eb Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 14 Apr 2014 12:04:12 +0200 Subject: allow to rename group share mount points --- apps/files_sharing/lib/sharedstorage.php | 43 ++++++++++++++++++++++++++------ lib/private/share/share.php | 1 + 2 files changed, 37 insertions(+), 7 deletions(-) (limited to 'lib/private') diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 7ce9dd58b41..25e6c0abd28 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -317,14 +317,27 @@ class Shared extends \OC\Files\Storage\Common { $relTargetPath = $this->stripUserFilesPath($targetPath); - // rename mount point - $query = \OC_DB::prepare( - 'Update `*PREFIX*share` - SET `file_target` = ? - WHERE `id` = ?' - ); + // if the user renames a mount point from a group share we need to create a new db entry + // for the unique name + if ($this->getShareType() === \OCP\Share::SHARE_TYPE_GROUP && $this->uniqueNameSet() === false) { + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`, `item_target`,' + .' `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,' + .' `file_target`, `token`, `parent`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)'); + $arguments = array($this->share['item_type'], $this->share['item_source'], $this->share['item_target'], + 2, \OCP\User::getUser(), $this->share['uid_owner'], $this->share['permissions'], $this->share['stime'], $this->share['file_source'], + $relTargetPath, $this->share['token'], $this->share['id']); - $result = $query->execute(array($relTargetPath, $this->getShareId())); + } else { + // rename mount point + $query = \OC_DB::prepare( + 'Update `*PREFIX*share` + SET `file_target` = ? + WHERE `id` = ?' + ); + $arguments = array($relTargetPath, $this->getShareId()); + } + + $result = $query->execute($arguments); if ($result) { // update the mount manager with the new paths @@ -333,6 +346,7 @@ class Shared extends \OC\Files\Storage\Common { $mount->setMountPoint($targetPath . '/'); $mountManager->addMount($mount); $mountManager->removeMount($sourcePath . '/'); + $this->setUniqueName(); } else { \OCP\Util::writeLog('file sharing', @@ -486,6 +500,21 @@ class Shared extends \OC\Files\Storage\Common { return $this->share['share_type']; } + /** + * @brief does the group share already has a user specific unique name + * @return bool + */ + private function uniqueNameSet() { + return (isset($this->share['unique_name']) && $this->share['unique_name']); + } + + /** + * @brief the share now uses a unique name of this user + */ + private function setUniqueName() { + $this->share['unique_name'] = true; + } + /** * @brief get share ID * @return integer unique share ID diff --git a/lib/private/share/share.php b/lib/private/share/share.php index 7af68d1b253..756a4d173e4 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -1139,6 +1139,7 @@ class Share extends \OC\Share\Constants { // Filter out duplicate group shares for users with unique targets if ($row['share_type'] == self::$shareTypeGroupUserUnique && isset($items[$row['parent']])) { $row['share_type'] = self::SHARE_TYPE_GROUP; + $row['unique_name'] = true; // remember that we use a unique name for this user $row['share_with'] = $items[$row['parent']]['share_with']; // Remove the parent group share unset($items[$row['parent']]); -- cgit v1.2.3 From 652d417a585ede1564456c446577aa1752253ccd Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 15 Apr 2014 11:19:31 +0200 Subject: we don't allow to share a folder if it contains a share mount point --- apps/files_sharing/lib/cache.php | 7 ++-- apps/files_sharing/lib/sharedstorage.php | 5 +++ apps/files_sharing/tests/api.php | 60 ++++++++++++++++++++++++++++++++ apps/files_sharing/tests/cache.php | 6 ++-- lib/private/files/view.php | 3 +- lib/private/share/share.php | 16 +++++++++ 6 files changed, 90 insertions(+), 7 deletions(-) (limited to 'lib/private') diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 7e44847e404..3d9fbcf4de9 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -411,7 +411,7 @@ class Shared_Cache extends Cache { } /** - * get the path of a file on this storage by it's id + * get the path of a file on this storage relative to the mount point by it's id * * @param int $id * @param string $pathEnd (optional) used internally for recursive calls @@ -419,8 +419,9 @@ class Shared_Cache extends Cache { */ public function getPathById($id, $pathEnd = '') { // direct shares are easy - if ($path = $this->getShareById($id)) { - return $path . $pathEnd; + $path = $this->getShareById($id); + if (is_string($path)) { + return ltrim($pathEnd, '/'); } else { // if the item is a direct share we try and get the path of the parent and append the name of the item to it list($parent, $name) = $this->getParentInfo($id); diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 25e6c0abd28..eedd279bf2b 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -347,6 +347,7 @@ class Shared extends \OC\Files\Storage\Common { $mountManager->addMount($mount); $mountManager->removeMount($sourcePath . '/'); $this->setUniqueName(); + $this->setMountPoint($relTargetPath); } else { \OCP\Util::writeLog('file sharing', @@ -500,6 +501,10 @@ class Shared extends \OC\Files\Storage\Common { return $this->share['share_type']; } + private function setMountPoint($path) { + $this->share['file_target'] = $path; + } + /** * @brief does the group share already has a user specific unique name * @return bool diff --git a/apps/files_sharing/tests/api.php b/apps/files_sharing/tests/api.php index 6354d1099bb..5975eb95882 100644 --- a/apps/files_sharing/tests/api.php +++ b/apps/files_sharing/tests/api.php @@ -866,6 +866,66 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { $this->assertTrue($result3->succeeded()); + // cleanup + \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); + + $result = \OCP\Share::unshare('folder', $fileInfo1['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); + + $this->assertTrue($result); + + + + } + + /** + * @brief share a folder which contains a share mount point, should be forbidden + */ + public function testShareFolderWithAMountPoint() { + // user 1 shares a folder with user2 + \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); + + $fileInfo = $this->view->getFileInfo($this->folder); + + $result = \OCP\Share::shareItem('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31); + + $this->assertTrue($result); + + // user2 shares a file from the folder as link + \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); + + $view = new \OC\Files\View('/' . \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2 . '/files'); + $view->mkdir("localDir"); + + // move mount point to the folder "localDir" + $result = $view->rename($this->folder, 'localDir/'.$this->folder); + $this->assertTrue($result !== false); + + // try to share "localDir" + $fileInfo2 = $view->getFileInfo('localDir'); + + $this->assertTrue($fileInfo2 instanceof \OC\Files\FileInfo); + + try { + $result2 = \OCP\Share::shareItem('folder', $fileInfo2['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER3, 31); + } catch (\Exception $e) { + $result2 = false; + } + + $this->assertFalse($result2); + + //cleanup + + $result = $view->rename('localDir/' . $this->folder, $this->folder); + $this->assertTrue($result !== false); + $view->unlink('localDir'); + + \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); + + \OCP\Share::unshare('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); } } diff --git a/apps/files_sharing/tests/cache.php b/apps/files_sharing/tests/cache.php index 7a52f403d8e..b8ebeab3c39 100644 --- a/apps/files_sharing/tests/cache.php +++ b/apps/files_sharing/tests/cache.php @@ -255,7 +255,7 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { */ $sharedCache = $sharedStorage->getCache(); - $this->assertEquals('test.txt', $sharedCache->getPathById($info->getId())); + $this->assertEquals('', $sharedCache->getPathById($info->getId())); } public function testGetPathByIdShareSubFolder() { @@ -276,7 +276,7 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { */ $sharedCache = $sharedStorage->getCache(); - $this->assertEquals('foo', $sharedCache->getPathById($folderInfo->getId())); - $this->assertEquals('foo/bar/test.txt', $sharedCache->getPathById($fileInfo->getId())); + $this->assertEquals('', $sharedCache->getPathById($folderInfo->getId())); + $this->assertEquals('bar/test.txt', $sharedCache->getPathById($fileInfo->getId())); } } diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 3f73632be13..a61d58aaf24 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -1168,7 +1168,8 @@ class View { * @var \OC\Files\Mount\Mount $mount */ $cache = $mount->getStorage()->getCache(); - if ($internalPath = $cache->getPathById($id)) { + $internalPath = $cache->getPathById($id); + if (is_string($internalPath)) { $fullPath = $mount->getMountPoint() . $internalPath; if (!is_null($path = $this->getRelativePath($fullPath))) { return $path; diff --git a/lib/private/share/share.php b/lib/private/share/share.php index 756a4d173e4..c07dd04b29f 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -489,6 +489,7 @@ class Share extends \OC\Share\Constants { $itemSourceName = $itemSource; } + // verify that the file exists before we try to share it if ($itemType === 'file' or $itemType === 'folder') { $path = \OC\Files\Filesystem::getPath($itemSource); @@ -499,6 +500,21 @@ class Share extends \OC\Share\Constants { } } + //verify that we don't share a folder which already contains a share mount point + if ($itemType === 'folder') { + $path = '/' . $uidOwner . '/files' . \OC\Files\Filesystem::getPath($itemSource) . '/'; + $mountManager = \OC\Files\Filesystem::getMountManager(); + $mounts = $mountManager->getAll(); + foreach ($mounts as $mountPoint => $mount) { + if ($mount->getStorage() instanceof \OC\Files\Storage\Shared && strpos($mountPoint, $path) === 0) { + $message = 'Sharing "' . $itemSourceName . '" failed, because it contains files shared with you!'; + \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); + throw new \Exception($message); + } + + } + } + // Verify share type and sharing conditions are met if ($shareType === self::SHARE_TYPE_USER) { if ($shareWith == $uidOwner) { -- cgit v1.2.3 From fb88aba8f4927b3175df34a2a499978a3b4c1b6b Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 15 Apr 2014 20:18:04 +0200 Subject: some fixes to make the gallery work, this made it necessary to adjust some tests and the encryption code --- apps/files_encryption/hooks/hooks.php | 127 ++++------------------------------ apps/files_encryption/lib/util.php | 101 ++------------------------- apps/files_sharing/lib/cache.php | 5 +- apps/files_sharing/tests/cache.php | 18 ++--- lib/private/share/share.php | 1 + 5 files changed, 33 insertions(+), 219 deletions(-) (limited to 'lib/private') diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 7a8b54e2d75..5f0494e62ca 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -302,25 +302,6 @@ class Hooks { */ public static function postShared($params) { - // NOTE: $params has keys: - // [itemType] => file - // itemSource -> int, filecache file ID - // [parent] => - // [itemTarget] => /13 - // shareWith -> string, uid of user being shared to - // fileTarget -> path of file being shared - // uidOwner -> owner of the original file being shared - // [shareType] => 0 - // [shareWith] => test1 - // [uidOwner] => admin - // [permissions] => 17 - // [fileSource] => 13 - // [fileTarget] => /test8 - // [id] => 10 - // [token] => - // [run] => whether emitting script should continue to run - // TODO: Should other kinds of item be encrypted too? - if (\OCP\App::isEnabled('files_encryption') === false) { return true; } @@ -331,68 +312,22 @@ class Hooks { $session = new \OCA\Encryption\Session($view); $userId = \OCP\User::getUser(); $util = new Util($view, $userId); - $path = $util->fileIdToPath($params['itemSource']); - - $share = $util->getParentFromShare($params['id']); - //if parent is set, then this is a re-share action - if ($share['parent'] !== null) { - - // get the parent from current share - $parent = $util->getShareParent($params['parent']); - - // if parent has the same type than the child it is a 1:1 share - if ($parent['item_type'] === $params['itemType']) { - $path = $parent['file_target']; - } else { - - // NOTE: parent is folder but shared was a file! - // we try to rebuild the missing path - // some examples we face here - // user1 share folder1 with user2 folder1 has - // the following structure - // /folder1/subfolder1/subsubfolder1/somefile.txt - // user2 re-share subfolder2 with user3 - // user3 re-share somefile.txt user4 - // so our path should be - // /Shared/subfolder1/subsubfolder1/somefile.txt - // while user3 is sharing - - if ($params['itemType'] === 'file') { - // get target path - $targetPath = $util->fileIdToPath($params['fileSource']); - $targetPathSplit = array_reverse(explode('/', $targetPath)); - - // init values - $path = ''; - $sharedPart = ltrim($parent['file_target'], '/'); - - // rebuild path - foreach ($targetPathSplit as $pathPart) { - if ($pathPart !== $sharedPart) { - $path = '/' . $pathPart . $path; - } else { - break; - } - } - $path = $parent['file_target'] . $path; - } else { - $path = $parent['file_target'] . $params['fileTarget']; - } - } - } + $path = \OC\Files\Filesystem::getPath($params['fileSource']); $sharingEnabled = \OCP\Share::isEnabled(); // get the path including mount point only if not a shared folder list($storage, ) = \OC\Files\Filesystem::resolvePath('/' . $userId . '/files' . $path); - if (!($storage instanceof \OC\Files\Storage\Shared)) { - // get path including the the storage mount point - $path = $util->getPathWithMountPoint($params['itemSource']); + + if (!($storage instanceof \OC\Files\Storage\Local)) { + $mountPoint = 'files' . $storage->getMountPoint(); + } else { + $mountPoint = ''; } // if a folder was shared, get a list of all (sub-)folders if ($params['itemType'] === 'folder') { - $allFiles = $util->getAllFiles($path); + $allFiles = $util->getAllFiles($path, $mountPoint); } else { $allFiles = array($path); } @@ -409,13 +344,6 @@ class Hooks { */ public static function postUnshare($params) { - // NOTE: $params has keys: - // [itemType] => file - // [itemSource] => 13 - // [shareType] => 0 - // [shareWith] => test1 - // [itemParent] => - if (\OCP\App::isEnabled('files_encryption') === false) { return true; } @@ -425,34 +353,7 @@ class Hooks { $view = new \OC_FilesystemView('/'); $userId = \OCP\User::getUser(); $util = new Util($view, $userId); - $path = $util->fileIdToPath($params['itemSource']); - - // check if this is a re-share - if ($params['itemParent']) { - - // get the parent from current share - $parent = $util->getShareParent($params['itemParent']); - - // get target path - $targetPath = $util->fileIdToPath($params['itemSource']); - $targetPathSplit = array_reverse(explode('/', $targetPath)); - - // init values - $path = ''; - $sharedPart = ltrim($parent['file_target'], '/'); - - // rebuild path - foreach ($targetPathSplit as $pathPart) { - if ($pathPart !== $sharedPart) { - $path = '/' . $pathPart . $path; - } else { - break; - } - } - - // prefix path with Shared - $path = $parent['file_target'] . $path; - } + $path = \OC\Files\Filesystem::getPath($params['fileSource']); // for group shares get a list of the group members if ($params['shareType'] === \OCP\Share::SHARE_TYPE_GROUP) { @@ -466,15 +367,17 @@ class Hooks { } // get the path including mount point only if not a shared folder - list($storage, ) = \OC\Files\Filesystem::resolvePath($path); - if (!($storage instanceof \OC\Files\Storage\Shared)) { - // get path including the the storage mount point - //$path = $util->getPathWithMountPoint($params['itemSource']); + list($storage, ) = \OC\Files\Filesystem::resolvePath('/' . $userId . '/files' . $path); + + if (!($storage instanceof \OC\Files\Storage\Local)) { + $mountPoint = 'files' . $storage->getMountPoint(); + } else { + $mountPoint = ''; } // if we unshare a folder we need a list of all (sub-)files if ($params['itemType'] === 'folder') { - $allFiles = $util->getAllFiles($path); + $allFiles = $util->getAllFiles($path, $mountPoint); } else { $allFiles = array($path); } diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 4be4ab95653..6372ab31b6e 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -969,33 +969,6 @@ class Util { } - /** - * @brief get path of a file. - * @param int $fileId id of the file - * @return string path of the file - */ - public static function fileIdToPath($fileId) { - - $sql = 'SELECT `path` FROM `*PREFIX*filecache` WHERE `fileid` = ?'; - - $query = \OCP\DB::prepare($sql); - - $result = $query->execute(array($fileId)); - - $path = false; - if (\OCP\DB::isError($result)) { - \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); - } else { - $row = $result->fetchRow(); - if ($row) { - $path = substr($row['path'], strlen('files')); - } - } - - return $path; - - } - /** * @brief Filter an array of UIDs to return only ones ready for sharing * @param array $unfilteredUsers users to be checked for sharing readiness @@ -1398,7 +1371,7 @@ class Util { * @param string $dir relative to the users files folder * @return array with list of files relative to the users files folder */ - public function getAllFiles($dir) { + public function getAllFiles($dir, $mountPoint = '') { $result = array(); $dirList = array($dir); @@ -1408,10 +1381,13 @@ class Util { $this->userFilesDir . '/' . $dir)); foreach ($content as $c) { + // getDirectoryContent() returns the paths relative to the mount points, so we need + // to re-construct the complete path + $path = ($mountPoint !== '') ? $mountPoint . '/' . $c['path'] : $c['path']; if ($c['type'] === 'dir') { - $dirList[] = substr($c['path'], strlen("files")); + $dirList[] = substr($path, strlen("files")); } else { - $result[] = substr($c['path'], strlen("files")); + $result[] = substr($path, strlen("files")); } } @@ -1420,54 +1396,6 @@ class Util { return $result; } - /** - * @brief get shares parent. - * @param int $id of the current share - * @return array of the parent - */ - public static function getShareParent($id) { - - $sql = 'SELECT `file_target`, `item_type` FROM `*PREFIX*share` WHERE `id` = ?'; - - $query = \OCP\DB::prepare($sql); - - $result = $query->execute(array($id)); - - $row = array(); - if (\OCP\DB::isError($result)) { - \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); - } else { - $row = $result->fetchRow(); - } - - return $row; - - } - - /** - * @brief get shares parent. - * @param int $id of the current share - * @return array of the parent - */ - public static function getParentFromShare($id) { - - $sql = 'SELECT `parent` FROM `*PREFIX*share` WHERE `id` = ?'; - - $query = \OCP\DB::prepare($sql); - - $result = $query->execute(array($id)); - - $row = array(); - if (\OCP\DB::isError($result)) { - \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); - } else { - $row = $result->fetchRow(); - } - - return $row; - - } - /** * @brief get owner of the shared files. * @param $id @@ -1709,23 +1637,6 @@ class Util { $this->recoverAllFiles('/', $privateKey); } - /** - * Get the path including the storage mount point - * @param int $id - * @return string the path including the mount point like AmazonS3/folder/file.txt - */ - public function getPathWithMountPoint($id) { - list($storage, $internalPath) = \OC\Files\Cache\Cache::getById($id); - $mount = \OC\Files\Filesystem::getMountByStorageId($storage); - $mountPoint = $mount[0]->getMountPoint(); - $path = \OC\Files\Filesystem::normalizePath($mountPoint . '/' . $internalPath); - - // reformat the path to be relative e.g. /user/files/folder becomes /folder/ - $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path); - - return $relativePath; - } - /** * @brief check if the file is stored on a system wide mount point * @param $path relative to /data/user with leading '/' diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 3d9fbcf4de9..4b473c60577 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -141,15 +141,14 @@ class Shared_Cache extends Cache { $folder = ''; } - $dir = 'files' . $this->storage->getMountPoint(); - $dir .= ($folder !== '') ? '/' . $folder : ''; + $dir = ($folder !== '') ? $folder . '/' : ''; $cache = $this->getSourceCache($folder); if ($cache) { $parent = $this->storage->getFile($folder); $sourceFolderContent = $cache->getFolderContents($this->files[$folder]); foreach ($sourceFolderContent as $key => $c) { - $sourceFolderContent[$key]['path'] = $dir . '/' . $c['name']; + $sourceFolderContent[$key]['path'] = $dir . $c['name']; $sourceFolderContent[$key]['uid_owner'] = $parent['uid_owner']; $sourceFolderContent[$key]['displayname_owner'] = $parent['uid_owner']; } diff --git a/apps/files_sharing/tests/cache.php b/apps/files_sharing/tests/cache.php index b8ebeab3c39..1af73c558d5 100644 --- a/apps/files_sharing/tests/cache.php +++ b/apps/files_sharing/tests/cache.php @@ -100,15 +100,15 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { $check = array( array( 'name' => 'bar.txt', - 'path' => 'files/shareddir/bar.txt' + 'path' => 'bar.txt' ), array( 'name' => 'another too.txt', - 'path' => 'files/shareddir/subdir/another too.txt' + 'path' => 'subdir/another too.txt' ), array( 'name' => 'another.txt', - 'path' => 'files/shareddir/subdir/another.txt' + 'path' => 'subdir/another.txt' ), ); $this->verifyFiles($check, $results); @@ -151,17 +151,17 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { array( array( 'name' => 'bar.txt', - 'path' => 'files/shareddir/bar.txt', + 'path' => 'bar.txt', 'mimetype' => 'text/plain', ), array( 'name' => 'emptydir', - 'path' => 'files/shareddir/emptydir', + 'path' => 'emptydir', 'mimetype' => 'httpd/unix-directory', ), array( 'name' => 'subdir', - 'path' => 'files/shareddir/subdir', + 'path' => 'subdir', 'mimetype' => 'httpd/unix-directory', ), ), @@ -185,17 +185,17 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { array( array( 'name' => 'another too.txt', - 'path' => 'files/subdir/another too.txt', + 'path' => 'another too.txt', 'mimetype' => 'text/plain', ), array( 'name' => 'another.txt', - 'path' => 'files/subdir/another.txt', + 'path' => 'another.txt', 'mimetype' => 'text/plain', ), array( 'name' => 'not a text file.xml', - 'path' => 'files/subdir/not a text file.xml', + 'path' => 'not a text file.xml', 'mimetype' => 'application/xml', ), ), diff --git a/lib/private/share/share.php b/lib/private/share/share.php index c07dd04b29f..4e3e261baf5 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -896,6 +896,7 @@ class Share extends \OC\Share\Constants { $hookParams = array( 'itemType' => $item['item_type'], 'itemSource' => $item['item_source'], + 'fileSource' => $item['file_source'], 'shareType' => $item['share_type'], 'shareWith' => $item['share_with'], 'itemParent' => $item['parent'], -- cgit v1.2.3 From 93469ca46865d02d33710a2f70f7f6092c8f5c58 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 16 Apr 2014 16:41:23 +0200 Subject: make it possible to move files out of a shared mount point --- apps/files_sharing/lib/helper.php | 31 +++++++++++++++++++++++++++++++ apps/files_sharing/lib/sharedstorage.php | 27 ++++++++++++++------------- lib/private/files/view.php | 8 ++++---- 3 files changed, 49 insertions(+), 17 deletions(-) (limited to 'lib/private') diff --git a/apps/files_sharing/lib/helper.php b/apps/files_sharing/lib/helper.php index e2780e98935..cc1f7d9ffdf 100644 --- a/apps/files_sharing/lib/helper.php +++ b/apps/files_sharing/lib/helper.php @@ -145,4 +145,35 @@ class Helper { return $result; } + + public static function getUidAndFilename($filename) { + $uid = \OC\Files\Filesystem::getOwner($filename); + \OC\Files\Filesystem::initMountPoints($uid); + if ( $uid != \OCP\User::getUser() ) { + $info = \OC\Files\Filesystem::getFileInfo($filename); + $ownerView = new \OC\Files\View('/'.$uid.'/files'); + $filename = $ownerView->getPath($info['fileid']); + } + return array($uid, $filename); + } + + /** + * @brief Format a path to be relative to the /user/files/ directory + * @param string $path the absolute path + * @return string e.g. turns '/admin/files/test.txt' into 'test.txt' + */ + public static function stripUserFilesPath($path) { + $trimmed = ltrim($path, '/'); + $split = explode('/', $trimmed); + + // it is not a file relative to data/user/files + if (count($split) < 3 || $split[1] !== 'files') { + return false; + } + + $sliced = array_slice($split, 2); + $relPath = implode('/', $sliced); + + return $relPath; + } } diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index b8a799f720d..5e478d5ead8 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -362,6 +362,9 @@ class Shared extends \OC\Files\Storage\Common { public function rename($path1, $path2) { $sourceMountPoint = \OC\Files\Filesystem::getMountPoint($path1); + $targetMountPoint = \OC\Files\Filesystem::getMountPoint($path2); + $relPath1 = \OCA\Files_Sharing\Helper::stripUserFilesPath($path1); + $relPath2 = \OCA\Files_Sharing\Helper::stripUserFilesPath($path2); // if we renamed the mount point we need to adjust the file_target in the // database @@ -369,21 +372,19 @@ class Shared extends \OC\Files\Storage\Common { return $this->renameMountPoint($path1, $path2); } - // Renaming/moving is only allowed within shared folders - $oldSource = $this->getSourcePath($path1); - if ($oldSource) { - $newSource = $this->getSourcePath(dirname($path2)) . '/' . basename($path2); - // Within the same folder, we only need UPDATE permissions - if (dirname($path1) == dirname($path2) and $this->isUpdatable($path1)) { - list($storage, $oldInternalPath) = \OC\Files\Filesystem::resolvePath($oldSource); - list(, $newInternalPath) = \OC\Files\Filesystem::resolvePath($newSource); - return $storage->rename($oldInternalPath, $newInternalPath); + + if ( // Within the same mount point, we only need UPDATE permissions + ($sourceMountPoint === $targetMountPoint && $this->isUpdatable($sourceMountPoint)) || // otherwise DELETE and CREATE permissions required - } elseif ($this->isDeletable($path1) && $this->isCreatable(dirname($path2))) { - $rootView = new \OC\Files\View(''); - return $rootView->rename($oldSource, $newSource); - } + ($this->isDeletable($path1) && $this->isCreatable(dirname($path2)))) { + + list($user1, $path1) = \OCA\Files_Sharing\Helper::getUidAndFilename($relPath1); + $targetFilename = basename($relPath2); + list($user2, $path2) = \OCA\Files_Sharing\Helper::getUidAndFilename(dirname($relPath2)); + $rootView = new \OC\Files\View(''); + return $rootView->rename('/' . $user1 . '/files/' . $path1, '/' . $user2 . '/files/' . $path2 . '/' . $targetFilename); } + return false; } diff --git a/lib/private/files/view.php b/lib/private/files/view.php index a61d58aaf24..58dfc73dcf3 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -410,16 +410,16 @@ class View { // if source and target are on the same storage we can call the rename operation from the // storage. If it is a "Shared" file/folder we call always the rename operation of the // shared storage to handle mount point renaming, etc correctly - if ($mp1 == $mp2) { + if ($storage1 instanceof \OC\Files\Storage\Shared) { if ($storage1) { - $result = $storage1->rename($internalPath1, $internalPath2); + $result = $storage1->rename($absolutePath1, $absolutePath2); \OC_FileProxy::runPostProxies('rename', $absolutePath1, $absolutePath2); } else { $result = false; } - } elseif ($storage1 instanceof \OC\Files\Storage\Shared) { + } elseif ($mp1 == $mp2) { if ($storage1) { - $result = $storage1->rename($absolutePath1, $absolutePath2); + $result = $storage1->rename($internalPath1, $internalPath2); \OC_FileProxy::runPostProxies('rename', $absolutePath1, $absolutePath2); } else { $result = false; -- cgit v1.2.3 From 7ef8f6d352811e635bc6cf99b56d9482a54eb791 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 17 Apr 2014 15:54:45 +0200 Subject: always allow to rename the share mount point --- apps/files/js/filelist.js | 13 ++++++++++++- apps/files/lib/helper.php | 3 +++ apps/files_sharing/lib/cache.php | 4 ++++ lib/private/connector/sabre/objecttree.php | 8 +++++++- 4 files changed, 26 insertions(+), 2 deletions(-) (limited to 'lib/private') diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 343da217416..390bf4e0577 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -178,6 +178,13 @@ window.FileList = { if (type === 'dir') { mime = mime || 'httpd/unix-directory'; } + + // user should always be able to rename a share mount point + var allowRename = 0; + if (fileData.isShareMountPoint) { + allowRename = OC.PERMISSION_UPDATE; + } + //containing tr var tr = $('').attr({ "data-id" : fileData.id, @@ -187,7 +194,7 @@ window.FileList = { "data-mime": mime, "data-mtime": mtime, "data-etag": fileData.etag, - "data-permissions": fileData.permissions || this.getDirectoryPermissions() + "data-permissions": fileData.permissions | allowRename || this.getDirectoryPermissions() }); if (type === 'dir') { @@ -283,6 +290,10 @@ window.FileList = { mime = fileData.mimetype, permissions = parseInt(fileData.permissions, 10) || 0; + if (fileData.isShareMountPoint) { + permissions = permissions | OC.PERMISSION_UPDATE; + } + if (type === 'dir') { mime = mime || 'httpd/unix-directory'; } diff --git a/apps/files/lib/helper.php b/apps/files/lib/helper.php index 88a5ffcfb61..0ae87d12fbf 100644 --- a/apps/files/lib/helper.php +++ b/apps/files/lib/helper.php @@ -96,6 +96,9 @@ class Helper if (isset($i['displayname_owner'])) { $entry['shareOwner'] = $i['displayname_owner']; } + if (isset($i['is_share_mount_point'])) { + $entry['isShareMountPoint'] = $i['is_share_mount_point']; + } return $entry; } diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 4a2f0ff08b2..67a0410ef76 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -91,6 +91,9 @@ class Shared_Cache extends Cache { $data = $cache->get($this->files[$file]); $data['displayname_owner'] = \OC_User::getDisplayName($this->storage->getSharedFrom()); $data['path'] = $path; + if ($file === '') { + $data['is_share_mount_point'] = true; + } return $data; } } else { @@ -123,6 +126,7 @@ class Shared_Cache extends Cache { } if (isset($mountPoint)) { $data['path'] = 'files/' . $mountPoint; + $data['is_share_mount_point'] = true; } return $data; } diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php index d2fa425b22c..2956f608380 100644 --- a/lib/private/connector/sabre/objecttree.php +++ b/lib/private/connector/sabre/objecttree.php @@ -87,9 +87,15 @@ class ObjectTree extends \Sabre_DAV_ObjectTree { list($sourceDir,) = \Sabre_DAV_URLUtil::splitPath($sourcePath); list($destinationDir,) = \Sabre_DAV_URLUtil::splitPath($destinationPath); + $isShareMountPoint = false; + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath( '/' . \OCP\User::getUser() . '/files/' . $sourcePath); + if ($storage instanceof \OC\Files\Storage\Shared && !$internalPath) { + $isShareMountPoint = true; + } + // check update privileges $fs = $this->getFileView(); - if (!$fs->isUpdatable($sourcePath)) { + if (!$fs->isUpdatable($sourcePath) && !$isShareMountPoint) { throw new \Sabre_DAV_Exception_Forbidden(); } if ($sourceDir !== $destinationDir) { -- cgit v1.2.3 From b312d38d38c4e391765beb0aadb6bd2eafd9cb2c Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 23 Apr 2014 12:59:22 +0200 Subject: remove hard-coded shared folder --- lib/private/share/share.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/private') diff --git a/lib/private/share/share.php b/lib/private/share/share.php index 4e3e261baf5..4a76a010ebd 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -223,7 +223,7 @@ class Share extends \OC\Share\Constants { } else { while ($row = $result->fetchRow()) { foreach ($fileTargets[$row['fileid']] as $uid => $shareData) { - $sharedPath = '/Shared' . $shareData['file_target']; + $sharedPath = $shareData['file_target']; $sharedPath .= substr($path, strlen($row['path']) -5); $sharePaths[$uid] = $sharedPath; } -- cgit v1.2.3 From ff0dab6e92f71dab31d902d2ae9a6ba87f0cea88 Mon Sep 17 00:00:00 2001 From: Volkan Gezer Date: Thu, 24 Apr 2014 01:42:18 +0200 Subject: This adds one more missing untranslated text from lib/share Also displays the untrusted domain warning in English --- lib/base.php | 5 +++-- lib/private/share/share.php | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'lib/private') diff --git a/lib/base.php b/lib/base.php index 83f54a8e4db..0f55c1175c7 100644 --- a/lib/base.php +++ b/lib/base.php @@ -698,6 +698,7 @@ class OC { * @brief Handle the request */ public static function handleRequest() { + $l = \OC_L10N::get('lib'); // load all the classpaths from the enabled apps so they are available // in the routing files of each app OC::loadAppClassPaths(); @@ -719,8 +720,8 @@ class OC { header('HTTP/1.1 400 Bad Request'); header('Status: 400 Bad Request'); OC_Template::printErrorPage( - 'You are accessing the server from an untrusted domain.', - 'Please contact your administrator' + $l->t('You are accessing the server from an untrusted domain.'), + $l->t('Please contact your administrator') ); return; } diff --git a/lib/private/share/share.php b/lib/private/share/share.php index 3751b035bd4..fe756b5ae7f 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -477,9 +477,10 @@ class Share extends \OC\Share\Constants { if ($itemType === 'file' or $itemType === 'folder') { $path = \OC\Files\Filesystem::getPath($itemSource); if (!$path) { - $message = 'Sharing ' . $itemSourceName . ' failed, because the file does not exist'; - \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); - throw new \Exception($message); + $message = 'Sharing %s failed, because the file does not exist'; + $message_t = $l->t('Sharing %s failed, because the file does not exist', array($itemSourceName)); + \OC_Log::write('OCP\Share', sprintf($message, $itemSourceName), \OC_Log::ERROR); + throw new \Exception($message_t); } } -- cgit v1.2.3 From 6650be99136bbeecc39a28cbe9c22de0c5cf08ac Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 23 Apr 2014 12:50:24 +0200 Subject: add setting to set default expire date --- lib/private/share/helper.php | 49 ++++++++++++++++++++++++++++++++++++++++ lib/private/share/share.php | 15 ++++++++++-- settings/admin.php | 4 ++++ settings/css/settings.css | 1 + settings/templates/admin.php | 19 +++++++++++++++- tests/lib/share/helper.php | 54 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 139 insertions(+), 3 deletions(-) create mode 100644 tests/lib/share/helper.php (limited to 'lib/private') diff --git a/lib/private/share/helper.php b/lib/private/share/helper.php index fde55667281..515ec85909a 100644 --- a/lib/private/share/helper.php +++ b/lib/private/share/helper.php @@ -199,4 +199,53 @@ class Helper extends \OC\Share\Constants { $query->execute(); } } + + /** + * @brief get default expire settings defined by the admin + * @return array contains 'defaultExpireDateSet', 'enforceExpireDate', 'expireAfterDays' + */ + public static function getDefaultExpireSetting() { + + $defaultExpireSettings = array('defaultExpireDateSet' => false); + + // get default expire settings + $defaultExpireDate = \OC_Appconfig::getValue('core', 'shareapi_default_expire_date', 'no'); + if ($defaultExpireDate === 'yes') { + $enforceExpireDate = \OC_Appconfig::getValue('core', 'shareapi_enforce_expire_date', 'no'); + $defaultExpireSettings['defaultExpireDateSet'] = true; + $defaultExpireSettings['expireAfterDays'] = (int)\OC_Appconfig::getValue('core', 'shareapi_expire_after_n_days', '7'); + $defaultExpireSettings['enforceExpireDate'] = $enforceExpireDate === 'yes' ? true : false; + } + + return $defaultExpireSettings; + } + + /** + * @brief calculate expire date + * @param array $defaultExpireSettings contains 'defaultExpireDateSet', 'enforceExpireDate', 'expireAfterDays' + * @param int $creationTime timestamp when the share was created + * @param int $userExpireDate expire timestamp set by the user + * @return mixed integer timestamp or False + */ + public static function calculateExpireDate($defaultExpireSettings, $creationTime, $userExpireDate = null) { + + $expires = false; + + if (isset($defaultExpireSettings['defaultExpireDateSet']) && $defaultExpireSettings['defaultExpireDateSet']) { + $expires = $creationTime + $defaultExpireSettings['expireAfterDays'] * 86400; + } + + + if (isset($userExpireDate)) { + // if the admin decided to enforce the default expire date then we only take + // the user defined expire date of it is before the default expire date + if ($expires && isset($defaultExpireSettings['enforceExpireDate']) && $defaultExpireSettings['enforceExpireDate']) { + $expires = ($userExpireDate < $expires) ? $userExpireDate : $expires; + } else { + $expires = $userExpireDate; + } + } + + return $expires; + } } diff --git a/lib/private/share/share.php b/lib/private/share/share.php index fe756b5ae7f..a18c54af8a3 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -844,9 +844,20 @@ class Share extends \OC\Share\Constants { * @return bool True if item was expired, false otherwise. */ protected static function expireItem(array $item) { + + // get default expire settings + $defaultSettings = Helper::getDefaultExpireSetting(); + // calculate expire date if (!empty($item['expiration'])) { - $now = new \DateTime(); - $expires = new \DateTime($item['expiration']); + $userDefinedExpire = new \DateTime($item['expiration']); + $userDefinedExpireTimestamp = $userDefinedExpire->getTimestamp(); + } else { + $userDefinedExpireTimestamp = null; + } + $expires = Helper::calculateExpireDate($defaultSettings, $item['stime'], $userDefinedExpireTimestamp); + + if (is_int($expires)) { + $now = time(); if ($now > $expires) { self::unshareItem($item); return true; diff --git a/settings/admin.php b/settings/admin.php index bce18b7cf6a..49dde59ce2a 100755 --- a/settings/admin.php +++ b/settings/admin.php @@ -45,6 +45,10 @@ $tmpl->assign('backgroundjobs_mode', OC_Appconfig::getValue('core', 'backgroundj $tmpl->assign('cron_log', OC_Config::getValue('cron_log', true)); $tmpl->assign('lastcron', OC_Appconfig::getValue('core', 'lastcron', false)); $tmpl->assign('shareAPIEnabled', OC_Appconfig::getValue('core', 'shareapi_enabled', 'yes')); +$tmpl->assign('shareDefaultExpireDateSet', OC_Appconfig::getValue('core', 'shareapi_default_expire_date', 'no')); +$tmpl->assign('shareExpireAfterNDays', OC_Appconfig::getValue('core', 'shareapi_expire_after_n_days', '7')); +$tmpl->assign('shareEnforceExpireDate', OC_Appconfig::getValue('core', 'shareapi_enforce_expire_date', 'no')); + // Check if connected using HTTPS if (OC_Request::serverProtocol() === 'https') { diff --git a/settings/css/settings.css b/settings/css/settings.css index a7680aad948..5d8f9a7541c 100644 --- a/settings/css/settings.css +++ b/settings/css/settings.css @@ -132,6 +132,7 @@ table.grid td.date{ span.securitywarning {color:#C33; font-weight:bold; } span.connectionwarning {color:#933; font-weight:bold; } table.shareAPI td { padding-bottom: 0.8em; } +table.shareAPI input#shareapi_expire_after_n_days {width: 25px;} #mail_settings p label:first-child { display: inline-block; diff --git a/settings/templates/admin.php b/settings/templates/admin.php index 07b5ee7860e..8eb1beb9566 100644 --- a/settings/templates/admin.php +++ b/settings/templates/admin.php @@ -254,6 +254,23 @@ if (!$_['internetconnectionworking']) { t('Allow users to send mail notification for shared files')); ?> + + + > + /> +
+ t( 'Expire after ' )); ?> + ' /> + t( 'days' )); ?> + /> +
+ t('Expire shares by default after N days')); ?> + + + @@ -296,7 +313,7 @@ if (!$_['internetconnectionworking']) {

t('This is used for sending out notifications.')); ?>

- +