Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5b39016db4 | |||
| 908d358670 | |||
| d17b4742a8 | |||
| 680ee05047 | |||
| 83128646f1 | |||
| 9df60c7956 | |||
| 35e2407f1d | |||
| 71992dcb18 | |||
| f882f6b551 | |||
| 8e640faf3a | |||
| 5a8278d9e6 | |||
| 12098383cc | |||
| b92831943d | |||
| 8b48a8f560 | |||
| ef6e26cb30 | |||
| f582521f12 | |||
| f8d819fbd0 | |||
| e8e24cbe6c | |||
| 0d5f56b465 | |||
| c1257761f1 | |||
| ed3d970322 | |||
| 31a37d4f19 | |||
| f94c8b8c18 | |||
| c163ac6620 | |||
| d4addbf511 | |||
| e20c49dab6 | |||
| 7f9b28f2c1 | |||
| c6acbb4e8b | |||
| aa3e4637b5 | |||
| 0130314102 | |||
| 36aa4e8aea | |||
| 4439adaf27 | |||
| 8beb496719 | |||
| 9bd8bffc0c | |||
| 1450cb2c82 | |||
| 8a7c8c3a65 | |||
| 7ef9cbd64a | |||
| d856793db0 | |||
| 8cd410539e | |||
| 9664a3b8cd | |||
| 9bb7860146 | |||
| 7af233cf8c | |||
| c141f48c46 | |||
| 1203ebab9a | |||
| 4951e1dd0c | |||
| fadc9872b7 | |||
| a4e658df39 | |||
| d9163c29f3 | |||
| a3a53075d8 | |||
| aab023b86c | |||
| f24f3b1bb9 |
@@ -1,4 +1,4 @@
|
||||
# Version: 8.2.5
|
||||
# Version: 8.2.6
|
||||
<IfModule mod_headers.c>
|
||||
<IfModule mod_fcgid.c>
|
||||
<IfModule mod_setenvif.c>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -443,8 +443,6 @@
|
||||
this.breadcrumb.setMaxWidth(containerWidth - actionsWidth - 10);
|
||||
|
||||
this.$table.find('>thead').width($('#app-content').width() - OC.Util.getScrollBarWidth());
|
||||
|
||||
this.updateSearch();
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"files",
|
||||
{
|
||||
"Download" : "Download"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
@@ -1,4 +0,0 @@
|
||||
{ "translations": {
|
||||
"Download" : "Download"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"files_external",
|
||||
{
|
||||
"Password" : "Secret Code"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
@@ -1,4 +0,0 @@
|
||||
{ "translations": {
|
||||
"Password" : "Secret Code"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"files_sharing",
|
||||
{
|
||||
"Password" : "Secret Code",
|
||||
"Download" : "Download"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
@@ -1,5 +0,0 @@
|
||||
{ "translations": {
|
||||
"Password" : "Secret Code",
|
||||
"Download" : "Download"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -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]);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"user_ldap",
|
||||
{
|
||||
"Password" : "Passcode"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
@@ -1,4 +0,0 @@
|
||||
{ "translations": {
|
||||
"Password" : "Passcode"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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())
|
||||
|
||||
@@ -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
@@ -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
|
||||
#
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"core",
|
||||
{
|
||||
"Password" : "Passcode"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
@@ -1,4 +0,0 @@
|
||||
{ "translations": {
|
||||
"Password" : "Passcode"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -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'])) { ?>
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"lib",
|
||||
{
|
||||
"web services under your control" : "web services under your control"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
@@ -1,4 +0,0 @@
|
||||
{ "translations": {
|
||||
"web services under your control" : "web services under your control"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
Vendored
+3
-1
@@ -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;
|
||||
|
||||
Vendored
+2
-2
@@ -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;
|
||||
}
|
||||
|
||||
Vendored
+4
-3
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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]);
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"settings",
|
||||
{
|
||||
"Password" : "Passcode"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
@@ -1,4 +0,0 @@
|
||||
{ "translations": {
|
||||
"Password" : "Passcode"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user