From efea86870473da5a2cdc867e171562525266c663 Mon Sep 17 00:00:00 2001 From: Florian Scholz Date: Mon, 17 Jun 2013 14:21:53 +0200 Subject: [PATCH 001/118] - removed slash-adding for logout-header-redirect --- lib/base.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/base.php b/lib/base.php index a6e4a47dbf5..ff9dd1ad1eb 100644 --- a/lib/base.php +++ b/lib/base.php @@ -641,7 +641,7 @@ class OC { OC_Preferences::deleteKey(OC_User::getUser(), 'login_token', $_COOKIE['oc_token']); } OC_User::logout(); - header("Location: " . OC::$WEBROOT . '/'); + header("Location: " . OC::$WEBROOT); } else { if (is_null($file)) { $param['file'] = 'index.php'; From b1fd9b39074f46b635d66c80d63994ffc99bf286 Mon Sep 17 00:00:00 2001 From: Florian Scholz Date: Tue, 25 Jun 2013 10:45:37 +0200 Subject: [PATCH 002/118] - add slash if webroot is an empty string - added comment --- lib/base.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/base.php b/lib/base.php index ff9dd1ad1eb..39e0249477b 100644 --- a/lib/base.php +++ b/lib/base.php @@ -641,7 +641,8 @@ class OC { OC_Preferences::deleteKey(OC_User::getUser(), 'login_token', $_COOKIE['oc_token']); } OC_User::logout(); - header("Location: " . OC::$WEBROOT); + // redirect to webroot and add slash if webroot is empty + header("Location: " . OC::$WEBROOT.(empty(OC::$WEBROOT) ? '/' : '')); } else { if (is_null($file)) { $param['file'] = 'index.php'; From 48e426b589029b8e616be2785afc8c0b4b4aecaf Mon Sep 17 00:00:00 2001 From: root Date: Fri, 6 Dec 2013 16:46:52 +0100 Subject: [PATCH 003/118] add support for nested groups --- apps/user_ldap/group_ldap.php | 79 +++++++++++++++++++++++---- apps/user_ldap/lib/configuration.php | 3 + apps/user_ldap/templates/settings.php | 1 + 3 files changed, 73 insertions(+), 10 deletions(-) diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php index 32e2cec5960..0a5ab192763 100644 --- a/apps/user_ldap/group_ldap.php +++ b/apps/user_ldap/group_ldap.php @@ -61,8 +61,7 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { return false; } //usually, LDAP attributes are said to be case insensitive. But there are exceptions of course. - $members = $this->access->readAttribute($dn_group, - $this->access->connection->ldapGroupMemberAssocAttr); + $members = array_keys($this->_groupMembers($dn_group)); if(!$members) { $this->access->connection->writeToCache('inGroup'.$uid.':'.$gid, false); return false; @@ -89,6 +88,39 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { return $isInGroup; } + private function _groupMembers($dn_group, &$groups_seen = null) { + if ($groups_seen == null) { + $groups_seen = array(); + } + $all_members = array(); + if (array_key_exists($dn_group, $groups_seen)) { + // avoid loops + return array(); + } + // used extensively in cron job, caching makes sense for nested groups + $cache_key = '_groupMembers'.$dn_group; + if($this->access->connection->isCached($cache_key)) { + \OCP\Util::writeLog('user_ldap', 'LEO _groupMembers('.$dn_group.') using cached value', \OCP\Util::DEBUG); + return $this->access->connection->getFromCache($cache_key); + } + $groups_seen[$dn_group] = 1; + $members = $this->access->readAttribute($dn_group, $this->access->connection->ldapGroupMemberAssocAttr, + $this->access->connection->ldapGroupFilter); + if ($members) { + foreach ($members as $member_dn) { + $all_members[$member_dn] = 1; + if ($this->access->connection->ldapNestedGroups) { + $submembers = $this->_groupMembers($member_dn, $groups_seen); + if ($submembers) { + $all_members = array_merge($all_members, $submembers); + } + } + } + } + $this->access->connection->writeToCache($cache_key, $all_members); + return $all_members; + } + /** * @brief Get all groups a user belongs to * @param $uid Name of the user @@ -124,18 +156,45 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { $uid = $userDN; } - $filter = $this->access->combineFilterWithAnd(array( - $this->access->connection->ldapGroupFilter, - $this->access->connection->ldapGroupMemberAssocAttr.'='.$uid - )); - $groups = $this->access->fetchListOfGroups($filter, - array($this->access->connection->ldapGroupDisplayName, 'dn')); + $groups = array_values($this->_getGroupsByMember($uid)); $groups = array_unique($this->access->ownCloudGroupNames($groups), SORT_LOCALE_STRING); + \OCP\Util::writeLog('user_ldap', 'LEO _getGroupsByMember('.$uid.'): '.implode(", ", $groups), \OCP\Util::DEBUG); $this->access->connection->writeToCache($cacheKey, $groups); return $groups; } + /* private */ public function _getGroupsByMember($dn, &$seen = null) { + if ($seen == null) { + $seen = array(); + } + $all_groups = array(); + if (array_key_exists($dn, $seen)) { + // avoid loops + return array(); + } + $seen[$dn] = 1; + $filter = $this->combineFilterWithAnd(array( + $this->access->connection->ldapGroupFilter, + $this->access->connection->ldapGroupMemberAssocAttr.'='.$dn + )); + $groups = $this->fetchListOfGroups($filter, + array($this->access->connection->ldapGroupDisplayName, 'dn')); + if ($groups) { + foreach ($groups as $groupobj) { + $group_dn = $groupobj['dn']; + $all_groups[$group_dn] = $groupobj; + if ($this->access->connection->ldapNestedGroups) { + $supergroups = $this->_getGroupsByMember($group_dn, $seen); + if ($supergroups) { + $all_groups = array_merge($all_groups, $supergroups); + } + } + } + } + return $all_groups; + } + /** * @brief get a list of all users in a group * @returns array with user ids @@ -172,8 +231,8 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { return array(); } - $members = $this->access->readAttribute($groupDN, - $this->access->connection->ldapGroupMemberAssocAttr); + $members = array_keys($this->_groupMembers($groupDN)); + \OCP\Util::writeLog('user_ldap', 'LEO _groupMembers('.$groupDN.'): '.implode(", ", $members), \OCP\Util::DEBUG); if(!$members) { //in case users could not be retrieved, return empty resultset $this->access->connection->writeToCache($cachekey, array()); diff --git a/apps/user_ldap/lib/configuration.php b/apps/user_ldap/lib/configuration.php index 874082f78f6..bceacdfdf80 100644 --- a/apps/user_ldap/lib/configuration.php +++ b/apps/user_ldap/lib/configuration.php @@ -76,6 +76,7 @@ class Configuration { 'ldapExpertUUIDUserAttr' => null, 'ldapExpertUUIDGroupAttr' => null, 'lastJpegPhotoLookup' => null, + 'ldapNestedGroups' => false, ); public function __construct($configPrefix, $autoread = true) { @@ -338,6 +339,7 @@ class Configuration { 'ldap_expert_uuid_group_attr' => '', 'has_memberof_filter_support' => 0, 'last_jpegPhoto_lookup' => 0, + 'ldap_nested_groups' => 0, ); } @@ -389,6 +391,7 @@ class Configuration { 'ldap_expert_uuid_group_attr' => 'ldapExpertUUIDGroupAttr', 'has_memberof_filter_support' => 'hasMemberOfFilterSupport', 'last_jpegPhoto_lookup' => 'lastJpegPhotoLookup', + 'ldap_nested_groups' => 'ldapNestedGroups', ); return $array; } diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php index 3ccc7a860f5..ad527c06343 100644 --- a/apps/user_ldap/templates/settings.php +++ b/apps/user_ldap/templates/settings.php @@ -58,6 +58,7 @@

t('Username-LDAP User Mapping'));?>

t('Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage.'));?>


+

From 86809be638a4dea6907322d24de618a1047bd9f0 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 8 Dec 2013 15:49:25 +0100 Subject: [PATCH 004/118] combineFilterWithAnd recently moved to Access --- apps/user_ldap/group_ldap.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php index 0a5ab192763..9286ece7ee1 100644 --- a/apps/user_ldap/group_ldap.php +++ b/apps/user_ldap/group_ldap.php @@ -174,12 +174,12 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { return array(); } $seen[$dn] = 1; - $filter = $this->combineFilterWithAnd(array( + $filter = $this->access->combineFilterWithAnd(array( $this->access->connection->ldapGroupFilter, $this->access->connection->ldapGroupMemberAssocAttr.'='.$dn )); - $groups = $this->fetchListOfGroups($filter, - array($this->access->connection->ldapGroupDisplayName, 'dn')); + $groups = $this->access->fetchListOfGroups($filter, + array($this->access->connection->ldapGroupDisplayName, 'dn')); if ($groups) { foreach ($groups as $groupobj) { $group_dn = $groupobj['dn']; From 4fb16804d6c0ac12b47efaa4c50234538aa93874 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 10 Dec 2013 18:47:59 +0100 Subject: [PATCH 005/118] move nested group checkbox to directory settings --- apps/user_ldap/templates/settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php index ad527c06343..79c4ae224c3 100644 --- a/apps/user_ldap/templates/settings.php +++ b/apps/user_ldap/templates/settings.php @@ -36,6 +36,7 @@

+

t('Special Attributes'));?>

@@ -58,7 +59,6 @@

t('Username-LDAP User Mapping'));?>

t('Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage.'));?>


-

From a18cff44795c5888c993f83b89b8bd7f0d0b4af6 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 10 Dec 2013 19:02:01 +0100 Subject: [PATCH 006/118] remove debug output --- apps/user_ldap/group_ldap.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php index 9286ece7ee1..1300a280b00 100644 --- a/apps/user_ldap/group_ldap.php +++ b/apps/user_ldap/group_ldap.php @@ -100,7 +100,6 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { // used extensively in cron job, caching makes sense for nested groups $cache_key = '_groupMembers'.$dn_group; if($this->access->connection->isCached($cache_key)) { - \OCP\Util::writeLog('user_ldap', 'LEO _groupMembers('.$dn_group.') using cached value', \OCP\Util::DEBUG); return $this->access->connection->getFromCache($cache_key); } $groups_seen[$dn_group] = 1; @@ -158,7 +157,6 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { $groups = array_values($this->_getGroupsByMember($uid)); $groups = array_unique($this->access->ownCloudGroupNames($groups), SORT_LOCALE_STRING); - \OCP\Util::writeLog('user_ldap', 'LEO _getGroupsByMember('.$uid.'): '.implode(", ", $groups), \OCP\Util::DEBUG); $this->access->connection->writeToCache($cacheKey, $groups); return $groups; @@ -232,7 +230,6 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { } $members = array_keys($this->_groupMembers($groupDN)); - \OCP\Util::writeLog('user_ldap', 'LEO _groupMembers('.$groupDN.'): '.implode(", ", $members), \OCP\Util::DEBUG); if(!$members) { //in case users could not be retrieved, return empty resultset $this->access->connection->writeToCache($cachekey, array()); From 2b127a6ac5c4da7a34c49f87878b643dafc5e40d Mon Sep 17 00:00:00 2001 From: root Date: Wed, 11 Dec 2013 10:43:48 +0100 Subject: [PATCH 007/118] fix indentation use identity test where appropriate use camelcase variable names _getGroupsByMember is a private function --- apps/user_ldap/group_ldap.php | 84 +++++++++++++++++------------------ 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php index 1300a280b00..fb47de7d945 100644 --- a/apps/user_ldap/group_ldap.php +++ b/apps/user_ldap/group_ldap.php @@ -88,37 +88,37 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { return $isInGroup; } - private function _groupMembers($dn_group, &$groups_seen = null) { - if ($groups_seen == null) { - $groups_seen = array(); + private function _groupMembers($dnGroup, &$seen = null) { + if ($seen === null) { + $seen = array(); } - $all_members = array(); - if (array_key_exists($dn_group, $groups_seen)) { + $allMembers = array(); + if (array_key_exists($dnGroup, $seen)) { // avoid loops return array(); } // used extensively in cron job, caching makes sense for nested groups - $cache_key = '_groupMembers'.$dn_group; - if($this->access->connection->isCached($cache_key)) { - return $this->access->connection->getFromCache($cache_key); + $cacheKey = '_groupMembers'.$dnGroup; + if($this->access->connection->isCached($cacheKey)) { + return $this->access->connection->getFromCache($cacheKey); } - $groups_seen[$dn_group] = 1; - $members = $this->access->readAttribute($dn_group, $this->access->connection->ldapGroupMemberAssocAttr, - $this->access->connection->ldapGroupFilter); + $seen[$dnGroup] = 1; + $members = $this->access->readAttribute($dnGroup, $this->access->connection->ldapGroupMemberAssocAttr, + $this->access->connection->ldapGroupFilter); if ($members) { - foreach ($members as $member_dn) { - $all_members[$member_dn] = 1; - if ($this->access->connection->ldapNestedGroups) { - $submembers = $this->_groupMembers($member_dn, $groups_seen); - if ($submembers) { - $all_members = array_merge($all_members, $submembers); - } - } - } - } - $this->access->connection->writeToCache($cache_key, $all_members); - return $all_members; - } + foreach ($members as $memberDN) { + $allMembers[$memberDN] = 1; + if ($this->access->connection->ldapNestedGroups) { + $subMembers = $this->_groupMembers($memberDN, $seen); + if ($subMembers) { + $allMembers = array_merge($allMembers, $subMembers); + } + } + } + } + $this->access->connection->writeToCache($cacheKey, $allMembers); + return $allMembers; + } /** * @brief Get all groups a user belongs to @@ -162,11 +162,11 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { return $groups; } - /* private */ public function _getGroupsByMember($dn, &$seen = null) { - if ($seen == null) { - $seen = array(); + private function _getGroupsByMember($dn, &$seen = null) { + if ($seen === null) { + $seen = array(); } - $all_groups = array(); + $allGroups = array(); if (array_key_exists($dn, $seen)) { // avoid loops return array(); @@ -177,20 +177,20 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { $this->access->connection->ldapGroupMemberAssocAttr.'='.$dn )); $groups = $this->access->fetchListOfGroups($filter, - array($this->access->connection->ldapGroupDisplayName, 'dn')); - if ($groups) { - foreach ($groups as $groupobj) { - $group_dn = $groupobj['dn']; - $all_groups[$group_dn] = $groupobj; - if ($this->access->connection->ldapNestedGroups) { - $supergroups = $this->_getGroupsByMember($group_dn, $seen); - if ($supergroups) { - $all_groups = array_merge($all_groups, $supergroups); - } - } - } - } - return $all_groups; + array($this->access->connection->ldapGroupDisplayName, 'dn')); + if ($groups) { + foreach ($groups as $groupobj) { + $groupDN = $groupobj['dn']; + $allGroups[$groupDN] = $groupobj; + if ($this->access->connection->ldapNestedGroups) { + $supergroups = $this->_getGroupsByMember($groupDN, $seen); + if ($supergroups) { + $allGroups = array_merge($allGroups, $supergroups); + } + } + } + } + return $allGroups; } /** From 66aa9b4e27deac3037ac382cc845cd26f05c682f Mon Sep 17 00:00:00 2001 From: Nicolai Ehemann Date: Fri, 17 Jan 2014 14:26:17 +0100 Subject: [PATCH 008/118] lib/files.php: make use of === instead of == --- lib/private/files.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/private/files.php b/lib/private/files.php index e6c81d58bd2..d4a8112d23b 100644 --- a/lib/private/files.php +++ b/lib/private/files.php @@ -51,7 +51,7 @@ class OC_Files { $xsendfile = true; } - if (is_array($files) && count($files) == 1) { + if (is_array($files) && count($files) === 1) { $files = $files[0]; } @@ -178,7 +178,7 @@ class OC_Files { if (isset($_SERVER['HTTP_RANGE']) && preg_match("/^bytes=([0-9]+)-([0-9]*)$/", $_SERVER['HTTP_RANGE'], $range)) { $filelength = filesize($filename); - if ($range[2] == "") { + if ($range[2] === "") { $range[2] = $filelength - 1; } header("Content-Range: bytes $range[1]-$range[2]/" . $filelength); @@ -280,7 +280,7 @@ class OC_Files { } //don't allow user to break his config -- broken or malicious size input - if (intval($size) == 0) { + if (intval($size) === 0) { return false; } @@ -302,7 +302,7 @@ class OC_Files { if ($content !== null) { $htaccess = $content; } - if ($hasReplaced == 0) { + if ($hasReplaced === 0) { $htaccess .= "\n" . $setting; } } From 791772abea631c503d95e21f584a66b47dc042f4 Mon Sep 17 00:00:00 2001 From: Nicolai Ehemann Date: Thu, 16 Jan 2014 17:21:19 +0100 Subject: [PATCH 009/118] refactored/cleaned up lib/files.php cleaned up get() logic fixed get() to only send headers if requested (xsendfile could get in the way) do no longer readfile() when already using mod_xsendfile or similar --- lib/private/files.php | 161 ++++++++++++++++++++++-------------------- 1 file changed, 84 insertions(+), 77 deletions(-) diff --git a/lib/private/files.php b/lib/private/files.php index d4a8112d23b..105c839177e 100644 --- a/lib/private/files.php +++ b/lib/private/files.php @@ -21,6 +21,12 @@ * */ +class GET_TYPE { + const FILE = 1; + const ZIP_FILES = 2; + const ZIP_DIR = 3; +} + /** * Class for fileserver access * @@ -36,6 +42,21 @@ class OC_Files { return \OC\Files\Filesystem::getDirectoryContent($path); } + private static function sendHeaders($filename, $name, $zip = false) { + OC_Response::setContentDispositionHeader($name, 'attachment'); + header('Content-Transfer-Encoding: binary'); + OC_Response::disableCaching(); + if ($zip) { + header('Content-Type: application/zip'); + } else { + $filesize = \OC\Files\Filesystem::filesize($filename); + header('Content-Type: '.\OC\Files\Filesystem::getMimeType($filename)); + if ($filesize > -1) { + header("Content-Length: ".$filesize); + } + } + } + /** * return the content of a file or return a zip file containing multiple files * @@ -56,87 +77,43 @@ class OC_Files { } if (is_array($files)) { - self::validateZipDownload($dir, $files); - $executionTime = intval(ini_get('max_execution_time')); - set_time_limit(0); - $zip = new ZipArchive(); - $filename = OC_Helper::tmpFile('.zip'); - if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { - $l = OC_L10N::get('lib'); - throw new Exception($l->t('cannot open "%s"', array($filename))); - } - foreach ($files as $file) { - $file = $dir . '/' . $file; - if (\OC\Files\Filesystem::is_file($file)) { - $tmpFile = \OC\Files\Filesystem::toTmpFile($file); - self::$tmpFiles[] = $tmpFile; - $zip->addFile($tmpFile, basename($file)); - } elseif (\OC\Files\Filesystem::is_dir($file)) { - self::zipAddDir($file, $zip); - } - } - $zip->close(); - if ($xsendfile) { - $filename = OC_Helper::moveToNoClean($filename); - } + $get_type = GET_TYPE::ZIP_FILES; $basename = basename($dir); if ($basename) { $name = $basename . '.zip'; } else { $name = 'owncloud.zip'; } - - set_time_limit($executionTime); - } elseif (\OC\Files\Filesystem::is_dir($dir . '/' . $files)) { + $filename = $dir . '/' . $name; + } else { + $filename = $dir . '/' . $files; + if (\OC\Files\Filesystem::is_dir($dir . '/' . $files)) { + $get_type = GET_TYPE::ZIP_DIR; + $name = $files . '.zip'; + } else { + $get_type = GET_TYPE::FILE; + $name = $files; + } + } + + if ($get_type === GET_TYPE::FILE) { + $zip = false; + if ($xsendfile && OC_App::isEnabled('files_encryption')) { + $xsendfile = false; + } + } else { self::validateZipDownload($dir, $files); - $executionTime = intval(ini_get('max_execution_time')); - set_time_limit(0); $zip = new ZipArchive(); $filename = OC_Helper::tmpFile('.zip'); if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { $l = OC_L10N::get('lib'); throw new Exception($l->t('cannot open "%s"', array($filename))); } - $file = $dir . '/' . $files; - self::zipAddDir($file, $zip); - $zip->close(); - if ($xsendfile) { - $filename = OC_Helper::moveToNoClean($filename); - } - $name = $files . '.zip'; - set_time_limit($executionTime); - } else { - $zip = false; - $filename = $dir . '/' . $files; - $name = $files; - if ($xsendfile && OC_App::isEnabled('files_encryption')) { - $xsendfile = false; - } } OC_Util::obEnd(); if ($zip or \OC\Files\Filesystem::isReadable($filename)) { - OC_Response::setContentDispositionHeader($name, 'attachment'); - header('Content-Transfer-Encoding: binary'); - OC_Response::disableCaching(); - if ($zip) { - ini_set('zlib.output_compression', 'off'); - header('Content-Type: application/zip'); - header('Content-Length: ' . filesize($filename)); - self::addSendfileHeader($filename); - }else{ - $filesize = \OC\Files\Filesystem::filesize($filename); - header('Content-Type: '.\OC\Files\Filesystem::getMimeType($filename)); - if ($filesize > -1) { - header("Content-Length: ".$filesize); - } - if ($xsendfile) { - list($storage) = \OC\Files\Filesystem::resolvePath(\OC\Files\Filesystem::getView()->getAbsolutePath($filename)); - if ($storage instanceof \OC\Files\Storage\Local) { - self::addSendfileHeader(\OC\Files\Filesystem::getLocalFile($filename)); - } - } - } - } elseif ($zip or !\OC\Files\Filesystem::file_exists($filename)) { + self::sendHeaders($filename, $name, $zip); + } elseif (!\OC\Files\Filesystem::file_exists($filename)) { header("HTTP/1.0 404 Not Found"); $tmpl = new OC_Template('', '404', 'guest'); $tmpl->assign('file', $name); @@ -149,19 +126,49 @@ class OC_Files { return ; } if ($zip) { - $handle = fopen($filename, 'r'); - if ($handle) { - $chunkSize = 8 * 1024; // 1 MB chunks - while (!feof($handle)) { - echo fread($handle, $chunkSize); - flush(); + $executionTime = intval(ini_get('max_execution_time')); + set_time_limit(0); + if ($get_type === GET_TYPE::ZIP_FILES) { + foreach ($files as $file) { + $file = $dir . '/' . $file; + if (\OC\Files\Filesystem::is_file($file)) { + $tmpFile = \OC\Files\Filesystem::toTmpFile($file); + self::$tmpFiles[] = $tmpFile; + $zip->addFile($tmpFile, basename($file)); + } elseif (\OC\Files\Filesystem::is_dir($file)) { + self::zipAddDir($file, $zip); + } + } + } elseif ($get_type === GET_TYPE::ZIP_DIR) { + $file = $dir . '/' . $files; + self::zipAddDir($file, $zip); + } + $zip->close(); + if ($xsendfile) { + $filename = OC_Helper::moveToNoClean($filename); + self::addSendfileHeader($filename); + } else { + $handle = fopen($filename, 'r'); + if ($handle) { + $chunkSize = 8 * 1024; // 1 MB chunks + while (!feof($handle)) { + echo fread($handle, $chunkSize); + flush(); + } } } - if (!$xsendfile) { - unlink($filename); + set_time_limit($executionTime); + } else { + if ($xsendfile) { + list($storage) = \OC\Files\Filesystem::resolvePath($filename); + if ($storage instanceof \OC\Files\Storage\Local) { + self::addSendfileHeader(\OC\Files\Filesystem::getLocalFile($filename)); + } else { + \OC\Files\Filesystem::readfile($filename); + } + } else { + \OC\Files\Filesystem::readfile($filename); } - }else{ - \OC\Files\Filesystem::readfile($filename); } foreach (self::$tmpFiles as $tmpFile) { if (file_exists($tmpFile) and is_file($tmpFile)) { @@ -175,7 +182,7 @@ class OC_Files { header("X-Sendfile: " . $filename); } if (isset($_SERVER['MOD_X_SENDFILE2_ENABLED'])) { - if (isset($_SERVER['HTTP_RANGE']) && + if (isset($_SERVER['HTTP_RANGE']) && preg_match("/^bytes=([0-9]+)-([0-9]*)$/", $_SERVER['HTTP_RANGE'], $range)) { $filelength = filesize($filename); if ($range[2] === "") { @@ -188,7 +195,7 @@ class OC_Files { header("X-Sendfile: " . $filename); } } - + if (isset($_SERVER['MOD_X_ACCEL_REDIRECT_ENABLED'])) { header("X-Accel-Redirect: " . $filename); } From 99ad4e80007bca5062709e16652b953ad9e73dc7 Mon Sep 17 00:00:00 2001 From: Nicolai Ehemann Date: Wed, 22 Jan 2014 12:49:52 +0100 Subject: [PATCH 010/118] switched zip file creation to ZipStreamer to create zip files directly in memory --- lib/private/files.php | 42 +++++++++--------------------------------- 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/lib/private/files.php b/lib/private/files.php index 105c839177e..5370f9e1678 100644 --- a/lib/private/files.php +++ b/lib/private/files.php @@ -20,6 +20,7 @@ * License along with this library. If not, see . * */ +require_once( 'ZipStreamer/ZipStreamer.php' ); class GET_TYPE { const FILE = 1; @@ -32,8 +33,6 @@ class GET_TYPE { * */ class OC_Files { - static $tmpFiles = array(); - static public function getFileInfo($path, $includeMountPoints = true){ return \OC\Files\Filesystem::getFileInfo($path, $includeMountPoints); } @@ -103,12 +102,7 @@ class OC_Files { } } else { self::validateZipDownload($dir, $files); - $zip = new ZipArchive(); - $filename = OC_Helper::tmpFile('.zip'); - if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { - $l = OC_L10N::get('lib'); - throw new Exception($l->t('cannot open "%s"', array($filename))); - } + $zip = new ZipStreamer(false); } OC_Util::obEnd(); if ($zip or \OC\Files\Filesystem::isReadable($filename)) { @@ -132,9 +126,9 @@ class OC_Files { foreach ($files as $file) { $file = $dir . '/' . $file; if (\OC\Files\Filesystem::is_file($file)) { - $tmpFile = \OC\Files\Filesystem::toTmpFile($file); - self::$tmpFiles[] = $tmpFile; - $zip->addFile($tmpFile, basename($file)); + $fh = \OC\Files\Filesystem::fopen($file, 'r'); + $zip->addFileFromStream($fh, basename($file)); + fclose($fh); } elseif (\OC\Files\Filesystem::is_dir($file)) { self::zipAddDir($file, $zip); } @@ -143,20 +137,7 @@ class OC_Files { $file = $dir . '/' . $files; self::zipAddDir($file, $zip); } - $zip->close(); - if ($xsendfile) { - $filename = OC_Helper::moveToNoClean($filename); - self::addSendfileHeader($filename); - } else { - $handle = fopen($filename, 'r'); - if ($handle) { - $chunkSize = 8 * 1024; // 1 MB chunks - while (!feof($handle)) { - echo fread($handle, $chunkSize); - flush(); - } - } - } + $zip->finalize(); set_time_limit($executionTime); } else { if ($xsendfile) { @@ -170,11 +151,6 @@ class OC_Files { \OC\Files\Filesystem::readfile($filename); } } - foreach (self::$tmpFiles as $tmpFile) { - if (file_exists($tmpFile) and is_file($tmpFile)) { - unlink($tmpFile); - } - } } private static function addSendfileHeader($filename) { @@ -210,9 +186,9 @@ class OC_Files { $filename=$file['name']; $file=$dir.'/'.$filename; if(\OC\Files\Filesystem::is_file($file)) { - $tmpFile=\OC\Files\Filesystem::toTmpFile($file); - OC_Files::$tmpFiles[]=$tmpFile; - $zip->addFile($tmpFile, $internalDir.$filename); + $fh = \OC\Files\Filesystem::fopen($file, 'r'); + $zip->addFileFromStream($fh, $internalDir.$filename); + fclose($fh); }elseif(\OC\Files\Filesystem::is_dir($file)) { self::zipAddDir($file, $zip, $internalDir); } From a521949bafdaba0cb94061967b6b8307bbbebc05 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 27 Jan 2014 15:41:56 +0100 Subject: [PATCH 011/118] Allow passing a root folder to get the used space from in the quota wrapper --- lib/private/files/storage/wrapper/quota.php | 8 +++++++- lib/private/util.php | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/private/files/storage/wrapper/quota.php b/lib/private/files/storage/wrapper/quota.php index a430e3e4617..83a5de5ca30 100644 --- a/lib/private/files/storage/wrapper/quota.php +++ b/lib/private/files/storage/wrapper/quota.php @@ -15,12 +15,18 @@ class Quota extends Wrapper { */ protected $quota; + /** + * @var string $freeSpaceRoot + */ + protected $sizeRoot; + /** * @param array $parameters */ public function __construct($parameters) { $this->storage = $parameters['storage']; $this->quota = $parameters['quota']; + $this->freeSpaceRoot = isset($parameters['root']) ? $parameters['root'] : ''; } protected function getSize($path) { @@ -43,7 +49,7 @@ class Quota extends Wrapper { if ($this->quota < 0) { return $this->storage->free_space($path); } else { - $used = $this->getSize(''); + $used = $this->getSize($this->freeSpaceRoot); if ($used < 0) { return \OC\Files\SPACE_NOT_COMPUTED; } else { diff --git a/lib/private/util.php b/lib/private/util.php index 8aa7a074d0d..66a770a33dc 100755 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -65,7 +65,7 @@ class OC_Util { $user = $storage->getUser()->getUID(); $quota = OC_Util::getUserQuota($user); if ($quota !== \OC\Files\SPACE_UNLIMITED) { - return new \OC\Files\Storage\Wrapper\Quota(array('storage' => $storage, 'quota' => $quota)); + return new \OC\Files\Storage\Wrapper\Quota(array('storage' => $storage, 'quota' => $quota, 'root' => 'files')); } } From c8207312c73f61b2be4aa8ca1d9ae6a8c33453cf Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 27 Jan 2014 16:00:10 +0100 Subject: [PATCH 012/118] Fix phpdoc --- lib/private/files/storage/wrapper/quota.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/files/storage/wrapper/quota.php b/lib/private/files/storage/wrapper/quota.php index 83a5de5ca30..2fc3119fc7d 100644 --- a/lib/private/files/storage/wrapper/quota.php +++ b/lib/private/files/storage/wrapper/quota.php @@ -16,7 +16,7 @@ class Quota extends Wrapper { protected $quota; /** - * @var string $freeSpaceRoot + * @var string $sizeRoot */ protected $sizeRoot; From 20c2aaab00e92d74547ccd6c964102e10ea34cbf Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 27 Jan 2014 16:26:54 +0100 Subject: [PATCH 013/118] Actually rename the variable --- lib/private/files/storage/wrapper/quota.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/private/files/storage/wrapper/quota.php b/lib/private/files/storage/wrapper/quota.php index 2fc3119fc7d..16127403181 100644 --- a/lib/private/files/storage/wrapper/quota.php +++ b/lib/private/files/storage/wrapper/quota.php @@ -26,7 +26,7 @@ class Quota extends Wrapper { public function __construct($parameters) { $this->storage = $parameters['storage']; $this->quota = $parameters['quota']; - $this->freeSpaceRoot = isset($parameters['root']) ? $parameters['root'] : ''; + $this->sizeRoot = isset($parameters['root']) ? $parameters['root'] : ''; } protected function getSize($path) { @@ -49,7 +49,7 @@ class Quota extends Wrapper { if ($this->quota < 0) { return $this->storage->free_space($path); } else { - $used = $this->getSize($this->freeSpaceRoot); + $used = $this->getSize($this->sizeRoot); if ($used < 0) { return \OC\Files\SPACE_NOT_COMPUTED; } else { From 3afdcd85e7d61c38ff8df909c317b73c2ed04353 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 4 Feb 2014 16:05:12 +0100 Subject: [PATCH 014/118] Add unit test for quote wrapper size root --- tests/lib/files/storage/wrapper/quota.php | 25 ++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/tests/lib/files/storage/wrapper/quota.php b/tests/lib/files/storage/wrapper/quota.php index 87bafb64d41..6610103cc4c 100644 --- a/tests/lib/files/storage/wrapper/quota.php +++ b/tests/lib/files/storage/wrapper/quota.php @@ -59,7 +59,7 @@ class Quota extends \Test\Files\Storage\Storage { $this->assertEquals('foobarqwe', $instance->file_get_contents('foo')); } - public function testReturnFalseWhenFopenFailed(){ + public function testReturnFalseWhenFopenFailed() { $failStorage = $this->getMock( '\OC\Files\Storage\Local', array('fopen'), @@ -73,7 +73,7 @@ class Quota extends \Test\Files\Storage\Storage { $this->assertFalse($instance->fopen('failedfopen', 'r')); } - public function testReturnRegularStreamOnRead(){ + public function testReturnRegularStreamOnRead() { $instance = $this->getLimitedStorage(9); // create test file first @@ -92,11 +92,30 @@ class Quota extends \Test\Files\Storage\Storage { fclose($stream); } - public function testReturnQuotaStreamOnWrite(){ + public function testReturnQuotaStreamOnWrite() { $instance = $this->getLimitedStorage(9); $stream = $instance->fopen('foo', 'w+'); $meta = stream_get_meta_data($stream); $this->assertEquals('user-space', $meta['wrapper_type']); fclose($stream); } + + public function testSpaceRoot() { + $storage = $this->getMockBuilder('\OC\Files\Storage\Local')->disableOriginalConstructor()->getMock(); + $cache = $this->getMockBuilder('\OC\Files\Cache\Cache')->disableOriginalConstructor()->getMock(); + $storage->expects($this->once()) + ->method('getCache') + ->will($this->returnValue($cache)); + $storage->expects($this->once()) + ->method('free_space') + ->will($this->returnValue(2048)); + $cache->expects($this->once()) + ->method('get') + ->with('files') + ->will($this->returnValue(array('size' => 50))); + + $instance = new \OC\Files\Storage\Wrapper\Quota(array('storage' => $storage, 'quota' => 1024, 'root' => 'files')); + + $this->assertEquals(1024 - 50, $instance->free_space('')); + } } From f830ad0e47df14e821161c49ab1b52694f74912a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 4 Feb 2014 16:28:41 +0100 Subject: [PATCH 015/118] Don't create new thumbnails on the write hook --- lib/private/image.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/image.php b/lib/private/image.php index 7761a3c7737..a6a2413f59f 100644 --- a/lib/private/image.php +++ b/lib/private/image.php @@ -230,7 +230,7 @@ class OC_Image { } /** - * @returns Returns the image resource in any. + * @returns resource Returns the image resource in any. */ public function resource() { return $this->resource; From a62b393d02fdfc49334b5ad4b1e847a711de741d Mon Sep 17 00:00:00 2001 From: Guillaume AMAT Date: Wed, 12 Feb 2014 00:54:35 +0100 Subject: [PATCH 016/118] Update page title when navigating through directories --- apps/files/js/filelist.js | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index a855d6cbe59..7691135e620 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -18,6 +18,15 @@ window.FileList={ $(this).attr('data-file',decodeURIComponent($(this).attr('data-file'))); }); }, + /** + * Sets a new page title + */ + setPageTitle: function(title){ + // Sets the page title with the " - ownCloud" suffix as in templates + window.document.title = title + ' - ownCloud'; + + return true; + }, /** * Returns the tr element for a given file name */ @@ -186,12 +195,22 @@ window.FileList={ changeDirectory: function(targetDir, changeUrl, force) { var $dir = $('#dir'), url, - currentDir = $dir.val() || '/'; + currentDir = $dir.val() || '/', + baseDir = targetDir.split('/').pop(), targetDir = targetDir || '/'; if (!force && currentDir === targetDir) { return; } + + if (baseDir !== '') { + FileList.setPageTitle(baseDir); + } + else { + FileList.setPageTitle(t('files', 'Files')); + } + FileList.setCurrentDir(targetDir, changeUrl); + $('#fileList').trigger( jQuery.Event('changeDirectory', { dir: targetDir, @@ -811,7 +830,8 @@ window.FileList={ }; $(document).ready(function() { - var isPublic = !!$('#isPublic').val(); + var baseDir, + isPublic = !!$('#isPublic').val(); // handle upload events var file_upload_start = $('#file_upload_start'); @@ -1095,6 +1115,14 @@ $(document).ready(function() { FileList.changeDirectory(parseCurrentDirFromUrl(), false, true); } } - + + + baseDir = parseCurrentDirFromUrl().split('/').pop(); + + if (baseDir !== '') { + FileList.setPageTitle(baseDir); + } + + FileList.createFileSummary(); }); From d10f6e94dcc92a2242aae2b2331b6f85da8d8b6c Mon Sep 17 00:00:00 2001 From: root Date: Wed, 12 Feb 2014 16:56:17 +0100 Subject: [PATCH 017/118] fix coding style to blizzz happy.. ;-) --- apps/user_ldap/group_ldap.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php index fb47de7d945..509f65712fd 100644 --- a/apps/user_ldap/group_ldap.php +++ b/apps/user_ldap/group_ldap.php @@ -105,10 +105,11 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { $seen[$dnGroup] = 1; $members = $this->access->readAttribute($dnGroup, $this->access->connection->ldapGroupMemberAssocAttr, $this->access->connection->ldapGroupFilter); - if ($members) { + if (is_array($members)) { foreach ($members as $memberDN) { $allMembers[$memberDN] = 1; - if ($this->access->connection->ldapNestedGroups) { + $nestedGroups = $this->access->connection->ldapNestedGroups; + if (!empty($nestedGroups)) { $subMembers = $this->_groupMembers($memberDN, $seen); if ($subMembers) { $allMembers = array_merge($allMembers, $subMembers); @@ -155,14 +156,14 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { $uid = $userDN; } - $groups = array_values($this->_getGroupsByMember($uid)); + $groups = array_values($this->getGroupsByMember($uid)); $groups = array_unique($this->access->ownCloudGroupNames($groups), SORT_LOCALE_STRING); $this->access->connection->writeToCache($cacheKey, $groups); return $groups; } - private function _getGroupsByMember($dn, &$seen = null) { + private function getGroupsByMember($dn, &$seen = null) { if ($seen === null) { $seen = array(); } @@ -178,13 +179,14 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { )); $groups = $this->access->fetchListOfGroups($filter, array($this->access->connection->ldapGroupDisplayName, 'dn')); - if ($groups) { + if (is_array($groups)) { foreach ($groups as $groupobj) { $groupDN = $groupobj['dn']; $allGroups[$groupDN] = $groupobj; - if ($this->access->connection->ldapNestedGroups) { - $supergroups = $this->_getGroupsByMember($groupDN, $seen); - if ($supergroups) { + $nestedGroups = $this->access->connection->ldapNestedGroups; + if (!empty($nestedGroups)) { + $supergroups = $this->getGroupsByMember($groupDN, $seen); + if (is_array($supergroups) && (count($supergroups)>0)) { $allGroups = array_merge($allGroups, $supergroups); } } From 01dee35ebe1f3ab0e8a7f986015a9fa43a80b061 Mon Sep 17 00:00:00 2001 From: Guillaume AMAT Date: Thu, 13 Feb 2014 10:47:03 +0100 Subject: [PATCH 018/118] Adds OC_Defaults values in javascript config --- core/js/config.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/core/js/config.php b/core/js/config.php index 517ea1615a8..7ec0904ec3d 100644 --- a/core/js/config.php +++ b/core/js/config.php @@ -16,6 +16,9 @@ header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Enable l10n support $l = OC_L10N::get('core'); +// Enable OC_Defaults support +$defaults = new OC_Defaults(); + // Get the config $apps_paths = array(); foreach(OC_App::getEnabledApps() as $app) { @@ -60,6 +63,20 @@ $array = array( 'session_lifetime' => \OCP\Config::getSystemValue('session_lifetime', 60 * 60 * 24), 'session_keepalive' => \OCP\Config::getSystemValue('session_keepalive', true) ) + ), + "oc_defaults" => json_encode( + array( + 'entity' => $defaults->getEntity(), + 'name' => $defaults->getName(), + 'title' => $defaults->getTitle(), + 'baseUrl' => $defaults->getBaseUrl(), + 'syncClientUrl' => $defaults->getSyncClientUrl(), + 'docBaseUrl' => $defaults->getDocBaseUrl(), + 'slogan' => $defaults->getSlogan(), + 'logoClaim' => $defaults->getLogoClaim(), + 'shortFooter' => $defaults->getShortFooter(), + 'longFooter' => $defaults->getLongFooter() + ) ) ); From 01dc7c5482e6b7486695fdba865a1c88ab05358d Mon Sep 17 00:00:00 2001 From: Guillaume AMAT Date: Thu, 13 Feb 2014 10:48:01 +0100 Subject: [PATCH 019/118] Gets the page title from oc_defaults in Files app --- apps/files/js/filelist.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 7691135e620..14f03121ff6 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -23,7 +23,7 @@ window.FileList={ */ setPageTitle: function(title){ // Sets the page title with the " - ownCloud" suffix as in templates - window.document.title = title + ' - ownCloud'; + window.document.title = title + ' - ' + oc_defaults.title; return true; }, From c732764eb5159b893cdb97fc780937a883f48b58 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 3 Feb 2014 18:00:39 +0100 Subject: [PATCH 020/118] Improve users list scrolling performance - fixed JS error when avatar mode is disabled - added spinner at the bottom of the table - scroll detection now happens earlier - single/multiselect init is deferred so that the new rows are first appended into the list (more responsive) and initialized afterwards - disabled users sorting after add (assuming they are always sorted on the server side) --- core/css/multiselect.css | 8 ++++- core/css/styles.css | 12 +++++++ settings/js/users.js | 77 +++++++++++++++++++++++++++------------- 3 files changed, 72 insertions(+), 25 deletions(-) diff --git a/core/css/multiselect.css b/core/css/multiselect.css index 60f2f47e698..8d949e7cdb7 100644 --- a/core/css/multiselect.css +++ b/core/css/multiselect.css @@ -48,7 +48,7 @@ ul.multiselectoptions > li input[type='checkbox']:checked+label { font-weight: bold; } -div.multiselect { +div.multiselect, select.multiselect { display: inline-block; max-width: 400px; min-width: 150px; @@ -58,6 +58,12 @@ div.multiselect { vertical-align: bottom; } +/* To make a select look like a multiselect until it's initialized */ +select.multiselect { + height: 30px; + min-width: 113px; +} + div.multiselect.active { background-color: #fff; position: relative; diff --git a/core/css/styles.css b/core/css/styles.css index bee44785f12..cbfab618ec4 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -933,3 +933,15 @@ div.crumb:active { opacity:.7; } +.appear { + opacity: 1; + transition: opacity 500ms ease 0s; + -moz-transition: opacity 500ms ease 0s; + -ms-transition: opacity 500ms ease 0s; + -o-transition: opacity 500ms ease 0s; + -webkit-transition: opacity 500ms ease 0s; +} +.appear.transparent { + opacity: 0; +} + diff --git a/settings/js/users.js b/settings/js/users.js index 6886db668b5..a6edc02e165 100644 --- a/settings/js/users.js +++ b/settings/js/users.js @@ -85,19 +85,24 @@ var UserList = { add: function (username, displayname, groups, subadmin, quota, sort) { var tr = $('tbody tr').first().clone(); - if (tr.find('div.avatardiv')){ + var subadminsEl; + var subadminSelect; + var groupsSelect; + if (tr.find('div.avatardiv').length){ $('div.avatardiv', tr).avatar(username, 32); } tr.attr('data-uid', username); tr.attr('data-displayName', displayname); tr.find('td.name').text(username); tr.find('td.displayName > span').text(displayname); - var groupsSelect = $('') + + // make them look like the multiselect buttons + // until they get time to really get initialized + groupsSelect = $('') .attr('data-username', username) .data('user-groups', groups); - tr.find('td.groups').empty(); if (tr.find('td.subadmins').length > 0) { - var subadminSelect = $('') .attr('data-username', username) .data('user-groups', groups) .data('subadmin', subadmin); @@ -109,11 +114,10 @@ var UserList = { subadminSelect.append($('')); } }); - tr.find('td.groups').append(groupsSelect); - UserList.applyMultiplySelect(groupsSelect); - if (tr.find('td.subadmins').length > 0) { - tr.find('td.subadmins').append(subadminSelect); - UserList.applyMultiplySelect(subadminSelect); + tr.find('td.groups').empty().append(groupsSelect); + subadminsEl = tr.find('td.subadmins'); + if (subadminsEl.length > 0) { + subadminsEl.append(subadminSelect); } if (tr.find('td.remove img').length === 0 && OC.currentUser !== username) { var rm_img = $('').attr({ @@ -139,11 +143,11 @@ var UserList = { } } $(tr).appendTo('tbody'); + if (sort) { UserList.doSort(); } - quotaSelect.singleSelect(); quotaSelect.on('change', function () { var uid = $(this).parent().parent().attr('data-uid'); var quota = $(this).val(); @@ -153,6 +157,16 @@ var UserList = { } }); }); + + // defer init so the user first sees the list appear more quickly + window.setTimeout(function(){ + quotaSelect.singleSelect(); + UserList.applyMultiplySelect(groupsSelect); + if (subadminSelect) { + UserList.applyMultiplySelect(subadminSelect); + } + }, 0); + return tr; }, // From http://my.opera.com/GreyWyvern/blog/show.dml/1671288 alphanum: function(a, b) { @@ -211,26 +225,34 @@ var UserList = { } UserList.updating = true; $.get(OC.Router.generate('settings_ajax_userlist', { offset: UserList.offset, limit: UserList.usersToLoad }), function (result) { + var loadedUsers = 0; + var trs = []; if (result.status === 'success') { //The offset does not mirror the amount of users available, //because it is backend-dependent. For correct retrieval, //always the limit(requested amount of users) needs to be added. - UserList.offset += UserList.usersToLoad; $.each(result.data, function (index, user) { if($('tr[data-uid="' + user.name + '"]').length > 0) { return true; } var tr = UserList.add(user.name, user.displayname, user.groups, user.subadmin, user.quota, false); - if (index === 9) { - $(tr).bind('inview', function (event, isInView, visiblePartX, visiblePartY) { - $(this).unbind(event); - UserList.update(); - }); - } + tr.addClass('appear transparent'); + trs.push(tr); + loadedUsers++; }); if (result.data.length > 0) { UserList.doSort(); } + else { + UserList.noMoreEntries = true; + } + UserList.offset += loadedUsers; + // animate + setTimeout(function() { + for (var i = 0; i < trs.length; i++) { + trs[i].removeClass('transparent'); + } + }, 0); } UserList.updating = false; }); @@ -239,7 +261,7 @@ var UserList = { applyMultiplySelect: function (element) { var checked = []; var user = element.attr('data-username'); - if ($(element).attr('class') === 'groupsselect') { + if ($(element).hasClass('groupsselect')) { if (element.data('userGroups')) { checked = element.data('userGroups'); } @@ -295,7 +317,7 @@ var UserList = { minWidth: 100 }); } - if ($(element).attr('class') === 'subadminsselect') { + if ($(element).hasClass('subadminsselect')) { if (element.data('subadmin')) { checked = element.data('subadmin'); } @@ -330,17 +352,24 @@ var UserList = { minWidth: 100 }); } - } + }, + + _onScroll: function(e) { + if (!!UserList.noMoreEntries) { + return; + } + if ($(window).scrollTop() + $(window).height() > $(document).height() - 500) { + UserList.update(true); + } + }, }; $(document).ready(function () { UserList.doSort(); UserList.availableGroups = $('#content table').data('groups'); - $('tbody tr:last').bind('inview', function (event, isInView, visiblePartX, visiblePartY) { - OC.Router.registerLoadedCallback(function () { - UserList.update(); - }); + OC.Router.registerLoadedCallback(function() { + $(window).scroll(function(e) {UserList._onScroll(e);}); }); $('select[multiple]').each(function (index, element) { From 58b1dc5e76bb18ebae7e980566153b04cd1c76b2 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 18 Feb 2014 10:52:05 +0100 Subject: [PATCH 021/118] Added loading spinner to users list on scroll --- settings/js/users.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/settings/js/users.js b/settings/js/users.js index a6edc02e165..1028a003bcf 100644 --- a/settings/js/users.js +++ b/settings/js/users.js @@ -223,6 +223,7 @@ var UserList = { if (UserList.updating) { return; } + $('table+.loading').css('visibility', 'visible'); UserList.updating = true; $.get(OC.Router.generate('settings_ajax_userlist', { offset: UserList.offset, limit: UserList.usersToLoad }), function (result) { var loadedUsers = 0; @@ -242,9 +243,11 @@ var UserList = { }); if (result.data.length > 0) { UserList.doSort(); + $('table+.loading').css('visibility', 'hidden'); } else { UserList.noMoreEntries = true; + $('table+.loading').remove(); } UserList.offset += loadedUsers; // animate @@ -371,6 +374,7 @@ $(document).ready(function () { OC.Router.registerLoadedCallback(function() { $(window).scroll(function(e) {UserList._onScroll(e);}); }); + $('table').after($('')); $('select[multiple]').each(function (index, element) { UserList.applyMultiplySelect($(element)); From 8387cd8ae35a0ad94a49a27ad8622bb7b8ed2b06 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 12 Feb 2014 17:21:41 +0100 Subject: [PATCH 022/118] Add option to change email settings in admin section Fix issue #7166 --- settings/admin.php | 10 ++++ settings/admin/controller.php | 83 +++++++++++++++++++++++++++++++++ settings/css/settings.css | 12 +++++ settings/js/admin.js | 38 +++++++++++++++ settings/routes.php | 3 ++ settings/templates/admin.php | 88 +++++++++++++++++++++++++++++++++++ 6 files changed, 234 insertions(+) create mode 100644 settings/admin/controller.php diff --git a/settings/admin.php b/settings/admin.php index c0e4570658a..42477bfc1ca 100755 --- a/settings/admin.php +++ b/settings/admin.php @@ -21,6 +21,16 @@ $entries=OC_Log_Owncloud::getEntries(3); $entriesremain = count(OC_Log_Owncloud::getEntries(4)) > 3; $tmpl->assign('loglevel', OC_Config::getValue( "loglevel", 2 )); +$tmpl->assign('mail_domain', OC_Config::getValue( "mail_domain", '' )); +$tmpl->assign('mail_from_address', OC_Config::getValue( "mail_from_address", '' )); +$tmpl->assign('mail_smtpmode', OC_Config::getValue( "mail_smtpmode", '' )); +$tmpl->assign('mail_smtpsecure', OC_Config::getValue( "mail_smtpsecure", '' )); +$tmpl->assign('mail_smtphost', OC_Config::getValue( "mail_smtphost", '' )); +$tmpl->assign('mail_smtpport', OC_Config::getValue( "mail_smtpport", '' )); +$tmpl->assign('mail_smtpauthtype', OC_Config::getValue( "mail_smtpauthtype", '' )); +$tmpl->assign('mail_smtpauth', OC_Config::getValue( "mail_smtpauth", false )); +$tmpl->assign('mail_smtpname', OC_Config::getValue( "mail_smtpname", '' )); +$tmpl->assign('mail_smtppassword', OC_Config::getValue( "mail_smtppassword", '' )); $tmpl->assign('entries', $entries); $tmpl->assign('entriesremain', $entriesremain); $tmpl->assign('htaccessworking', $htaccessworking); diff --git a/settings/admin/controller.php b/settings/admin/controller.php new file mode 100644 index 00000000000..9bbcd356580 --- /dev/null +++ b/settings/admin/controller.php @@ -0,0 +1,83 @@ +. +*/ + +namespace OC\Settings\Admin; + +class Controller { + public static function setMailSettings($args) { + \OC_Util::checkAdminUser(); + \OCP\JSON::callCheck(); + + $l = \OC_L10N::get('settings'); + + $smtp_settings = array( + 'mail_domain' => null, + 'mail_from_address' => null, + 'mail_smtpmode' => array('sendmail', 'smtp', 'qmail', 'php'), + 'mail_smtpsecure' => array('', 'ssl', 'tls'), + 'mail_smtphost' => null, + 'mail_smtpport' => null, + 'mail_smtpauthtype' => array('LOGIN', 'PLAIN', 'NTLM'), + 'mail_smtpauth' => true, + 'mail_smtpname' => null, + 'mail_smtppassword' => null, + ); + + foreach ($smtp_settings as $setting => $validate) { + if (!$validate) { + if (!isset($_POST[$setting]) || $_POST[$setting] === '') { + \OC_Config::deleteKey( $setting ); + } else { + \OC_Config::setValue( $setting, $_POST[$setting] ); + } + } + else if (is_bool($validate)) { + if (!empty($_POST[$setting])) { + \OC_Config::setValue( $setting, (bool) $_POST[$setting] ); + } else { + \OC_Config::deleteKey( $setting ); + } + } + else if (is_array($validate)) { + if (!isset($_POST[$setting]) || $_POST[$setting] === '') { + \OC_Config::deleteKey( $setting ); + } else if (in_array($_POST[$setting], $validate)) { + \OC_Config::setValue( $setting, $_POST[$setting] ); + } else { + $message = $l->t('Invalid value supplied for %s', array(self::getFieldname($setting, $l))); + \OC_JSON::error( array( "data" => array( "message" => $message)) ); + exit; + } + } + } + + \OC_JSON::success(array("data" => array( "message" => $l->t("Saved") ))); + } + + public static function getFieldname($setting, $l) { + switch ($setting) { + case 'mail_smtpmode': + return $l->t( 'SMTP mode' ); + case 'mail_smtpsecure': + return $l->t( 'Secure SMTP' ); + case 'mail_smtpauthtype': + return $l->t( 'Authentification method for SMTP' ); + } + } +} diff --git a/settings/css/settings.css b/settings/css/settings.css index 8a96885b789..ad205e761cb 100644 --- a/settings/css/settings.css +++ b/settings/css/settings.css @@ -150,6 +150,18 @@ span.connectionwarning {color:#933; font-weight:bold; } input[type=radio] { width:1em; } table.shareAPI td { padding-bottom: 0.8em; } +#mail_settings p label:first-child { + display: inline-block; + width: 300px; + text-align: right; +} +#mail_settings p select:nth-child(2) { + width: 143px; +} +#mail_smtpport { + width: 40px; +} + /* HELP */ .pressed {background-color:#DDD;} diff --git a/settings/js/admin.js b/settings/js/admin.js index e957bd68f1f..f39f53d413a 100644 --- a/settings/js/admin.js +++ b/settings/js/admin.js @@ -34,4 +34,42 @@ $(document).ready(function(){ $('#security').change(function(){ $.post(OC.filePath('settings','ajax','setsecurity.php'), { enforceHTTPS: $('#forcessl').val() },function(){} ); }); + + $('#mail_smtpauth').change(function() { + if (!this.checked) { + $('#mail_credentials').toggle(false); + } else { + $('#mail_credentials').toggle(true); + } + }); + + $('#mail_settings').change(function(){ + OC.msg.startSaving('#mail_settings .msg'); + var post = $( "#mail_settings" ).serialize(); + $.post(OC.Router.generate('settings_mail_settings'), post, function(data){ + OC.msg.finishedSaving('#mail_settings .msg', data); + }); + }); }); + +OC.msg={ + startSaving:function(selector){ + $(selector) + .html( t('settings', 'Saving...') ) + .removeClass('success') + .removeClass('error') + .stop(true, true) + .show(); + }, + finishedSaving:function(selector, data){ + if( data.status === "success" ){ + $(selector).html( data.data.message ) + .addClass('success') + .stop(true, true) + .delay(3000) + .fadeOut(900); + }else{ + $(selector).html( data.data.message ).addClass('error'); + } + } +}; diff --git a/settings/routes.php b/settings/routes.php index 60f9d8e1001..aa16ad491f8 100644 --- a/settings/routes.php +++ b/settings/routes.php @@ -70,6 +70,9 @@ $this->create('settings_ajax_getlog', '/settings/ajax/getlog.php') ->actionInclude('settings/ajax/getlog.php'); $this->create('settings_ajax_setloglevel', '/settings/ajax/setloglevel.php') ->actionInclude('settings/ajax/setloglevel.php'); +$this->create('settings_mail_settings', '/settings/admin/mailsettings') + ->post() + ->action('OC\Settings\Admin\Controller', 'setMailSettings'); $this->create('settings_ajax_setsecurity', '/settings/ajax/setsecurity.php') ->actionInclude('settings/ajax/setsecurity.php'); $this->create('isadmin', '/settings/js/isadmin.js') diff --git a/settings/templates/admin.php b/settings/templates/admin.php index 0eabffb9316..d81840b5b66 100644 --- a/settings/templates/admin.php +++ b/settings/templates/admin.php @@ -11,6 +11,27 @@ $levelLabels = array( $l->t( 'Errors and fatal issues' ), $l->t( 'Fatal issues only' ), ); + +$mail_smtpauthtype = array( + '' => $l->t('None'), + 'LOGIN' => $l->t('Login'), + 'PLAIN' => $l->t('Plain'), + 'NTLM' => $l->t('NT LAN Manager'), +); + +$mail_smtpsecure = array( + '' => $l->t('None'), + 'ssl' => $l->t('SSL'), + 'tls' => $l->t('TLS'), +); + +$mail_smtpmode = array( + 'sendmail', + 'smtp', + 'qmail', + 'php', +); + ?> +
+

t('Email Server'));?>

+ +

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

+ +

+ + + + + +

+ +

+ + + + /> + +

+ + + +

+ + ' /> + : + ' /> +

+ +

+ + ' /> + @ + ' /> +

+ +
+

t('Log'));?>

t('Log level'));?> Date: Wed, 19 Feb 2014 22:50:49 +0100 Subject: [PATCH 028/118] Uses OC.basename instead of custom code --- apps/files/js/filelist.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 14f03121ff6..7d0818ef1ee 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -196,7 +196,7 @@ window.FileList={ var $dir = $('#dir'), url, currentDir = $dir.val() || '/', - baseDir = targetDir.split('/').pop(), + baseDir = OC.basename(targetDir), targetDir = targetDir || '/'; if (!force && currentDir === targetDir) { return; @@ -1117,7 +1117,7 @@ $(document).ready(function() { } - baseDir = parseCurrentDirFromUrl().split('/').pop(); + baseDir = OC.basename(parseCurrentDirFromUrl()); if (baseDir !== '') { FileList.setPageTitle(baseDir); From b61f0f11c5aa03240d3c18f02a1c790bd43522c0 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Thu, 20 Feb 2014 10:26:05 +0100 Subject: [PATCH 029/118] Move oc_isadmin to the config JS script --- core/js/config.php | 1 + core/js/js.js | 1 - core/templates/layout.user.php | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/js/config.php b/core/js/config.php index b6875fb73f9..6185be523e7 100644 --- a/core/js/config.php +++ b/core/js/config.php @@ -24,6 +24,7 @@ foreach(OC_App::getEnabledApps() as $app) { $array = array( "oc_debug" => (defined('DEBUG') && DEBUG) ? 'true' : 'false', + "ox_isadmin" => p(OC_User::isAdminUser(OC_User::getUser()) ? 'true' : 'false'); "oc_webroot" => "\"".OC::$WEBROOT."\"", "oc_appswebroots" => str_replace('\\/', '/', json_encode($apps_paths)), // Ugly unescape slashes waiting for better solution "datepickerFormatDate" => json_encode($l->l('jsdate', 'jsdate')), diff --git a/core/js/js.js b/core/js/js.js index 3b3e0e99455..d4d2583f1e5 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -10,7 +10,6 @@ var oc_webroot; var oc_current_user = document.getElementsByTagName('head')[0].getAttribute('data-user'); var oc_requesttoken = document.getElementsByTagName('head')[0].getAttribute('data-requesttoken'); -var oc_isadmin = document.getElementsByTagName('head')[0].getAttribute('data-isAdmin'); window.oc_config = window.oc_config || {}; diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php index d46f97852cc..bc1c700402e 100644 --- a/core/templates/layout.user.php +++ b/core/templates/layout.user.php @@ -6,7 +6,7 @@ - + <?php p(!empty($_['application'])?$_['application'].' - ':''); From ba7a79372a1e7f29f8f9de015fcc8500b6fed8dc Mon Sep 17 00:00:00 2001 From: Lukas Reschke <lukas@statuscode.ch> Date: Thu, 20 Feb 2014 10:28:11 +0100 Subject: [PATCH 030/118] Variable value is expected and not an echoed output --- core/js/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/js/config.php b/core/js/config.php index 6185be523e7..a9fd9d01098 100644 --- a/core/js/config.php +++ b/core/js/config.php @@ -24,7 +24,7 @@ foreach(OC_App::getEnabledApps() as $app) { $array = array( "oc_debug" => (defined('DEBUG') && DEBUG) ? 'true' : 'false', - "ox_isadmin" => p(OC_User::isAdminUser(OC_User::getUser()) ? 'true' : 'false'); + "ox_isadmin" => OC_User::isAdminUser(OC_User::getUser()) ? 'true' : 'false', "oc_webroot" => "\"".OC::$WEBROOT."\"", "oc_appswebroots" => str_replace('\\/', '/', json_encode($apps_paths)), // Ugly unescape slashes waiting for better solution "datepickerFormatDate" => json_encode($l->l('jsdate', 'jsdate')), From b060a17b59f7117a670f09550215cb005dd822bc Mon Sep 17 00:00:00 2001 From: Vincent Petry <pvince81@owncloud.com> Date: Wed, 19 Feb 2014 19:08:28 +0100 Subject: [PATCH 031/118] Added extra checks for ext storage class --- apps/files_external/lib/config.php | 8 +++++++- apps/files_external/tests/mountconfig.php | 25 +++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 94dc5fb7ad8..cd3e7f3a4a6 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -277,15 +277,21 @@ class OC_Mount_Config { $mountType, $applicable, $isPersonal = false) { + $backends = self::getBackends(); $mountPoint = OC\Files\Filesystem::normalizePath($mountPoint); if ($mountPoint === '' || $mountPoint === '/' || $mountPoint == '/Shared') { // can't mount at root or "Shared" folder return false; } + + if (!isset($backends[$class])) { + // invalid backend + return false; + } if ($isPersonal) { // Verify that the mount point applies for the current user // Prevent non-admin users from mounting local storage - if ($applicable != OCP\User::getUser() || $class == '\OC\Files\Storage\Local') { + if ($applicable !== OCP\User::getUser() || strtolower($class) === '\oc\files\storage\local') { return false; } $mountPoint = '/'.$applicable.'/files/'.ltrim($mountPoint, '/'); diff --git a/apps/files_external/tests/mountconfig.php b/apps/files_external/tests/mountconfig.php index 941aec680bb..24ebcf51346 100644 --- a/apps/files_external/tests/mountconfig.php +++ b/apps/files_external/tests/mountconfig.php @@ -48,4 +48,29 @@ class Test_Mount_Config extends \PHPUnit_Framework_TestCase { $this->assertEquals(false, OC_Mount_Config::addMountPoint('/Shared', $storageClass, array(), $mountType, $applicable, $isPersonal)); } + + public function testAddMountPointSingleUser() { + \OC_User::setUserId('test'); + $mountType = 'user'; + $applicable = 'test'; + $isPersonal = true; + // local + $this->assertEquals(false, OC_Mount_Config::addMountPoint('/ext', '\OC\Files\storage\local', array(), $mountType, $applicable, $isPersonal)); + // non-local + // FIXME: can't test this yet as the class (write operation) is not mockable + // $this->assertEquals(true, OC_Mount_Config::addMountPoint('/ext', '\OC\Files\Storage\SFTP', array(), $mountType, $applicable, $isPersonal)); + + } + + public function testAddMountPointUnexistClass() { + \OC_User::setUserId('test'); + $storageClass = 'Unexist_Storage'; + $mountType = 'user'; + $applicable = 'test'; + $isPersonal = true; + // local + // non-local + $this->assertEquals(false, OC_Mount_Config::addMountPoint('/ext', $storageClass, array(), $mountType, $applicable, $isPersonal)); + + } } From 3ce77a35e5eeb22b580e243e50a2daeba761d7fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <thomas.mueller@tmit.eu> Date: Thu, 20 Feb 2014 10:42:54 +0100 Subject: [PATCH 032/118] fixing js syntax error --- core/js/tags.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/js/tags.js b/core/js/tags.js index 16dd3d4bf97..bc6d7b4e071 100644 --- a/core/js/tags.js +++ b/core/js/tags.js @@ -25,11 +25,11 @@ OC.Tags= { }); self.deleteButton = { text: t('core', 'Delete'), - click: function() {self._deleteTags(self, type, self._selectedIds())}, + click: function() {self._deleteTags(self, type, self._selectedIds())} }; self.addButton = { text: t('core', 'Add'), - click: function() {self._addTag(self, type, self.$taginput.val())}, + click: function() {self._addTag(self, type, self.$taginput.val())} }; self._fillTagList(type, self.$taglist); @@ -349,5 +349,5 @@ OC.Tags= { console.warn(response); }); } -} +}; From 3e2c56157bfb20fbc48bdf668bd56fb47bd7cc1f Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt <hey@jancborchardt.net> Date: Thu, 20 Feb 2014 11:33:46 +0100 Subject: [PATCH 033/118] reduce width of searchbox on mobile, fix overlap, fix #7282 --- core/css/mobile.css | 20 ++++++++++++++++++++ core/css/styles.css | 10 ++++++---- lib/base.php | 1 + 3 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 core/css/mobile.css diff --git a/core/css/mobile.css b/core/css/mobile.css new file mode 100644 index 00000000000..a4cca6f37f6 --- /dev/null +++ b/core/css/mobile.css @@ -0,0 +1,20 @@ +@media only screen and (max-width: 600px) { + +/* compress search box on mobile, expand when focused */ +.searchbox input[type="search"] { + width: 17%; + -webkit-transition: width 100ms; + -moz-transition: width 100ms; + -o-transition: width 100ms; + transition: width 100ms; +} +.searchbox input[type="search"]:focus, +.searchbox input[type="search"]:active { + width: 155px; + -webkit-transition: width 100ms; + -moz-transition: width 100ms; + -o-transition: width 100ms; + transition: width 100ms; +} + +} diff --git a/core/css/styles.css b/core/css/styles.css index bee44785f12..c17d0a9bc07 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -205,17 +205,19 @@ textarea:disabled { color: #bbb; } - +/* Searchbox */ .searchbox input[type="search"] { + position: relative; font-size: 1.2em; - padding: .2em .5em .2em 1.5em; + padding-left: 1.5em; background: #fff url('../img/actions/search.svg') no-repeat .5em center; border: 0; - border-radius: 1em; + border-radius: 2em; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; filter:alpha(opacity=70); opacity: .7; - margin-top: 10px; + margin-top: 6px; float: right; } + input[type="submit"].enabled { background: #66f866; border: 1px solid #5e5; diff --git a/lib/base.php b/lib/base.php index a5f064bdb4b..84177c7ba6c 100644 --- a/lib/base.php +++ b/lib/base.php @@ -332,6 +332,7 @@ class OC { } OC_Util::addStyle("styles"); + OC_Util::addStyle("mobile"); OC_Util::addStyle("icons"); OC_Util::addStyle("apps"); OC_Util::addStyle("fixes"); From 169f4cf7ff26932ec1e07bfc3676f22c06859db7 Mon Sep 17 00:00:00 2001 From: Lukas Reschke <lukas@statuscode.ch> Date: Thu, 20 Feb 2014 12:51:15 +0100 Subject: [PATCH 034/118] Fix typo --- core/js/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/js/config.php b/core/js/config.php index a9fd9d01098..139c3b6d485 100644 --- a/core/js/config.php +++ b/core/js/config.php @@ -24,7 +24,7 @@ foreach(OC_App::getEnabledApps() as $app) { $array = array( "oc_debug" => (defined('DEBUG') && DEBUG) ? 'true' : 'false', - "ox_isadmin" => OC_User::isAdminUser(OC_User::getUser()) ? 'true' : 'false', + "oc_isadmin" => OC_User::isAdminUser(OC_User::getUser()) ? 'true' : 'false', "oc_webroot" => "\"".OC::$WEBROOT."\"", "oc_appswebroots" => str_replace('\\/', '/', json_encode($apps_paths)), // Ugly unescape slashes waiting for better solution "datepickerFormatDate" => json_encode($l->l('jsdate', 'jsdate')), From bf22ed7bdbb4289253a85fe423b99d4f96a57fba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <thomas.mueller@tmit.eu> Date: Thu, 20 Feb 2014 13:10:56 +0100 Subject: [PATCH 035/118] kill old minimizer code --- .htaccess | 1 - core/routes.php | 3 -- lib/base.php | 26 +++----------- lib/private/minimizer.php | 64 ----------------------------------- lib/private/minimizer/css.php | 38 --------------------- lib/private/minimizer/js.php | 21 ------------ 6 files changed, 4 insertions(+), 149 deletions(-) delete mode 100644 lib/private/minimizer.php delete mode 100644 lib/private/minimizer/css.php delete mode 100644 lib/private/minimizer/js.php diff --git a/.htaccess b/.htaccess index 4ba5095e144..fef8c4fb8d0 100755 --- a/.htaccess +++ b/.htaccess @@ -26,7 +26,6 @@ RewriteRule ^.well-known/carddav /remote.php/carddav/ [R] RewriteRule ^.well-known/caldav /remote.php/caldav/ [R] RewriteRule ^apps/calendar/caldav.php remote.php/caldav/ [QSA,L] RewriteRule ^apps/contacts/carddav.php remote.php/carddav/ [QSA,L] -RewriteRule ^apps/([^/]*)/(.*\.(php))$ index.php?app=$1&getfile=$2 [QSA,L] RewriteRule ^remote/(.*) remote.php [QSA,L] </IfModule> <IfModule mod_mime.c> diff --git a/core/routes.php b/core/routes.php index f8454877e03..aea788bdc6b 100644 --- a/core/routes.php +++ b/core/routes.php @@ -100,9 +100,6 @@ $this->create('core_avatar_post_cropped', '/avatar/cropped') ->action('OC\Core\Avatar\Controller', 'postCroppedAvatar'); // Not specifically routed -$this->create('app_css', '/apps/{app}/{file}') - ->requirements(array('file' => '.*.css')) - ->action('OC', 'loadCSSFile'); $this->create('app_index_script', '/apps/{app}/') ->defaults(array('file' => 'index.php')) //->requirements(array('file' => '.*.php')) diff --git a/lib/base.php b/lib/base.php index a5f064bdb4b..b39a96f331f 100644 --- a/lib/base.php +++ b/lib/base.php @@ -284,10 +284,10 @@ class OC { if (self::needUpgrade()) { if ($showTemplate && !OC_Config::getValue('maintenance', false)) { OC_Config::setValue('theme', ''); - $minimizerCSS = new OC_Minimizer_CSS(); - $minimizerCSS->clearCache(); - $minimizerJS = new OC_Minimizer_JS(); - $minimizerJS->clearCache(); +// $minimizerCSS = new OC_Minimizer_CSS(); +// $minimizerCSS->clearCache(); +// $minimizerJS = new OC_Minimizer_JS(); +// $minimizerJS->clearCache(); OC_Util::addScript('config'); // needed for web root OC_Util::addScript('update'); $tmpl = new OC_Template('', 'update.admin', 'guest'); @@ -724,11 +724,6 @@ class OC { $app = OC::$REQUESTEDAPP; $file = OC::$REQUESTEDFILE; $param = array('app' => $app, 'file' => $file); - // Handle app css files - if (substr($file, -3) == 'css') { - self::loadCSSFile($param); - return; - } // Handle redirect URL for logged in users if (isset($_REQUEST['redirect_url']) && OC_User::isLoggedIn()) { @@ -795,19 +790,6 @@ class OC { return false; } - public static function loadCSSFile($param) { - $app = $param['app']; - $file = $param['file']; - $app_path = OC_App::getAppPath($app); - if (file_exists($app_path . '/' . $file)) { - $app_web_path = OC_App::getAppWebPath($app); - $filepath = $app_web_path . '/' . $file; - $minimizer = new OC_Minimizer_CSS(); - $info = array($app_path, $app_web_path, $file); - $minimizer->output(array($info), $filepath); - } - } - protected static function handleLogin() { OC_App::loadApps(array('prelogin')); $error = array(); diff --git a/lib/private/minimizer.php b/lib/private/minimizer.php deleted file mode 100644 index db522de74dc..00000000000 --- a/lib/private/minimizer.php +++ /dev/null @@ -1,64 +0,0 @@ -<?php - -abstract class OC_Minimizer { - public function generateETag($files) { - $fullpath_files = array(); - foreach($files as $file_info) { - $fullpath_files[] = $file_info[0] . '/' . $file_info[2]; - } - return OC_Cache::generateCacheKeyFromFiles($fullpath_files); - } - - abstract public function minimizeFiles($files); - - public function output($files, $cache_key) { - header('Content-Type: '.$this->contentType); - OC_Response::enableCaching(); - $etag = $this->generateETag($files); - $cache_key .= '-'.$etag; - - $gzout = false; - $cache = OC_Cache::getGlobalCache(); - if (!OC_Request::isNoCache() && (!defined('DEBUG') || !DEBUG)) { - OC_Response::setETagHeader($etag); - $gzout = $cache->get($cache_key.'.gz'); - } - - if (!$gzout) { - $out = $this->minimizeFiles($files); - $gzout = gzencode($out); - $cache->set($cache_key.'.gz', $gzout); - OC_Response::setETagHeader($etag); - } - // on some systems (e.g. SLES 11, but not Ubuntu) mod_deflate and zlib compression will compress the output twice. - // This results in broken core.css and core.js. To avoid it, we switch off zlib compression. - // Since mod_deflate is still active, Apache will compress what needs to be compressed, i.e. no disadvantage. - if(function_exists('apache_get_modules') && ini_get('zlib.output_compression') && in_array('mod_deflate', apache_get_modules())) { - ini_set('zlib.output_compression', 'Off'); - } - if ($encoding = OC_Request::acceptGZip()) { - header('Content-Encoding: '.$encoding); - $out = $gzout; - } else { - $out = gzdecode($gzout); - } - header('Content-Length: '.strlen($out)); - echo $out; - } - - public function clearCache() { - $cache = OC_Cache::getGlobalCache(); - $cache->clear('core.css'); - $cache->clear('core.js'); - } -} - -if (!function_exists('gzdecode')) { - function gzdecode($data, $maxlength=null, &$filename='', &$error='') - { - if (strcmp(substr($data, 0, 9),"\x1f\x8b\x8\0\0\0\0\0\0")) { - return null; // Not the GZIP format we expect (See RFC 1952) - } - return gzinflate(substr($data, 10, -8)); - } -} diff --git a/lib/private/minimizer/css.php b/lib/private/minimizer/css.php deleted file mode 100644 index 8d130572e2b..00000000000 --- a/lib/private/minimizer/css.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -require_once 'mediawiki/CSSMin.php'; - -class OC_Minimizer_CSS extends OC_Minimizer -{ - protected $contentType = 'text/css'; - - public function minimizeFiles($files) { - $css_out = ''; - $webroot = (string) OC::$WEBROOT; - foreach($files as $file_info) { - $file = $file_info[0] . '/' . $file_info[2]; - $css_out .= '/* ' . $file . ' */' . "\n"; - $css = file_get_contents($file); - - $in_root = false; - foreach(OC::$APPSROOTS as $app_root) { - if(strpos($file, $app_root['path'].'/') === 0) { - $in_root = rtrim($webroot.$app_root['url'], '/'); - break; - } - } - if ($in_root !== false) { - $css = str_replace('%appswebroot%', $in_root, $css); - $css = str_replace('%webroot%', $webroot, $css); - } - $remote = $file_info[1]; - $remote .= '/'; - $remote .= dirname($file_info[2]); - $css_out .= CSSMin::remap($css, dirname($file), $remote, true); - } - if (!defined('DEBUG') || !DEBUG) { - $css_out = CSSMin::minify($css_out); - } - return $css_out; - } -} diff --git a/lib/private/minimizer/js.php b/lib/private/minimizer/js.php deleted file mode 100644 index bd2d836deb0..00000000000 --- a/lib/private/minimizer/js.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php - -require_once 'mediawiki/JavaScriptMinifier.php'; - -class OC_Minimizer_JS extends OC_Minimizer -{ - protected $contentType = 'application/javascript'; - - public function minimizeFiles($files) { - $js_out = ''; - foreach($files as $file_info) { - $file = $file_info[0] . '/' . $file_info[2]; - $js_out .= '/* ' . $file . ' */' . "\n"; - $js_out .= file_get_contents($file); - } - if (!defined('DEBUG') || !DEBUG) { - $js_out = JavaScriptMinifier::minify($js_out); - } - return $js_out; - } -} From ac8e6b15b64d5ad3b07b1fc3f845a4a67e49eaea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <thomas.mueller@tmit.eu> Date: Thu, 20 Feb 2014 13:23:24 +0100 Subject: [PATCH 036/118] kill references to core.js and core.css --- core/minimizer.php | 15 --------------- lib/private/setup.php | 2 -- 2 files changed, 17 deletions(-) delete mode 100644 core/minimizer.php diff --git a/core/minimizer.php b/core/minimizer.php deleted file mode 100644 index eeeddf86a81..00000000000 --- a/core/minimizer.php +++ /dev/null @@ -1,15 +0,0 @@ -<?php -session_write_close(); - -OC_App::loadApps(); - -if ($service == 'core.css') { - $minimizer = new OC_Minimizer_CSS(); - $files = OC_TemplateLayout::findStylesheetFiles(OC_Util::$coreStyles); - $minimizer->output($files, $service); -} -else if ($service == 'core.js') { - $minimizer = new OC_Minimizer_JS(); - $files = OC_TemplateLayout::findJavascriptFiles(OC_Util::$coreScripts); - $minimizer->output($files, $service); -} diff --git a/lib/private/setup.php b/lib/private/setup.php index 17ef75bc7b5..7bf75be0165 100644 --- a/lib/private/setup.php +++ b/lib/private/setup.php @@ -97,8 +97,6 @@ class OC_Setup { $appConfig = \OC::$server->getAppConfig(); $appConfig->setValue('core', 'installedat', microtime(true)); $appConfig->setValue('core', 'lastupdatedat', microtime(true)); - $appConfig->setValue('core', 'remote_core.css', '/core/minimizer.php'); - $appConfig->setValue('core', 'remote_core.js', '/core/minimizer.php'); OC_Group::createGroup('admin'); OC_Group::addToGroup($username, 'admin'); From 328428e40a17779199da065086307060799d0575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <thomas.mueller@tmit.eu> Date: Thu, 20 Feb 2014 13:26:23 +0100 Subject: [PATCH 037/118] reference 3rdparty branch add-assetic --- 3rdparty | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty b/3rdparty index 7c2c94c904c..f776a03d060 160000 --- a/3rdparty +++ b/3rdparty @@ -1 +1 @@ -Subproject commit 7c2c94c904c2721763e97d5bafd115f863080a60 +Subproject commit f776a03d06088cd64cdc94aa61834ba358ad36f5 From 7242d00aa6cbf1b0fda0bfeb4392263d909cc3e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <thomas.mueller@tmit.eu> Date: Thu, 20 Feb 2014 13:27:46 +0100 Subject: [PATCH 038/118] enable static delivery of css files --- lib/private/template/cssresourcelocator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/template/cssresourcelocator.php b/lib/private/template/cssresourcelocator.php index 8e7831ca549..e26daa25827 100644 --- a/lib/private/template/cssresourcelocator.php +++ b/lib/private/template/cssresourcelocator.php @@ -22,7 +22,7 @@ class CSSResourceLocator extends ResourceLocator { $app = substr($style, 0, strpos($style, '/')); $style = substr($style, strpos($style, '/')+1); $app_path = \OC_App::getAppPath($app); - $app_url = $this->webroot . '/index.php/apps/' . $app; + $app_url = \OC_App::getAppWebPath($app); if ($this->appendIfExist($app_path, $style.$this->form_factor.'.css', $app_url) || $this->appendIfExist($app_path, $style.'.css', $app_url) ) { From 8cf73ca42fd3e2d362a75e11a0f3ac1ae0ab3a34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <thomas.mueller@tmit.eu> Date: Thu, 20 Feb 2014 13:28:27 +0100 Subject: [PATCH 039/118] integrate assetic for asset pipeline-ing --- config/config.sample.php | 3 + lib/private/templatelayout.php | 113 +++++++++++++++++++++++++-------- 2 files changed, 91 insertions(+), 25 deletions(-) diff --git a/config/config.sample.php b/config/config.sample.php index 0cd321d095d..4e8bd79d797 100755 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -263,4 +263,7 @@ $CONFIG = array( /* whether usage of the instance should be restricted to admin users only */ 'singleuser' => false, + + /* all css and js files will be served by the web server statically in one js file and ons css file*/ + 'asset-pipeline.enabled' => false, ); diff --git a/lib/private/templatelayout.php b/lib/private/templatelayout.php index 7bca5bc4836..af17adb11c6 100644 --- a/lib/private/templatelayout.php +++ b/lib/private/templatelayout.php @@ -1,4 +1,11 @@ <?php +use Assetic\Asset\AssetCollection; +use Assetic\Asset\FileAsset; +use Assetic\Asset\GlobAsset; +use Assetic\AssetManager; +use Assetic\AssetWriter; +use Assetic\Filter\CssRewriteFilter; + /** * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl> * This file is licensed under the Affero General Public License version 3 or @@ -57,35 +64,38 @@ class OC_TemplateLayout extends OC_Template { } else { parent::__construct('core', 'layout.base'); } + $versionParameter = '?v=' . md5(implode(OC_Util::getVersion())); - // Add the js files - $jsfiles = self::findJavascriptFiles(OC_Util::$scripts); - $this->assign('jsfiles', array(), false); - if (OC_Config::getValue('installed', false) && $renderas!='error') { + $useAssetPipeline = OC_Config::getValue('asset-pipeline.enabled', false); + if ($useAssetPipeline) { + $this->append( 'jsfiles', OC_Helper::linkToRoute('js_config') . $versionParameter); - } - if (!empty(OC_Util::$coreScripts)) { - $this->append( 'jsfiles', OC_Helper::linkToRemoteBase('core.js', false) . $versionParameter); - } - foreach($jsfiles as $info) { - $root = $info[0]; - $web = $info[1]; - $file = $info[2]; - $this->append( 'jsfiles', $web.'/'.$file . $versionParameter); - } - // Add the css files - $cssfiles = self::findStylesheetFiles(OC_Util::$styles); - $this->assign('cssfiles', array()); - if (!empty(OC_Util::$coreStyles)) { - $this->append( 'cssfiles', OC_Helper::linkToRemoteBase('core.css', false) . $versionParameter); - } - foreach($cssfiles as $info) { - $root = $info[0]; - $web = $info[1]; - $file = $info[2]; + $this->generateAssets(); - $this->append( 'cssfiles', $web.'/'.$file . $versionParameter); + } else { + + // Add the js files + $jsfiles = self::findJavascriptFiles(OC_Util::$scripts); + $this->assign('jsfiles', array(), false); + if (OC_Config::getValue('installed', false) && $renderas!='error') { + $this->append( 'jsfiles', OC_Helper::linkToRoute('js_config') . $versionParameter); + } + foreach($jsfiles as $info) { + $web = $info[1]; + $file = $info[2]; + $this->append( 'jsfiles', $web.'/'.$file . $versionParameter); + } + + // Add the css files + $cssfiles = self::findStylesheetFiles(OC_Util::$styles); + $this->assign('cssfiles', array()); + foreach($cssfiles as $info) { + $web = $info[1]; + $file = $info[2]; + + $this->append( 'cssfiles', $web.'/'.$file . $versionParameter); + } } } @@ -116,4 +126,57 @@ class OC_TemplateLayout extends OC_Template { $locator->find($scripts); return $locator->getResources(); } + + public function generateAssets() + { + $jsFiles = self::findJavascriptFiles(OC_Util::$scripts); + $jsHash = self::hashScriptNames($jsFiles); + + if (!file_exists("assets/$jsHash.js")) { + $jsFiles = array_map(function ($item) { + $root = $item[0]; + $file = $item[2]; + return new FileAsset($root . '/' . $file, array(), $root, $file); + }, $jsFiles); + $jsCollection = new AssetCollection($jsFiles); + $jsCollection->setTargetPath("assets/$jsHash.js"); + + $writer = new AssetWriter(\OC::$SERVERROOT); + $writer->writeAsset($jsCollection); + } + + $cssFiles = self::findStylesheetFiles(OC_Util::$styles); + $cssHash = self::hashScriptNames($cssFiles); + + if (!file_exists("assets/$cssHash.css")) { + $cssFiles = array_map(function ($item) { + $root = $item[0]; + $file = $item[2]; + $assetPath = $root . '/' . $file; + $sourceRoot = \OC::$SERVERROOT; + $sourcePath = substr($assetPath, strlen(\OC::$SERVERROOT)); + return new FileAsset($assetPath, array(new CssRewriteFilter()), $sourceRoot, $sourcePath); + }, $cssFiles); + $cssCollection = new AssetCollection($cssFiles); + $cssCollection->setTargetPath("assets/$cssHash.css"); + + $writer = new AssetWriter(\OC::$SERVERROOT); + $writer->writeAsset($cssCollection); + } + + $this->append('jsfiles', OC_Helper::linkTo('assets', "$jsHash.js")); + $this->append('cssfiles', OC_Helper::linkTo('assets', "$cssHash.css")); + } + + private static function hashScriptNames($files) + { + $files = array_map(function ($item) { + $root = $item[0]; + $file = $item[2]; + return $root . '/' . $file; + }, $files); + + sort($files); + return hash('md5', implode('', $files)); + } } From 92d57cb5a7de41e576c9cbd3fae70e9802561187 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt <hey@jancborchardt.net> Date: Thu, 20 Feb 2014 13:36:52 +0100 Subject: [PATCH 040/118] move avatar into clickable area of user menu --- core/css/styles.css | 8 ++++---- core/js/js.js | 4 +++- core/templates/layout.user.php | 6 +++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/core/css/styles.css b/core/css/styles.css index c17d0a9bc07..1c80a3ea160 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -37,11 +37,12 @@ body { background:#fefefe; font:normal .8em/1.6em "Helvetica Neue",Helvetica,Ari .header-right { float:right; vertical-align:middle; padding:0.5em; } .header-right > * { vertical-align:middle; } +/* Profile picture in header */ #header .avatardiv { float: left; display: inline-block; + margin-right: 5px; } - #header .avatardiv img { opacity: 1; } @@ -708,12 +709,11 @@ label.infield { cursor:text !important; top:1.05em; left:.85em; } /* USER MENU */ #settings { float: right; - margin-top: 7px; - margin-left: 10px; color: #bbb; } #expand { - padding: 15px 15px 15px 5px; + display: block; + padding: 7px 12px 6px 7px; cursor: pointer; font-weight: bold; } diff --git a/core/js/js.js b/core/js/js.js index d4d2583f1e5..59d48806418 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -860,6 +860,7 @@ function initCore() { // checkShowCredentials(); // $('input#user, input#password').keyup(checkShowCredentials); + // user menu $('#settings #expand').keydown(function(event) { if (event.which === 13 || event.which === 32) { $('#expand').click() @@ -872,7 +873,8 @@ function initCore() { $('#settings #expanddiv').click(function(event){ event.stopPropagation(); }); - $(document).click(function(){//hide the settings menu when clicking outside it + //hide the user menu when clicking outside it + $(document).click(function(){ $('#settings #expanddiv').slideUp(200); }); diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php index bc1c700402e..8b9e1e0f4fe 100644 --- a/core/templates/layout.user.php +++ b/core/templates/layout.user.php @@ -50,12 +50,12 @@ <div id="logo-claim" style="display:none;"><?php p($theme->getLogoClaim()); ?></div> <div id="settings" class="svg"> <span id="expand" tabindex="0" role="link"> + <?php if ($_['enableAvatars']): ?> + <div class="avatardiv"></div> + <?php endif; ?> <span id="expandDisplayName"><?php p(trim($_['user_displayname']) != '' ? $_['user_displayname'] : $_['user_uid']) ?></span> <img class="svg" alt="" src="<?php print_unescaped(image_path('', 'actions/caret.svg')); ?>" /> </span> - <?php if ($_['enableAvatars']): ?> - <div class="avatardiv"></div> - <?php endif; ?> <div id="expanddiv"> <ul> <?php foreach($_['settingsnavigation'] as $entry):?> From 20b740f8e4674ab16f44127bc809a35b8db24910 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt <hey@jancborchardt.net> Date: Thu, 20 Feb 2014 13:37:23 +0100 Subject: [PATCH 041/118] do not show display name on mobile when profile picture is present --- core/css/mobile.css | 6 ++++++ core/js/avatar.js | 9 ++++++++- core/js/jquery.avatar.js | 10 +++++++++- settings/js/personal.js | 2 ++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/core/css/mobile.css b/core/css/mobile.css index a4cca6f37f6..65c756aa91a 100644 --- a/core/css/mobile.css +++ b/core/css/mobile.css @@ -17,4 +17,10 @@ transition: width 100ms; } +/* do not show display name on mobile when profile picture is present */ +#header .avatardiv.avatardiv-shown + #expandDisplayName { + display: none; +} + + } diff --git a/core/js/avatar.js b/core/js/avatar.js index c54c4068768..67d6b9b7b95 100644 --- a/core/js/avatar.js +++ b/core/js/avatar.js @@ -1,6 +1,13 @@ $(document).ready(function(){ if (OC.currentUser) { - $('#header .avatardiv').avatar(OC.currentUser, 32, undefined, true); + var callback = function() { + // do not show display name on mobile when profile picture is present + if($('#header .avatardiv').children().length > 0) { + $('#header .avatardiv').addClass('avatardiv-shown'); + } + }; + + $('#header .avatardiv').avatar(OC.currentUser, 32, undefined, true, callback); // Personal settings $('#avatar .avatardiv').avatar(OC.currentUser, 128); } diff --git a/core/js/jquery.avatar.js b/core/js/jquery.avatar.js index 6012eccfad6..02a40c088b4 100644 --- a/core/js/jquery.avatar.js +++ b/core/js/jquery.avatar.js @@ -39,10 +39,15 @@ * This will behave like the first example, but it will hide the avatardiv, if * it will display the default placeholder. undefined is the ie8fix from * example 4 and can be either true, or false/undefined, to be ignored. + * + * 6. $('.avatardiv').avatar('jdoe', 128, undefined, true, callback); + * This will behave like the above example, but it will call the function + * defined in callback after the avatar is placed into the DOM. + * */ (function ($) { - $.fn.avatar = function(user, size, ie8fix, hidedefault) { + $.fn.avatar = function(user, size, ie8fix, hidedefault, callback) { if (typeof(size) === 'undefined') { if (this.height() > 0) { size = this.height(); @@ -91,6 +96,9 @@ $div.html('<img src="'+url+'">'); } } + if(typeof callback === 'function') { + callback(); + } }); }); }; diff --git a/settings/js/personal.js b/settings/js/personal.js index ef261b50bbc..5944272067b 100644 --- a/settings/js/personal.js +++ b/settings/js/personal.js @@ -52,9 +52,11 @@ function updateAvatar (hidedefault) { if(hidedefault) { $headerdiv.hide(); + $('#header .avatardiv').removeClass('avatardiv-shown'); } else { $headerdiv.css({'background-color': ''}); $headerdiv.avatar(OC.currentUser, 32, true); + $('#header .avatardiv').addClass('avatardiv-shown'); } $displaydiv.css({'background-color': ''}); $displaydiv.avatar(OC.currentUser, 128, true); From 2955d9b48372c5ff8d364757cca94508441c1be1 Mon Sep 17 00:00:00 2001 From: Lukas Reschke <lukas@statuscode.ch> Date: Thu, 20 Feb 2014 13:54:05 +0100 Subject: [PATCH 042/118] Indentation --- config/config.sample.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/config.sample.php b/config/config.sample.php index 4e8bd79d797..d4cccd3443d 100755 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -264,6 +264,6 @@ $CONFIG = array( /* whether usage of the instance should be restricted to admin users only */ 'singleuser' => false, - /* all css and js files will be served by the web server statically in one js file and ons css file*/ - 'asset-pipeline.enabled' => false, +/* all css and js files will be served by the web server statically in one js file and ons css file*/ +'asset-pipeline.enabled' => false, ); From d5690a174e42ad97cf7e9bffa3b62f42b69f6a82 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon <blizzz@owncloud.com> Date: Thu, 20 Feb 2014 14:05:45 +0100 Subject: [PATCH 043/118] LDAP: fix and extend tests --- apps/user_ldap/tests/access.php | 71 ++++++++++++++++++++ apps/user_ldap/tests/user_ldap.php | 101 ++++++++++++++++++++++++++++- 2 files changed, 169 insertions(+), 3 deletions(-) create mode 100644 apps/user_ldap/tests/access.php diff --git a/apps/user_ldap/tests/access.php b/apps/user_ldap/tests/access.php new file mode 100644 index 00000000000..9beb2b97336 --- /dev/null +++ b/apps/user_ldap/tests/access.php @@ -0,0 +1,71 @@ +<?php +/** +* ownCloud +* +* @author Arthur Schiwon +* @copyright 2013 Arthur Schiwon blizzz@owncloud.com +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +* License as published by the Free Software Foundation; either +* version 3 of the License, or any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU AFFERO GENERAL PUBLIC LICENSE for more details. +* +* You should have received a copy of the GNU Affero General Public +* License along with this library. If not, see <http://www.gnu.org/licenses/>. +* +*/ + +namespace OCA\user_ldap\tests; + +use \OCA\user_ldap\lib\Access; +use \OCA\user_ldap\lib\Connection; +use \OCA\user_ldap\lib\ILDAPWrapper; + +class Test_Access extends \PHPUnit_Framework_TestCase { + private function getConnecterAndLdapMock() { + static $conMethods; + static $accMethods; + + if(is_null($conMethods) || is_null($accMethods)) { + $conMethods = get_class_methods('\OCA\user_ldap\lib\Connection'); + $accMethods = get_class_methods('\OCA\user_ldap\lib\Access'); + } + $lw = $this->getMock('\OCA\user_ldap\lib\ILDAPWrapper'); + $connector = $this->getMock('\OCA\user_ldap\lib\Connection', + $conMethods, + array($lw, null, null)); + + return array($lw, $connector); + } + + public function testEscapeFilterPartValidChars() { + list($lw, $con) = $this->getConnecterAndLdapMock(); + $access = new Access($con, $lw); + + $input = 'okay'; + $this->assertTrue($input === $access->escapeFilterPart($input)); + } + + public function testEscapeFilterPartEscapeWildcard() { + list($lw, $con) = $this->getConnecterAndLdapMock(); + $access = new Access($con, $lw); + + $input = '*'; + $expected = '\\\\*'; + $this->assertTrue($expected === $access->escapeFilterPart($input)); + } + + public function testEscapeFilterPartEscapeWildcard2() { + list($lw, $con) = $this->getConnecterAndLdapMock(); + $access = new Access($con, $lw); + + $input = 'foo*bar'; + $expected = 'foo\\\\*bar'; + $this->assertTrue($expected === $access->escapeFilterPart($input)); + } +} \ No newline at end of file diff --git a/apps/user_ldap/tests/user_ldap.php b/apps/user_ldap/tests/user_ldap.php index 9193a005ae5..8c8d85b3c33 100644 --- a/apps/user_ldap/tests/user_ldap.php +++ b/apps/user_ldap/tests/user_ldap.php @@ -83,6 +83,12 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase { * @return void */ private function prepareAccessForCheckPassword(&$access) { + $access->expects($this->once()) + ->method('escapeFilterPart') + ->will($this->returnCallback(function($uid) { + return $uid; + })); + $access->connection->expects($this->any()) ->method('__get') ->will($this->returnCallback(function($name) { @@ -116,17 +122,34 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase { })); } - public function testCheckPassword() { + public function testCheckPasswordUidReturn() { $access = $this->getAccessMock(); + $this->prepareAccessForCheckPassword($access); $backend = new UserLDAP($access); \OC_User::useBackend($backend); $result = $backend->checkPassword('roland', 'dt19'); $this->assertEquals('gunslinger', $result); + } + + public function testCheckPasswordWrongPassword() { + $access = $this->getAccessMock(); + + $this->prepareAccessForCheckPassword($access); + $backend = new UserLDAP($access); + \OC_User::useBackend($backend); $result = $backend->checkPassword('roland', 'wrong'); $this->assertFalse($result); + } + + public function testCheckPasswordWrongUser() { + $access = $this->getAccessMock(); + + $this->prepareAccessForCheckPassword($access); + $backend = new UserLDAP($access); + \OC_User::useBackend($backend); $result = $backend->checkPassword('mallory', 'evil'); $this->assertFalse($result); @@ -140,9 +163,23 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase { $result = \OCP\User::checkPassword('roland', 'dt19'); $this->assertEquals('gunslinger', $result); + } + + public function testCheckPasswordPublicAPIWrongPassword() { + $access = $this->getAccessMock(); + $this->prepareAccessForCheckPassword($access); + $backend = new UserLDAP($access); + \OC_User::useBackend($backend); $result = \OCP\User::checkPassword('roland', 'wrong'); $this->assertFalse($result); + } + + public function testCheckPasswordPublicAPIWrongUser() { + $access = $this->getAccessMock(); + $this->prepareAccessForCheckPassword($access); + $backend = new UserLDAP($access); + \OC_User::useBackend($backend); $result = \OCP\User::checkPassword('mallory', 'evil'); $this->assertFalse($result); @@ -154,6 +191,12 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase { * @return void */ private function prepareAccessForGetUsers(&$access) { + $access->expects($this->once()) + ->method('escapeFilterPart') + ->will($this->returnCallback(function($search) { + return $search; + })); + $access->expects($this->any()) ->method('getFilterPartForUserSearch') ->will($this->returnCallback(function($search) { @@ -191,28 +234,52 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase { ->will($this->returnArgument(0)); } - public function testGetUsers() { + public function testGetUsersNoParam() { $access = $this->getAccessMock(); $this->prepareAccessForGetUsers($access); $backend = new UserLDAP($access); $result = $backend->getUsers(); $this->assertEquals(3, count($result)); + } + + public function testGetUsersLimitOffset() { + $access = $this->getAccessMock(); + $this->prepareAccessForGetUsers($access); + $backend = new UserLDAP($access); $result = $backend->getUsers('', 1, 2); $this->assertEquals(1, count($result)); + } + + public function testGetUsersLimitOffset2() { + $access = $this->getAccessMock(); + $this->prepareAccessForGetUsers($access); + $backend = new UserLDAP($access); $result = $backend->getUsers('', 2, 1); $this->assertEquals(2, count($result)); + } + + public function testGetUsersSearchWithResult() { + $access = $this->getAccessMock(); + $this->prepareAccessForGetUsers($access); + $backend = new UserLDAP($access); $result = $backend->getUsers('yo'); $this->assertEquals(2, count($result)); + } + + public function testGetUsersSearchEmptyResult() { + $access = $this->getAccessMock(); + $this->prepareAccessForGetUsers($access); + $backend = new UserLDAP($access); $result = $backend->getUsers('nix'); $this->assertEquals(0, count($result)); } - public function testGetUsersViaAPI() { + public function testGetUsersViaAPINoParam() { $access = $this->getAccessMock(); $this->prepareAccessForGetUsers($access); $backend = new UserLDAP($access); @@ -220,15 +287,43 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase { $result = \OCP\User::getUsers(); $this->assertEquals(3, count($result)); + } + + public function testGetUsersViaAPILimitOffset() { + $access = $this->getAccessMock(); + $this->prepareAccessForGetUsers($access); + $backend = new UserLDAP($access); + \OC_User::useBackend($backend); $result = \OCP\User::getUsers('', 1, 2); $this->assertEquals(1, count($result)); + } + + public function testGetUsersViaAPILimitOffset2() { + $access = $this->getAccessMock(); + $this->prepareAccessForGetUsers($access); + $backend = new UserLDAP($access); + \OC_User::useBackend($backend); $result = \OCP\User::getUsers('', 2, 1); $this->assertEquals(2, count($result)); + } + + public function testGetUsersViaAPISearchWithResult() { + $access = $this->getAccessMock(); + $this->prepareAccessForGetUsers($access); + $backend = new UserLDAP($access); + \OC_User::useBackend($backend); $result = \OCP\User::getUsers('yo'); $this->assertEquals(2, count($result)); + } + + public function testGetUsersViaAPISearchEmptyResult() { + $access = $this->getAccessMock(); + $this->prepareAccessForGetUsers($access); + $backend = new UserLDAP($access); + \OC_User::useBackend($backend); $result = \OCP\User::getUsers('nix'); $this->assertEquals(0, count($result)); From a0e790227e2fe9c33930bfe4259a7ddfb3de585f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <thomas.mueller@tmit.eu> Date: Thu, 20 Feb 2014 14:10:09 +0100 Subject: [PATCH 044/118] remove unused functions - have been introduced with the old minimizer approach --- lib/private/request.php | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/lib/private/request.php b/lib/private/request.php index 0fd20b3cc1f..d0128f95d96 100755 --- a/lib/private/request.php +++ b/lib/private/request.php @@ -179,33 +179,6 @@ class OC_Request { } } - /** - * @brief Check if this is a no-cache request - * @return boolean true for no-cache - */ - static public function isNoCache() { - if (!isset($_SERVER['HTTP_CACHE_CONTROL'])) { - return false; - } - return $_SERVER['HTTP_CACHE_CONTROL'] == 'no-cache'; - } - - /** - * @brief Check if the requestor understands gzip - * @return false|string true for gzip encoding supported - */ - static public function acceptGZip() { - if (!isset($_SERVER['HTTP_ACCEPT_ENCODING'])) { - return false; - } - $HTTP_ACCEPT_ENCODING = $_SERVER["HTTP_ACCEPT_ENCODING"]; - if( strpos($HTTP_ACCEPT_ENCODING, 'x-gzip') !== false ) - return 'x-gzip'; - else if( strpos($HTTP_ACCEPT_ENCODING, 'gzip') !== false ) - return 'gzip'; - return false; - } - /** * @brief Check if the requester sent along an mtime * @return false or an mtime From 01929096fed3be1689e7b0e53ab4b6a49791901f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <thomas.mueller@tmit.eu> Date: Thu, 20 Feb 2014 14:10:35 +0100 Subject: [PATCH 045/118] revert wrong change to .htaccess --- .htaccess | 1 + 1 file changed, 1 insertion(+) diff --git a/.htaccess b/.htaccess index fef8c4fb8d0..4ba5095e144 100755 --- a/.htaccess +++ b/.htaccess @@ -26,6 +26,7 @@ RewriteRule ^.well-known/carddav /remote.php/carddav/ [R] RewriteRule ^.well-known/caldav /remote.php/caldav/ [R] RewriteRule ^apps/calendar/caldav.php remote.php/caldav/ [QSA,L] RewriteRule ^apps/contacts/carddav.php remote.php/carddav/ [QSA,L] +RewriteRule ^apps/([^/]*)/(.*\.(php))$ index.php?app=$1&getfile=$2 [QSA,L] RewriteRule ^remote/(.*) remote.php [QSA,L] </IfModule> <IfModule mod_mime.c> From fbea02bebb561f7a76a876065066c9face6e484e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <thomas.mueller@tmit.eu> Date: Thu, 20 Feb 2014 14:18:01 +0100 Subject: [PATCH 046/118] kill $coreStyles and $coreScripts --- lib/base.php | 4 ---- lib/private/app.php | 11 ----------- lib/private/util.php | 2 -- 3 files changed, 17 deletions(-) diff --git a/lib/base.php b/lib/base.php index b39a96f331f..b3911094dbf 100644 --- a/lib/base.php +++ b/lib/base.php @@ -284,10 +284,6 @@ class OC { if (self::needUpgrade()) { if ($showTemplate && !OC_Config::getValue('maintenance', false)) { OC_Config::setValue('theme', ''); -// $minimizerCSS = new OC_Minimizer_CSS(); -// $minimizerCSS->clearCache(); -// $minimizerJS = new OC_Minimizer_JS(); -// $minimizerJS->clearCache(); OC_Util::addScript('config'); // needed for web root OC_Util::addScript('update'); $tmpl = new OC_Template('', 'update.admin', 'guest'); diff --git a/lib/private/app.php b/lib/private/app.php index 47f983cce35..048d4d4aeb1 100644 --- a/lib/private/app.php +++ b/lib/private/app.php @@ -69,17 +69,6 @@ class OC_App{ } ob_end_clean(); - if (!defined('DEBUG') || !DEBUG) { - if (is_null($types) - && empty(OC_Util::$coreScripts) - && empty(OC_Util::$coreStyles)) { - OC_Util::$coreScripts = OC_Util::$scripts; - OC_Util::$scripts = array(); - OC_Util::$coreStyles = OC_Util::$styles; - OC_Util::$styles = array(); - } - } - // return return true; } diff --git a/lib/private/util.php b/lib/private/util.php index b7856436527..b39304c485c 100755 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -11,8 +11,6 @@ class OC_Util { public static $headers=array(); private static $rootMounted=false; private static $fsSetup=false; - public static $coreStyles=array(); - public static $coreScripts=array(); /** * @brief Can be set up From 476444ab1a6f925b87ca6f6382953633fd060283 Mon Sep 17 00:00:00 2001 From: Vincent Petry <pvince81@owncloud.com> Date: Thu, 20 Feb 2014 14:56:28 +0100 Subject: [PATCH 047/118] Fixed title format --- apps/files/js/filelist.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 6bf134eed3b..3fd3c406b2f 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -22,6 +22,13 @@ window.FileList={ * Sets a new page title */ setPageTitle: function(title){ + if (title) { + title += ' - '; + } + else { + title = ''; + } + title += t('files', 'Files'); // Sets the page title with the " - ownCloud" suffix as in templates window.document.title = title + ' - ' + oc_defaults.title; @@ -206,7 +213,7 @@ window.FileList={ FileList.setPageTitle(baseDir); } else { - FileList.setPageTitle(t('files', 'Files')); + FileList.setPageTitle(); } FileList.setCurrentDir(targetDir, changeUrl); From 44441b56d63783a0be5c9b24f5b1ee9264509bef Mon Sep 17 00:00:00 2001 From: Vincent Petry <pvince81@owncloud.com> Date: Thu, 20 Feb 2014 15:16:45 +0100 Subject: [PATCH 048/118] Fixed trashbin title --- apps/files/js/filelist.js | 36 +++++++++++++----------------- apps/files_trashbin/js/filelist.js | 32 +++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 22 deletions(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 3fd3c406b2f..edcc5519b20 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -11,6 +11,7 @@ /* global OC, t, n, FileList, FileActions, Files */ /* global procesSelection, dragOptions, SVGSupport, replaceSVG */ window.FileList={ + appName: t('files', 'Files'), useUndo:true, postProcessList: function() { $('#fileList tr').each(function() { @@ -28,7 +29,7 @@ window.FileList={ else { title = ''; } - title += t('files', 'Files'); + title += FileList.appName; // Sets the page title with the " - ownCloud" suffix as in templates window.document.title = title + ' - ' + oc_defaults.title; @@ -202,22 +203,12 @@ window.FileList={ changeDirectory: function(targetDir, changeUrl, force) { var $dir = $('#dir'), url, - currentDir = $dir.val() || '/', - baseDir = OC.basename(targetDir), + currentDir = $dir.val() || '/'; targetDir = targetDir || '/'; if (!force && currentDir === targetDir) { return; } - - if (baseDir !== '') { - FileList.setPageTitle(baseDir); - } - else { - FileList.setPageTitle(); - } - FileList.setCurrentDir(targetDir, changeUrl); - $('#fileList').trigger( jQuery.Event('changeDirectory', { dir: targetDir, @@ -230,7 +221,16 @@ window.FileList={ return OC.linkTo('files', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/'); }, setCurrentDir: function(targetDir, changeUrl) { - var url; + var url, + baseDir = OC.basename(targetDir); + + if (baseDir !== '') { + FileList.setPageTitle(baseDir); + } + else { + FileList.setPageTitle(); + } + $('#dir').val(targetDir); if (changeUrl !== false) { if (window.history.pushState && changeUrl !== false) { @@ -1158,14 +1158,8 @@ $(document).ready(function() { FileList.changeDirectory(parseCurrentDirFromUrl(), false, true); } } - - - baseDir = OC.basename(parseCurrentDirFromUrl()); - - if (baseDir !== '') { - FileList.setPageTitle(baseDir); - } - + + FileList.setCurrentDir(parseCurrentDirFromUrl(), false); FileList.createFileSummary(); }); diff --git a/apps/files_trashbin/js/filelist.js b/apps/files_trashbin/js/filelist.js index f42abb6d029..a88459b0a9a 100644 --- a/apps/files_trashbin/js/filelist.js +++ b/apps/files_trashbin/js/filelist.js @@ -1,3 +1,4 @@ +/* globals OC, FileList, t */ // override reload with own ajax call FileList.reload = function(){ FileList.showMask(); @@ -17,7 +18,36 @@ FileList.reload = function(){ FileList.reloadCallback(result); } }); -} +}; + +FileList.appName = t('files_trashbin', 'Deleted files'); + +FileList._deletedRegExp = new RegExp(/^(.+)\.d[0-9]+$/); + +/** + * Convert a file name in the format filename.d12345 to the real file name. + * This will use basename. + * The name will not be changed if it has no ".d12345" suffix. + * @param name file name + * @return converted file name + */ +FileList.getDeletedFileName = function(name) { + name = OC.basename(name); + var match = FileList._deletedRegExp.exec(name); + if (match && match.length > 1) { + name = match[1]; + } + return name; +}; +var oldSetCurrentDir = FileList.setCurrentDir; +FileList.setCurrentDir = function(targetDir) { + oldSetCurrentDir.apply(this, arguments); + + var baseDir = OC.basename(targetDir); + if (baseDir !== '') { + FileList.setPageTitle(FileList.getDeletedFileName(baseDir)); + } +}; FileList.linkTo = function(dir){ return OC.linkTo('files_trashbin', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/'); From 658758c3f7e0f18a37c00ce107c8d3b4917183e0 Mon Sep 17 00:00:00 2001 From: Morris Jobke <morris.jobke@gmail.com> Date: Thu, 20 Feb 2014 15:36:52 +0100 Subject: [PATCH 049/118] fix intendation --- apps/files/js/filelist.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index edcc5519b20..2dacabaa9d6 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -32,7 +32,7 @@ window.FileList={ title += FileList.appName; // Sets the page title with the " - ownCloud" suffix as in templates window.document.title = title + ' - ' + oc_defaults.title; - + return true; }, /** @@ -874,7 +874,7 @@ window.FileList={ $(document).ready(function() { var baseDir, - isPublic = !!$('#isPublic').val(); + isPublic = !!$('#isPublic').val(); // handle upload events var file_upload_start = $('#file_upload_start'); @@ -1160,6 +1160,6 @@ $(document).ready(function() { } FileList.setCurrentDir(parseCurrentDirFromUrl(), false); - + FileList.createFileSummary(); }); From f710205ee766cb2c12cf21d28cd5295d9fff432c Mon Sep 17 00:00:00 2001 From: Robin Appelman <icewind@owncloud.com> Date: Thu, 20 Feb 2014 16:56:09 +0100 Subject: [PATCH 050/118] Make unit tests expect the svg icons --- apps/files/tests/ajax_rename.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/files/tests/ajax_rename.php b/apps/files/tests/ajax_rename.php index a1a5c8983ba..e53c0fb3dd1 100644 --- a/apps/files/tests/ajax_rename.php +++ b/apps/files/tests/ajax_rename.php @@ -110,7 +110,9 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { $this->assertEquals('/test', $result['data']['directory']); $this->assertEquals(18, $result['data']['size']); $this->assertEquals('httpd/unix-directory', $result['data']['mime']); - $this->assertEquals(\OC_Helper::mimetypeIcon('dir'), $result['data']['icon']); + $icon = \OC_Helper::mimetypeIcon('dir'); + $icon = substr($icon, 0, -3) . 'svg'; + $this->assertEquals($icon, $result['data']['icon']); $this->assertFalse($result['data']['isPreviewAvailable']); } @@ -165,7 +167,9 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { $this->assertEquals(18, $result['data']['size']); $this->assertEquals('httpd/unix-directory', $result['data']['mime']); $this->assertEquals('abcdef', $result['data']['etag']); - $this->assertEquals(\OC_Helper::mimetypeIcon('dir'), $result['data']['icon']); + $icon = \OC_Helper::mimetypeIcon('dir'); + $icon = substr($icon, 0, -3) . 'svg'; + $this->assertEquals($icon, $result['data']['icon']); $this->assertFalse($result['data']['isPreviewAvailable']); } From d46645846985fe181fcb252bec158624a1ee2957 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt <hey@jancborchardt.net> Date: Thu, 20 Feb 2014 17:37:48 +0100 Subject: [PATCH 051/118] restrict zooming in to not mangle layout accidentally --- core/templates/layout.user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php index 8b9e1e0f4fe..9e1555cfe6d 100644 --- a/core/templates/layout.user.php +++ b/core/templates/layout.user.php @@ -15,7 +15,7 @@ - + From d9bb21146f1169eb7e5a3617c23695e395aaee91 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 20 Feb 2014 18:14:40 +0100 Subject: [PATCH 052/118] fix IE10 viewport sizeing --- core/css/styles.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/css/styles.css b/core/css/styles.css index 0be0eaf3441..22ba60dd2b7 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -958,3 +958,8 @@ div.crumb:active { opacity: 0; } +/* for IE10 */ +@-ms-viewport { + width: device-width; +} + From 6cb64a4fced31906938159eb237159cac815ca26 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Thu, 20 Feb 2014 18:34:27 +0100 Subject: [PATCH 053/118] Fix code to search for mount.json in custom data folders --- apps/files_external/lib/config.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index b2109e5eacd..ed9a0126dd1 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -353,7 +353,8 @@ class OC_Mount_Config { $jsonFile = OC_User::getHome(OCP\User::getUser()).'/mount.json'; } else { $phpFile = OC::$SERVERROOT.'/config/mount.php'; - $jsonFile = \OC_Config::getValue("mount_file", \OC::$SERVERROOT . "/data/mount.json"); + $datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data/"); + $jsonFile = \OC_Config::getValue("mount_file", $datadir . "/mount.json"); } if (is_file($jsonFile)) { $mountPoints = json_decode(file_get_contents($jsonFile), true); From d5739e83d16dd4af1865999180c7867a7f77734f Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Thu, 20 Feb 2014 18:38:33 +0100 Subject: [PATCH 054/118] remove additional transition rule, reduce width of collapsed search bar --- core/css/mobile.css | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/core/css/mobile.css b/core/css/mobile.css index 65c756aa91a..a63aa902d34 100644 --- a/core/css/mobile.css +++ b/core/css/mobile.css @@ -2,7 +2,7 @@ /* compress search box on mobile, expand when focused */ .searchbox input[type="search"] { - width: 17%; + width: 15%; -webkit-transition: width 100ms; -moz-transition: width 100ms; -o-transition: width 100ms; @@ -11,10 +11,6 @@ .searchbox input[type="search"]:focus, .searchbox input[type="search"]:active { width: 155px; - -webkit-transition: width 100ms; - -moz-transition: width 100ms; - -o-transition: width 100ms; - transition: width 100ms; } /* do not show display name on mobile when profile picture is present */ From daf28225b7da283763ec84930608e154f49dee46 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 20 Feb 2014 18:42:59 +0100 Subject: [PATCH 055/118] fix viewport size on windows phone --- core/js/js.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/core/js/js.js b/core/js/js.js index d4d2583f1e5..c7024430aa7 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -987,6 +987,17 @@ OC.set=function(name, value) { context[tail]=value; }; +// fix device width on windows phone +(function() { + if ("-ms-user-select" in document.documentElement.style && navigator.userAgent.match(/IEMobile\/10\.0/)) { + var msViewportStyle = document.createElement("style"); + msViewportStyle.appendChild( + document.createTextNode("@-ms-viewport{width:auto!important}") + ); + document.getElementsByTagName("head")[0].appendChild(msViewportStyle); + } +})(); + /** * select a range in an input field * @link http://stackoverflow.com/questions/499126/jquery-set-cursor-position-in-text-area From f11658698d48e0fdd2065466651c4c86c22a80f2 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Thu, 20 Feb 2014 18:53:37 +0100 Subject: [PATCH 056/118] Fix path to the mount file --- lib/private/files/filesystem.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php index 952f9f9febf..7f7b6f7f468 100644 --- a/lib/private/files/filesystem.php +++ b/lib/private/files/filesystem.php @@ -320,7 +320,8 @@ class Filesystem { else { self::mount('\OC\Files\Storage\Local', array('datadir' => $root), $user); } - $mount_file = \OC_Config::getValue("mount_file", \OC::$SERVERROOT . "/data/mount.json"); + $datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data"); + $mount_file = \OC_Config::getValue("mount_file", $datadir . "/mount.json"); //move config file to it's new position if (is_file(\OC::$SERVERROOT . '/config/mount.json')) { From 1ae6e9ec21415ade8122a05d01dd091091cb4bcd Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 20 Feb 2014 18:50:27 +0100 Subject: [PATCH 057/118] add unit test for \OC\URLGenerator::getAbsoluteURL to verify #6935 --- tests/lib/urlgenerator.php | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/lib/urlgenerator.php diff --git a/tests/lib/urlgenerator.php b/tests/lib/urlgenerator.php new file mode 100644 index 00000000000..875a7f06580 --- /dev/null +++ b/tests/lib/urlgenerator.php @@ -0,0 +1,34 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +class Test_Urlgenerator extends PHPUnit_Framework_TestCase { + + + /** + * @small + * @brief test absolute URL construction + * @dataProvider provideURLs + */ + function testGetAbsoluteURL($url, $expectedResult) { + + $urlGenerator = new \OC\URLGenerator(null); + $result = $urlGenerator->getAbsoluteURL($url); + + $this->assertEquals($expectedResult, $result); + } + + public function provideURLs() { + return array( + array("index.php", "http://localhost/index.php"), + array("/index.php", "http://localhost/index.php"), + array("/apps/index.php", "http://localhost/apps/index.php"), + array("apps/index.php", "http://localhost/apps/index.php"), + ); + } +} + From 58be2eb955b8c23a8698bdbb7bae8077eb402ee3 Mon Sep 17 00:00:00 2001 From: ringmaster Date: Thu, 20 Feb 2014 18:13:27 -0500 Subject: [PATCH 058/118] Allow apps to add/modify config js output via hook. --- core/js/config.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/core/js/config.php b/core/js/config.php index 139c3b6d485..edb9ccfd0fb 100644 --- a/core/js/config.php +++ b/core/js/config.php @@ -10,8 +10,8 @@ header("Content-type: text/javascript"); // Disallow caching -header("Cache-Control: no-cache, must-revalidate"); -header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); +header("Cache-Control: no-cache, must-revalidate"); +header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Enable l10n support $l = OC_L10N::get('core'); @@ -62,7 +62,10 @@ $array = array( 'session_keepalive' => \OCP\Config::getSystemValue('session_keepalive', true) ) ) - ); +); + +// Allow hooks to modify the output values +OC_Hook::emit('\OCP\Config', 'js', array('array' => &$array)); // Echo it foreach ($array as $setting => $value) { From 69325c5eebef1f21b514a5edeb48d71d53815668 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 21 Feb 2014 08:11:07 +0100 Subject: [PATCH 059/118] Move session_regenerate_id to `login()` --- lib/private/user.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/private/user.php b/lib/private/user.php index 08ead712028..a89b7286c10 100644 --- a/lib/private/user.php +++ b/lib/private/user.php @@ -227,6 +227,7 @@ class OC_User { * Log in a user and regenerate a new session - if the password is ok */ public static function login($uid, $password) { + session_regenerate_id(true); return self::getUserSession()->login($uid, $password); } From f7fa8662e21fdb93383e771ba629f82d8344582a Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 21 Feb 2014 08:12:45 +0100 Subject: [PATCH 060/118] Remove `session_id_regenerate` from here Jenkins somewhat complains that there are already sent headers. --- lib/private/user/session.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/private/user/session.php b/lib/private/user/session.php index cd03b30205f..1740bad5abe 100644 --- a/lib/private/user/session.php +++ b/lib/private/user/session.php @@ -157,7 +157,6 @@ class Session implements Emitter, \OCP\IUserSession { if($user !== false) { if (!is_null($user)) { if ($user->isEnabled()) { - session_regenerate_id(true); $this->setUser($user); $this->setLoginName($uid); $this->manager->emit('\OC\User', 'postLogin', array($user, $password)); From b22d82f941d29157d659ec29689c75a8b53a530c Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Fri, 21 Feb 2014 09:42:19 +0100 Subject: [PATCH 061/118] code style: else on same line --- apps/files/js/filelist.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 2dacabaa9d6..35fbdeecd39 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -25,8 +25,7 @@ window.FileList={ setPageTitle: function(title){ if (title) { title += ' - '; - } - else { + } else { title = ''; } title += FileList.appName; From 229356348826402e4dc8090e1a805f278d6c9ad0 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 21 Feb 2014 10:02:03 +0100 Subject: [PATCH 062/118] Remove unit tests which causes the filesystem tests to fail --- tests/lib/connector/sabre/file.php | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/tests/lib/connector/sabre/file.php b/tests/lib/connector/sabre/file.php index 50b8711a90d..c2f0ffa12d4 100644 --- a/tests/lib/connector/sabre/file.php +++ b/tests/lib/connector/sabre/file.php @@ -48,21 +48,6 @@ class Test_OC_Connector_Sabre_File extends PHPUnit_Framework_TestCase { $etag = $file->put('test data'); } - /** - * Test setting name with setName() - */ - public function testSetName() { - // setup - $file = new OC_Connector_Sabre_File('/test.txt'); - $file->fileView = $this->getMock('\OC\Files\View', array('isUpdatable'), array(), '', FALSE); - $file->fileView->expects($this->any())->method('isUpdatable')->withAnyParameters()->will($this->returnValue(true)); - $etag = $file->put('test data'); - $file->setName('/renamed.txt'); - $this->assertTrue($file->fileView->file_exists('/renamed.txt')); - // clean up - $file->delete(); - } - /** * Test setting name with setName() with invalid chars * @expectedException Sabre_DAV_Exception_BadRequest From 0e2ce33ab0e6bd5cd4cda9f0f1c0b9081b75ecde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Fri, 21 Feb 2014 10:03:02 +0100 Subject: [PATCH 063/118] updating 3rdparty --- 3rdparty | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty b/3rdparty index 41f8d5a38b4..e13a1213ff1 160000 --- a/3rdparty +++ b/3rdparty @@ -1 +1 @@ -Subproject commit 41f8d5a38b491d3ada4b43273462535c015eba08 +Subproject commit e13a1213ff1539ed93751ba5c5adf6327d3ad51c From 2f6639875e88c54a95f94a28e2b0ffb18e1c3d1b Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Fri, 21 Feb 2014 10:58:05 +0100 Subject: [PATCH 064/118] ignore optional additional config files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 25cb1b227f9..e61ec6f0359 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /data /owncloud /config/config.php +/config/*.config.php /config/mount.php /apps/inc.php From cf7ef0d35686a4a418abab2c7ad798b56a9317a3 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 19 Feb 2014 16:56:37 +0100 Subject: [PATCH 065/118] fix sharing unit tests --- tests/lib/share/backend.php | 8 ++++---- tests/lib/share/share.php | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/lib/share/backend.php b/tests/lib/share/backend.php index 2f6c84678ff..420bd9d88b3 100644 --- a/tests/lib/share/backend.php +++ b/tests/lib/share/backend.php @@ -26,7 +26,7 @@ class Test_Share_Backend implements OCP\Share_Backend { const FORMAT_SOURCE = 0; const FORMAT_TARGET = 1; const FORMAT_PERMISSIONS = 2; - + private $testItem1 = 'test.txt'; private $testItem2 = 'share.txt'; @@ -57,11 +57,11 @@ class Test_Share_Backend implements OCP\Share_Backend { public function formatItems($items, $format, $parameters = null) { $testItems = array(); foreach ($items as $item) { - if ($format == self::FORMAT_SOURCE) { + if ($format === self::FORMAT_SOURCE) { $testItems[] = $item['item_source']; - } else if ($format == self::FORMAT_TARGET) { + } else if ($format === self::FORMAT_TARGET) { $testItems[] = $item['item_target']; - } else if ($format == self::FORMAT_PERMISSIONS) { + } else if ($format === self::FORMAT_PERMISSIONS) { $testItems[] = $item['permissions']; } } diff --git a/tests/lib/share/share.php b/tests/lib/share/share.php index a89f100d97a..b5cba9430aa 100644 --- a/tests/lib/share/share.php +++ b/tests/lib/share/share.php @@ -622,21 +622,21 @@ class Test_Share extends PHPUnit_Framework_TestCase { OC_User::setUserId($this->user1); $this->assertEquals( array('test.txt', 'test.txt'), - OCP\Share::getItemsShared('test', 'test.txt'), + OCP\Share::getItemsShared('test', Test_Share_Backend::FORMAT_SOURCE), 'Failed asserting that the test.txt file is shared exactly two times by user1.' ); OC_User::setUserId($this->user2); $this->assertEquals( array('test.txt'), - OCP\Share::getItemsShared('test', 'test.txt'), + OCP\Share::getItemsShared('test', Test_Share_Backend::FORMAT_SOURCE), 'Failed asserting that the test.txt file is shared exactly once by user2.' ); OC_User::setUserId($this->user3); $this->assertEquals( array('test.txt'), - OCP\Share::getItemsShared('test', 'test.txt'), + OCP\Share::getItemsShared('test', Test_Share_Backend::FORMAT_SOURCE), 'Failed asserting that the test.txt file is shared exactly once by user3.' ); From 6ca4d3bfde1c372937597bed2075ec9027944b60 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 6 Feb 2014 10:06:20 +0100 Subject: [PATCH 066/118] fix usersPath and add unit tests --- apps/files_sharing/lib/cache.php | 12 ++-- apps/files_sharing/tests/cache.php | 108 ++++++++++++++++++++++++++++- 2 files changed, 110 insertions(+), 10 deletions(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index aadc54e4a7f..4b0da0b002d 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -131,19 +131,15 @@ class Shared_Cache extends Cache { foreach ($files as &$file) { $file['mimetype'] = $this->getMimetype($file['mimetype']); $file['mimepart'] = $this->getMimetype($file['mimepart']); + $file['usersPath'] = 'files/Shared/' . ltrim($file['path'], '/'); } return $files; } else { - if ($cache = $this->getSourceCache($folder)) { + $cache = $this->getSourceCache($folder); + if ($cache) { $sourceFolderContent = $cache->getFolderContents($this->files[$folder]); foreach ($sourceFolderContent as $key => $c) { - $ownerPathParts = explode('/', \OC_Filesystem::normalizePath($c['path'])); - $userPathParts = explode('/', \OC_Filesystem::normalizePath($folder)); - $usersPath = 'files/Shared/'.$userPathParts[1]; - foreach (array_slice($ownerPathParts, 3) as $part) { - $usersPath .= '/'.$part; - } - $sourceFolderContent[$key]['usersPath'] = $usersPath; + $sourceFolderContent[$key]['usersPath'] = 'files/Shared/' . $folder . '/' . $c['name']; } return $sourceFolderContent; diff --git a/apps/files_sharing/tests/cache.php b/apps/files_sharing/tests/cache.php index 56a51c83f6b..5e61eb86dd7 100644 --- a/apps/files_sharing/tests/cache.php +++ b/apps/files_sharing/tests/cache.php @@ -2,8 +2,9 @@ /** * ownCloud * - * @author Vincent Petry + * @author Vincent Petry, Bjoern Schiessle * @copyright 2014 Vincent Petry + * 2014 Bjoern Schiessle * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -23,13 +24,19 @@ require_once __DIR__ . '/base.php'; class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { + /** + * @var OC_FilesystemView + */ + public $user2View; + function setUp() { parent::setUp(); self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + $this->user2View = new \OC\Files\View('/'. self::TEST_FILES_SHARING_API_USER2 . '/files'); + // prepare user1's dir structure - $textData = "dummy file data\n"; $this->view->mkdir('container'); $this->view->mkdir('container/shareddir'); $this->view->mkdir('container/shareddir/subdir'); @@ -115,6 +122,103 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { $this->verifyFiles($check, $results); } + function testGetFolderContentsInRoot() { + $results = $this->user2View->getDirectoryContent('/Shared/'); + + $this->verifyFiles( + array( + array( + 'name' => 'shareddir', + 'path' => '/shareddir', + 'mimetype' => 'httpd/unix-directory', + 'usersPath' => 'files/Shared/shareddir' + ), + array( + 'name' => 'shared single file.txt', + 'path' => '/shared single file.txt', + 'mimetype' => 'text/plain', + 'usersPath' => 'files/Shared/shared single file.txt' + ), + ), + $results + ); + } + + function testGetFolderContentsInSubdir() { + //$results = $this->sharedStorage->getCache()->getFolderContents('shareddir'); + $results = $this->user2View->getDirectoryContent('/Shared/shareddir'); + + $this->verifyFiles( + array( + array( + 'name' => 'bar.txt', + 'path' => 'files/container/shareddir/bar.txt', + 'mimetype' => 'text/plain', + 'usersPath' => 'files/Shared/shareddir/bar.txt' + ), + array( + 'name' => 'emptydir', + 'path' => 'files/container/shareddir/emptydir', + 'mimetype' => 'httpd/unix-directory', + 'usersPath' => 'files/Shared/shareddir/emptydir' + ), + array( + 'name' => 'subdir', + 'path' => 'files/container/shareddir/subdir', + 'mimetype' => 'httpd/unix-directory', + 'usersPath' => 'files/Shared/shareddir/subdir' + ), + ), + $results + ); + } + + function testGetFolderContentsWhenSubSubdirShared() { + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + + $fileinfo = $this->view->getFileInfo('container/shareddir/subdir'); + \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER3, 31); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER3); + + $thirdView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER3 . '/files'); + //list($this->sharedStorage, $internalPath) = $thirdView->resolvePath('files/Shared'); + $results = $thirdView->getDirectoryContent('/Shared/subdir'); + + $this->verifyFiles( + array( + array( + 'name' => 'another too.txt', + 'path' => 'files/container/shareddir/subdir/another too.txt', + //'path' => '/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' => '/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' => '/subdir/not a text file.xml', + 'mimetype' => 'application/xml', + 'usersPath' => 'files/Shared/subdir/not a text file.xml' + ), + ), + $results + ); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + + \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER3); + } + /** * Checks that all provided attributes exist in the files list, * only the values provided in $examples will be used to check against From 0c0e4fced5fb64c814d8af1cf532b1ca42b49692 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 10 Feb 2014 14:50:04 +0100 Subject: [PATCH 067/118] fix test so that it doesn't depend on the array order --- apps/files_sharing/tests/cache.php | 39 +++++++++++++++++++----------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/apps/files_sharing/tests/cache.php b/apps/files_sharing/tests/cache.php index 5e61eb86dd7..a75e1860527 100644 --- a/apps/files_sharing/tests/cache.php +++ b/apps/files_sharing/tests/cache.php @@ -145,7 +145,6 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { } function testGetFolderContentsInSubdir() { - //$results = $this->sharedStorage->getCache()->getFolderContents('shareddir'); $results = $this->user2View->getDirectoryContent('/Shared/shareddir'); $this->verifyFiles( @@ -183,7 +182,6 @@ 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'); - //list($this->sharedStorage, $internalPath) = $thirdView->resolvePath('files/Shared'); $results = $thirdView->getDirectoryContent('/Shared/subdir'); $this->verifyFiles( @@ -191,21 +189,18 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { array( 'name' => 'another too.txt', 'path' => 'files/container/shareddir/subdir/another too.txt', - //'path' => '/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' => '/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' => '/subdir/not a text file.xml', 'mimetype' => 'application/xml', 'usersPath' => 'files/Shared/subdir/not a text file.xml' ), @@ -220,19 +215,35 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { } /** - * Checks that all provided attributes exist in the files list, - * only the values provided in $examples will be used to check against - * the file list. The files order also needs to be the same. + * Check if 'results' contains the expected 'examples' only. * * @param array $examples array of example files - * @param array $files array of files + * @param array $results array of files */ - private function verifyFiles($examples, $files) { - $this->assertEquals(count($examples), count($files)); - foreach ($files as $i => $file) { - foreach ($examples[$i] as $key => $value) { - $this->assertEquals($value, $file[$key]); + private function verifyFiles($examples, $results) { + $this->assertEquals(count($examples), count($results)); + + foreach ($examples as $example) { + foreach ($results as $key => $result) { + if ($result['name'] === $example['name']) { + $this->verifyKeys($example, $result); + unset($results[$key]); + break; + } } } + $this->assertTrue(empty($results)); } + + /** + * @brief verify if each value from the result matches the expected result + * @param array $example array with the expected results + * @param array $result array with the results + */ + private function verifyKeys($example, $result) { + foreach ($example as $key => $value) { + $this->assertEquals($value, $result[$key]); + } + } + } From d9e333c0da352eea6731f66e7c89f63edd837426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Fri, 21 Feb 2014 11:18:23 +0100 Subject: [PATCH 068/118] use directory from original instead of current dir --- core/js/oc-dialogs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/js/oc-dialogs.js b/core/js/oc-dialogs.js index f4e3ec01447..d1bcb4659b8 100644 --- a/core/js/oc-dialogs.js +++ b/core/js/oc-dialogs.js @@ -293,7 +293,7 @@ var OCdialogs = { conflict.find('.replacement .size').text(humanFileSize(replacement.size)); conflict.find('.replacement .mtime').text(formatDate(replacement.lastModifiedDate)); } - var path = getPathForPreview(original.name); + var path = original.directory + '/' +original.name; Files.lazyLoadPreview(path, original.mime, function(previewpath){ conflict.find('.original .icon').css('background-image','url('+previewpath+')'); }, 96, 96, original.etag); From 4715fb12c8001b8642c2e6dcef57ac216ef92c3d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 21 Feb 2014 14:06:15 +0100 Subject: [PATCH 069/118] Add url parameter to control whether previews should return 404 when the mimetype is unsupported --- apps/files/js/files.js | 1 + core/ajax/preview.php | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/files/js/files.js b/apps/files/js/files.js index 8b252e69a1d..1f4bd6794f3 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -786,6 +786,7 @@ Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) { } previewURL = previewURL.replace('(', '%28'); previewURL = previewURL.replace(')', '%29'); + previewURL += '&always=0'; // preload image to prevent delay // this will make the browser cache the image diff --git a/core/ajax/preview.php b/core/ajax/preview.php index 5c6d5ce25ab..285af3a8a76 100644 --- a/core/ajax/preview.php +++ b/core/ajax/preview.php @@ -11,6 +11,7 @@ $file = array_key_exists('file', $_GET) ? (string)$_GET['file'] : ''; $maxX = array_key_exists('x', $_GET) ? (int)$_GET['x'] : '36'; $maxY = array_key_exists('y', $_GET) ? (int)$_GET['y'] : '36'; $scalingUp = array_key_exists('scalingup', $_GET) ? (bool)$_GET['scalingup'] : true; +$always = array_key_exists('always', $_GET) ? (bool)$_GET['always'] : true; if ($file === '') { //400 Bad Request @@ -28,7 +29,7 @@ if ($maxX === 0 || $maxY === 0) { try { $preview = new \OC\Preview(\OC_User::getUser(), 'files'); - if (!$preview->isMimeSupported(\OC\Files\Filesystem::getMimeType($file))) { + if (!$always and !$preview->isMimeSupported(\OC\Files\Filesystem::getMimeType($file))) { \OC_Response::setStatus(404); } else { $preview->setFile($file); From 877cfb963ac67dc4a2eb7ea9f4923aa43894d38d Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Fri, 21 Feb 2014 14:07:25 +0100 Subject: [PATCH 070/118] use SVG icons from icons.css for New file menu --- apps/files/css/files.css | 24 +++++++++++++++++------- apps/files/templates/index.php | 17 +++++++++++------ core/css/icons.css | 6 ++++++ 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 3ad167054c2..2824d04d596 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -20,7 +20,7 @@ padding: 10px; font-weight: normal; } -#new>a { +#new > a { padding: 14px 10px; position: relative; top: 7px; @@ -30,7 +30,7 @@ border-bottom-right-radius: 0; border-bottom: none; } -#new>ul { +#new > ul { display: none; position: fixed; min-width: 112px; @@ -39,16 +39,26 @@ padding-bottom: 0; margin-top: 14px; margin-left: -1px; - text-align:left; + text-align: left; background: #f8f8f8; border: 1px solid #ddd; border-radius: 5px; border-top-left-radius: 0; - box-shadow:0 2px 7px rgba(170,170,170,.4); + box-shadow: 0 2px 7px rgba(170,170,170,.4); +} +#new > ul > li { + height: 36px; + margin: 5px; + padding-left: 48px; + padding-bottom: 2px; + background-position: initial; + cursor: pointer; +} +#new > ul > li > p { + cursor: pointer; + padding-top: 7px; + padding-bottom: 7px; } -#new>ul>li { height:36px; margin:5px; padding-left:48px; padding-bottom:2px; - background-repeat:no-repeat; cursor:pointer; } -#new>ul>li>p { cursor:pointer; padding-top: 7px; padding-bottom: 7px;} #new .error, #fileList .error { color: #e9322d; diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php index 939043b2c9f..ed15e46a5ac 100644 --- a/apps/files/templates/index.php +++ b/apps/files/templates/index.php @@ -5,12 +5,17 @@
t('New'));?>
    -
  • .txt'>

    t('Text file'));?>

  • -
  • '>

    t('Folder'));?>

  • -
  • t('From link'));?>

  • +
  • +

    t('Text file'));?>

    +
  • +
  • +

    t('Folder'));?>

    +
  • +
diff --git a/core/css/icons.css b/core/css/icons.css index 2dc35084122..814749c5af8 100644 --- a/core/css/icons.css +++ b/core/css/icons.css @@ -226,6 +226,12 @@ .icon-folder { background-image: url('../img/places/folder.svg'); } +.icon-filetype-text { + background-image: url('../img/filetypes/text.svg'); +} +.icon-filetype-folder { + background-image: url('../img/filetypes/folder.svg'); +} .icon-home { background-image: url('../img/places/home.svg'); From 6f56fd99a65253c638eaaefa064634d372e3c8bf Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Fri, 21 Feb 2014 14:10:13 +0100 Subject: [PATCH 071/118] fix too much distance between text and icon --- apps/files/css/files.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 2824d04d596..af863aca33e 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -49,7 +49,7 @@ #new > ul > li { height: 36px; margin: 5px; - padding-left: 48px; + padding-left: 42px; padding-bottom: 2px; background-position: initial; cursor: pointer; From c0a6af82193b6cc9e69fad23acef997f7240a1b3 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 21 Feb 2014 15:12:15 +0100 Subject: [PATCH 072/118] Updated submodule to include XML processing fixes --- 3rdparty | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty b/3rdparty index c7b4cdbcc1f..478de4b756f 160000 --- a/3rdparty +++ b/3rdparty @@ -1 +1 @@ -Subproject commit c7b4cdbcc1faa56df2489a5753b457627f460c07 +Subproject commit 478de4b756f3729f762d838b29f69f2a40e5f4f8 From fe44ac264bd8f636c1189d6ad6430ac991038ae6 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 18 Feb 2014 16:26:37 +0100 Subject: [PATCH 073/118] Add overwritehost config on setup and upgrade --- config/config.sample.php | 3 +++ lib/private/request.php | 46 +++++++++++++++++++++++++++------------- lib/private/setup.php | 1 + lib/private/updater.php | 15 +++++++++++++ 4 files changed, 50 insertions(+), 15 deletions(-) diff --git a/config/config.sample.php b/config/config.sample.php index 0cd321d095d..ed37c60adf0 100755 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -53,6 +53,9 @@ $CONFIG = array( /* The optional authentication for the proxy to use to connect to the internet. The format is: [username]:[password] */ "proxyuserpwd" => "", +/* List of trusted domains, to prevent host header poisoning ownCloud is only using these Host headers */ +'trusted_domains' => array('demo.owncloud.org'), + /* Theme to use for ownCloud */ "theme" => "", diff --git a/lib/private/request.php b/lib/private/request.php index 2c5b907846e..c3e28a9f08b 100755 --- a/lib/private/request.php +++ b/lib/private/request.php @@ -24,6 +24,16 @@ class OC_Request { or ($type !== 'protocol' and OC_Config::getValue('forcessl', false)); } + /** + * @brief Checks whether a domain is considered as trusted. This is used to prevent Host Header Poisoning. + * @param string $host + * @return bool + */ + public static function isTrustedDomain($domain) { + $trustedList = \OC_Config::getValue('trusted_domains', array('')); + return in_array($domain, $trustedList); + } + /** * @brief Returns the server host * @returns string the server host @@ -43,21 +53,27 @@ class OC_Request { $host = trim(array_pop(explode(",", $_SERVER['HTTP_X_FORWARDED_HOST']))); } else{ - $host=$_SERVER['HTTP_X_FORWARDED_HOST']; + $host = $_SERVER['HTTP_X_FORWARDED_HOST']; } - } - else{ + } else { if (isset($_SERVER['HTTP_HOST'])) { - return $_SERVER['HTTP_HOST']; + $host = $_SERVER['HTTP_HOST']; } if (isset($_SERVER['SERVER_NAME'])) { - return $_SERVER['SERVER_NAME']; + $host = $_SERVER['SERVER_NAME']; } - return 'localhost'; } - return $host; - } + // Verify that the host is a trusted domain if the trusted domains + // are defined + // If no trusted domain is provided the first trusted domain is returned + if(self::isTrustedDomain($host) || \OC_Config::getValue('trusted_domains', "") === "") { + return $host; + } else { + $trustedList = \OC_Config::getValue('trusted_domains', array('')); + return $trustedList[0]; + } + } /** * @brief Returns the server protocol @@ -71,14 +87,14 @@ class OC_Request { } if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) { $proto = strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']); - }else{ - if(isset($_SERVER['HTTPS']) and !empty($_SERVER['HTTPS']) and ($_SERVER['HTTPS']!='off')) { - $proto = 'https'; - }else{ - $proto = 'http'; - } + // Verify that the protocol is always HTTP or HTTPS + // default to http if an invalid value is provided + return $proto === 'https' ? 'https' : 'http'; + } + if (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') { + return 'https'; } - return $proto; + return 'http'; } /** diff --git a/lib/private/setup.php b/lib/private/setup.php index 5232398d1d7..f3ef4df200d 100644 --- a/lib/private/setup.php +++ b/lib/private/setup.php @@ -65,6 +65,7 @@ class OC_Setup { OC_Config::setValue('passwordsalt', $salt); //write the config file + OC_Config::setValue('trusted_domains', array(OC_Request::serverHost())); OC_Config::setValue('datadirectory', $datadir); OC_Config::setValue('dbtype', $dbtype); OC_Config::setValue('version', implode('.', OC_Util::getVersion())); diff --git a/lib/private/updater.php b/lib/private/updater.php index 764a0f14120..f05d5038b76 100644 --- a/lib/private/updater.php +++ b/lib/private/updater.php @@ -102,6 +102,20 @@ class Updater extends BasicEmitter { $this->log->debug('starting upgrade from ' . $installedVersion . ' to ' . $currentVersion, array('app' => 'core')); } $this->emit('\OC\Updater', 'maintenanceStart'); + + /* + * START CONFIG CHANGES FOR OLDER VERSIONS + */ + if (version_compare($currentVersion, '6.90.1', '<')) { + // Add the overwriteHost config if it is not existant + // This is added to prevent host header poisoning + \OC_Config::setValue('trusted_domains', \OC_Config::getValue('trusted_domains', array(\OC_Request::serverHost()))); + } + /* + * STOP CONFIG CHANGES FOR OLDER VERSIONS + */ + + try { \OC_DB::updateDbFromStructure(\OC::$SERVERROOT . '/db_structure.xml'); $this->emit('\OC\Updater', 'dbUpgrade'); @@ -162,3 +176,4 @@ class Updater extends BasicEmitter { $this->emit('\OC\Updater', 'filecacheDone'); } } + From dd98e6333f59de05e04a1bd6a887ff1554233e28 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 21 Feb 2014 15:35:12 +0100 Subject: [PATCH 074/118] Split getFolderContentById --- lib/private/files/cache/cache.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php index dbdc42ecc48..fcc7099bbc9 100644 --- a/lib/private/files/cache/cache.php +++ b/lib/private/files/cache/cache.php @@ -169,6 +169,16 @@ class Cache { if (is_null($fileId)) { $fileId = $this->getId($folder); } + return $this->getFolderContentsById($fileId); + } + + /** + * get the metadata of all files stored in $folder + * + * @param int $fileId the file id of the folder + * @return array + */ + public function getFolderContentsById($fileId) { if ($fileId > -1) { $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `storage_mtime`, `encrypted`, `unencrypted_size`, `etag` From 3487a95eaba04e6ced29d86a7cba9151513a1703 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 21 Feb 2014 15:36:24 +0100 Subject: [PATCH 075/118] Remove fileid parameter for getFolderContent --- lib/private/files/cache/cache.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php index fcc7099bbc9..9b18257088c 100644 --- a/lib/private/files/cache/cache.php +++ b/lib/private/files/cache/cache.php @@ -162,13 +162,10 @@ class Cache { * get the metadata of all files stored in $folder * * @param string $folder - * @param int $fileId (optional) the file id of the folder * @return array */ - public function getFolderContents($folder, $fileId = null) { - if (is_null($fileId)) { - $fileId = $this->getId($folder); - } + public function getFolderContents($folder) { + $fileId = $this->getId($folder); return $this->getFolderContentsById($fileId); } From 300b1131b47842252395d54ad28b4d6691d7775e Mon Sep 17 00:00:00 2001 From: root Date: Fri, 21 Feb 2014 17:09:36 +0100 Subject: [PATCH 076/118] replace spaces with tabs use true instead of 1 --- apps/user_ldap/group_ldap.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php index 509f65712fd..cef9ca3c4cf 100644 --- a/apps/user_ldap/group_ldap.php +++ b/apps/user_ldap/group_ldap.php @@ -94,8 +94,8 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { } $allMembers = array(); if (array_key_exists($dnGroup, $seen)) { - // avoid loops - return array(); + // avoid loops + return array(); } // used extensively in cron job, caching makes sense for nested groups $cacheKey = '_groupMembers'.$dnGroup; @@ -107,7 +107,7 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { $this->access->connection->ldapGroupFilter); if (is_array($members)) { foreach ($members as $memberDN) { - $allMembers[$memberDN] = 1; + $allMembers[$memberDN] = 1; $nestedGroups = $this->access->connection->ldapNestedGroups; if (!empty($nestedGroups)) { $subMembers = $this->_groupMembers($memberDN, $seen); @@ -117,7 +117,7 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { } } } - $this->access->connection->writeToCache($cacheKey, $allMembers); + $this->access->connection->writeToCache($cacheKey, $allMembers); return $allMembers; } @@ -172,7 +172,7 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { // avoid loops return array(); } - $seen[$dn] = 1; + $seen[$dn] = true; $filter = $this->access->combineFilterWithAnd(array( $this->access->connection->ldapGroupFilter, $this->access->connection->ldapGroupMemberAssocAttr.'='.$dn From e549977d0e2fd7afae5adb253038494247a27322 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Fri, 21 Feb 2014 17:31:24 +0100 Subject: [PATCH 077/118] update 3rdparty submodule to current master --- 3rdparty | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty b/3rdparty index f776a03d060..478de4b756f 160000 --- a/3rdparty +++ b/3rdparty @@ -1 +1 @@ -Subproject commit f776a03d06088cd64cdc94aa61834ba358ad36f5 +Subproject commit 478de4b756f3729f762d838b29f69f2a40e5f4f8 From 80c61d480cfe0964707a9044738526a853c1211f Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 24 Feb 2014 09:45:02 +0100 Subject: [PATCH 078/118] Added oc_defaults stub in specHelper.js This is needed for JS Unit tests to run properly as they are expecting the new "oc_default" map to exist. --- core/js/tests/specHelper.js | 1 + 1 file changed, 1 insertion(+) diff --git a/core/js/tests/specHelper.js b/core/js/tests/specHelper.js index 1848d08354e..b1193240580 100644 --- a/core/js/tests/specHelper.js +++ b/core/js/tests/specHelper.js @@ -63,6 +63,7 @@ window.oc_config = { session_lifetime: 600 * 1000, session_keepalive: false }; +window.oc_defaults = {}; // global setup for all tests (function setupTests() { From 539ea0882bb8e0ee02d7adaf72109dcbda608d36 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 24 Feb 2014 10:35:24 +0100 Subject: [PATCH 079/118] Fixed mount config path --- apps/files_external/lib/config.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index ed9a0126dd1..1a17e0139d9 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -353,8 +353,8 @@ class OC_Mount_Config { $jsonFile = OC_User::getHome(OCP\User::getUser()).'/mount.json'; } else { $phpFile = OC::$SERVERROOT.'/config/mount.php'; - $datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data/"); - $jsonFile = \OC_Config::getValue("mount_file", $datadir . "/mount.json"); + $datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT . '/data/'); + $jsonFile = \OC_Config::getValue('mount_file', $datadir . '/mount.json'); } if (is_file($jsonFile)) { $mountPoints = json_decode(file_get_contents($jsonFile), true); @@ -380,7 +380,8 @@ class OC_Mount_Config { if ($isPersonal) { $file = OC_User::getHome(OCP\User::getUser()).'/mount.json'; } else { - $file = \OC_Config::getValue("mount_file", \OC::$SERVERROOT . "/data/mount.json"); + $datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT . '/data/'); + $file = \OC_Config::getValue('mount_file', $datadir . '/mount.json'); } $content = json_encode($data); @file_put_contents($file, $content); From c465835e856601ccbe2643f690b0bc38ca5c3aa8 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 24 Feb 2014 12:20:11 +0100 Subject: [PATCH 080/118] Replace deleteAll call with unlink call The method deleteAll() doesn't officially exist on the Storage class as it's not defined on the interface, which means it fails on the Quota storage wrapper and might fail on some external storage classes. Also, this here is the only use case for that one method. --- lib/private/files/view.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 530aa8f7514..5206e4f01b7 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -413,7 +413,7 @@ class View { $result = $this->copy($path1, $path2); if ($result === true) { list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); - $result = $storage1->deleteAll($internalPath1); + $result = $storage1->unlink($internalPath1); } } else { $source = $this->fopen($path1 . $postFix1, 'r'); From a23ef25010f8232c36337bb6b48c9a0bd7a59b40 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 24 Feb 2014 12:21:48 +0100 Subject: [PATCH 081/118] Removed unused deleteAll method on Common storage class The "deleteAll" method on the Common storage class isn't used anywhere. Also, it isn't defined on the Storage interface so this fix removes it completely. --- lib/private/files/storage/common.php | 37 ---------------------------- 1 file changed, 37 deletions(-) diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php index d4dca780ff3..9e826dd6192 100644 --- a/lib/private/files/storage/common.php +++ b/lib/private/files/storage/common.php @@ -140,43 +140,6 @@ abstract class Common implements \OC\Files\Storage\Storage { return $result; } - /** - * @brief Deletes all files and folders recursively within a directory - * @param string $directory The directory whose contents will be deleted - * @param bool $empty Flag indicating whether directory will be emptied - * @returns bool - * - * @note By default the directory specified by $directory will be - * deleted together with its contents. To avoid this set $empty to true - */ - public function deleteAll($directory, $empty = false) { - $directory = trim($directory, '/'); - if (!$this->is_dir($directory) || !$this->isReadable($directory)) { - return false; - } else { - $directoryHandle = $this->opendir($directory); - if (is_resource($directoryHandle)) { - while (($contents = readdir($directoryHandle)) !== false) { - if (!\OC\Files\Filesystem::isIgnoredDir($contents)) { - $path = $directory . '/' . $contents; - if ($this->is_dir($path)) { - $this->deleteAll($path); - } else { - $this->unlink($path); - } - } - } - } - if ($empty === false) { - if (!$this->rmdir($directory)) { - return false; - } - } - return true; - } - - } - public function getMimeType($path) { if ($this->is_dir($path)) { return 'httpd/unix-directory'; From 7c4f81bd78b0933928056f6f59020837e1291525 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 24 Feb 2014 13:24:10 +0100 Subject: [PATCH 082/118] rename url parameter --- apps/files/js/files.js | 2 +- core/ajax/preview.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files/js/files.js b/apps/files/js/files.js index 1f4bd6794f3..f4546120702 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -786,7 +786,7 @@ Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) { } previewURL = previewURL.replace('(', '%28'); previewURL = previewURL.replace(')', '%29'); - previewURL += '&always=0'; + previewURL += '&forceIcon=0'; // preload image to prevent delay // this will make the browser cache the image diff --git a/core/ajax/preview.php b/core/ajax/preview.php index 285af3a8a76..526719e8a1b 100644 --- a/core/ajax/preview.php +++ b/core/ajax/preview.php @@ -11,7 +11,7 @@ $file = array_key_exists('file', $_GET) ? (string)$_GET['file'] : ''; $maxX = array_key_exists('x', $_GET) ? (int)$_GET['x'] : '36'; $maxY = array_key_exists('y', $_GET) ? (int)$_GET['y'] : '36'; $scalingUp = array_key_exists('scalingup', $_GET) ? (bool)$_GET['scalingup'] : true; -$always = array_key_exists('always', $_GET) ? (bool)$_GET['always'] : true; +$always = array_key_exists('forceIcon', $_GET) ? (bool)$_GET['forceIcon'] : true; if ($file === '') { //400 Bad Request From ebd73aee8ff96f7252fab65ab4dc7230d2eb551c Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 24 Feb 2014 13:56:53 +0100 Subject: [PATCH 083/118] don't overwrite keys if rename was done by a stream copy --- apps/files_encryption/hooks/hooks.php | 17 +++++++++++++---- lib/private/files/view.php | 2 ++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 3af43f10264..0b6c5adf3fb 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -501,11 +501,20 @@ class Hooks { * @param array $params with the old path and the new path */ public static function preRename($params) { - $util = new Util(new \OC_FilesystemView('/'), \OCP\User::getUser()); + $user = \OCP\User::getUser(); + $view = new \OC_FilesystemView('/'); + $util = new Util($view, $user); list($ownerOld, $pathOld) = $util->getUidAndFilename($params['oldpath']); - self::$renamedFiles[$params['oldpath']] = array( - 'uid' => $ownerOld, - 'path' => $pathOld); + + // we only need to rename the keys if the rename happens on the same mountpoint + // otherwise we perform a stream copy, so we get a new set of keys + $mp1 = $view->getMountPoint('/' . $user . '/files/' . $params['oldpath']); + $mp2 = $view->getMountPoint('/' . $user . '/files/' . $params['newpath']); + if ($mp1 === $mp2) { + self::$renamedFiles[$params['oldpath']] = array( + 'uid' => $ownerOld, + 'path' => $pathOld); + } } /** diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 530aa8f7514..e2c565c5cbb 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -534,6 +534,8 @@ class View { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); list($count, $result) = \OC_Helper::streamCopy($source, $target); + fclose($source); + fclose($target); } } if ($this->shouldEmitHooks() && $result !== false) { From d3a24e945b72f07b51b5d9aa3e11c70a70bf9c8c Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 24 Feb 2014 16:33:57 +0100 Subject: [PATCH 084/118] add test case if a file gets moved out from the shared folder --- apps/files_encryption/tests/hooks.php | 55 +++++++++++++++++++++ apps/files_encryption/tests/share.php | 70 +++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/apps/files_encryption/tests/hooks.php b/apps/files_encryption/tests/hooks.php index 7d926caea1b..d0e4b5f732e 100644 --- a/apps/files_encryption/tests/hooks.php +++ b/apps/files_encryption/tests/hooks.php @@ -47,6 +47,7 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { public $rootView; // view on /data/user public $data; public $filename; + public $folder; public static function setUpBeforeClass() { // reset backend @@ -89,6 +90,7 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { // init short data $this->data = 'hats'; $this->filename = 'enc_hooks_tests-' . uniqid() . '.txt'; + $this->folder = 'enc_hooks_tests_folder-' . uniqid(); } @@ -268,4 +270,57 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { } } + /** + * @brief test rename operation + */ + function testRenameHook() { + + // save file with content + $cryptedFile = file_put_contents('crypt:///' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->filename, $this->data); + + // test that data was successfully written + $this->assertTrue(is_int($cryptedFile)); + + // check if keys exists + $this->assertTrue($this->rootView->file_exists( + '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/' + . $this->filename . '.' . self::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey')); + + $this->assertTrue($this->rootView->file_exists( + '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/' + . $this->filename . '.key')); + + // make subfolder + $this->rootView->mkdir('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder); + + $this->assertTrue($this->rootView->is_dir('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder)); + + // move the file out of the shared folder + $root = $this->rootView->getRoot(); + $this->rootView->chroot('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/'); + $this->rootView->rename($this->filename, '/' . $this->folder . '/' . $this->filename); + $this->rootView->chroot($root); + + $this->assertFalse($this->rootView->file_exists('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->filename)); + $this->assertTrue($this->rootView->file_exists('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder . '/' . $this->filename)); + + // keys should be renamed too + $this->assertFalse($this->rootView->file_exists( + '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/' + . $this->filename . '.' . self::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey')); + $this->assertFalse($this->rootView->file_exists( + '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/' + . $this->filename . '.key')); + + $this->assertTrue($this->rootView->file_exists( + '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/' . $this->folder . '/' + . $this->filename . '.' . self::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey')); + $this->assertTrue($this->rootView->file_exists( + '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/' . $this->folder . '/' + . $this->filename . '.key')); + + // cleanup + $this->rootView->unlink('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder); + } + } diff --git a/apps/files_encryption/tests/share.php b/apps/files_encryption/tests/share.php index 46a21dd55cd..be56968ac09 100755 --- a/apps/files_encryption/tests/share.php +++ b/apps/files_encryption/tests/share.php @@ -127,6 +127,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { \OC_User::deleteUser(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4); } + /** * @medium * @param bool $withTeardown @@ -498,6 +499,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { } } + function testPublicShareFile() { // login as admin \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); @@ -864,6 +866,13 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { \OCA\Encryption\Helper::adminDisableRecovery('test123'); $this->assertEquals(0, \OC::$server->getAppConfig()->getValue('files_encryption', 'recoveryAdminEnabled')); + + //clean up, reset passwords + \OC_User::setPassword(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, 'test123'); + $params = array('uid' => \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, + 'password' => \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, + 'recoveryPassword' => 'test123'); + \OCA\Encryption\Hooks::setPassphrase($params); } /** @@ -947,4 +956,65 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { $this->view->chroot('/'); } + + /** + * @brief test moving a shared file out of the Shared folder + */ + function testRename() { + + // login as admin + \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + + // save file with content + $cryptedFile = file_put_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename, $this->dataShort); + + // test that data was successfully written + $this->assertTrue(is_int($cryptedFile)); + + // get the file info from previous created file + $fileInfo = $this->view->getFileInfo( + '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename); + + // check if we have a valid file info + $this->assertTrue($fileInfo instanceof \OC\Files\FileInfo); + + // share the file + \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, OCP\PERMISSION_ALL); + + // check if share key for user2exists + $this->assertTrue($this->view->file_exists( + '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/' + . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); + + + // login as user2 + \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); + + $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/Shared/' . $this->filename)); + + // get file contents + $retrievedCryptedFile = $this->view->file_get_contents( + '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/Shared/' . $this->filename); + + // check if data is the same as we previously written + $this->assertEquals($this->dataShort, $retrievedCryptedFile); + + // move the file out of the shared folder + $this->view->rename('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/Shared/' . $this->filename, + '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename); + + // check if we can read the moved file + $retrievedRenamedFile = $this->view->file_get_contents( + '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename); + + // check if data is the same as we previously written + $this->assertEquals($this->dataShort, $retrievedRenamedFile); + + // the owners file should be deleted + $this->assertFalse($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename)); + + // cleanup + $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename); + } + } From d28fd8f64d52bdcc766000e5b8ae10517e09a992 Mon Sep 17 00:00:00 2001 From: jbtbnl Date: Mon, 24 Feb 2014 22:37:19 +0100 Subject: [PATCH 085/118] Remove necessity of icon class Only the icon specific class is needed --- core/css/icons.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/css/icons.css b/core/css/icons.css index 814749c5af8..aea59750c79 100644 --- a/core/css/icons.css +++ b/core/css/icons.css @@ -1,4 +1,4 @@ -.icon { +[class^="icon-"], [class*=" icon-"] { background-repeat: no-repeat; background-position: center; } From 432a42d846a7f180811fc9cd396c39175d5e5764 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 25 Feb 2014 11:22:53 +0100 Subject: [PATCH 086/118] Fix case where port is missing Forward port of 6d3b5b24fd4f82c1cbfbc4cade5246a0335f8dda to master --- lib/private/request.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/request.php b/lib/private/request.php index 14f3bf2cbb7..afd3fda4f2d 100755 --- a/lib/private/request.php +++ b/lib/private/request.php @@ -59,7 +59,7 @@ class OC_Request { if (isset($_SERVER['HTTP_HOST'])) { $host = $_SERVER['HTTP_HOST']; } - if (isset($_SERVER['SERVER_NAME'])) { + else if (isset($_SERVER['SERVER_NAME'])) { $host = $_SERVER['SERVER_NAME']; } } From e3f676e00982458d9f04ce0b71e60a273f3d67c3 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 25 Feb 2014 15:28:21 +0100 Subject: [PATCH 087/118] fix path in sharing results if it is a file in the Shared folder --- apps/files_sharing/tests/api.php | 68 +++++++++++++++++++++++++++++++ apps/files_sharing/tests/base.php | 1 + lib/public/share.php | 16 +++++++- 3 files changed, 84 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/tests/api.php b/apps/files_sharing/tests/api.php index 1278e0c4d1f..0d3d9b98b2e 100644 --- a/apps/files_sharing/tests/api.php +++ b/apps/files_sharing/tests/api.php @@ -33,13 +33,16 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { parent::setUp(); $this->folder = '/folder_share_api_test'; + $this->subfolder = '/subfolder_share_api_test'; $this->filename = 'share-api-test.txt'; // save file with content $this->view->file_put_contents($this->filename, $this->data); $this->view->mkdir($this->folder); + $this->view->mkdir($this->folder . '/' . $this->subfolder); $this->view->file_put_contents($this->folder.'/'.$this->filename, $this->data); + $this->view->file_put_contents($this->folder.'/' . $this->subfolder . '/' .$this->filename, $this->data); } function tearDown() { @@ -286,6 +289,71 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { } + /** + * @brief share a folder, than reshare a file within the shared folder and check if we construct the correct path + * @medium + */ + function testGetShareFromFolderReshares() { + + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + + $fileInfo1 = $this->view->getFileInfo($this->folder); + $fileInfo2 = $this->view->getFileInfo($this->folder.'/'.$this->filename); + $fileInfo3 = $this->view->getFileInfo($this->folder.'/' . $this->subfolder . '/' .$this->filename); + + // share root folder to user2 + $result = \OCP\Share::shareItem('folder', $fileInfo1['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31); + + // share was successful? + $this->assertTrue($result); + + // login as user2 + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + + // share file in root folder + $result = \OCP\Share::shareItem('file', $fileInfo2['fileid'], \OCP\Share::SHARE_TYPE_LINK, null, 1); + // share was successful? + $this->assertTrue(is_string($result)); + + // share file in subfolder + $result = \OCP\Share::shareItem('file', $fileInfo3['fileid'], \OCP\Share::SHARE_TYPE_LINK, null, 1); + // share was successful? + $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), + ); + foreach ($testValues as $value) { + + $_GET['path'] = $value['query']; + $_GET['subfiles'] = 'true'; + + $result = Share\Api::getAllShares(array()); + + $this->assertTrue($result->succeeded()); + + // test should return one share within $this->folder + $data = $result->getData(); + + $this->assertEquals($value['expectedResult'], $data[0]['path']); + } + + // cleanup + + \OCP\Share::unshare('file', $fileInfo2['fileid'], \OCP\Share::SHARE_TYPE_LINK, null); + \OCP\Share::unshare('file', $fileInfo3['fileid'], \OCP\Share::SHARE_TYPE_LINK, null); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + + \OCP\Share::unshare('folder', $fileInfo1['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); + + } + /** * @medium */ diff --git a/apps/files_sharing/tests/base.php b/apps/files_sharing/tests/base.php index 3e283271f5d..d44972d01f1 100644 --- a/apps/files_sharing/tests/base.php +++ b/apps/files_sharing/tests/base.php @@ -43,6 +43,7 @@ abstract class Test_Files_Sharing_Base extends \PHPUnit_Framework_TestCase { */ public $view; public $folder; + public $subfolder; public static function setUpBeforeClass() { // reset backend diff --git a/lib/public/share.php b/lib/public/share.php index ebc555dba5f..2fed41488ca 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -1250,7 +1250,21 @@ class Share { // Remove root from file source paths if retrieving own shared items if (isset($uidOwner) && isset($row['path'])) { if (isset($row['parent'])) { - $row['path'] = '/Shared/'.basename($row['path']); + $query = \OC_DB::prepare('SELECT `file_target` FROM `*PREFIX*share` WHERE `id` = ?'); + $parentResult = $query->execute(array($row['parent'])); + if (\OC_DB::isError($result)) { + \OC_Log::write('OCP\Share', 'Can\'t select parent: ' . + \OC_DB::getErrorMessage($result) . ', select=' . $select . ' where=' . $where, + \OC_Log::ERROR); + } else { + $parentRow = $parentResult->fetchRow(); + $splitPath = explode('/', $row['path']); + $tmpPath = '/Shared' . $parentRow['file_target']; + foreach (array_slice($splitPath, 2) as $pathPart) { + $tmpPath = $tmpPath . '/' . $pathPart; + } + $row['path'] = $tmpPath; + } } else { if (!isset($mounts[$row['storage']])) { $mountPoints = \OC\Files\Filesystem::getMountByNumericId($row['storage']); From 574883c47a45940f53a7603fb4e107cd7093a741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Tue, 25 Feb 2014 23:06:23 +0100 Subject: [PATCH 088/118] introduce new theme function to allow full creation of documentation links: buildDocLinkToKey() --- lib/private/defaults.php | 7 +++++++ lib/private/helper.php | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/private/defaults.php b/lib/private/defaults.php index 0b97497baa1..59630cda5c0 100644 --- a/lib/private/defaults.php +++ b/lib/private/defaults.php @@ -174,4 +174,11 @@ class OC_Defaults { return $footer; } + public function buildDocLinkToKey($key) { + if ($this->themeExist('buildDocLinkToKey')) { + return $this->theme->buildDocLinkToKey($key); + } + return $this->getDocBaseUrl() . '/server/6.0/go.php?to=' . $key; + } + } diff --git a/lib/private/helper.php b/lib/private/helper.php index 1aab2f296e1..d8c4650f666 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -64,7 +64,7 @@ class OC_Helper { */ public static function linkToDocs($key) { $theme = new OC_Defaults(); - return $theme->getDocBaseUrl() . '/server/6.0/go.php?to=' . $key; + return $theme->buildDocLinkToKey($key); } /** From e32acf933d51f1024a7db3239309da7beafc6089 Mon Sep 17 00:00:00 2001 From: kondou Date: Wed, 26 Feb 2014 04:03:41 +0100 Subject: [PATCH 089/118] Highlight the selected app in app-settings --- settings/css/settings.css | 2 +- settings/js/apps.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/settings/css/settings.css b/settings/css/settings.css index 8a96885b789..b8a8941a35d 100644 --- a/settings/css/settings.css +++ b/settings/css/settings.css @@ -61,7 +61,7 @@ td.remove { width:1em; padding-right:1em; } tr:hover>td.password>span, tr:hover>td.displayName>span { margin:0; cursor:pointer; } tr:hover>td.remove>a, tr:hover>td.password>img,tr:hover>td.displayName>img, tr:hover>td.quota>img { visibility:visible; cursor:pointer; } tr:hover>td.remove>a { float:right; } -li.selected { background-color:#ddd; } +li.selected, #leftcontent li.selected { background-color:#ddd; } table.grid { width:100%; } #rightcontent { padding-left: 10px; } div.quota { diff --git a/settings/js/apps.js b/settings/js/apps.js index 2c6f77d9314..7c71453e105 100644 --- a/settings/js/apps.js +++ b/settings/js/apps.js @@ -249,6 +249,8 @@ $(document).ready(function(){ var app = item.data('app'); OC.Settings.Apps.loadApp(app); } + $('#leftcontent .selected').removeClass('selected'); + item.addClass('selected'); return false; }); $('#rightcontent input.enable').click(function(){ From 1a561fced066e0d9103eb5dc72946e452beb2b83 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Wed, 26 Feb 2014 09:32:20 +0100 Subject: [PATCH 090/118] fix for coding style --- settings/css/settings.css | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/settings/css/settings.css b/settings/css/settings.css index b8a8941a35d..60abbc10862 100644 --- a/settings/css/settings.css +++ b/settings/css/settings.css @@ -61,7 +61,12 @@ td.remove { width:1em; padding-right:1em; } tr:hover>td.password>span, tr:hover>td.displayName>span { margin:0; cursor:pointer; } tr:hover>td.remove>a, tr:hover>td.password>img,tr:hover>td.displayName>img, tr:hover>td.quota>img { visibility:visible; cursor:pointer; } tr:hover>td.remove>a { float:right; } -li.selected, #leftcontent li.selected { background-color:#ddd; } + +li.selected, +#leftcontent li.selected { + background-color: #ddd; +} + table.grid { width:100%; } #rightcontent { padding-left: 10px; } div.quota { From 2b423e5a445718928b6f75e9acc33bfa339dc6ef Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Wed, 26 Feb 2014 10:16:54 +0100 Subject: [PATCH 091/118] coding style fixes, cut long lines, comments not on same lines, curly braces --- apps/files/js/admin.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/apps/files/js/admin.js b/apps/files/js/admin.js index f735079fcbe..842b73c0cae 100644 --- a/apps/files/js/admin.js +++ b/apps/files/js/admin.js @@ -8,19 +8,22 @@ * */ -function switchPublicFolder() -{ +function switchPublicFolder() { var publicEnable = $('#publicEnable').is(':checked'); - var sharingaimGroup = $('input:radio[name=sharingaim]'); //find all radiobuttons of that group + // find all radiobuttons of that group + var sharingaimGroup = $('input:radio[name=sharingaim]'); $.each(sharingaimGroup, function(index, sharingaimItem) { - sharingaimItem.disabled = !publicEnable; //set all buttons to the correct state + // set all buttons to the correct state + sharingaimItem.disabled = !publicEnable; }); } -$(document).ready(function(){ - switchPublicFolder(); // Execute the function after loading DOM tree - $('#publicEnable').click(function(){ - switchPublicFolder(); // To get rid of onClick() +$(document).ready(function() { + // Execute the function after loading DOM tree + switchPublicFolder(); + $('#publicEnable').click(function() { + // To get rid of onClick() + switchPublicFolder(); }); $('#allowZipDownload').bind('change', function() { From 331bd527a7d130ec050018e971f1d42f9ea35a5b Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 19 Feb 2014 17:42:05 +0100 Subject: [PATCH 092/118] Hide SMTP options based on selected send mode Fix #7166 --- settings/js/admin.js | 22 ++++++++++++++++++++-- settings/templates/admin.php | 32 ++++++++++++++++---------------- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/settings/js/admin.js b/settings/js/admin.js index 923e267513e..e2bc125b8f5 100644 --- a/settings/js/admin.js +++ b/settings/js/admin.js @@ -37,9 +37,27 @@ $(document).ready(function(){ $('#mail_smtpauth').change(function() { if (!this.checked) { - $('#mail_credentials').toggle(false); + $('#mail_credentials').addClass('hidden'); } else { - $('#mail_credentials').toggle(true); + $('#mail_credentials').removeClass('hidden'); + } + }); + + $('#mail_smtpmode').change(function() { + if ($(this).val() != 'smtp') { + $('#setting_smtpauth').addClass('hidden'); + $('#setting_smtphost').addClass('hidden'); + $('#mail_smtpsecure_label').addClass('hidden'); + $('#mail_smtpsecure').addClass('hidden'); + $('#mail_credentials').addClass('hidden'); + } else { + $('#setting_smtpauth').removeClass('hidden'); + $('#setting_smtphost').removeClass('hidden'); + $('#mail_smtpsecure_label').removeClass('hidden'); + $('#mail_smtpsecure').removeClass('hidden'); + if ($('#mail_smtpauth').attr('checked')) { + $('#mail_credentials').removeClass('hidden'); + } } }); diff --git a/settings/templates/admin.php b/settings/templates/admin.php index d81840b5b66..377c05eb4b9 100644 --- a/settings/templates/admin.php +++ b/settings/templates/admin.php @@ -288,8 +288,8 @@ if (!$_['internetconnectionworking']) { - - > $name): $selected = ''; if ($secure == $_['mail_smtpsecure']): @@ -301,7 +301,14 @@ if (!$_['internetconnectionworking']) {

- + + ' /> + @ + ' /> +

+ + - -

- +

-

- - ' /> - @ - ' /> +

From bc1c136cd6c27905d9e9118f355680b26a607eb6 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Wed, 26 Feb 2014 10:34:38 +0100 Subject: [PATCH 093/118] coding style fixes: cut long lines, whitespace --- settings/js/apps.js | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/settings/js/apps.js b/settings/js/apps.js index 2c6f77d9314..26aecbee310 100644 --- a/settings/js/apps.js +++ b/settings/js/apps.js @@ -207,12 +207,24 @@ OC.Settings.Apps = OC.Settings.Apps || { a.prepend(filename); a.prepend(img); li.append(a); - // append the new app as last item in the list (.push is from sticky footer) + + // append the new app as last item in the list + // (.push is from sticky footer) $('#apps .wrapper .push').before(li); - // scroll the app navigation down so the newly added app is seen - $('#navigation').animate({ scrollTop: $('#navigation').height() }, 'slow'); - // draw attention to the newly added app entry by flashing it twice - container.children('li[data-id="'+entry.id+'"]').animate({opacity:.3}).animate({opacity:1}).animate({opacity:.3}).animate({opacity:1}); + + // scroll the app navigation down + // so the newly added app is seen + $('#navigation').animate({ + scrollTop: $('#navigation').height() + }, 'slow'); + + // draw attention to the newly added app entry + // by flashing it twice + container.children('li[data-id="' + entry.id + '"]') + .animate({opacity: 0.3}) + .animate({opacity: 1}) + .animate({opacity: 0.3}) + .animate({opacity: 1}); if (!SVGSupport() && entry.icon.match(/\.svg$/i)) { $(img).addClass('svg'); From 593adab2583cb70ebccf6e687073c6f4a55baf9e Mon Sep 17 00:00:00 2001 From: kondou Date: Wed, 26 Feb 2014 11:41:32 +0100 Subject: [PATCH 094/118] Fix scrutinizer issue in settings/js/apps.js --- settings/js/apps.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/settings/js/apps.js b/settings/js/apps.js index 7c71453e105..b6bd9ee7205 100644 --- a/settings/js/apps.js +++ b/settings/js/apps.js @@ -248,9 +248,9 @@ $(document).ready(function(){ var item = tgt.is('li') ? $(tgt) : $(tgt).parent(); var app = item.data('app'); OC.Settings.Apps.loadApp(app); + $('#leftcontent .selected').removeClass('selected'); + item.addClass('selected'); } - $('#leftcontent .selected').removeClass('selected'); - item.addClass('selected'); return false; }); $('#rightcontent input.enable').click(function(){ From cb14b1c58dbfc605352193020cdbf19da797bb69 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 26 Feb 2014 11:40:41 +0100 Subject: [PATCH 095/118] Add owncloud version to JS scope Fix #5361 --- core/js/config.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/js/config.php b/core/js/config.php index c606ef35056..7e23f3e2e41 100644 --- a/core/js/config.php +++ b/core/js/config.php @@ -61,8 +61,10 @@ $array = array( "firstDay" => json_encode($l->l('firstday', 'firstday')) , "oc_config" => json_encode( array( - 'session_lifetime' => \OCP\Config::getSystemValue('session_lifetime', ini_get('session.gc_maxlifetime')), - 'session_keepalive' => \OCP\Config::getSystemValue('session_keepalive', true) + 'session_lifetime' => \OCP\Config::getSystemValue('session_lifetime', ini_get('session.gc_maxlifetime')), + 'session_keepalive' => \OCP\Config::getSystemValue('session_keepalive', true), + 'version' => implode('.', OC_Util::getVersion()), + 'versionstring' => OC_Util::getVersionString(), ) ), "oc_defaults" => json_encode( From df1a5a2dfa9757ea723789b32c18e555fa776062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 26 Feb 2014 12:22:21 +0100 Subject: [PATCH 096/118] Update 3rdparty submodule --- 3rdparty | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty b/3rdparty index bbc37618c74..177d3ff656b 160000 --- a/3rdparty +++ b/3rdparty @@ -1 +1 @@ -Subproject commit bbc37618c74a5439f729cc3e8ed369f674cb5415 +Subproject commit 177d3ff656bcf1153b4def12403c5f2d4fc53e73 From 3be5e48b0c255012667c0ba1f334970f62b789a6 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 26 Feb 2014 12:52:35 +0100 Subject: [PATCH 097/118] only add "received_from" if a share was found --- apps/files_sharing/lib/api.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/files_sharing/lib/api.php b/apps/files_sharing/lib/api.php index 19a2d22b068..0ba58aa896a 100644 --- a/apps/files_sharing/lib/api.php +++ b/apps/files_sharing/lib/api.php @@ -172,12 +172,12 @@ class Api { // workaround because folders are named 'dir' in this context $itemType = $file['type'] === 'file' ? 'file' : 'folder'; $share = \OCP\Share::getItemShared($itemType, $file['fileid']); - $receivedFrom = \OCP\Share::getItemSharedWithBySource($itemType, $file['fileid']); - if ($receivedFrom) { - $share['received_from'] = $receivedFrom['uid_owner']; - $share['received_from_displayname'] = \OCP\User::getDisplayName($receivedFrom['uid_owner']); - } - if ($share) { + if($share) { + $receivedFrom = \OCP\Share::getItemSharedWithBySource($itemType, $file['fileid']); + if ($receivedFrom) { + $share['received_from'] = $receivedFrom['uid_owner']; + $share['received_from_displayname'] = \OCP\User::getDisplayName($receivedFrom['uid_owner']); + } $result = array_merge($result, $share); } } From 9847912257de1910f99879caac8ea925fb85caed Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 26 Feb 2014 13:10:46 +0100 Subject: [PATCH 098/118] Remove unused variables, add doc blocks and break lines Fix #7166 --- core/js/js.js | 4 ++-- settings/admin/controller.php | 18 ++++++++++++++---- settings/js/admin.js | 2 +- settings/templates/admin.php | 29 ++++++++++++++++++++--------- 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/core/js/js.js b/core/js/js.js index ac79f13a6d1..88b70723dd1 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -468,8 +468,8 @@ OC.addStyle.loaded=[]; OC.addScript.loaded=[]; OC.msg={ - startSaving:function(selector, message){ - OC.msg.startAction(selector, t('settings', 'Saving...')); + startSaving:function(selector){ + OC.msg.startAction(selector, t('core', 'Saving...')); }, finishedSaving:function(selector, data){ OC.msg.finishedAction(selector, data); diff --git a/settings/admin/controller.php b/settings/admin/controller.php index 9bbcd356580..a075d774361 100644 --- a/settings/admin/controller.php +++ b/settings/admin/controller.php @@ -20,7 +20,10 @@ namespace OC\Settings\Admin; class Controller { - public static function setMailSettings($args) { + /** + * Set mail settings + */ + public static function setMailSettings() { \OC_Util::checkAdminUser(); \OCP\JSON::callCheck(); @@ -70,14 +73,21 @@ class Controller { \OC_JSON::success(array("data" => array( "message" => $l->t("Saved") ))); } + /** + * Get the field name to use it in error messages + * + * @param $setting string + * @param $l \OC_L10N + * @return string + */ public static function getFieldname($setting, $l) { switch ($setting) { case 'mail_smtpmode': - return $l->t( 'SMTP mode' ); + return $l->t( 'Send mode' ); case 'mail_smtpsecure': - return $l->t( 'Secure SMTP' ); + return $l->t( 'Encryption' ); case 'mail_smtpauthtype': - return $l->t( 'Authentification method for SMTP' ); + return $l->t( 'Authentification method' ); } } } diff --git a/settings/js/admin.js b/settings/js/admin.js index e2bc125b8f5..5ea6a5af2df 100644 --- a/settings/js/admin.js +++ b/settings/js/admin.js @@ -44,7 +44,7 @@ $(document).ready(function(){ }); $('#mail_smtpmode').change(function() { - if ($(this).val() != 'smtp') { + if ($(this).val() !== 'smtp') { $('#setting_smtpauth').addClass('hidden'); $('#setting_smtphost').addClass('hidden'); $('#mail_smtpsecure_label').addClass('hidden'); diff --git a/settings/templates/admin.php b/settings/templates/admin.php index 377c05eb4b9..139a9dd076c 100644 --- a/settings/templates/admin.php +++ b/settings/templates/admin.php @@ -288,8 +288,12 @@ if (!$_['internetconnectionworking']) { - - > $name): $selected = ''; if ($secure == $_['mail_smtpsecure']): @@ -302,9 +306,11 @@ if (!$_['internetconnectionworking']) {

- ' /> + ' /> @ - ' /> + ' />

From 6c5cc4638008d08f4f933db775348fe9d1db57f9 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Wed, 26 Feb 2014 14:48:15 +0100 Subject: [PATCH 099/118] disable autocomplete for shared link password input, fix #7419 --- apps/files_sharing/templates/authenticate.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/templates/authenticate.php b/apps/files_sharing/templates/authenticate.php index 928be93fc96..19b1fb27630 100644 --- a/apps/files_sharing/templates/authenticate.php +++ b/apps/files_sharing/templates/authenticate.php @@ -8,7 +8,10 @@

- +

From 86b3cdc132a2ae19caf327985d5613a58804d1b5 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 26 Feb 2014 17:18:38 +0100 Subject: [PATCH 100/118] close encryption session after decryption was finished --- apps/files_encryption/lib/session.php | 8 ++++++++ apps/files_encryption/lib/util.php | 8 ++++++++ settings/ajax/decryptall.php | 2 ++ 3 files changed, 18 insertions(+) diff --git a/apps/files_encryption/lib/session.php b/apps/files_encryption/lib/session.php index aa58e33e9d2..3daaa06425f 100644 --- a/apps/files_encryption/lib/session.php +++ b/apps/files_encryption/lib/session.php @@ -134,6 +134,14 @@ class Session { } + /** + * @brief remove encryption keys and init status from session + */ + public function closeSession() { + \OC::$session->remove('encryptionInitialized'); + \OC::$session->remove('privateKey'); + } + /** * @brief Gets status if we already tried to initialize the encryption app diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index ec06bd52f5e..6bf69cd8ee1 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -1772,4 +1772,12 @@ class Util { return $session; } + /* + * @brief remove encryption related keys from the session + */ + public function closeEncryptionSession() { + $session = new \OCA\Encryption\Session($this->view); + $session->closeSession(); + } + } diff --git a/settings/ajax/decryptall.php b/settings/ajax/decryptall.php index d7c104ab151..4782a4cfc81 100644 --- a/settings/ajax/decryptall.php +++ b/settings/ajax/decryptall.php @@ -24,6 +24,8 @@ if ($result !== false) { $successful = false; } + $util->closeEncryptionSession(); + if ($successful === true) { \OCP\JSON::success(array('data' => array('message' => 'Files decrypted successfully'))); } else { From 922c1909f828d32c74d4f465ec302610c7818a39 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 26 Feb 2014 15:19:42 +0100 Subject: [PATCH 101/118] Translate string when an error occured while sending a forgot password mail Fix #7423 --- core/lostpassword/controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lostpassword/controller.php b/core/lostpassword/controller.php index fd20c6ba249..c858696885b 100644 --- a/core/lostpassword/controller.php +++ b/core/lostpassword/controller.php @@ -69,7 +69,7 @@ class Controller { $defaults = new \OC_Defaults(); \OC_Mail::send($email, $_POST['user'], $l->t('%s password reset', array($defaults->getName())), $msg, $from, $defaults->getName()); } catch (Exception $e) { - \OC_Template::printErrorPage( 'A problem occurs during sending the e-mail please contact your administrator.'); + \OC_Template::printErrorPage( $l->t('A problem has occurred whilst sending the email, please contact your administrator.') ); } self::displayLostPasswordPage(false, true); } else { From 459b5086d56d97b2ccf42b1fd50a7924883b6c7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 26 Feb 2014 20:42:45 +0100 Subject: [PATCH 102/118] adding test for migrations on columns using keywords --- tests/data/db_structure.xml | 15 +++++++++++++++ tests/data/db_structure2.xml | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/tests/data/db_structure.xml b/tests/data/db_structure.xml index d98066c4b7e..5fffd5475f9 100644 --- a/tests/data/db_structure.xml +++ b/tests/data/db_structure.xml @@ -223,4 +223,19 @@ + + *dbprefix*migratekeyword + + + + + key + text + + true + 255 + + +
+ diff --git a/tests/data/db_structure2.xml b/tests/data/db_structure2.xml index ae5f22e9573..aa6e94a2a84 100644 --- a/tests/data/db_structure2.xml +++ b/tests/data/db_structure2.xml @@ -119,4 +119,19 @@ + + *dbprefix*migratekeyword + + + + + key + text + + false + 255 + + +
+ From 230e5e3788f8289447602b70e2445c134e532e0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 26 Feb 2014 20:47:07 +0100 Subject: [PATCH 103/118] let's name the column 'select' because this is a keyword on all platforms --- tests/data/db_structure.xml | 2 +- tests/data/db_structure2.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/data/db_structure.xml b/tests/data/db_structure.xml index 5fffd5475f9..858c9ab1002 100644 --- a/tests/data/db_structure.xml +++ b/tests/data/db_structure.xml @@ -229,7 +229,7 @@ - key + select text true diff --git a/tests/data/db_structure2.xml b/tests/data/db_structure2.xml index aa6e94a2a84..568d90ab0a9 100644 --- a/tests/data/db_structure2.xml +++ b/tests/data/db_structure2.xml @@ -125,7 +125,7 @@ - key + select text false From ab850b961dd576a4caf7c2269d8559fdbe6d62e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 26 Feb 2014 23:56:46 +0100 Subject: [PATCH 104/118] remove unused code and fix wrong variable names - some PHPDoc updated --- lib/private/image.php | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/lib/private/image.php b/lib/private/image.php index 17caaa012f5..da32aa4760f 100644 --- a/lib/private/image.php +++ b/lib/private/image.php @@ -41,8 +41,7 @@ class OC_Image { // exif_imagetype throws "read error!" if file is less than 12 byte if (filesize($filePath) > 11) { $imageType = exif_imagetype($filePath); - } - else { + } else { $imageType = false; } return $imageType ? image_type_to_mime_type($imageType) : ''; @@ -50,7 +49,7 @@ class OC_Image { /** * @brief Constructor. - * @param $imageref The path to a local file, a base64 encoded string or a resource created by an imagecreate* function. + * @param string|resource $imageref The path to a local file, a base64 encoded string or a resource created by an imagecreate* function. * @returns bool False on error */ public function __construct($imageRef = null) { @@ -115,13 +114,11 @@ class OC_Image { case 3: case 4: // Not tested return $this->width(); - break; case 5: // Not tested case 6: case 7: // Not tested case 8: return $this->height(); - break; } return $this->width(); } @@ -140,13 +137,11 @@ class OC_Image { case 3: case 4: // Not tested return $this->height(); - break; case 5: // Not tested case 6: case 7: // Not tested case 8: return $this->width(); - break; } return $this->height(); } @@ -197,7 +192,6 @@ class OC_Image { return false; } - $retVal = false; switch($this->imageType) { case IMAGETYPE_GIF: $retVal = imagegif($this->resource, $filePath); @@ -264,8 +258,8 @@ class OC_Image { } /** - * @returns Returns a base64 encoded string suitable for embedding in a VCard. - */ + * @return string - base64 encoded, which is suitable for embedding in a VCard. + */ function __toString() { return base64_encode($this->data()); } @@ -307,43 +301,33 @@ class OC_Image { $o = $this->getOrientation(); OC_Log::write('core', 'OC_Image->fixOrientation() Orientation: '.$o, OC_Log::DEBUG); $rotate = 0; - $flip = false; switch($o) { case -1: return false; //Nothing to fix - break; case 1: $rotate = 0; - $flip = false; break; case 2: // Not tested $rotate = 0; - $flip = true; break; case 3: $rotate = 180; - $flip = false; break; case 4: // Not tested $rotate = 180; - $flip = true; break; case 5: // Not tested $rotate = 90; - $flip = true; break; case 6: //$rotate = 90; $rotate = 270; - $flip = false; break; case 7: // Not tested $rotate = 270; - $flip = true; break; case 8: $rotate = 90; - $flip = false; break; } if($rotate) { @@ -367,6 +351,7 @@ class OC_Image { return false; } } + return false; } /** @@ -599,9 +584,9 @@ class OC_Image { $meta['imagesize'] = $meta['filesize'] - $meta['offset']; // in rare cases filesize is equal to offset so we need to read physical size if ($meta['imagesize'] < 1) { - $meta['imagesize'] = @filesize($filename) - $meta['offset']; + $meta['imagesize'] = @filesize($fileName) - $meta['offset']; if ($meta['imagesize'] < 1) { - trigger_error('imagecreatefrombmp: Can not obtain filesize of ' . $filename . '!', E_USER_WARNING); + trigger_error('imagecreatefrombmp: Can not obtain filesize of ' . $fileName . '!', E_USER_WARNING); return false; } } @@ -947,7 +932,7 @@ if ( ! function_exists( 'imagebmp') ) { $index = imagecolorat($im, $i, $j); if ($index !== $lastIndex || $sameNum > 255) { if ($sameNum != 0) { - $bmpData .= chr($same_num) . chr($lastIndex); + $bmpData .= chr($sameNum) . chr($lastIndex); } $lastIndex = $index; $sameNum = 1; From 22adc397dea060150e6982ba9dda1483eebbfa67 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 26 Feb 2014 16:26:16 +0100 Subject: [PATCH 105/118] Also quote old column name during DB migration This fixes alter table commands that didn't quote the old column name --- lib/private/db/mdb2schemamanager.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/private/db/mdb2schemamanager.php b/lib/private/db/mdb2schemamanager.php index c050d47b499..aaf2ea543b9 100644 --- a/lib/private/db/mdb2schemamanager.php +++ b/lib/private/db/mdb2schemamanager.php @@ -82,6 +82,9 @@ class MDB2SchemaManager { $platform = $this->conn->getDatabasePlatform(); foreach($schemaDiff->changedTables as $tableDiff) { $tableDiff->name = $platform->quoteIdentifier($tableDiff->name); + foreach($tableDiff->changedColumns as $column) { + $column->oldColumnName = $platform->quoteIdentifier($column->oldColumnName); + } } if ($generateSql) { From 39f2f564a99ebe719748f349aafe92ed9910bc0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Thu, 27 Feb 2014 09:39:34 +0100 Subject: [PATCH 106/118] use assertSame and assertNotSame for etag checks --- apps/files_encryption/tests/util.php | 4 +-- tests/lib/appframework/http/ResponseTest.php | 2 +- tests/lib/files/cache/scanner.php | 26 ++++++++++++++------ tests/lib/files/etagtest.php | 6 ++++- tests/lib/files/view.php | 2 +- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/apps/files_encryption/tests/util.php b/apps/files_encryption/tests/util.php index f70e30c4d73..203ba55dbfd 100755 --- a/apps/files_encryption/tests/util.php +++ b/apps/files_encryption/tests/util.php @@ -344,7 +344,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { // check if mtime and etags unchanged $this->assertEquals($fileInfoEncrypted['mtime'], $fileInfoUnencrypted['mtime']); - $this->assertEquals($fileInfoEncrypted['etag'], $fileInfoUnencrypted['etag']); + $this->assertSame($fileInfoEncrypted['etag'], $fileInfoUnencrypted['etag']); $this->view->unlink($this->userId . '/files/' . $filename); } @@ -373,7 +373,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { // check if mtime and etags unchanged $this->assertEquals($fileInfoEncrypted['mtime'], $fileInfoUnencrypted['mtime']); - $this->assertEquals($fileInfoEncrypted['etag'], $fileInfoUnencrypted['etag']); + $this->assertSame($fileInfoEncrypted['etag'], $fileInfoUnencrypted['etag']); // file should no longer be encrypted $this->assertEquals(0, $fileInfoUnencrypted['encrypted']); diff --git a/tests/lib/appframework/http/ResponseTest.php b/tests/lib/appframework/http/ResponseTest.php index 4f21d77a170..063ab8b5d33 100644 --- a/tests/lib/appframework/http/ResponseTest.php +++ b/tests/lib/appframework/http/ResponseTest.php @@ -78,7 +78,7 @@ class ResponseTest extends \PHPUnit_Framework_TestCase { public function testGetEtag() { $this->childResponse->setEtag('hi'); - $this->assertEquals('hi', $this->childResponse->getEtag()); + $this->assertSame('hi', $this->childResponse->getEtag()); } diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 3f5604b4d45..9df98c36fa8 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -150,13 +150,15 @@ class Scanner extends \PHPUnit_Framework_TestCase { $this->cache->put('folder', array('mtime' => $this->storage->filemtime('folder'), 'storage_mtime' => $this->storage->filemtime('folder'))); $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_SIZE); $newData = $this->cache->get(''); - $this->assertNotEquals($oldData['etag'], $newData['etag']); + $this->assertTrue(is_string($oldData['etag']), 'Expected a string'); + $this->assertTrue(is_string($newData['etag']), 'Expected a string'); + $this->assertNotSame($oldData['etag'], $newData['etag']); $this->assertEquals($oldData['size'], $newData['size']); $oldData = $newData; $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG); $newData = $this->cache->get(''); - $this->assertEquals($oldData['etag'], $newData['etag']); + $this->assertSame($oldData['etag'], $newData['etag']); $this->assertEquals(-1, $newData['size']); $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE); @@ -164,17 +166,17 @@ class Scanner extends \PHPUnit_Framework_TestCase { $this->assertNotEquals(-1, $oldData['size']); $this->scanner->scanFile('', \OC\Files\Cache\Scanner::REUSE_ETAG + \OC\Files\Cache\Scanner::REUSE_SIZE); $newData = $this->cache->get(''); - $this->assertEquals($oldData['etag'], $newData['etag']); + $this->assertSame($oldData['etag'], $newData['etag']); $this->assertEquals($oldData['size'], $newData['size']); $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE, \OC\Files\Cache\Scanner::REUSE_ETAG + \OC\Files\Cache\Scanner::REUSE_SIZE); $newData = $this->cache->get(''); - $this->assertEquals($oldData['etag'], $newData['etag']); + $this->assertSame($oldData['etag'], $newData['etag']); $this->assertEquals($oldData['size'], $newData['size']); $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG + \OC\Files\Cache\Scanner::REUSE_SIZE); $newData = $this->cache->get(''); - $this->assertEquals($oldData['etag'], $newData['etag']); + $this->assertSame($oldData['etag'], $newData['etag']); $this->assertEquals($oldData['size'], $newData['size']); } @@ -217,8 +219,11 @@ class Scanner extends \PHPUnit_Framework_TestCase { // manipulate etag to simulate an empty etag $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG); $data0 = $this->cache->get('folder/bar.txt'); + $this->assertTrue(is_string($data0['etag']), 'Expected a string'); $data1 = $this->cache->get('folder'); + $this->assertTrue(is_string($data1['etag']), 'Expected a string'); $data2 = $this->cache->get(''); + $this->assertTrue(is_string($data2['etag']), 'Expected a string'); $data0['etag'] = ''; $this->cache->put('folder/bar.txt', $data0); @@ -227,10 +232,15 @@ class Scanner extends \PHPUnit_Framework_TestCase { // verify cache content $newData0 = $this->cache->get('folder/bar.txt'); + $this->assertTrue(is_string($newData0['etag']), 'Expected a string'); + $this->assertNotEmpty($newData0['etag']); + $newData1 = $this->cache->get('folder'); + $this->assertTrue(is_string($newData1['etag']), 'Expected a string'); + $this->assertNotSame($data1['etag'], $newData1['etag']); + $newData2 = $this->cache->get(''); - $this->assertNotEmpty($newData0['etag']); - $this->assertNotEquals($data1['etag'], $newData1['etag']); - $this->assertNotEquals($data2['etag'], $newData2['etag']); + $this->assertTrue(is_string($newData2['etag']), 'Expected a string'); + $this->assertNotSame($data2['etag'], $newData2['etag']); } } diff --git a/tests/lib/files/etagtest.php b/tests/lib/files/etagtest.php index ce05adb188a..af9f66835f0 100644 --- a/tests/lib/files/etagtest.php +++ b/tests/lib/files/etagtest.php @@ -65,7 +65,11 @@ class EtagTest extends \PHPUnit_Framework_TestCase { $scanner = new \OC\Files\Utils\Scanner($user1); $scanner->backgroundScan('/'); - $this->assertEquals($originalEtags, $this->getEtags($files)); + $newEtags = $this->getEtags($files); + // loop over array and use assertSame over assertEquals to prevent false positives + foreach ($originalEtags as $file => $originalEtag) { + $this->assertSame($originalEtag, $newEtags[$file]); + } } /** diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 371d1ed1798..c85f1128dbe 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -563,6 +563,6 @@ class View extends \PHPUnit_Framework_TestCase { $scanner->scanFile('test', \OC\Files\Cache\Scanner::REUSE_ETAG); $info2 = $view->getFileInfo('/test/test'); - $this->assertEquals($info['etag'], $info2['etag']); + $this->assertSame($info['etag'], $info2['etag']); } } From 131c12ad8d51c4a0acad03299bd617907c9f1d66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Thu, 27 Feb 2014 09:51:26 +0100 Subject: [PATCH 107/118] use assertInternalType for typechecking --- tests/lib/files/cache/scanner.php | 16 +++--- tests/lib/files/cache/updater.php | 84 +++++++++++++++++++++++-------- 2 files changed, 71 insertions(+), 29 deletions(-) diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 9df98c36fa8..5182fac8b10 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -150,8 +150,8 @@ class Scanner extends \PHPUnit_Framework_TestCase { $this->cache->put('folder', array('mtime' => $this->storage->filemtime('folder'), 'storage_mtime' => $this->storage->filemtime('folder'))); $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_SIZE); $newData = $this->cache->get(''); - $this->assertTrue(is_string($oldData['etag']), 'Expected a string'); - $this->assertTrue(is_string($newData['etag']), 'Expected a string'); + $this->assertInternalType('string', $oldData['etag']); + $this->assertInternalType('string', $newData['etag']); $this->assertNotSame($oldData['etag'], $newData['etag']); $this->assertEquals($oldData['size'], $newData['size']); @@ -219,11 +219,11 @@ class Scanner extends \PHPUnit_Framework_TestCase { // manipulate etag to simulate an empty etag $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG); $data0 = $this->cache->get('folder/bar.txt'); - $this->assertTrue(is_string($data0['etag']), 'Expected a string'); + $this->assertInternalType('string', $data0['etag']); $data1 = $this->cache->get('folder'); - $this->assertTrue(is_string($data1['etag']), 'Expected a string'); + $this->assertInternalType('string', $data1['etag']); $data2 = $this->cache->get(''); - $this->assertTrue(is_string($data2['etag']), 'Expected a string'); + $this->assertInternalType('string', $data2['etag']); $data0['etag'] = ''; $this->cache->put('folder/bar.txt', $data0); @@ -232,15 +232,15 @@ class Scanner extends \PHPUnit_Framework_TestCase { // verify cache content $newData0 = $this->cache->get('folder/bar.txt'); - $this->assertTrue(is_string($newData0['etag']), 'Expected a string'); + $this->assertInternalType('string', $newData0['etag']); $this->assertNotEmpty($newData0['etag']); $newData1 = $this->cache->get('folder'); - $this->assertTrue(is_string($newData1['etag']), 'Expected a string'); + $this->assertInternalType('string', $newData1['etag']); $this->assertNotSame($data1['etag'], $newData1['etag']); $newData2 = $this->cache->get(''); - $this->assertTrue(is_string($newData2['etag']), 'Expected a string'); + $this->assertInternalType('string', $newData2['etag']); $this->assertNotSame($data2['etag'], $newData2['etag']); } } diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php index 48986149a73..57c799e608b 100644 --- a/tests/lib/files/cache/updater.php +++ b/tests/lib/files/cache/updater.php @@ -96,10 +96,14 @@ class Updater extends \PHPUnit_Framework_TestCase { Filesystem::file_put_contents('foo.txt', 'asd'); $cachedData = $this->cache->get('foo.txt'); $this->assertEquals(3, $cachedData['size']); - $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $fooCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($fooCachedData['etag'], $cachedData['etag']); $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize + 3, $cachedData['size']); - $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $rootCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']); $rootCachedData = $cachedData; $this->assertFalse($this->cache->inCache('bar.txt')); @@ -110,7 +114,9 @@ class Updater extends \PHPUnit_Framework_TestCase { $mtime = $cachedData['mtime']; $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize + 2 * 3, $cachedData['size']); - $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $rootCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']); $this->assertGreaterThanOrEqual($rootCachedData['mtime'], $mtime); } @@ -127,11 +133,15 @@ class Updater extends \PHPUnit_Framework_TestCase { $mtime = $cachedData['mtime']; $cachedData = $cache2->get(''); - $this->assertNotEquals($substorageCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $substorageCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($substorageCachedData['etag'], $cachedData['etag']); $this->assertEquals($mtime, $cachedData['mtime']); $cachedData = $this->cache->get('folder'); - $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $folderCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($folderCachedData['etag'], $cachedData['etag']); $this->assertEquals($mtime, $cachedData['mtime']); } @@ -146,19 +156,25 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertFalse($this->cache->inCache('foo.txt')); $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize, $cachedData['size']); - $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $rootCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']); $this->assertGreaterThanOrEqual($rootCachedData['mtime'], $cachedData['mtime']); $rootCachedData = $cachedData; Filesystem::mkdir('bar_folder'); $this->assertTrue($this->cache->inCache('bar_folder')); $cachedData = $this->cache->get(''); - $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $rootCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']); $rootCachedData = $cachedData; Filesystem::rmdir('bar_folder'); $this->assertFalse($this->cache->inCache('bar_folder')); $cachedData = $this->cache->get(''); - $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $rootCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']); $this->assertGreaterThanOrEqual($rootCachedData['mtime'], $cachedData['mtime']); } @@ -174,11 +190,15 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertFalse($cache2->inCache('foo.txt')); $cachedData = $cache2->get(''); - $this->assertNotEquals($substorageCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $substorageCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($substorageCachedData['etag'], $cachedData['etag']); $this->assertGreaterThanOrEqual($substorageCachedData['mtime'], $cachedData['mtime']); $cachedData = $this->cache->get('folder'); - $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $folderCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($folderCachedData['etag'], $cachedData['etag']); $this->assertGreaterThanOrEqual($folderCachedData['mtime'], $cachedData['mtime']); } @@ -199,7 +219,9 @@ class Updater extends \PHPUnit_Framework_TestCase { $mtime = $cachedData['mtime']; $cachedData = $this->cache->get(''); $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); - $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $rootCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']); } public function testRenameExtension() { @@ -227,12 +249,16 @@ class Updater extends \PHPUnit_Framework_TestCase { $mtime = $cachedData['mtime']; $cachedData = $cache2->get(''); - $this->assertNotEquals($substorageCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $substorageCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($substorageCachedData['etag'], $cachedData['etag']); // rename can cause mtime change - invalid assert // $this->assertEquals($mtime, $cachedData['mtime']); $cachedData = $this->cache->get('folder'); - $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $folderCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($folderCachedData['etag'], $cachedData['etag']); // rename can cause mtime change - invalid assert // $this->assertEquals($mtime, $cachedData['mtime']); } @@ -242,11 +268,15 @@ class Updater extends \PHPUnit_Framework_TestCase { $fooCachedData = $this->cache->get('foo.txt'); Filesystem::touch('foo.txt'); $cachedData = $this->cache->get('foo.txt'); - $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $fooCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($fooCachedData['etag'], $cachedData['etag']); $this->assertGreaterThanOrEqual($fooCachedData['mtime'], $cachedData['mtime']); $cachedData = $this->cache->get(''); - $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $rootCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']); $this->assertGreaterThanOrEqual($rootCachedData['mtime'], $cachedData['mtime']); $rootCachedData = $cachedData; @@ -255,14 +285,20 @@ class Updater extends \PHPUnit_Framework_TestCase { $folderCachedData = $this->cache->get('folder'); Filesystem::touch('folder/bar.txt', $time); $cachedData = $this->cache->get('folder/bar.txt'); - $this->assertNotEquals($barCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $barCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($barCachedData['etag'], $cachedData['etag']); $this->assertEquals($time, $cachedData['mtime']); $cachedData = $this->cache->get('folder'); - $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $folderCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($folderCachedData['etag'], $cachedData['etag']); $cachedData = $this->cache->get(''); - $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $rootCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']); $this->assertEquals($time, $cachedData['mtime']); } @@ -279,14 +315,20 @@ class Updater extends \PHPUnit_Framework_TestCase { $time = 1371006070; Filesystem::touch('folder/substorage/foo.txt', $time); $cachedData = $cache2->get('foo.txt'); - $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $fooCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($fooCachedData['etag'], $cachedData['etag']); $this->assertEquals($time, $cachedData['mtime']); $cachedData = $cache2->get(''); - $this->assertNotEquals($substorageCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $substorageCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($substorageCachedData['etag'], $cachedData['etag']); $cachedData = $this->cache->get('folder'); - $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']); + $this->assertInternalType('string', $folderCachedData['etag']); + $this->assertInternalType('string', $cachedData['etag']); + $this->assertNotSame($folderCachedData['etag'], $cachedData['etag']); $this->assertEquals($time, $cachedData['mtime']); } From f0cd08ab5d819bd11640dc51338f4ee3d52a623f Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Thu, 27 Feb 2014 12:13:09 +0100 Subject: [PATCH 108/118] remove border from log in input fields, simpler and works better with themes --- core/css/styles.css | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/core/css/styles.css b/core/css/styles.css index 341a507ce37..082d2c714cf 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -405,11 +405,9 @@ input[name="adminpass-clone"] { padding-left:1.8em; width:11.7em !important; } /* General new input field look */ #body-login input[type="text"], #body-login input[type="password"], -#body-login input[type="email"] { - border: 1px solid #323233; - border-radius: 5px; -} -#body-login input[type='submit'] { +#body-login input[type="email"], +#body-login input[type="submit"] { + border: none; border-radius: 5px; } From a5a671392c4a86fb865ba36e5e1cd0539fb26ad0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 27 Feb 2014 12:16:58 +0100 Subject: [PATCH 109/118] rename config to camelcase --- .jshintrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.jshintrc b/.jshintrc index f40dd22b5fd..90cec5c5961 100644 --- a/.jshintrc +++ b/.jshintrc @@ -1,5 +1,5 @@ { - "camelCase": true, + "camelcase": true, "eqeqeq": true, "immed": true, "latedef": false, From af467d92f642309fdd13a305367ad11cd6976a62 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Thu, 27 Feb 2014 12:21:05 +0100 Subject: [PATCH 110/118] Installation: relabel 'Advanced' to more descriptive 'Storage & database' --- core/templates/installation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/templates/installation.php b/core/templates/installation.php index d3adb34f412..d9f3c38ab11 100644 --- a/core/templates/installation.php +++ b/core/templates/installation.php @@ -67,7 +67,7 @@ 0): ?>
- t( 'Advanced' )); ?> + t( 'Storage & database' )); ?>
From 2ba6cd4e2b779d43424fd2a037319923749666d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Thu, 27 Feb 2014 12:42:53 +0100 Subject: [PATCH 111/118] initialize etags of temporary storage --- tests/lib/files/cache/updater.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php index 57c799e608b..a6ee8c46661 100644 --- a/tests/lib/files/cache/updater.php +++ b/tests/lib/files/cache/updater.php @@ -122,6 +122,7 @@ class Updater extends \PHPUnit_Framework_TestCase { public function testWriteWithMountPoints() { $storage2 = new \OC\Files\Storage\Temporary(array()); + $storage2->getScanner()->scan(''); //initialize etags $cache2 = $storage2->getCache(); Filesystem::mount($storage2, array(), '/' . self::$user . '/files/folder/substorage'); $folderCachedData = $this->cache->get('folder'); From 58bc6aee51a5b380ae8943c489f6fdd7434bcc42 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Thu, 27 Feb 2014 12:48:25 +0100 Subject: [PATCH 112/118] icons: automatically show delete hover instead of using explicit class --- core/css/icons.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/css/icons.css b/core/css/icons.css index 814749c5af8..d3d4d7da709 100644 --- a/core/css/icons.css +++ b/core/css/icons.css @@ -66,7 +66,8 @@ .icon-delete { background-image: url('../img/actions/delete.svg'); } -.icon-delete-hover { +.icon-delete:hover, +.icon-delete:focus { background-image: url('../img/actions/delete-hover.svg'); } From 7c92e2e3ad9555746aca7df38431a56bc4aced83 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 27 Feb 2014 14:04:19 +0100 Subject: [PATCH 113/118] Update rawlist to work with new fileinfo object --- apps/files/ajax/rawlist.php | 59 +++++++++++++++----------------- lib/private/files/filesystem.php | 2 +- 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/apps/files/ajax/rawlist.php b/apps/files/ajax/rawlist.php index 40da32b223a..89c21a172fc 100644 --- a/apps/files/ajax/rawlist.php +++ b/apps/files/ajax/rawlist.php @@ -1,12 +1,12 @@ getPreviewManager()->isMimeSupported($file['mimetype']); - $file["date"] = OCP\Util::formatDate($file["mtime"]); - $file['mimetype_icon'] = \OCA\Files\Helper::determineIcon($file); - $files[] = $file; - } +if ($mimetypes && !in_array('httpd/unix-directory', $mimetypes)) { + $files = array_merge($files, \OC\Files\Filesystem::getDirectoryContent($dir, 'httpd/unix-directory')); } if (is_array($mimetypes) && count($mimetypes)) { foreach ($mimetypes as $mimetype) { - foreach( \OC\Files\Filesystem::getDirectoryContent( $dir, $mimetype ) as $file ) { - $file['directory'] = $dir; - $file['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($file['mimetype']); - $file["date"] = OCP\Util::formatDate($file["mtime"]); - $file['mimetype_icon'] = \OCA\Files\Helper::determineIcon($file); - $files[] = $file; - } + $files = array_merge($files, \OC\Files\Filesystem::getDirectoryContent($dir, $mimetype)); } } else { - foreach( \OC\Files\Filesystem::getDirectoryContent( $dir ) as $file ) { - $file['directory'] = $dir; - $file['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($file['mimetype']); - $file["date"] = OCP\Util::formatDate($file["mtime"]); - $file['mimetype_icon'] = \OCA\Files\Helper::determineIcon($file); - $files[] = $file; - } + $files = array_merge($files, \OC\Files\Filesystem::getDirectoryContent($dir)); +} + +$result = array(); +foreach ($files as $file) { + $fileData = array(); + $fileData['directory'] = $dir; + $fileData['name'] = $file->getName(); + $fileData['type'] = $file->getType(); + $fileData['path'] = $file['path']; + $fileData['id'] = $file->getId(); + $fileData['size'] = $file->getSize(); + $fileData['mtime'] = $file->getMtime(); + $fileData['mimetype'] = $file->getMimetype(); + $fileData['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($file->getMimetype()); + $fileData["date"] = OCP\Util::formatDate($file->getMtime()); + $fileData['mimetype_icon'] = \OCA\Files\Helper::determineIcon($file); + $result[] = $fileData; } // Sort by name -usort($files, function ($a, $b) { - if ($a['name'] === $b['name']) { - return 0; - } - return ($a['name'] < $b['name']) ? -1 : 1; -}); +usort($result, array('\OCA\Files\Helper', 'fileCmp')); -OC_JSON::success(array('data' => $files)); +OC_JSON::success(array('data' => $result)); diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php index 7f7b6f7f468..6478854eae8 100644 --- a/lib/private/files/filesystem.php +++ b/lib/private/files/filesystem.php @@ -761,7 +761,7 @@ class Filesystem { * * @param string $directory path under datadirectory * @param string $mimetype_filter limit returned content to this mimetype or mimepart - * @return array + * @return \OC\Files\FileInfo[] */ public static function getDirectoryContent($directory, $mimetype_filter = '') { return self::$defaultInstance->getDirectoryContent($directory, $mimetype_filter); From 4ace1a273d705a21736f92ba3a38f08d8465bca0 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 27 Feb 2014 13:58:51 +0100 Subject: [PATCH 114/118] remember original fopen access type in pre-proxy because sometimes they change during the fopen call, e.g. 'r' becomes 'r+' if we open an URL --- apps/files_encryption/lib/proxy.php | 32 ++++++++++++++++++++++------ apps/files_encryption/lib/stream.php | 3 +++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 9d456f6c517..3b9a1f08338 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -38,6 +38,7 @@ class Proxy extends \OC_FileProxy { private static $blackList = null; //mimetypes blacklisted from encryption private static $unencryptedSizes = array(); // remember unencrypted size + private static $fopenMode = array(); // remember the fopen mode /** * Check if a file requires encryption @@ -213,6 +214,16 @@ class Proxy extends \OC_FileProxy { return true; } + /** + * @brief remember initial fopen mode because sometimes it gets changed during the request + * @param string $path path + * @param string $mode type of access + */ + public function preFopen($path, $mode) { + self::$fopenMode[$path] = $mode; + } + + /** * @param $path * @param $result @@ -240,7 +251,15 @@ class Proxy extends \OC_FileProxy { $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - $meta = stream_get_meta_data($result); + // if we remember the mode from the pre proxy we re-use it + // oterwise we fall back to stream_get_meta_data() + if (isset(self::$fopenMode[$path])) { + $mode = self::$fopenMode[$path]; + unset(self::$fopenMode[$path]); + } else { + $meta = stream_get_meta_data($result); + $mode = $meta['mode']; + } $view = new \OC_FilesystemView(''); @@ -258,14 +277,15 @@ class Proxy extends \OC_FileProxy { // Open the file using the crypto stream wrapper // protocol and let it do the decryption work instead - $result = fopen('crypt://' . $path, $meta['mode']); + $result = fopen('crypt://' . $path, $mode); } elseif ( - self::shouldEncrypt($path) - and $meta['mode'] !== 'r' - and $meta['mode'] !== 'rb' + self::shouldEncrypt($path) + and $mode !== 'r' + and $mode !== 'rb' + ) { - $result = fopen('crypt://' . $path, $meta['mode']); + $result = fopen('crypt://' . $path, $mode); } // Re-enable the proxy diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index 88eacc6f136..58ac03373a7 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -167,6 +167,9 @@ class Stream { } else { $this->meta = stream_get_meta_data($this->handle); + // sometimes fopen changes the mode, e.g. for a url "r" convert to "r+" + // but we need to remember the original access type + $this->meta['mode'] = $mode; } From 49b331be39162bbca738cadfedd6042028613b94 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Thu, 27 Feb 2014 14:39:16 +0100 Subject: [PATCH 115/118] add BMP mimetype for BMP previews --- lib/private/mimetypes.list.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/private/mimetypes.list.php b/lib/private/mimetypes.list.php index 9bd07b89023..a216414c9dd 100644 --- a/lib/private/mimetypes.list.php +++ b/lib/private/mimetypes.list.php @@ -31,6 +31,7 @@ return array( 'bash' => 'text/x-shellscript', 'blend' => 'application/x-blender', 'bin' => 'application/x-bin', + 'bmp' => 'image/bmp', 'cb7' => 'application/x-cbr', 'cba' => 'application/x-cbr', 'cbr' => 'application/x-cbr', From fefd7248585e2831adfb1ae9d40c49e94529e36d Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Thu, 27 Feb 2014 19:50:16 +0100 Subject: [PATCH 116/118] Fixed wrong field name This re-fixes an issue where the unencrypted size isn't updated correctly when saving a text file in the UI multiple times. Fixes #7467 --- apps/files_encryption/lib/proxy.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 9d456f6c517..6b1e4b7745b 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -146,7 +146,7 @@ class Proxy extends \OC_FileProxy { if ( isset(self::$unencryptedSizes[$normalizedPath]) ) { $view = new \OC_FilesystemView('/'); $view->putFileInfo($normalizedPath, - array('encrypted' => true, 'encrypted_size' => self::$unencryptedSizes[$normalizedPath])); + array('encrypted' => true, 'unencrypted_size' => self::$unencryptedSizes[$normalizedPath])); unset(self::$unencryptedSizes[$normalizedPath]); } From e78da036c11b600bfcf15387ecb053a87150444a Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Fri, 28 Feb 2014 10:09:34 +0100 Subject: [PATCH 117/118] profile image: relabel technical 'Abort' to more widely used 'Cancel' --- settings/templates/personal.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings/templates/personal.php b/settings/templates/personal.php index 188ff75f96b..470b8180bcc 100644 --- a/settings/templates/personal.php +++ b/settings/templates/personal.php @@ -108,7 +108,7 @@ if($_['passwordChangeSupported']) { From 4c4bb70cb67fb20739ec48fc2d06400485413dda Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 28 Feb 2014 11:14:18 +0100 Subject: [PATCH 118/118] CSS is now loaded directly instead via PHP 269f24cf9617397aaf501b27ec1af2c8e3154cf8 was not changed in setup.php which prevented loading of CSS files in some environments (e.g. my local setup) for apps. --- lib/private/setup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/setup.php b/lib/private/setup.php index 3906204bda3..0d5bf424b33 100644 --- a/lib/private/setup.php +++ b/lib/private/setup.php @@ -147,7 +147,7 @@ class OC_Setup { $content.= "RewriteRule ^.well-known/host-meta /public.php?service=host-meta [QSA,L]\n"; $content.= "RewriteRule ^.well-known/carddav /remote.php/carddav/ [R]\n"; $content.= "RewriteRule ^.well-known/caldav /remote.php/caldav/ [R]\n"; - $content.= "RewriteRule ^apps/([^/]*)/(.*\.(css|php))$ index.php?app=$1&getfile=$2 [QSA,L]\n"; + $content.= "RewriteRule ^apps/([^/]*)/(.*\.(php))$ index.php?app=$1&getfile=$2 [QSA,L]\n"; $content.= "RewriteRule ^remote/(.*) remote.php [QSA,L]\n"; $content.= "\n"; $content.= "\n";