Compare commits

...

51 Commits

Author SHA1 Message Date
Vincent Petry 5b39016db4 Also increase htaccess version 2016-06-16 20:06:32 +02:00
Daniel Molkentin 908d358670 ownCloud 8.2.6 RC1 2016-06-16 18:33:01 +02:00
Vincent Petry d17b4742a8 Merge pull request #25139 from owncloud/stable82-backport-25126
[stable8.2] load authentication apps first
2016-06-16 14:32:33 +02:00
Joas Schilling 680ee05047 Merge pull request #25122 from owncloud/scanner-locking-shared-82
Fix scanner lock on shared storages resulting into locked files
2016-06-16 14:03:21 +02:00
Christoph Wurst 83128646f1 load authentication apps first 2016-06-16 11:40:43 +02:00
Robin Appelman 9df60c7956 Fix scanner lock on shared storages resulting into locked files 2016-06-15 16:10:25 +02:00
Vincent Petry 35e2407f1d Merge pull request #25101 from owncloud/cross-storage-move-updater-82
fix updating folder sizes with cross storage move
2016-06-15 13:00:34 +02:00
Robin Appelman 71992dcb18 fix updating folder sizes with cross storage move 2016-06-14 16:42:56 +02:00
Vincent Petry f882f6b551 Merge pull request #25037 from owncloud/handle_delete_with_unavailable_storage
Handle "storage not available" to show an error message
2016-06-13 15:56:29 +02:00
Juan Pablo Villafáñez 8e640faf3a Fix typo 2016-06-10 14:42:59 +02:00
Juan Pablo Villafáñez 5a8278d9e6 Handle storage not available to show an error message 2016-06-10 14:42:59 +02:00
Vincent Petry 12098383cc Merge pull request #25040 from owncloud/stable8.2-construct-path
[Stable8.2]  Construct path to the version file from the current directory and fil…
2016-06-09 16:21:29 +02:00
Victor Dubiniuk b92831943d Construct path to the version file from the current directory and filename. Fixes #22450 2016-06-08 20:59:21 +03:00
Vincent Petry 8b48a8f560 Merge pull request #24945 from owncloud/fix_21173_stable8.2
stable8.2: normalize path in getInternalPath
2016-06-02 15:30:55 +02:00
Vincent Petry ef6e26cb30 Merge pull request #24959 from owncloud/stable8.2_24869
[stable8.2] Use a capped memory cache for the user/group cache
2016-06-02 10:38:42 +02:00
Roeland Jago Douma f582521f12 Use a capped memory cache for the user/group cache
For #24403
When upgrading huge installations this can lead to memory problems as
the cache will only grow and grow.

Capping this memory will make sure we don't run out while during normal
operation still basically cache everything.
2016-06-01 21:36:10 +02:00
Georg Ehrke f8d819fbd0 normalize path in getInternalPath 2016-06-01 13:25:53 +02:00
Christoph Wurst e8e24cbe6c Merge pull request #24924 from owncloud/stable8.2-backport-24795
[8.2] Allow opening the password reset link in a new window when its a URL
2016-06-01 12:12:26 +02:00
Christoph Wurst 0d5f56b465 Merge pull request #24418 from owncloud/fix_24182_8.2
[stable8.2] first call the post_login hooks, before we call getUserFolder.
2016-06-01 12:04:26 +02:00
Vincent Petry c1257761f1 Merge pull request #23571 from owncloud/stable8.2-backport-23362
[stable8.2] Read available l10n files also from theme folder
2016-06-01 11:17:47 +02:00
Joas Schilling ed3d970322 Add a warning when the transaction isolation level is not READ_COMMITED (#24916) 2016-06-01 06:58:05 +02:00
Joas Schilling 31a37d4f19 Allow opening the password reset link in a new window when its a URL 2016-05-31 14:22:19 +02:00
Roeland Douma f94c8b8c18 Merge pull request #24893 from owncloud/scanner-size-propagation-82
[8.2] trigger size calculation after scanning
2016-05-31 10:45:50 +02:00
Robin Appelman c163ac6620 trigger size calculation after scanning 2016-05-30 14:23:13 +02:00
Georg Ehrke d4addbf511 dont update search onResize (#24862)
this.updateSearch() sets the current file list instance and clears the box. This is unnecessary and makes the search box unsuable on some mobile devices where a keyboard fade-in causes a onResize trigger, which would then clear and blur the box.
2016-05-30 12:12:35 +02:00
Roeland Douma e20c49dab6 Merge pull request #24841 from owncloud/islocal-cache
[8.2] cache isLocal for shared storage
2016-05-30 08:12:01 +02:00
Robin Appelman 7f9b28f2c1 cache isLocal for shared storage 2016-05-25 14:56:29 +02:00
Vincent Petry c6acbb4e8b Merge pull request #24818 from owncloud/filesystem_check_changes-8.2
clarify filesystem_check_changes in config.sample.php
2016-05-25 09:40:29 +02:00
Carla Schroder aa3e4637b5 clarify filesystem_check_changes in config.sample.php 2016-05-24 08:19:05 -07:00
Roeland Douma 0130314102 [Stable8.2] Use a CappedCache in the user database backend (#24413)
* Use a CappedCache in the user database backend

When running with a user database backend on large installations the
cache can grow to significant sizes. This can be especially problematic
when running big cron/repair jobs.

* Allow indirect set in CappedMemoryCache
2016-05-24 14:19:27 +02:00
Vincent Petry 36aa4e8aea Merge pull request #24704 from owncloud/locking-mark-reload-free-82
[8.2] free up memory when releasing the last shared lock
2016-05-19 10:28:33 +02:00
Vincent Petry 4439adaf27 Merge pull request #24692 from owncloud/stable8.2-fixchunkttl
[stable8.2] Allow chunk GC mtime tolerance for unfinished part chunks
2016-05-18 18:19:58 +02:00
Robin Appelman 8beb496719 free up memory when releasing the last shared lock 2016-05-18 16:20:30 +02:00
Vincent Petry 9bd8bffc0c Allow chunk GC mtime tolerance for unfinished part chunks
Whenever part chunks are written, every fwrite in the write loop will
reset the mtime to the current mtime. Only at the end will the touch()
operation set the mtime to now + ttl, in the future.

However the GC code is expecting that every chunk with mtime < now are
old and must be deleted. This causes the GC to sometimes delete part
chunks in which the write loop is slow.

To fix this, a tolerance value is added in the GC code to allow for
more time before a part chunk gets deleted.
2016-05-18 13:57:26 +02:00
Thomas Müller 1450cb2c82 [stable8.2] Wait a while even after successful connect ... (#24535)
Wait a while even after successful connect ...
2016-05-17 21:45:39 +02:00
Vincent Petry 8a7c8c3a65 Merge pull request #24656 from owncloud/can-not-disable-server2server-sharing-anymore
Correctly load server2server sharing configs
2016-05-17 11:02:16 +02:00
Joas Schilling 7ef9cbd64a Correctly load server2server sharing configs 2016-05-17 09:46:09 +02:00
Vincent Petry d856793db0 Merge pull request #24391 from owncloud/capped-normalized-cache-82
[8.2] cap the normalized path cache
2016-05-13 16:17:30 +02:00
Vincent Petry 8cd410539e Merge pull request #24498 from owncloud/backport-20804-8.2
[stable8.2] LDAP: do not attempt to process user records without display name, fi…
2016-05-13 16:16:55 +02:00
Vincent Petry 9664a3b8cd Merge pull request #24504 from owncloud/stable8.2-updater-server-configurable
[stable8.2] Make update server URL configurable
2016-05-13 16:14:19 +02:00
C Montero-Luque 9bb7860146 8.2.5 2016-05-12 15:57:38 -04:00
Thomas Müller 7af233cf8c Merge pull request #24573 from owncloud/stable8.2_24568
[Stable 8.2] Fix etag propegation test race condition
2016-05-11 16:29:17 +02:00
Roeland Jago Douma c141f48c46 Fix test race condition
E-tag propagation replies on the mtime of the file. Order of events:

1. add file 'foo.txt' with content 'bar'
2. Set mtime to now() - 1
3. Check if etag changed.

Now this goes right often when 1 and 2 happen in the same second.
However imagine

1. add file 'foo.txt' with content 'bar' (at t=0.999)
2. Set mtime to now() - 1 (at t=1.001)

Now the mtime will be set to the same time. Thus not chaning the etag.
2016-05-11 14:55:44 +02:00
Thomas Müller 1203ebab9a Merge pull request #24555 from owncloud/kill-en@pirate-stable8.2
[stable8.2] Yo-ho-oh - Murder all band 'o pirates
2016-05-11 14:29:23 +02:00
Thomas Müller 4951e1dd0c Yo-ho-oh - Murder all band 'o pirates 2016-05-11 11:29:49 +02:00
Lukas Reschke fadc9872b7 Make update server URL configurable
Currently testing the updates is a big problem and not really super easy possible. Since we now have a new updater server we should also make this configurable so that people can properly test updates.
2016-05-09 12:05:29 +02:00
Arthur Schiwon a4e658df39 LDAP: do not attempt to process user records without display name, fixes fatal error 2016-05-09 11:11:03 +02:00
Björn Schießle d9163c29f3 first call the post_login hooks, before we call getUserFolder.
The login process needs to be completed before we can safely create
the users home folder. For example we need to give encryption a chance
to initialize the users encryption keys in order to copy the skeleton
files correctly
2016-05-03 14:22:26 +02:00
Thomas Müller a3a53075d8 Fixes #23899 2016-05-03 14:21:57 +02:00
Robin Appelman aab023b86c cap the normalized path cache 2016-05-02 15:25:31 +02:00
Morris Jobke f24f3b1bb9 Read available l10n files also from theme folder
The old behaviour was that only languages could be used for an app
that are already present in the apps/$app/l10n folder. If there is
a themed l10n that is not present in the apps default l10n folder
the language could not be used and the texts are not translated.

With this change this is possible and also the l10n files are
loaded even if the default l10n doesn't contain the l10n file.
2016-03-24 17:59:12 +01:00
49 changed files with 332 additions and 180 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
# Version: 8.2.5
# Version: 8.2.6
<IfModule mod_headers.c>
<IfModule mod_fcgid.c>
<IfModule mod_setenvif.c>
+3
View File
@@ -72,6 +72,9 @@ try {
} catch(\OCP\Files\NotFoundException $e) {
OCP\JSON::error(['data' => ['message' => 'File not found']]);
return;
} catch(\OCP\Files\StorageNotAvailableException $e) {
OCP\JSON::error(['data' => ['message' => 'Storage not available']]);
return;
}
if ($success) {
-2
View File
@@ -443,8 +443,6 @@
this.breadcrumb.setMaxWidth(containerWidth - actionsWidth - 10);
this.$table.find('>thead').width($('#app-content').width() - OC.Util.getScrollBarWidth());
this.updateSearch();
},
/**
-6
View File
@@ -1,6 +0,0 @@
OC.L10N.register(
"files",
{
"Download" : "Download"
},
"nplurals=2; plural=(n != 1);");
-4
View File
@@ -1,4 +0,0 @@
{ "translations": {
"Download" : "Download"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
-6
View File
@@ -1,6 +0,0 @@
OC.L10N.register(
"files_external",
{
"Password" : "Secret Code"
},
"nplurals=2; plural=(n != 1);");
-4
View File
@@ -1,4 +0,0 @@
{ "translations": {
"Password" : "Secret Code"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
-7
View File
@@ -1,7 +0,0 @@
OC.L10N.register(
"files_sharing",
{
"Password" : "Secret Code",
"Download" : "Download"
},
"nplurals=2; plural=(n != 1);");
-5
View File
@@ -1,5 +0,0 @@
{ "translations": {
"Password" : "Secret Code",
"Download" : "Download"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+8 -4
View File
@@ -44,6 +44,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
private $share; // the shared resource
private $files = array();
private static $isInitialized = array();
private $local = null;
/**
* @var \OC\Files\View
@@ -705,9 +706,12 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
}
public function isLocal() {
$this->init();
$ownerPath = $this->ownerView->getPath($this->share['item_source']);
list($targetStorage) = $this->ownerView->resolvePath($ownerPath);
return $targetStorage->isLocal();
if (!is_null($this->local)) {
$this->init();
$ownerPath = $this->ownerView->getPath($this->share['item_source']);
list($targetStorage) = $this->ownerView->resolvePath($ownerPath);
$this->local = $targetStorage->isLocal();
}
return $this->local;
}
}
@@ -122,6 +122,8 @@ class EtagPropagation extends PropagationTestCase {
public function testOwnerWritesToSingleFileShare() {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
Filesystem::file_put_contents('/foo.txt', 'bar');
$t = (int)Filesystem::filemtime('/foo.txt') - 1;
Filesystem::touch('/foo.txt', $t);
$this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4, self::TEST_FILES_SHARING_API_USER3]);
$this->assertEtagsChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2]);
+6 -4
View File
@@ -496,13 +496,15 @@ class Storage {
$files = $view->getDirectoryContent($dir);
foreach ($files as $file) {
$fileData = $file->getData();
$filePath = $dir . '/' . $fileData['name'];
if ($file['type'] === 'dir') {
array_push($dirs, $file['path']);
array_push($dirs, $filePath);
} else {
$versionsBegin = strrpos($file['path'], '.v');
$versionsBegin = strrpos($filePath, '.v');
$relPathStart = strlen(self::VERSIONS_ROOT);
$version = substr($file['path'], $versionsBegin + 2);
$relpath = substr($file['path'], $relPathStart, $versionsBegin - $relPathStart);
$version = substr($filePath, $versionsBegin + 2);
$relpath = substr($filePath, $relPathStart, $versionsBegin - $relPathStart);
$key = $version . '#' . $relpath;
$versions[$key] = array('path' => $relpath, 'timestamp' => $version);
}
+6 -2
View File
@@ -33,6 +33,7 @@ namespace OCA\user_ldap;
use OCA\user_ldap\lib\Access;
use OCA\user_ldap\lib\BackendUtility;
use OC\Cache\CappedMemoryCache;
class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
protected $enabled = false;
@@ -40,12 +41,12 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
/**
* @var string[] $cachedGroupMembers array of users with gid as key
*/
protected $cachedGroupMembers = array();
protected $cachedGroupMembers;
/**
* @var string[] $cachedGroupsByMember array of groups with uid as key
*/
protected $cachedGroupsByMember = array();
protected $cachedGroupsByMember;
public function __construct(Access $access) {
parent::__construct($access);
@@ -54,6 +55,9 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
if(!empty($filter) && !empty($gassoc)) {
$this->enabled = true;
}
$this->cachedGroupMembers = new CappedMemoryCache();
$this->cachedGroupsByMember = new CappedMemoryCache();
}
/**
-6
View File
@@ -1,6 +0,0 @@
OC.L10N.register(
"user_ldap",
{
"Password" : "Passcode"
},
"nplurals=2; plural=(n != 1);");
-4
View File
@@ -1,4 +0,0 @@
{ "translations": {
"Password" : "Passcode"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+8
View File
@@ -712,8 +712,16 @@ class Access extends LDAPUtility implements user\IUserTools {
* @param array $ldapRecords
*/
public function batchApplyUserAttributes(array $ldapRecords){
$displayNameAttribute = strtolower($this->connection->ldapUserDisplayName);
foreach($ldapRecords as $userRecord) {
if(!isset($userRecord[$displayNameAttribute])) {
// displayName is obligatory
continue;
}
$ocName = $this->dn2ocname($userRecord['dn'][0]);
if($ocName === false) {
continue;
}
$this->cacheUserExists($ocName);
$user = $this->userManager->get($ocName);
if($user instanceof OfflineUser) {
@@ -0,0 +1,72 @@
<?php
/**
* @author Arthur Schiwon <blizzz@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OCA\user_ldap\tests\integration\lib;
use OCA\User_LDAP\Mapping\UserMapping;
use OCA\user_ldap\tests\integration\AbstractIntegrationTest;
require_once __DIR__ . '/../../../../../lib/base.php';
class IntegrationTestBatchApplyUserAttributes extends AbstractIntegrationTest {
/**
* prepares the LDAP environment and sets up a test configuration for
* the LDAP backend.
*/
public function init() {
require(__DIR__ . '/../setup-scripts/createExplicitUsers.php');
require(__DIR__ . '/../setup-scripts/createUsersWithoutDisplayName.php');
parent::init();
$this->mapping = new UserMapping(\OC::$server->getDatabaseConnection());
$this->mapping->clear();
$this->access->setUserMapper($this->mapping);
}
/**
* sets up the LDAP configuration to be used for the test
*/
protected function initConnection() {
parent::initConnection();
$this->connection->setConfiguration([
'ldapUserDisplayName' => 'displayname',
]);
}
/**
* indirectly tests whether batchApplyUserAttributes does it job properly,
* when a user without display name is included in the result set from LDAP.
*
* @return bool
*/
protected function case1() {
$result = $this->access->fetchListOfUsers('objectclass=person', 'dn');
// on the original issue, PHP would emit a fatal error
// cannot catch it here, but will render the test as unsuccessful
return is_array($result) && !empty($result);
}
}
require_once(__DIR__ . '/../setup-scripts/config.php');
$test = new IntegrationTestBatchApplyUserAttributes($host, $port, $adn, $apwd, $bdn);
$test->init();
$test->run();
@@ -0,0 +1,59 @@
<?php
/**
* @author Arthur Schiwon <blizzz@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
if(php_sapi_name() !== 'cli') {
print('Only via CLI, please.');
exit(1);
}
include __DIR__ . '/config.php';
$cr = ldap_connect($host, $port);
ldap_set_option($cr, LDAP_OPT_PROTOCOL_VERSION, 3);
$ok = ldap_bind($cr, $adn, $apwd);
if (!$ok) {
die(ldap_error($cr));
}
$ouName = 'Users';
$ouDN = 'ou=' . $ouName . ',' . $bdn;
$users = ['robot'];
foreach ($users as $uid) {
$newDN = 'uid=' . $uid . ',' . $ouDN;
$fn = ucfirst($uid);
$sn = ucfirst(str_shuffle($uid)); // not so explicit but it's OK.
$entry = [];
$entry['cn'] = ucfirst($uid);
$entry['objectclass'][] = 'inetOrgPerson';
$entry['objectclass'][] = 'person';
$entry['sn'] = $sn;
$entry['userPassword'] = $uid;
$ok = ldap_add($cr, $newDN, $entry);
if ($ok) {
echo('created user ' . ': ' . $entry['cn'] . PHP_EOL);
} else {
die(ldap_error($cr));
}
}
+1 -1
View File
@@ -306,7 +306,7 @@ class Test_User_Ldap_Direct extends \Test\TestCase {
$access->expects($this->any())
->method('combineFilterWithAnd')
->will($this->returnCallback(function($param) {
return $param[1];
return $param[2];
}));
$access->expects($this->any())
+1
View File
@@ -172,6 +172,7 @@ class USER_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn
}
$filter = $this->access->combineFilterWithAnd(array(
$this->access->connection->ldapUserFilter,
$this->access->connection->ldapUserDisplayName . '=*',
$this->access->getFilterPartForUserSearch($search)
));
$attrs = array($this->access->connection->ldapUserDisplayName, 'dn');
+4 -3
View File
@@ -215,7 +215,7 @@ function execute_tests {
if [ ! -z "$USEDOCKER" ] ; then
echo "Fire up the postgres docker"
DOCKER_CONTAINER_ID=$(docker run -e POSTGRES_USER="$DATABASEUSER" -e POSTGRES_PASSWORD=owncloud -d postgres)
DATABASEHOST=$(docker inspect "$DOCKER_CONTAINER_ID" | grep IPAddress | cut -d '"' -f 4)
DATABASEHOST=$(docker inspect --format="{{.NetworkSettings.IPAddress}}" "$DOCKER_CONTAINER_ID")
echo "Waiting for Postgres initialisation ..."
@@ -230,14 +230,14 @@ function execute_tests {
if [ "$DB" == "oci" ] ; then
echo "Fire up the oracle docker"
DOCKER_CONTAINER_ID=$(docker run -d deepdiver/docker-oracle-xe-11g)
DATABASEHOST=$(docker inspect "$DOCKER_CONTAINER_ID" | grep IPAddress | cut -d '"' -f 4)
DATABASEHOST=$(docker inspect --format="{{.NetworkSettings.IPAddress}}" "$DOCKER_CONTAINER_ID")
echo "Waiting for Oracle initialization ... "
# Try to connect to the OCI host via sqlplus to ensure that the connection is already running
for i in {1..48}
do
if sqlplus "system/oracle@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=$DATABASEHOST)(Port=1521))(CONNECT_DATA=(SID=XE)))" < /dev/null | grep 'Connected to'; then
if sqlplus "autotest/owncloud@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=$DATABASEHOST)(Port=1521))(CONNECT_DATA=(SID=XE)))" < /dev/null | grep 'Connected to'; then
break;
fi
sleep 5
@@ -324,3 +324,4 @@ fi
# - DON'T TRY THIS AT HOME!
# - if you really need it: we feel sorry for you
#
+8 -2
View File
@@ -472,6 +472,11 @@ $CONFIG = array(
*/
'updatechecker' => true,
/**
* URL that ownCloud should use to look for updates
*/
'updater.server.url' => 'https://updates.owncloud.com/server/',
/**
* Is ownCloud connected to the Internet or running in a closed network?
*/
@@ -1050,8 +1055,9 @@ $CONFIG = array(
'quota_include_external_storage' => false,
/**
* Specifies how often the filesystem is checked for changes made outside
* ownCloud.
* Specifies how often the local filesystem (the ownCloud data/ directory, and
* NFS mounts in data/) is checked for changes made outside ownCloud. This
* does not apply to external storages.
*
* 0 -> Never check the filesystem for outside changes, provides a performance
* increase when it's certain that no changes are made directly to the
-6
View File
@@ -1,6 +0,0 @@
OC.L10N.register(
"core",
{
"Password" : "Passcode"
},
"nplurals=2; plural=(n != 1);");
-4
View File
@@ -1,4 +0,0 @@
{ "translations": {
"Password" : "Passcode"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+1 -1
View File
@@ -57,7 +57,7 @@ script('core', [
</p>
<?php if (!empty($_['invalidpassword']) && !empty($_['canResetPassword'])) { ?>
<a id="lost-password" class="warning" href="">
<a id="lost-password" class="warning" href="<?php p($_['resetPasswordLink']); ?>">
<?php p($l->t('Wrong password. Reset it?')); ?>
</a>
<?php } else if (!empty($_['invalidpassword'])) { ?>
-6
View File
@@ -1,6 +0,0 @@
OC.L10N.register(
"lib",
{
"web services under your control" : "web services under your control"
},
"nplurals=2; plural=(n != 1);");
-4
View File
@@ -1,4 +0,0 @@
{ "translations": {
"web services under your control" : "web services under your control"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+7 -1
View File
@@ -284,7 +284,13 @@ class AppConfig implements IAppConfig {
$sql->expr()->in('configkey', $sql->createParameter('legit_configs'))
))
->setParameter('appid', 'files_sharing', \PDO::PARAM_STR)
->setParameter('legit_configs', ['enabled', 'installed_version', 'types'], Connection::PARAM_STR_ARRAY);
->setParameter('legit_configs', [
'enabled',
'installed_version',
'types',
'incoming_server2server_share_enabled',
'outgoing_server2server_share_enabled',
], Connection::PARAM_STR_ARRAY);
$result = $sql->execute();
while ($row = $result->fetch()) {
+2 -2
View File
@@ -64,8 +64,8 @@ class CappedMemoryCache implements ICache, \ArrayAccess {
return $this->hasKey($offset);
}
public function offsetGet($offset) {
return $this->get($offset);
public function &offsetGet($offset) {
return $this->cache[$offset];
}
public function offsetSet($offset, $value) {
+3 -1
View File
@@ -170,7 +170,9 @@ class File implements ICache {
public function gc() {
$storage = $this->getStorage();
if ($storage and $storage->is_dir('/')) {
$now = time();
// extra hour safety, in case of stray part chunks that take longer to write,
// because touch() is only called after the chunk was finished
$now = time() - 3600;
$dh = $storage->opendir('/');
if (!is_resource($dh)) {
return null;
+2 -2
View File
@@ -261,7 +261,7 @@ class Scanner extends BasicEmitter {
$reuse = ($recursive === self::SCAN_SHALLOW) ? self::REUSE_ETAG | self::REUSE_SIZE : self::REUSE_ETAG;
}
if ($lock) {
$this->storage->acquireLock('scanner::' . $path, ILockingProvider::LOCK_EXCLUSIVE, $this->lockingProvider);
$this->lockingProvider->acquireLock('scanner::' . $this->storageId . '::' . $path, ILockingProvider::LOCK_EXCLUSIVE);
$this->storage->acquireLock($path, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
}
$data = $this->scanFile($path, $reuse, -1, null, $lock);
@@ -271,7 +271,7 @@ class Scanner extends BasicEmitter {
}
if ($lock) {
$this->storage->releaseLock($path, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
$this->storage->releaseLock('scanner::' . $path, ILockingProvider::LOCK_EXCLUSIVE, $this->lockingProvider);
$this->lockingProvider->releaseLock('scanner::' . $this->storageId . '::' . $path, ILockingProvider::LOCK_EXCLUSIVE);
}
return $data;
}
+4 -3
View File
@@ -189,8 +189,9 @@ class Updater {
list($targetStorage, $targetInternalPath) = $this->view->resolvePath($target);
if ($sourceStorage && $targetStorage) {
$targetCache = $targetStorage->getCache($sourceInternalPath);
if ($sourceStorage->getCache($sourceInternalPath)->inCache($sourceInternalPath)) {
$sourceCache = $sourceStorage->getCache($sourceInternalPath);
$targetCache = $targetStorage->getCache($targetInternalPath);
if ($sourceCache->inCache($sourceInternalPath)) {
if ($targetCache->inCache($targetInternalPath)) {
$targetCache->remove($targetInternalPath);
}
@@ -208,7 +209,7 @@ class Updater {
$targetCache->update($fileId, array('mimetype' => $mimeType));
}
$targetCache->correctFolderSize($sourceInternalPath);
$sourceCache->correctFolderSize($sourceInternalPath);
$targetCache->correctFolderSize($targetInternalPath);
$this->correctParentStorageMtime($sourceStorage, $sourceInternalPath);
$this->correctParentStorageMtime($targetStorage, $targetInternalPath);
+6 -1
View File
@@ -59,6 +59,7 @@
namespace OC\Files;
use OC\Cache\File;
use OC\Cache\CappedMemoryCache;
use OC\Files\Config\MountProviderCollection;
use OC\Files\Storage\StorageFactory;
use OCP\Files\Config\IMountProvider;
@@ -79,7 +80,7 @@ class Filesystem {
static private $usersSetup = array();
static private $normalizedPathCache = array();
static private $normalizedPathCache = null;
static private $listeningForProviders = false;
@@ -786,6 +787,10 @@ class Filesystem {
* @return string
*/
public static function normalizePath($path, $stripTrailingSlash = true, $isAbsolutePath = false) {
if (is_null(self::$normalizedPathCache)) {
self::$normalizedPathCache = new CappedMemoryCache();
}
/**
* FIXME: This is a workaround for existing classes and files which call
* this function with another type than a valid string. This
+1
View File
@@ -188,6 +188,7 @@ class MountPoint implements IMountPoint {
* @return string
*/
public function getInternalPath($path) {
$path = Filesystem::normalizePath($path);
if ($this->mountPoint === $path or $this->mountPoint . '/' === $path) {
$internalPath = '';
} else {
+6
View File
@@ -28,6 +28,7 @@ namespace OC\Files\Utils;
use OC\Files\View;
use OC\Files\Cache\ChangePropagator;
use OC\Files\Cache\Cache;
use OC\Files\Filesystem;
use OC\ForbiddenException;
use OC\Hooks\PublicEmitter;
@@ -176,6 +177,11 @@ class Scanner extends PublicEmitter {
}
try {
$scanner->scan($relativePath, \OC\Files\Cache\Scanner::SCAN_RECURSIVE, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE);
$cache = $storage->getCache();
if ($cache instanceof Cache) {
// only re-calculate for the root folder we scanned, anything below that is taken care of by the scanner
$cache->correctFolderSize($relativePath);
}
} catch (StorageNotAvailableException $e) {
$this->logger->error('Storage ' . $storage->getId() . ' not available');
$this->logger->logException($e);
+25 -9
View File
@@ -190,15 +190,15 @@ class OC_L10N implements \OCP\IL10N {
)
&& file_exists($transFile)) {
// load the translations file
if($this->load($transFile)) {
//merge with translations from theme
$theme = \OC::$server->getConfig()->getSystemValue('theme');
if (!empty($theme)) {
$transFile = OC::$SERVERROOT.'/themes/'.$theme.substr($transFile, strlen(OC::$SERVERROOT));
if (file_exists($transFile)) {
$this->load($transFile, true);
}
}
$this->load($transFile);
}
//merge with translations from theme
$theme = \OC::$server->getConfig()->getSystemValue('theme');
if (!empty($theme)) {
$transFile = OC::$SERVERROOT.'/themes/'.$theme.substr($transFile, strlen(OC::$SERVERROOT));
if (file_exists($transFile)) {
$this->load($transFile, true);
}
}
@@ -480,6 +480,22 @@ class OC_L10N implements \OCP\IL10N {
}
}
$config = \OC::$server->getConfig();
// merge with translations from theme
$theme = $config->getSystemValue('theme');
if(!empty($theme)) {
$themeDir = \OC::$SERVERROOT . '/themes/' . $theme . substr($dir, strlen(\OC::$SERVERROOT));
if(is_dir($themeDir)) {
$files=scandir($dir);
foreach($files as $file) {
if(substr($file, -5, 5) === '.json' && substr($file, 0, 4) !== 'l10n') {
$i = substr($file, 0, -5);
$available[] = $i;
}
}
}
}
self::$availableLanguages[$app] = $available;
return $available;
}
@@ -77,6 +77,9 @@ abstract class AbstractLockingProvider implements ILockingProvider {
if ($type === self::LOCK_SHARED) {
if (isset($this->acquiredLocks['shared'][$path]) and $this->acquiredLocks['shared'][$path] > 0) {
$this->acquiredLocks['shared'][$path]--;
if ($this->acquiredLocks['shared'][$path] === 0) {
unset($this->acquiredLocks['shared'][$path]);
}
}
} else if ($type === self::LOCK_EXCLUSIVE) {
unset($this->acquiredLocks['exclusive'][$path]);
+2 -5
View File
@@ -126,19 +126,16 @@ class Updater extends BasicEmitter {
/**
* Check if a new version is available
*
* @param string $updaterUrl the url to check, i.e. 'http://apps.owncloud.com/updater.php'
* @return array|bool
*/
public function check($updaterUrl = null) {
public function check() {
// Look up the cache - it is invalidated all 30 minutes
if (((int)$this->config->getAppValue('core', 'lastupdatedat') + 1800) > time()) {
return json_decode($this->config->getAppValue('core', 'lastupdateResult'), true);
}
if (is_null($updaterUrl)) {
$updaterUrl = 'https://updates.owncloud.com/server/';
}
$updaterUrl = $this->config->getSystemValue('updater.server.url', 'https://updates.owncloud.com/server/');
$this->config->setAppValue('core', 'lastupdatedat', time());
+9 -1
View File
@@ -287,8 +287,16 @@ class OC_User {
self::setUserId($uid);
self::setDisplayName($uid);
self::getUserSession()->setLoginName($uid);
// setup the filesystem
OC_Util::setupFS($uid);
// first call the post_login hooks, the login-process needs to be
// completed before we can safely create the users folder.
// For example encryption needs to initialize the users keys first
// before we can create the user folder with the skeleton files
OC_Hook::emit("OC_User", "post_login", array("uid" => $uid, 'password' => ''));
//trigger creation of user home and /files folder
\OC::$server->getUserFolder($uid);
}
return true;
}
+11 -1
View File
@@ -48,11 +48,21 @@
*
*/
use OC\Cache\CappedMemoryCache;
/**
* Class for user management in a SQL Database (e.g. MySQL, SQLite)
*/
class OC_User_Database extends OC_User_Backend implements \OCP\IUserBackend {
private $cache = array();
/** @var CappedMemoryCache */
private $cache;
/**
* OC_User_Database constructor.
*/
public function __construct() {
$this->cache = new CappedMemoryCache();
}
/**
* Create a new user
+2 -1
View File
@@ -948,7 +948,8 @@ class OC_Util {
}
$parameters['canResetPassword'] = true;
if (!\OC::$server->getSystemConfig()->getValue('lost_password_link')) {
$parameters['resetPasswordLink'] = \OC::$server->getSystemConfig()->getValue('lost_password_link', '');
if (!$parameters['resetPasswordLink']) {
if (isset($_REQUEST['user'])) {
$user = \OC::$server->getUserManager()->get($_REQUEST['user']);
if ($user instanceof \OCP\IUser) {
+2
View File
@@ -42,6 +42,8 @@ use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
try {
OC_App::loadApps(['session']);
OC_App::loadApps(['authentication']);
// load all apps to get all api routes properly setup
OC_App::loadApps();
+13
View File
@@ -94,6 +94,19 @@ $externalBackends = (count($backends) > 1) ? true : false;
$template->assign('encryptionReady', \OC::$server->getEncryptionManager()->isReady());
$template->assign('externalBackendsEnabled', $externalBackends);
/** @var \Doctrine\DBAL\Connection $connection */
$connection = \OC::$server->getDatabaseConnection();
try {
if ($connection->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\SqlitePlatform) {
$template->assign('invalidTransactionIsolationLevel', false);
} else {
$template->assign('invalidTransactionIsolationLevel', $connection->getTransactionIsolation() !== \Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED);
}
} catch (\Doctrine\DBAL\DBALException $e) {
// ignore
$template->assign('invalidTransactionIsolationLevel', false);
}
$encryptionModules = \OC::$server->getEncryptionManager()->getEncryptionModules();
$defaultEncryptionModuleId = \OC::$server->getEncryptionManager()->getDefaultEncryptionModuleId();
-6
View File
@@ -1,6 +0,0 @@
OC.L10N.register(
"settings",
{
"Password" : "Passcode"
},
"nplurals=2; plural=(n != 1);");
-4
View File
@@ -1,4 +0,0 @@
{ "translations": {
"Password" : "Passcode"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+9
View File
@@ -97,6 +97,15 @@ if (!$_['isAnnotationsWorking']) {
<?php
}
// Is the Transaction isolation level READ_COMMITED?
if ($_['invalidTransactionIsolationLevel']) {
?>
<li>
<?php p($l->t('Your database does not run with "READ COMMITED" transaction isolation level. This can cause problems when multiple actions are executed in parallel.')); ?>
</li>
<?php
}
// Windows Warning
if ($_['WindowsWarning']) {
?>
+12
View File
@@ -64,4 +64,16 @@ class CappedMemoryCache extends \Test_Cache {
$this->assertFalse($this->instance->hasKey('2_value1'));
$this->assertFalse($this->instance->hasKey('3_value1'));
}
function testIndirectSet() {
$this->instance->set('array', []);
$this->instance['array'][] = 'foo';
$this->assertEquals(['foo'], $this->instance->get('array'));
$this->instance['array']['bar'] = 'qwerty';
$this->assertEquals(['foo', 'bar' => 'qwerty'], $this->instance->get('array'));
}
}
+31 -59
View File
@@ -202,20 +202,25 @@ class UpdaterTest extends \Test\TestCase {
->will($this->returnValue(0));
$this->config
->expects($this->at(1))
->method('getSystemValue')
->with('updater.server.url', 'https://updates.owncloud.com/server/')
->willReturn('https://updates.owncloud.com/server/');
$this->config
->expects($this->at(2))
->method('setAppValue')
->with('core', 'lastupdatedat', $this->isType('integer'));
$this->config
->expects($this->at(3))
->expects($this->at(4))
->method('getAppValue')
->with('core', 'installedat')
->will($this->returnValue('installedat'));
$this->config
->expects($this->at(4))
->expects($this->at(5))
->method('getAppValue')
->with('core', 'lastupdatedat')
->will($this->returnValue('lastupdatedat'));
$this->config
->expects($this->at(5))
->expects($this->at(6))
->method('setAppValue')
->with('core', 'lastupdateResult', json_encode($expectedResult));
@@ -243,20 +248,25 @@ class UpdaterTest extends \Test\TestCase {
->will($this->returnValue(0));
$this->config
->expects($this->at(1))
->method('getSystemValue')
->with('updater.server.url', 'https://updates.owncloud.com/server/')
->willReturn('https://updates.owncloud.com/server/');
$this->config
->expects($this->at(2))
->method('setAppValue')
->with('core', 'lastupdatedat', $this->isType('integer'));
$this->config
->expects($this->at(3))
->expects($this->at(4))
->method('getAppValue')
->with('core', 'installedat')
->will($this->returnValue('installedat'));
$this->config
->expects($this->at(4))
->expects($this->at(5))
->method('getAppValue')
->with('core', 'lastupdatedat')
->will($this->returnValue('lastupdatedat'));
$this->config
->expects($this->at(5))
->expects($this->at(6))
->method('setAppValue')
->with('core', 'lastupdateResult', 'false');
@@ -270,54 +280,6 @@ class UpdaterTest extends \Test\TestCase {
$this->assertSame([], $this->updater->check());
}
public function testCheckWithUpdateUrl() {
$expectedResult = [
'version' => '8.0.4.2',
'versionstring' => 'ownCloud 8.0.4',
'url' => 'https://download.owncloud.org/community/owncloud-8.0.4.zip',
'web' => 'http://doc.owncloud.org/server/8.0/admin_manual/maintenance/upgrade.html',
];
$this->config
->expects($this->at(0))
->method('getAppValue')
->with('core', 'lastupdatedat')
->will($this->returnValue(0));
$this->config
->expects($this->at(1))
->method('setAppValue')
->with('core', 'lastupdatedat', $this->isType('integer'));
$this->config
->expects($this->at(3))
->method('getAppValue')
->with('core', 'installedat')
->will($this->returnValue('installedat'));
$this->config
->expects($this->at(4))
->method('getAppValue')
->with('core', 'lastupdatedat')
->will($this->returnValue('lastupdatedat'));
$this->config
->expects($this->at(5))
->method('setAppValue')
->with('core', 'lastupdateResult', json_encode($expectedResult));
$updateXml = '<?xml version="1.0"?>
<owncloud>
<version>8.0.4.2</version>
<versionstring>ownCloud 8.0.4</versionstring>
<url>https://download.owncloud.org/community/owncloud-8.0.4.zip</url>
<web>http://doc.owncloud.org/server/8.0/admin_manual/maintenance/upgrade.html</web>
</owncloud>';
$this->httpHelper
->expects($this->once())
->method('getUrlContent')
->with($this->buildUpdateUrl('https://myupdater.com/'))
->will($this->returnValue($updateXml));
$this->assertSame($expectedResult, $this->updater->check('https://myupdater.com/'));
}
public function testCheckWithEmptyValidXmlResponse() {
$expectedResult = [
'version' => '',
@@ -333,15 +295,20 @@ class UpdaterTest extends \Test\TestCase {
->will($this->returnValue(0));
$this->config
->expects($this->at(1))
->method('getSystemValue')
->with('updater.server.url', 'https://updates.owncloud.com/server/')
->willReturn('https://updates.owncloud.com/server/');
$this->config
->expects($this->at(2))
->method('setAppValue')
->with('core', 'lastupdatedat', $this->isType('integer'));
$this->config
->expects($this->at(3))
->expects($this->at(4))
->method('getAppValue')
->with('core', 'installedat')
->will($this->returnValue('installedat'));
$this->config
->expects($this->at(4))
->expects($this->at(5))
->method('getAppValue')
->with('core', 'lastupdatedat')
->will($this->returnValue('lastupdatedat'));
@@ -372,20 +339,25 @@ class UpdaterTest extends \Test\TestCase {
->will($this->returnValue(0));
$this->config
->expects($this->at(1))
->method('getSystemValue')
->with('updater.server.url', 'https://updates.owncloud.com/server/')
->willReturn('https://updates.owncloud.com/server/');
$this->config
->expects($this->at(2))
->method('setAppValue')
->with('core', 'lastupdatedat', $this->isType('integer'));
$this->config
->expects($this->at(3))
->expects($this->at(4))
->method('getAppValue')
->with('core', 'installedat')
->will($this->returnValue('installedat'));
$this->config
->expects($this->at(4))
->expects($this->at(5))
->method('getAppValue')
->with('core', 'lastupdatedat')
->will($this->returnValue('lastupdatedat'));
$this->config
->expects($this->at(5))
->expects($this->at(6))
->method('setAppValue')
->with('core', 'lastupdateResult', json_encode($expectedResult));
+2 -2
View File
@@ -25,10 +25,10 @@
// We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel
// when updating major/minor version number.
$OC_Version = array(8, 2, 5, 1);
$OC_Version = array(8, 2, 6, 1);
// The human readable string
$OC_VersionString = '8.2.5 RC2';
$OC_VersionString = '8.2.6 RC1';
$OC_VersionCanBeUpgradedFrom = array(8, 1);