summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/files/appinfo/update.php8
-rw-r--r--apps/files/js/file-upload.js15
-rw-r--r--apps/files/tests/ajax_rename.php2
-rw-r--r--apps/files/tests/helper.php3
-rw-r--r--apps/files/tests/js/filelistSpec.js2
-rw-r--r--apps/files_encryption/lib/helper.php4
-rwxr-xr-xapps/files_encryption/tests/crypt.php19
-rw-r--r--apps/files_external/lib/config.php2
-rw-r--r--apps/files_external/lib/config/configadapter.php5
-rw-r--r--apps/files_external/lib/sftp.php2
-rw-r--r--apps/files_external/templates/settings.php2
-rw-r--r--apps/files_external/tests/js/mountsfilelistSpec.js2
-rw-r--r--apps/files_sharing/lib/external/storage.php8
-rw-r--r--apps/files_sharing/lib/helper.php4
-rw-r--r--apps/files_sharing/tests/api.php9
-rw-r--r--apps/files_sharing/tests/helper.php2
-rw-r--r--apps/files_sharing/tests/share.php2
-rw-r--r--apps/files_trashbin/lib/helper.php6
-rw-r--r--apps/files_trashbin/lib/trashbin.php2
-rw-r--r--apps/user_ldap/appinfo/update.php30
-rw-r--r--apps/user_ldap/lib/access.php2
-rw-r--r--apps/user_ldap/user_ldap.php2
-rw-r--r--config/config.sample.php14
-rw-r--r--core/js/installation.js5
-rw-r--r--core/js/js.js29
-rw-r--r--core/templates/installation.php6
-rw-r--r--core/templates/login.php13
-rw-r--r--lib/base.php2
-rw-r--r--lib/private/connector/sabre/directory.php2
-rw-r--r--lib/private/connector/sabre/objecttree.php6
-rw-r--r--lib/private/files/fileinfo.php21
-rw-r--r--lib/private/files/mount/mountpoint.php33
-rw-r--r--lib/private/files/node/node.php4
-rw-r--r--lib/private/files/view.php48
-rw-r--r--lib/private/image.php2
-rw-r--r--lib/private/memcache/factory.php4
-rw-r--r--lib/private/memcache/redis.php94
-rw-r--r--lib/private/preview.php5
-rw-r--r--lib/private/template.php2
-rw-r--r--lib/private/util.php34
-rw-r--r--lib/public/files/fileinfo.php7
-rw-r--r--lib/public/files/mount/imountpoint.php9
-rw-r--r--settings/application.php13
-rw-r--r--settings/controller/userscontroller.php88
-rw-r--r--settings/js/personal.js1
-rw-r--r--settings/js/users/users.js23
-rw-r--r--settings/templates/email.new_user.php36
-rw-r--r--settings/templates/email.new_user_plain_text.php10
-rw-r--r--settings/templates/personal.php1
-rw-r--r--settings/templates/users/main.php6
-rw-r--r--settings/templates/users/part.createuser.php3
-rw-r--r--tests/lib/connector/sabre/file.php16
-rw-r--r--tests/lib/connector/sabre/objecttree.php2
-rw-r--r--tests/lib/files/node/file.php2
-rw-r--r--tests/lib/files/node/folder.php2
-rw-r--r--tests/lib/files/node/node.php2
-rw-r--r--tests/lib/files/node/root.php2
-rw-r--r--tests/lib/memcache/redis.php29
-rw-r--r--tests/settings/controller/userscontrollertest.php70
59 files changed, 635 insertions, 144 deletions
diff --git a/apps/files/appinfo/update.php b/apps/files/appinfo/update.php
deleted file mode 100644
index de635e5ce6b..00000000000
--- a/apps/files/appinfo/update.php
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-
-// this drops the keys below, because they aren't needed anymore
-// core related
-if (version_compare(\OCP\Config::getSystemValue('version', '0.0.0'), '7.0.0', '<')) {
- \OCP\Config::deleteSystemValue('allowZipDownload');
- \OCP\Config::deleteSystemValue('maxZipInputSize');
-}
diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js
index c8b3a150caa..8b0753fc647 100644
--- a/apps/files/js/file-upload.js
+++ b/apps/files/js/file-upload.js
@@ -501,6 +501,21 @@ OC.Upload = {
}
});
+ } else {
+ // for all browsers that don't support the progress bar
+ // IE 8 & 9
+
+ // show a spinner
+ fileupload.on('fileuploadstart', function() {
+ $('#upload').addClass('icon-loading');
+ $('#upload .icon-upload').hide();
+ });
+
+ // hide a spinner
+ fileupload.on('fileuploadstop fileuploadfail', function() {
+ $('#upload').removeClass('icon-loading');
+ $('#upload .icon-upload').show();
+ });
}
}
diff --git a/apps/files/tests/ajax_rename.php b/apps/files/tests/ajax_rename.php
index 48aed05823b..1cfecf9e58c 100644
--- a/apps/files/tests/ajax_rename.php
+++ b/apps/files/tests/ajax_rename.php
@@ -107,7 +107,7 @@ class Test_OC_Files_App_Rename extends \Test\TestCase {
'etag' => 'abcdef',
'directory' => '/',
'name' => 'new_name',
- ))));
+ ), null)));
$result = $this->files->rename($dir, $oldname, $newname);
diff --git a/apps/files/tests/helper.php b/apps/files/tests/helper.php
index 1b7c8eef43a..ea96e41d1d1 100644
--- a/apps/files/tests/helper.php
+++ b/apps/files/tests/helper.php
@@ -24,7 +24,8 @@ class Test_Files_Helper extends \Test\TestCase {
'mtime' => $mtime,
'type' => $isDir ? 'dir' : 'file',
'mimetype' => $isDir ? 'httpd/unix-directory' : 'application/octet-stream'
- )
+ ),
+ null
);
}
diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js
index 6c83f214c39..6dafa262715 100644
--- a/apps/files/tests/js/filelistSpec.js
+++ b/apps/files/tests/js/filelistSpec.js
@@ -275,7 +275,7 @@ describe('OCA.Files.FileList tests', function() {
mtime: -1
};
var $tr = fileList.add(fileData);
- expect($tr.find('.date').text()).toEqual('?');
+ expect($tr.find('.date .modified').text()).toEqual('?');
});
it('adds new file to the end of the list', function() {
var $tr;
diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php
index 6a8ea25d44e..b9d45f67363 100644
--- a/apps/files_encryption/lib/helper.php
+++ b/apps/files_encryption/lib/helper.php
@@ -427,7 +427,7 @@ class Helper {
*/
public static function getOpenSSLConfig() {
$config = array('private_key_bits' => 4096);
- $config = array_merge(\OCP\Config::getSystemValue('openssl', array()), $config);
+ $config = array_merge(\OC::$server->getConfig()->getSystemValue('openssl', array()), $config);
return $config;
}
@@ -460,7 +460,7 @@ class Helper {
*/
public static function getCipher() {
- $cipher = \OCP\Config::getSystemValue('cipher', Crypt::DEFAULT_CIPHER);
+ $cipher = \OC::$server->getConfig()->getSystemValue('cipher', Crypt::DEFAULT_CIPHER);
if ($cipher !== 'AES-256-CFB' && $cipher !== 'AES-128-CFB') {
\OCP\Util::writeLog('files_encryption',
diff --git a/apps/files_encryption/tests/crypt.php b/apps/files_encryption/tests/crypt.php
index 451fa62fe57..3165279c558 100755
--- a/apps/files_encryption/tests/crypt.php
+++ b/apps/files_encryption/tests/crypt.php
@@ -30,6 +30,9 @@ class Crypt extends TestCase {
public $genPrivateKey;
public $genPublicKey;
+ /** @var \OCP\IConfig */
+ private $config;
+
public static function setUpBeforeClass() {
parent::setUpBeforeClass();
@@ -65,6 +68,8 @@ class Crypt extends TestCase {
// we don't want to tests with app files_trashbin enabled
\OC_App::disable('files_trashbin');
+
+ $this->config = \OC::$server->getConfig();
}
protected function tearDown() {
@@ -76,7 +81,7 @@ class Crypt extends TestCase {
}
$this->assertTrue(\OC_FileProxy::$enabled);
- \OCP\Config::deleteSystemValue('cipher');
+ $this->config->deleteSystemValue('cipher');
parent::tearDown();
}
@@ -198,14 +203,14 @@ class Crypt extends TestCase {
$filename = 'tmp-' . $this->getUniqueID() . '.test';
- \OCP\Config::setSystemValue('cipher', 'AES-128-CFB');
+ $this->config->setSystemValue('cipher', 'AES-128-CFB');
$cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/'. $filename, $this->dataShort);
// Test that data was successfully written
$this->assertTrue(is_int($cryptedFile));
- \OCP\Config::deleteSystemValue('cipher');
+ $this->config->deleteSystemValue('cipher');
// Disable encryption proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy::$enabled;
@@ -282,7 +287,7 @@ class Crypt extends TestCase {
// Generate a a random filename
$filename = 'tmp-' . $this->getUniqueID() . '.test';
- \OCP\Config::setSystemValue('cipher', 'AES-128-CFB');
+ $this->config->setSystemValue('cipher', 'AES-128-CFB');
// Save long data as encrypted file using stream wrapper
$cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong . $this->dataLong);
@@ -294,7 +299,7 @@ class Crypt extends TestCase {
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
- \OCP\Config::deleteSystemValue('cipher');
+ $this->config->deleteSystemValue('cipher');
// Get file contents without using any wrapper to get it's actual contents on disk
$retreivedCryptedFile = $this->view->file_get_contents($this->userId . '/files/' . $filename);
@@ -326,12 +331,12 @@ class Crypt extends TestCase {
// Generate a a random filename
$filename = 'tmp-' . $this->getUniqueID() . '.test';
- \OCP\Config::setSystemValue('cipher', 'AES-128-CFB');
+ $this->config->setSystemValue('cipher', 'AES-128-CFB');
// Save long data as encrypted file using stream wrapper
$cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong . $this->dataLong);
- \OCP\Config::deleteSystemValue('cipher');
+ $this->config->deleteSystemValue('cipher');
// Test that data was successfully written
$this->assertTrue(is_int($cryptedFile));
diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php
index f09b29a522b..823c0bcbfc1 100644
--- a/apps/files_external/lib/config.php
+++ b/apps/files_external/lib/config.php
@@ -862,7 +862,7 @@ class OC_Mount_Config {
include('Crypt/AES.php');
}
$cipher = new Crypt_AES(CRYPT_AES_MODE_CBC);
- $cipher->setKey(\OCP\Config::getSystemValue('passwordsalt'));
+ $cipher->setKey(\OC::$server->getConfig()->getSystemValue('passwordsalt', null));
return $cipher;
}
diff --git a/apps/files_external/lib/config/configadapter.php b/apps/files_external/lib/config/configadapter.php
index 6294e27a774..de484a44698 100644
--- a/apps/files_external/lib/config/configadapter.php
+++ b/apps/files_external/lib/config/configadapter.php
@@ -33,10 +33,11 @@ class ConfigAdapter implements IMountProvider {
$objectClass = $options['options']['objectstore']['class'];
$options['options']['objectstore'] = new $objectClass($options['options']['objectstore']);
}
+ $mountOptions = isset($options['mountOptions']) ? $options['mountOptions'] : [];
if (isset($options['personal']) && $options['personal']) {
- $mounts[] = new PersonalMount($options['class'], $mountPoint, $options['options'], $loader);
+ $mounts[] = new PersonalMount($options['class'], $mountPoint, $options['options'], $loader, $mountOptions);
} else {
- $mounts[] = new MountPoint($options['class'], $mountPoint, $options['options'], $loader);
+ $mounts[] = new MountPoint($options['class'], $mountPoint, $options['options'], $loader, $mountOptions);
}
}
return $mounts;
diff --git a/apps/files_external/lib/sftp.php b/apps/files_external/lib/sftp.php
index f0a6f145422..f6c56669734 100644
--- a/apps/files_external/lib/sftp.php
+++ b/apps/files_external/lib/sftp.php
@@ -112,7 +112,7 @@ class SFTP extends \OC\Files\Storage\Common {
try {
$storage_view = \OCP\Files::getStorage('files_external');
if ($storage_view) {
- return \OCP\Config::getSystemValue('datadirectory') .
+ return \OC::$server->getConfig()->getSystemValue('datadirectory') .
$storage_view->getAbsolutePath('') .
'ssh_hostKeys';
}
diff --git a/apps/files_external/templates/settings.php b/apps/files_external/templates/settings.php
index 072f856dfbd..79950f30385 100644
--- a/apps/files_external/templates/settings.php
+++ b/apps/files_external/templates/settings.php
@@ -76,7 +76,7 @@
<?php endif; ?>
<?php endif; ?>
<?php endforeach; ?>
- <?php if (isset($_['backends'][$mount['class']]['custom']) && !in_array('files_external/js/'.$_['backends'][$mount['class']]['custom'], \OC_Util::$scripts)): ?>
+ <?php if (isset($_['backends'][$mount['class']]['custom'])): ?>
<?php OCP\Util::addScript('files_external', $_['backends'][$mount['class']]['custom']); ?>
<?php endif; ?>
<?php endif; ?>
diff --git a/apps/files_external/tests/js/mountsfilelistSpec.js b/apps/files_external/tests/js/mountsfilelistSpec.js
index 50603081b6a..a4e4fec1177 100644
--- a/apps/files_external/tests/js/mountsfilelistSpec.js
+++ b/apps/files_external/tests/js/mountsfilelistSpec.js
@@ -144,7 +144,7 @@ describe('OCA.External.FileList tests', function() {
'?dir=/mount%20points/smb%20mount'
);
expect($tr.find('.nametext').text().trim()).toEqual('smb mount');
- expect($tr.find('.column-scope').text().trim()).toEqual('Personal');
+ expect($tr.find('.column-scope > span').text().trim()).toEqual('Personal');
expect($tr.find('.column-backend').text().trim()).toEqual('SMB');
});
diff --git a/apps/files_sharing/lib/external/storage.php b/apps/files_sharing/lib/external/storage.php
index 3f1d631a35f..306a7b8db8a 100644
--- a/apps/files_sharing/lib/external/storage.php
+++ b/apps/files_sharing/lib/external/storage.php
@@ -167,6 +167,14 @@ class Storage extends DAV implements ISharedStorage {
}
}
+ public function file_exists($path) {
+ if ($path === '') {
+ return true;
+ } else {
+ return parent::file_exists($path);
+ }
+ }
+
/**
* check if the configured remote is a valid ownCloud instance
*
diff --git a/apps/files_sharing/lib/helper.php b/apps/files_sharing/lib/helper.php
index c83debe952f..71519bd1d4a 100644
--- a/apps/files_sharing/lib/helper.php
+++ b/apps/files_sharing/lib/helper.php
@@ -280,7 +280,7 @@ class Helper {
* @return string
*/
public static function getShareFolder() {
- $shareFolder = \OCP\Config::getSystemValue('share_folder', '/');
+ $shareFolder = \OC::$server->getConfig()->getSystemValue('share_folder', '/');
return \OC\Files\Filesystem::normalizePath($shareFolder);
}
@@ -291,7 +291,7 @@ class Helper {
* @param string $shareFolder
*/
public static function setShareFolder($shareFolder) {
- \OCP\Config::setSystemValue('share_folder', $shareFolder);
+ \OC::$server->getConfig()->setSystemValue('share_folder', $shareFolder);
}
}
diff --git a/apps/files_sharing/tests/api.php b/apps/files_sharing/tests/api.php
index dd6de15010f..278e7130199 100644
--- a/apps/files_sharing/tests/api.php
+++ b/apps/files_sharing/tests/api.php
@@ -948,10 +948,11 @@ class Test_Files_Sharing_Api extends TestCase {
function testUpdateShareExpireDate() {
$fileInfo = $this->view->getFileInfo($this->folder);
+ $config = \OC::$server->getConfig();
// enforce expire date, by default 7 days after the file was shared
- \OCP\Config::setAppValue('core', 'shareapi_default_expire_date', 'yes');
- \OCP\Config::setAppValue('core', 'shareapi_enforce_expire_date', 'yes');
+ $config->setAppValue('core', 'shareapi_default_expire_date', 'yes');
+ $config->setAppValue('core', 'shareapi_enforce_expire_date', 'yes');
$dateWithinRange = new \DateTime();
$dateWithinRange->add(new \DateInterval('P5D'));
@@ -1008,8 +1009,8 @@ class Test_Files_Sharing_Api extends TestCase {
$this->assertEquals($dateWithinRange->format('Y-m-d') . ' 00:00:00', $updatedLinkShare['expiration']);
// cleanup
- \OCP\Config::setAppValue('core', 'shareapi_default_expire_date', 'no');
- \OCP\Config::setAppValue('core', 'shareapi_enforce_expire_date', 'no');
+ $config->setAppValue('core', 'shareapi_default_expire_date', 'no');
+ $config->setAppValue('core', 'shareapi_enforce_expire_date', 'no');
\OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null);
}
diff --git a/apps/files_sharing/tests/helper.php b/apps/files_sharing/tests/helper.php
index 1a27739ec34..a9245ddafe5 100644
--- a/apps/files_sharing/tests/helper.php
+++ b/apps/files_sharing/tests/helper.php
@@ -35,7 +35,7 @@ class Test_Files_Sharing_Helper extends TestCase {
$this->assertSame('/Shared', \OCA\Files_Sharing\Helper::getShareFolder());
// cleanup
- \OCP\Config::deleteSystemValue('share_folder');
+ \OC::$server->getConfig()->deleteSystemValue('share_folder');
}
diff --git a/apps/files_sharing/tests/share.php b/apps/files_sharing/tests/share.php
index f76f92734d0..83ef17f49d1 100644
--- a/apps/files_sharing/tests/share.php
+++ b/apps/files_sharing/tests/share.php
@@ -243,7 +243,7 @@ class Test_Files_Sharing extends OCA\Files_sharing\Tests\TestCase {
$this->assertTrue(\OC\Files\Filesystem::file_exists('/Shared/subfolder/' . $this->folder));
//cleanup
- \OCP\Config::deleteSystemValue('share_folder');
+ \OC::$server->getConfig()->deleteSystemValue('share_folder');
}
/**
diff --git a/apps/files_trashbin/lib/helper.php b/apps/files_trashbin/lib/helper.php
index c99662480df..d9e69b71aa0 100644
--- a/apps/files_trashbin/lib/helper.php
+++ b/apps/files_trashbin/lib/helper.php
@@ -31,8 +31,10 @@ class Helper
return $result;
}
- list($storage, $internalPath) = $view->resolvePath($dir);
+ $mount = $view->getMount($dir);
+ $storage = $mount->getStorage();
$absoluteDir = $view->getAbsolutePath($dir);
+ $internalPath = $mount->getInternalPath($absoluteDir);
if (is_resource($dirContent)) {
$originalLocations = \OCA\Files_Trashbin\Trashbin::getLocations($user);
@@ -65,7 +67,7 @@ class Helper
if ($originalPath) {
$i['extraData'] = $originalPath.'/'.$id;
}
- $result[] = new FileInfo($absoluteDir . '/' . $i['name'], $storage, $internalPath . '/' . $i['name'], $i);
+ $result[] = new FileInfo($absoluteDir . '/' . $i['name'], $storage, $internalPath . '/' . $i['name'], $i, $mount);
}
}
closedir($dirContent);
diff --git a/apps/files_trashbin/lib/trashbin.php b/apps/files_trashbin/lib/trashbin.php
index 1e8f31dbd2a..952af56bacc 100644
--- a/apps/files_trashbin/lib/trashbin.php
+++ b/apps/files_trashbin/lib/trashbin.php
@@ -874,7 +874,7 @@ class Trashbin {
* @return integer size of the folder
*/
private static function calculateSize($view) {
- $root = \OCP\Config::getSystemValue('datadirectory') . $view->getAbsolutePath('');
+ $root = \OC::$server->getConfig()->getSystemValue('datadirectory') . $view->getAbsolutePath('');
if (!file_exists($root)) {
return 0;
}
diff --git a/apps/user_ldap/appinfo/update.php b/apps/user_ldap/appinfo/update.php
index 5fad23de4f6..9bf0ca4ab53 100644
--- a/apps/user_ldap/appinfo/update.php
+++ b/apps/user_ldap/appinfo/update.php
@@ -1,13 +1,15 @@
<?php
+$configInstance = \OC::$server->getConfig();
+
//detect if we can switch on naming guidelines. We won't do it on conflicts.
//it's a bit spaghetti, but hey.
-$state = OCP\Config::getSystemValue('ldapIgnoreNamingRules', 'unset');
+$state = $configInstance->getSystemValue('ldapIgnoreNamingRules', 'unset');
if($state === 'unset') {
- OCP\Config::setSystemValue('ldapIgnoreNamingRules', false);
+ $configInstance->setSystemValue('ldapIgnoreNamingRules', false);
}
-$installedVersion = OCP\Config::getAppValue('user_ldap', 'installed_version');
+$installedVersion = $configInstance->getAppValue('user_ldap', 'installed_version');
$enableRawMode = version_compare($installedVersion, '0.4.1', '<');
$configPrefixes = OCA\user_ldap\lib\Helper::getServerConfigurationPrefixes(true);
@@ -15,31 +17,31 @@ $ldap = new OCA\user_ldap\lib\LDAP();
foreach($configPrefixes as $config) {
$connection = new OCA\user_ldap\lib\Connection($ldap, $config);
- $state = \OCP\Config::getAppValue(
+ $state = $configInstance->getAppValue(
'user_ldap', $config.'ldap_uuid_user_attribute', 'not existing');
if($state === 'non existing') {
- $value = \OCP\Config::getAppValue(
+ $value = $configInstance->getAppValue(
'user_ldap', $config.'ldap_uuid_attribute', '');
- \OCP\Config::setAppValue(
+ $configInstance->setAppValue(
'user_ldap', $config.'ldap_uuid_user_attribute', $value);
- \OCP\Config::setAppValue(
+ $configInstance->setAppValue(
'user_ldap', $config.'ldap_uuid_group_attribute', $value);
}
- $state = \OCP\Config::getAppValue(
+ $state = $configInstance->getAppValue(
'user_ldap', $config.'ldap_expert_uuid_user_attr', 'not existing');
if($state === 'non existing') {
- $value = \OCP\Config::getAppValue(
+ $value = $configInstance->getAppValue(
'user_ldap', $config.'ldap_expert_uuid_attr', '');
- \OCP\Config::setAppValue(
+ $configInstance->setAppValue(
'user_ldap', $config.'ldap_expert_uuid_user_attr', $value);
- \OCP\Config::setAppValue(
+ $configInstance->setAppValue(
'user_ldap', $config.'ldap_expert_uuid_group_attr', $value);
}
if($enableRawMode) {
- \OCP\Config::setAppValue('user_ldap', $config.'ldap_user_filter_mode', 1);
- \OCP\Config::setAppValue('user_ldap', $config.'ldap_login_filter_mode', 1);
- \OCP\Config::setAppValue('user_ldap', $config.'ldap_group_filter_mode', 1);
+ $configInstance->setAppValue('user_ldap', $config.'ldap_user_filter_mode', 1);
+ $configInstance->setAppValue('user_ldap', $config.'ldap_login_filter_mode', 1);
+ $configInstance->setAppValue('user_ldap', $config.'ldap_group_filter_mode', 1);
}
}
diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php
index 76747be70cf..22510302061 100644
--- a/apps/user_ldap/lib/access.php
+++ b/apps/user_ldap/lib/access.php
@@ -673,7 +673,7 @@ class Access extends LDAPUtility implements user\IUserTools {
$table = $this->getMapTable($isUser);
$sqlAdjustment = '';
- $dbType = \OCP\Config::getSystemValue('dbtype');
+ $dbType = \OC::$server->getConfig()->getSystemValue('dbtype', null);
if($dbType === 'mysql' || $dbType == 'oci') {
$sqlAdjustment = 'FROM DUAL';
}
diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php
index 52278082312..6c7db662ffb 100644
--- a/apps/user_ldap/user_ldap.php
+++ b/apps/user_ldap/user_ldap.php
@@ -199,7 +199,7 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface {
) {
$homedir = $path;
} else {
- $homedir = \OCP\Config::getSystemValue('datadirectory',
+ $homedir = \OC::$server->getConfig()->getSystemValue('datadirectory',
\OC::$SERVERROOT.'/data' ) . '/' . $homedir[0];
}
$this->access->connection->writeToCache($cacheKey, $homedir);
diff --git a/config/config.sample.php b/config/config.sample.php
index 791ffa3df90..35e3f6ce5f1 100644
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -749,9 +749,21 @@ $CONFIG = array(
*/
'cipher' => 'AES-256-CFB',
+
+/**
+ * Connection details for redis to use for memory caching.
+ * Redis is only used if other memory cache options (xcache, apc, apcu) are
+ * not available.
+ */
+'redis' => array(
+ 'host' => 'localhost', // can also be a unix domain socket: '/tmp/redis.sock'
+ 'port' => 6379,
+ 'timeout' => 0.0
+),
+
/**
* Server details for one or more memcached servers to use for memory caching.
- * Memcache is only used if other memory cache options (xcache, apc, apcu) are
+ * Memcache is only used if other memory cache options (xcache, apc, apcu, redis) are
* not available.
*/
'memcached_servers' => array(
diff --git a/core/js/installation.js b/core/js/installation.js
new file mode 100644
index 00000000000..20ff346215f
--- /dev/null
+++ b/core/js/installation.js
@@ -0,0 +1,5 @@
+
+$(document).ready(function() {
+ $('#adminpass').showPassword().keyup();
+ $('#dbpass').showPassword().keyup();
+});
diff --git a/core/js/js.js b/core/js/js.js
index f01c0eb77c1..57ce1ab6955 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -1081,35 +1081,6 @@ function initCore() {
}
});
- var setShowPassword = function(input, label) {
- input.showPassword().keyup();
- };
- setShowPassword($('#adminpass'), $('label[for=show]'));
- setShowPassword($('#pass2'), $('label[for=personal-show]'));
- setShowPassword($('#dbpass'), $('label[for=dbpassword]'));
-
- var checkShowCredentials = function() {
- var empty = false;
- $('input#user, input#password').each(function() {
- if ($(this).val() === '') {
- empty = true;
- }
- });
- if(empty) {
- $('#submit').fadeOut();
- $('#remember_login').hide();
- $('#remember_login+label').fadeOut();
- } else {
- $('#submit').fadeIn();
- $('#remember_login').show();
- $('#remember_login+label').fadeIn();
- }
- };
- // hide log in button etc. when form fields not filled
- // commented out due to some browsers having issues with it
- // checkShowCredentials();
- // $('input#user, input#password').keyup(checkShowCredentials);
-
// user menu
$('#settings #expand').keydown(function(event) {
if (event.which === 13 || event.which === 32) {
diff --git a/core/templates/installation.php b/core/templates/installation.php
index 9ef63dbfe8c..0b3b0d46c5c 100644
--- a/core/templates/installation.php
+++ b/core/templates/installation.php
@@ -1,3 +1,9 @@
+<?php
+script('core', [
+ 'jquery-showpassword',
+ 'installation'
+]);
+?>
<input type='hidden' id='hasMySQL' value='<?php p($_['hasMySQL']) ?>'>
<input type='hidden' id='hasSQLite' value='<?php p($_['hasSQLite']) ?>'>
<input type='hidden' id='hasPostgreSQL' value='<?php p($_['hasPostgreSQL']) ?>'>
diff --git a/core/templates/login.php b/core/templates/login.php
index 86a1b605df5..2198f063dbc 100644
--- a/core/templates/login.php
+++ b/core/templates/login.php
@@ -1,5 +1,11 @@
<?php /** @var $l OC_L10N */ ?>
-<?php vendor_script('jsTimezoneDetect/jstz') ?>
+<?php
+vendor_script('jsTimezoneDetect/jstz');
+script('core', [
+ 'visitortimezone',
+ 'lostpassword'
+]);
+?>
<!--[if IE 8]><style>input[type="checkbox"]{padding:0;}</style><![endif]-->
<form method="post" name="login">
@@ -65,8 +71,5 @@
</ul>
</fieldset>
</form>
-<?php } ?>
+<?php }
-<?php
-OCP\Util::addscript('core', 'visitortimezone');
-OCP\Util::addScript('core', 'lostpassword');
diff --git a/lib/base.php b/lib/base.php
index ae87ecff394..009732ead7b 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -336,7 +336,6 @@ class OC {
public static function initTemplateEngine() {
// Add the stuff we need always
-
// following logic will import all vendor libraries that are
// specified in core/js/core.json
$fileContent = file_get_contents(OC::$SERVERROOT . '/core/js/core.json');
@@ -351,7 +350,6 @@ class OC {
throw new \Exception('Cannot read core/js/core.json');
}
- OC_Util::addScript("jquery-showpassword");
OC_Util::addScript("placeholders");
OC_Util::addScript("jquery-tipsy");
OC_Util::addScript("compatibility");
diff --git a/lib/private/connector/sabre/directory.php b/lib/private/connector/sabre/directory.php
index ec5f82f9daa..bbe0f3452a7 100644
--- a/lib/private/connector/sabre/directory.php
+++ b/lib/private/connector/sabre/directory.php
@@ -72,7 +72,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node
$path = $this->fileView->getAbsolutePath($this->path) . '/' . $name;
// using a dummy FileInfo is acceptable here since it will be refreshed after the put is complete
- $info = new \OC\Files\FileInfo($path, null, null, array());
+ $info = new \OC\Files\FileInfo($path, null, null, array(), null);
$node = new OC_Connector_Sabre_File($this->fileView, $info);
return $node->put($data);
} catch (\OCP\Files\StorageNotAvailableException $e) {
diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php
index 14a55b5cada..d2759d7a3ba 100644
--- a/lib/private/connector/sabre/objecttree.php
+++ b/lib/private/connector/sabre/objecttree.php
@@ -71,7 +71,9 @@ class ObjectTree extends \Sabre\DAV\ObjectTree {
if (pathinfo($path, PATHINFO_EXTENSION) === 'part') {
// read from storage
$absPath = $this->fileView->getAbsolutePath($path);
- list($storage, $internalPath) = Filesystem::resolvePath('/' . $absPath);
+ $mount = $this->fileView->getMount($path);
+ $storage = $mount->getStorage();
+ $internalPath = $mount->getInternalPath($absPath);
if ($storage) {
/**
* @var \OC\Files\Storage\Storage $storage
@@ -79,7 +81,7 @@ class ObjectTree extends \Sabre\DAV\ObjectTree {
$scanner = $storage->getScanner($internalPath);
// get data directly
$data = $scanner->getData($internalPath);
- $info = new FileInfo($absPath, $storage, $internalPath, $data);
+ $info = new FileInfo($absPath, $storage, $internalPath, $data, $mount);
} else {
$info = null;
}
diff --git a/lib/private/files/fileinfo.php b/lib/private/files/fileinfo.php
index 8bab51f0737..e4a397dcca2 100644
--- a/lib/private/files/fileinfo.php
+++ b/lib/private/files/fileinfo.php
@@ -30,14 +30,23 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
private $internalPath;
/**
+ * @var \OCP\Files\Mount\IMountPoint
+ */
+ private $mount;
+
+ /**
* @param string|boolean $path
* @param Storage\Storage $storage
+ * @param string $internalPath
+ * @param array $data
+ * @param \OCP\Files\Mount\IMountPoint $mount
*/
- public function __construct($path, $storage, $internalPath, $data) {
+ public function __construct($path, $storage, $internalPath, $data, $mount) {
$this->path = $path;
$this->storage = $storage;
$this->internalPath = $internalPath;
$this->data = $data;
+ $this->mount = $mount;
}
public function offsetSet($offset, $value) {
@@ -208,6 +217,7 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
/**
* Check if a file or folder is shared
+ *
* @return bool
*/
public function isShared() {
@@ -229,4 +239,13 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
return false;
}
+
+ /**
+ * Get the mountpoint the file belongs to
+ *
+ * @return \OCP\Files\Mount\IMountPoint
+ */
+ public function getMountPoint() {
+ return $this->mount;
+ }
}
diff --git a/lib/private/files/mount/mountpoint.php b/lib/private/files/mount/mountpoint.php
index b2c50f9d881..77a51a17020 100644
--- a/lib/private/files/mount/mountpoint.php
+++ b/lib/private/files/mount/mountpoint.php
@@ -20,10 +20,23 @@ class MountPoint implements IMountPoint {
protected $storage = null;
protected $class;
protected $storageId;
+
+ /**
+ * Configuration options for the storage backend
+ *
+ * @var array
+ */
protected $arguments = array();
protected $mountPoint;
/**
+ * Mount specific options
+ *
+ * @var array
+ */
+ protected $mountOptions = array();
+
+ /**
* @var \OC\Files\Storage\StorageFactory $loader
*/
private $loader;
@@ -31,10 +44,11 @@ class MountPoint implements IMountPoint {
/**
* @param string|\OC\Files\Storage\Storage $storage
* @param string $mountpoint
- * @param array $arguments (optional)\
+ * @param array $arguments (optional) configuration for the storage backend
* @param \OCP\Files\Storage\IStorageFactory $loader
+ * @param array $mountOptions mount specific options
*/
- public function __construct($storage, $mountpoint, $arguments = null, $loader = null) {
+ public function __construct($storage, $mountpoint, $arguments = null, $loader = null, $mountOptions = null) {
if (is_null($arguments)) {
$arguments = array();
}
@@ -44,6 +58,10 @@ class MountPoint implements IMountPoint {
$this->loader = $loader;
}
+ if (!is_null($mountOptions)) {
+ $this->mountOptions = $mountOptions;
+ }
+
$mountpoint = $this->formatPath($mountpoint);
if ($storage instanceof Storage) {
$this->class = get_class($storage);
@@ -161,4 +179,15 @@ class MountPoint implements IMountPoint {
public function wrapStorage($wrapper) {
$this->storage = $wrapper($this->mountPoint, $this->getStorage());
}
+
+ /**
+ * Get a mount option
+ *
+ * @param string $name Name of the mount option to get
+ * @param mixed $default Default value for the mount option
+ * @return mixed
+ */
+ public function getOption($name, $default) {
+ return isset($this->mountOptions[$name]) ? $this->mountOptions[$name] : $default;
+ }
}
diff --git a/lib/private/files/node/node.php b/lib/private/files/node/node.php
index 87d4a4b9156..17907a53044 100644
--- a/lib/private/files/node/node.php
+++ b/lib/private/files/node/node.php
@@ -288,4 +288,8 @@ class Node implements \OCP\Files\Node, FileInfo {
public function isEncrypted() {
return $this->getFileInfo()->isEncrypted();
}
+
+ public function getMountPoint() {
+ return $this->getFileInfo()->getMountPoint();
+ }
}
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index c01763cdad3..f1c15e197d9 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -113,6 +113,19 @@ class View {
}
/**
+ * get the mountpoint of the storage object for a path
+ * ( note: because a storage is not always mounted inside the fakeroot, the
+ * returned mountpoint is relative to the absolute root of the filesystem
+ * and doesn't take the chroot into account )
+ *
+ * @param string $path
+ * @return \OCP\Files\Mount\IMountPoint
+ */
+ public function getMount($path) {
+ return Filesystem::getMountManager()->find($this->getAbsolutePath($path));
+ }
+
+ /**
* resolve a path to a storage and internal path
*
* @param string $path
@@ -280,6 +293,11 @@ class View {
}
public function isDeletable($path) {
+ $absolutePath = $this->getAbsolutePath($path);
+ $mount = Filesystem::getMountManager()->find($absolutePath);
+ if ($mount->getInternalPath($absolutePath) === '') {
+ return $mount instanceof MoveableMount;
+ }
return $this->basicOperation('isDeletable', $path);
}
@@ -938,7 +956,7 @@ class View {
$data = \OC_FileProxy::runPostProxies('getFileInfo', $path, $data);
- return new FileInfo($path, $storage, $internalPath, $data);
+ return new FileInfo($path, $storage, $internalPath, $data, $mount);
}
/**
@@ -955,8 +973,10 @@ class View {
return $result;
}
$path = $this->getAbsolutePath($directory);
- /** @var \OC\Files\Storage\Storage $storage */
- list($storage, $internalPath) = $this->resolvePath($directory);
+ $path = Filesystem::normalizePath($path);
+ $mount = $this->getMount($directory);
+ $storage = $mount->getStorage();
+ $internalPath = $mount->getInternalPath($path);
if ($storage) {
$cache = $storage->getCache($internalPath);
$user = \OC_User::getUser();
@@ -990,7 +1010,7 @@ class View {
if (\OCP\Util::isSharingDisabledForUser()) {
$content['permissions'] = $content['permissions'] & ~\OCP\Constants::PERMISSION_SHARE;
}
- $files[] = new FileInfo($path . '/' . $content['name'], $storage, $content['path'], $content);
+ $files[] = new FileInfo($path . '/' . $content['name'], $storage, $content['path'], $content, $mount);
}
//add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders
@@ -998,7 +1018,7 @@ class View {
$dirLength = strlen($path);
foreach ($mounts as $mount) {
$mountPoint = $mount->getMountPoint();
- $subStorage = Filesystem::getStorage($mountPoint);
+ $subStorage = $mount->getStorage();
if ($subStorage) {
$subCache = $subStorage->getCache('');
@@ -1044,7 +1064,7 @@ class View {
$content['permissions'] = $content['permissions'] & ~\OCP\Constants::PERMISSION_SHARE;
}
- $files[] = new FileInfo($path . '/' . $rootEntry['name'], $subStorage, '', $rootEntry);
+ $files[] = new FileInfo($path . '/' . $rootEntry['name'], $subStorage, '', $rootEntry, $mount);
}
}
}
@@ -1154,8 +1174,9 @@ class View {
$files = array();
$rootLength = strlen($this->fakeRoot);
- $mountPoint = Filesystem::getMountPoint($this->fakeRoot);
- $storage = Filesystem::getStorage($mountPoint);
+ $mount = $this->getMount('');
+ $mountPoint = $mount->getMountPoint();
+ $storage = $mount->getStorage();
if ($storage) {
$cache = $storage->getCache('');
@@ -1165,13 +1186,14 @@ class View {
$internalPath = $result['path'];
$path = $mountPoint . $result['path'];
$result['path'] = substr($mountPoint . $result['path'], $rootLength);
- $files[] = new FileInfo($path, $storage, $internalPath, $result);
+ $files[] = new FileInfo($path, $storage, $internalPath, $result, $mount);
}
}
- $mountPoints = Filesystem::getMountPoints($this->fakeRoot);
- foreach ($mountPoints as $mountPoint) {
- $storage = Filesystem::getStorage($mountPoint);
+ $mounts = Filesystem::getMountManager()->findIn($this->fakeRoot);
+ foreach ($mounts as $mount) {
+ $mountPoint = $mount->getMountPoint();
+ $storage = $mount->getStorage();
if ($storage) {
$cache = $storage->getCache('');
@@ -1182,7 +1204,7 @@ class View {
$internalPath = $result['path'];
$result['path'] = rtrim($relativeMountPoint . $result['path'], '/');
$path = rtrim($mountPoint . $internalPath, '/');
- $files[] = new FileInfo($path, $storage, $internalPath, $result);
+ $files[] = new FileInfo($path, $storage, $internalPath, $result, $mount);
}
}
}
diff --git a/lib/private/image.php b/lib/private/image.php
index 78cacc84452..07cfb0f72d3 100644
--- a/lib/private/image.php
+++ b/lib/private/image.php
@@ -37,7 +37,7 @@ class OC_Image {
*/
static public function getMimeTypeForFile($filePath) {
// exif_imagetype throws "read error!" if file is less than 12 byte
- if (filesize($filePath) > 11) {
+ if ($filePath !== null && filesize($filePath) > 11) {
$imageType = exif_imagetype($filePath);
} else {
$imageType = false;
diff --git a/lib/private/memcache/factory.php b/lib/private/memcache/factory.php
index 8e47a8899fc..dba9e8a0e00 100644
--- a/lib/private/memcache/factory.php
+++ b/lib/private/memcache/factory.php
@@ -37,6 +37,8 @@ class Factory implements ICacheFactory {
return new APCu($prefix);
} elseif (APC::isAvailable()) {
return new APC($prefix);
+ } elseif (Redis::isAvailable()) {
+ return new Redis($prefix);
} elseif (Memcached::isAvailable()) {
return new Memcached($prefix);
} else {
@@ -50,7 +52,7 @@ class Factory implements ICacheFactory {
* @return bool
*/
public function isAvailable() {
- return XCache::isAvailable() || APCu::isAvailable() || APC::isAvailable() || Memcached::isAvailable();
+ return XCache::isAvailable() || APCu::isAvailable() || APC::isAvailable() || Redis::isAvailable() || Memcached::isAvailable();
}
/**
diff --git a/lib/private/memcache/redis.php b/lib/private/memcache/redis.php
new file mode 100644
index 00000000000..f21619887d0
--- /dev/null
+++ b/lib/private/memcache/redis.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * Copyright (c) 2014 Jörn Friedrich Dreyer <jfd@butonic.de>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Memcache;
+
+class Redis extends Cache {
+
+ /**
+ * @var \Redis $cache
+ */
+ private static $cache = null;
+
+ public function __construct($prefix = '') {
+ parent::__construct($prefix);
+ if (is_null(self::$cache)) {
+ // TODO allow configuring a RedisArray, see https://github.com/nicolasff/phpredis/blob/master/arrays.markdown#redis-arrays
+ self::$cache = new \Redis();
+ $config = \OC::$server->getSystemConfig()->getValue('redis', array());
+ if (isset($config['host'])) {
+ $host = $config['host'];
+ } else {
+ $host = '127.0.0.1';
+ }
+ if (isset($config['port'])) {
+ $port = $config['port'];
+ } else {
+ $port = 6379;
+ }
+ if (isset($config['timeout'])) {
+ $timeout = $config['timeout'];
+ } else {
+ $timeout = 0.0; // unlimited
+ }
+ self::$cache->connect( $host, $port, $timeout );
+ }
+ }
+
+ /**
+ * entries in redis get namespaced to prevent collisions between ownCloud instances and users
+ */
+ protected function getNameSpace() {
+ return $this->prefix;
+ }
+
+ public function get($key) {
+ $result = self::$cache->get($this->getNamespace() . $key);
+ if ($result === false and ! self::$cache->exists($this->getNamespace() . $key)) {
+ return null;
+ } else {
+ return $result;
+ }
+ }
+
+ public function set($key, $value, $ttl = 0) {
+ if ($ttl > 0) {
+ return self::$cache->setex($this->getNamespace() . $key, $ttl, $value);
+ } else {
+ return self::$cache->set($this->getNamespace() . $key, $value);
+ }
+ }
+
+ public function hasKey($key) {
+ return self::$cache->exists($this->getNamespace() . $key);
+ }
+
+ public function remove($key) {
+ if (self::$cache->delete($this->getNamespace() . $key)) {
+ return true;
+ } else {
+ return false;
+ }
+
+ }
+
+ public function clear($prefix = '') {
+ $prefix = $this->getNamespace() . $prefix.'*';
+ $it = null;
+ self::$cache->setOption(\Redis::OPT_SCAN, \Redis::SCAN_RETRY);
+ while($keys = self::$cache->scan($it, $prefix)) {
+ self::$cache->delete($keys);
+ }
+ return true;
+ }
+
+ static public function isAvailable() {
+ return extension_loaded('redis');
+ }
+}
+
diff --git a/lib/private/preview.php b/lib/private/preview.php
index 7305bf1cc0e..a586c94fd11 100644
--- a/lib/private/preview.php
+++ b/lib/private/preview.php
@@ -922,6 +922,11 @@ class Preview {
return false;
}
+ $mount = $file->getMountPoint();
+ if ($mount and !$mount->getOption('previews', true)){
+ return false;
+ }
+
//check if there are preview backends
if (empty(self::$providers)) {
self::initProviders();
diff --git a/lib/private/template.php b/lib/private/template.php
index bda802fd2e2..78ebb506385 100644
--- a/lib/private/template.php
+++ b/lib/private/template.php
@@ -122,7 +122,7 @@ class OC_Template extends \OC\Template\Base {
foreach(OC_Util::$headers as $header) {
$headers .= '<'.OC_Util::sanitizeHTML($header['tag']);
foreach($header['attributes'] as $name=>$value) {
- $headers .= ' "'.OC_Util::sanitizeHTML($name).'"="'.OC_Util::sanitizeHTML($value).'"';
+ $headers .= ' '.OC_Util::sanitizeHTML($name).'="'.OC_Util::sanitizeHTML($value).'"';
}
if ($header['text'] !== null) {
$headers .= '>'.OC_Util::sanitizeHTML($header['text']).'</'.OC_Util::sanitizeHTML($header['tag']).'>';
diff --git a/lib/private/util.php b/lib/private/util.php
index 6ccb9dba087..b97c0684629 100644
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -333,9 +333,9 @@ class OC_Util {
/**
* generates a path for JS/CSS files. If no application is provided it will create the path for core.
*
- * @param $application application to get the files from
- * @param $directory directory withing this application (css, js, vendor, etc)
- * @param $file the file inside of the above folder
+ * @param string $application application to get the files from
+ * @param string $directory directory withing this application (css, js, vendor, etc)
+ * @param string $file the file inside of the above folder
* @return string the path
*/
private static function generatePath($application, $directory, $file) {
@@ -358,7 +358,10 @@ class OC_Util {
* @return void
*/
public static function addScript($application, $file = null) {
- self::$scripts[] = OC_Util::generatePath($application, 'js', $file);
+ $path = OC_Util::generatePath($application, 'js', $file);
+ if (!in_array($path, self::$scripts)) {
+ self::$scripts[] = $path;
+ }
}
/**
@@ -369,7 +372,10 @@ class OC_Util {
* @return void
*/
public static function addVendorScript($application, $file = null) {
- self::$scripts[] = OC_Util::generatePath($application, 'vendor', $file);
+ $path = OC_Util::generatePath($application, 'vendor', $file);
+ if (!in_array($path, self::$scripts)) {
+ self::$scripts[] = $path;
+ }
}
/**
@@ -384,9 +390,12 @@ class OC_Util {
$languageCode = $l->getLanguageCode($application);
}
if (!empty($application)) {
- self::$scripts[] = "$application/l10n/$languageCode";
+ $path = "$application/l10n/$languageCode";
} else {
- self::$scripts[] = "l10n/$languageCode";
+ $path = "l10n/$languageCode";
+ }
+ if (!in_array($path, self::$scripts)) {
+ self::$scripts[] = $path;
}
}
@@ -398,7 +407,10 @@ class OC_Util {
* @return void
*/
public static function addStyle($application, $file = null) {
- self::$styles[] = OC_Util::generatePath($application, 'css', $file);
+ $path = OC_Util::generatePath($application, 'css', $file);
+ if (!in_array($path, self::$styles)) {
+ self::$styles[] = $path;
+ }
}
/**
@@ -409,7 +421,10 @@ class OC_Util {
* @return void
*/
public static function addVendorStyle($application, $file = null) {
- self::$styles[] = OC_Util::generatePath($application, 'vendor', $file);
+ $path = OC_Util::generatePath($application, 'vendor', $file);
+ if (!in_array($path, self::$styles)) {
+ self::$styles[] = $path;
+ }
}
/**
@@ -1344,4 +1359,5 @@ class OC_Util {
public static function isPhpCharSetUtf8() {
return ini_get('default_charset') === 'UTF-8';
}
+
}
diff --git a/lib/public/files/fileinfo.php b/lib/public/files/fileinfo.php
index 3a407ed67ca..ec68ed475c5 100644
--- a/lib/public/files/fileinfo.php
+++ b/lib/public/files/fileinfo.php
@@ -169,4 +169,11 @@ interface FileInfo {
* @return bool
*/
public function isMounted();
+
+ /**
+ * Get the mountpoint the file belongs to
+ *
+ * @return \OCP\Files\Mount\IMountPoint
+ */
+ public function getMountPoint();
}
diff --git a/lib/public/files/mount/imountpoint.php b/lib/public/files/mount/imountpoint.php
index dac634bae4c..af7819ae160 100644
--- a/lib/public/files/mount/imountpoint.php
+++ b/lib/public/files/mount/imountpoint.php
@@ -55,4 +55,13 @@ interface IMountPoint {
* @param callable $wrapper
*/
public function wrapStorage($wrapper);
+
+ /**
+ * Get a mount option
+ *
+ * @param string $name Name of the mount option to get
+ * @param mixed $default Default value for the mount option
+ * @return mixed
+ */
+ public function getOption($name, $default);
}
diff --git a/settings/application.php b/settings/application.php
index 0a80bd8b1e7..74d021c5bf3 100644
--- a/settings/application.php
+++ b/settings/application.php
@@ -83,7 +83,12 @@ class Application extends App {
$c->query('UserSession'),
$c->query('Config'),
$c->query('IsAdmin'),
- $c->query('L10N')
+ $c->query('L10N'),
+ $c->query('Logger'),
+ $c->query('Defaults'),
+ $c->query('Mail'),
+ $c->query('DefaultMailAddress'),
+ $c->query('URLGenerator')
);
});
@@ -134,5 +139,11 @@ class Application extends App {
$container->registerService('DefaultMailAddress', function(IContainer $c) {
return Util::getDefaultEmailAddress('no-reply');
});
+ $container->registerService('Logger', function(IContainer $c) {
+ return $c->query('ServerContainer')->getLogger();
+ });
+ $container->registerService('URLGenerator', function(IContainer $c) {
+ return $c->query('ServerContainer')->getURLGenerator();
+ });
}
}
diff --git a/settings/controller/userscontroller.php b/settings/controller/userscontroller.php
index c25989af1a9..0349a4c3d16 100644
--- a/settings/controller/userscontroller.php
+++ b/settings/controller/userscontroller.php
@@ -15,10 +15,13 @@ use OC\User\Manager;
use OC\User\User;
use \OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\Http\TemplateResponse;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\IL10N;
+use OCP\ILogger;
use OCP\IRequest;
+use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserManager;
use OCP\IUserSession;
@@ -39,6 +42,16 @@ class UsersController extends Controller {
private $groupManager;
/** @var IConfig */
private $config;
+ /** @var ILogger */
+ private $log;
+ /** @var \OC_Defaults */
+ private $defaults;
+ /** @var \OC_Mail */
+ private $mail;
+ /** @var string */
+ private $fromMailAddress;
+ /** @var IURLGenerator */
+ private $urlGenerator;
/**
* @param string $appName
@@ -49,6 +62,10 @@ class UsersController extends Controller {
* @param IConfig $config
* @param bool $isAdmin
* @param IL10N $l10n
+ * @param ILogger $log
+ * @param \OC_Defaults $defaults
+ * @param \OC_Mail $mail
+ * @param string $fromMailAddress
*/
public function __construct($appName,
IRequest $request,
@@ -57,7 +74,12 @@ class UsersController extends Controller {
IUserSession $userSession,
IConfig $config,
$isAdmin,
- IL10N $l10n) {
+ IL10N $l10n,
+ ILogger $log,
+ \OC_Defaults $defaults,
+ \OC_Mail $mail,
+ $fromMailAddress,
+ IURLGenerator $urlGenerator) {
parent::__construct($appName, $request);
$this->userManager = $userManager;
$this->groupManager = $groupManager;
@@ -65,6 +87,11 @@ class UsersController extends Controller {
$this->config = $config;
$this->isAdmin = $isAdmin;
$this->l10n = $l10n;
+ $this->log = $log;
+ $this->defaults = $defaults;
+ $this->mail = $mail;
+ $this->fromMailAddress = $fromMailAddress;
+ $this->urlGenerator = $urlGenerator;
}
/**
@@ -164,12 +191,23 @@ class UsersController extends Controller {
* @param string $username
* @param string $password
* @param array $groups
+ * @param string $email
* @return DataResponse
*
* TODO: Tidy up and write unit tests - code is mainly static method calls
*/
- public function create($username, $password, array $groups) {
+ public function create($username, $password, array $groups=array(), $email='') {
+ if($email !== '' && !$this->mail->validateAddress($email)) {
+ return new DataResponse(
+ array(
+ 'message' => (string)$this->l10n->t('Invalid mail address')
+ ),
+ Http::STATUS_UNPROCESSABLE_ENTITY
+ );
+ }
+
+ // TODO FIXME get rid of the static calls to OC_Subadmin
if (!$this->isAdmin) {
if (!empty($groups)) {
foreach ($groups as $key => $group) {
@@ -195,13 +233,49 @@ class UsersController extends Controller {
}
if($user instanceof User) {
- foreach( $groups as $groupName ) {
- $group = $this->groupManager->get($groupName);
+ if($groups !== null) {
+ foreach( $groups as $groupName ) {
+ $group = $this->groupManager->get($groupName);
+
+ if(empty($group)) {
+ $group = $this->groupManager->createGroup($groupName);
+ }
+ $group->addUser($user);
+ }
+ }
+ /**
+ * Send new user mail only if a mail is set
+ */
+ if($email !== '') {
+ $this->config->setUserValue($username, 'settings', 'email', $email);
+
+ // data for the mail template
+ $mailData = array(
+ 'username' => $username,
+ 'url' => $this->urlGenerator->getAbsoluteURL('/')
+ );
+
+ $mail = new TemplateResponse('settings', 'email.new_user', $mailData, 'blank');
+ $mailContent = $mail->render();
+
+ $mail = new TemplateResponse('settings', 'email.new_user_plain_text', $mailData, 'blank');
+ $plainTextMailContent = $mail->render();
+
+ $subject = $this->l10n->t('Your %s account was created', [$this->defaults->getName()]);
- if(empty($group)) {
- $group = $this->groupManager->createGroup($groupName);
+ try {
+ $this->mail->send(
+ $email,
+ $username,
+ $subject,
+ $mailContent,
+ $this->fromMailAddress,
+ $this->defaults->getName(),
+ 1,
+ $plainTextMailContent);
+ } catch(\Exception $e) {
+ $this->log->error("Can't send new user mail to $email: " . $e->getMessage(), array('app' => 'settings'));
}
- $group->addUser($user);
}
}
diff --git a/settings/js/personal.js b/settings/js/personal.js
index b2efa7c37f9..ac29f69037e 100644
--- a/settings/js/personal.js
+++ b/settings/js/personal.js
@@ -157,6 +157,7 @@ function avatarResponseHandler (data) {
}
$(document).ready(function () {
+ $('#pass2').showPassword().keyup();
$("#passwordbutton").click(function () {
if ($('#pass1').val() !== '' && $('#pass2').val() !== '') {
// Serialize the data
diff --git a/settings/js/users/users.js b/settings/js/users/users.js
index d910e1ec129..e0eb5ff1601 100644
--- a/settings/js/users/users.js
+++ b/settings/js/users/users.js
@@ -695,6 +695,7 @@ $(document).ready(function () {
event.preventDefault();
var username = $('#newusername').val();
var password = $('#newuserpassword').val();
+ var email = $('#newemail').val();
if ($.trim(username) === '') {
OC.dialogs.alert(
t('settings', 'A valid username must be provided'),
@@ -707,14 +708,24 @@ $(document).ready(function () {
t('settings', 'Error creating user'));
return false;
}
- var groups = $('#newusergroups').val();
+ if(!$('#CheckboxMailOnUserCreate').is(':checked')) {
+ email = '';
+ }
+ if ($('#CheckboxMailOnUserCreate').is(':checked') && $.trim(email) === '') {
+ OC.dialogs.alert(
+ t('settings', 'A valid email must be provided'),
+ t('settings', 'Error creating user'));
+ return false;
+ }
+ var groups = $('#newusergroups').val() || [];
$('#newuser').get(0).reset();
$.post(
OC.generateUrl('/settings/users/users'),
{
username: username,
password: password,
- groups: groups
+ groups: groups,
+ email: email
},
function (result) {
if (result.groups) {
@@ -774,6 +785,14 @@ $(document).ready(function () {
$("#userlist .userBackend").hide();
}
});
+ // Option to display/hide the "E-Mail" input field
+ $('#CheckboxMailOnUserCreate').click(function() {
+ if ($('#CheckboxMailOnUserCreate').is(':checked')) {
+ $("#newemail").show();
+ } else {
+ $("#newemail").hide();
+ }
+ });
// calculate initial limit of users to load
var initialUserCountLimit = 20,
diff --git a/settings/templates/email.new_user.php b/settings/templates/email.new_user.php
new file mode 100644
index 00000000000..74149632cb8
--- /dev/null
+++ b/settings/templates/email.new_user.php
@@ -0,0 +1,36 @@
+<table cellspacing="0" cellpadding="0" border="0" width="100%">
+ <tr><td>
+ <table cellspacing="0" cellpadding="0" border="0" width="600px">
+ <tr>
+ <td bgcolor="<?php p($theme->getMailHeaderColor());?>" width="20px">&nbsp;</td>
+ <td bgcolor="<?php p($theme->getMailHeaderColor());?>">
+ <img src="<?php p(OC_Helper::makeURLAbsolute(image_path('', 'logo-mail.gif'))); ?>" alt="<?php p($theme->getName()); ?>"/>
+ </td>
+ </tr>
+ <tr><td colspan="2">&nbsp;</td></tr>
+ <tr>
+ <td width="20px">&nbsp;</td>
+ <td style="font-weight:normal; font-size:0.8em; line-height:1.2em; font-family:verdana,'arial',sans;">
+ <?php
+ print_unescaped($l->t('Hey there,<br><br>just letting you know that you now have an %s account.<br><br>Your username: %s<br>Access it: <a href="%s">%s</a><br><br>', array($theme->getName(), $_['username'], $_['url'], $_['url'])));
+
+ // TRANSLATORS term at the end of a mail
+ p($l->t('Cheers!'));
+ ?>
+ </td>
+ </tr>
+ <tr><td colspan="2">&nbsp;</td></tr>
+ <tr>
+ <td width="20px">&nbsp;</td>
+ <td style="font-weight:normal; font-size:0.8em; line-height:1.2em; font-family:verdana,'arial',sans;">--<br>
+ <?php p($theme->getName()); ?> -
+ <?php p($theme->getSlogan()); ?>
+ <br><a href="<?php p($theme->getBaseUrl()); ?>"><?php p($theme->getBaseUrl());?></a>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">&nbsp;</td>
+ </tr>
+ </table>
+ </td></tr>
+</table>
diff --git a/settings/templates/email.new_user_plain_text.php b/settings/templates/email.new_user_plain_text.php
new file mode 100644
index 00000000000..79559a87020
--- /dev/null
+++ b/settings/templates/email.new_user_plain_text.php
@@ -0,0 +1,10 @@
+<?php
+print_unescaped($l->t("Hey there,\n\njust letting you know that you now have an %s account.\n\nYour username: %s\nAccess it: %s\n\n", array($theme->getName(), $_['username'], $_['url'])));
+
+// TRANSLATORS term at the end of a mail
+p($l->t("Cheers!"));
+?>
+
+ --
+<?php p($theme->getName() . ' - ' . $theme->getSlogan()); ?>
+<?php print_unescaped("\n".$theme->getBaseUrl());
diff --git a/settings/templates/personal.php b/settings/templates/personal.php
index 83cf9c72f76..ad61f398b1c 100644
--- a/settings/templates/personal.php
+++ b/settings/templates/personal.php
@@ -66,6 +66,7 @@
<?php
if($_['passwordChangeSupported']) {
+ script('jquery-showpassword');
?>
<form id="passwordform" class="section">
<h2><?php p($l->t('Password'));?></h2>
diff --git a/settings/templates/users/main.php b/settings/templates/users/main.php
index c32c8df6809..2004c10b9ac 100644
--- a/settings/templates/users/main.php
+++ b/settings/templates/users/main.php
@@ -62,6 +62,12 @@ translation('settings');
<?php p($l->t('Show user backend')) ?>
</label>
</p>
+ <p>
+ <input type="checkbox" name="MailOnUserCreate" value="MailOnUserCreate" id="CheckboxMailOnUserCreate">
+ <label for="CheckboxMailOnUserCreate">
+ <?php p($l->t('Send mail to new user')) ?>
+ </label>
+ </p>
</div>
</div>
</div>
diff --git a/settings/templates/users/part.createuser.php b/settings/templates/users/part.createuser.php
index d3ebbfb987a..9d9886f694c 100644
--- a/settings/templates/users/part.createuser.php
+++ b/settings/templates/users/part.createuser.php
@@ -7,6 +7,9 @@
type="password" id="newuserpassword"
placeholder="<?php p($l->t('Password'))?>"
autocomplete="off" autocapitalize="off" autocorrect="off" />
+ <input id="newemail" type="text" style="display:none"
+ placeholder="<?php p($l->t('E-Mail'))?>"
+ autocomplete="off" autocapitalize="off" autocorrect="off" />
<select
class="groupsselect" id="newusergroups" data-placeholder="groups"
title="<?php p($l->t('Groups'))?>" multiple="multiple">
diff --git a/tests/lib/connector/sabre/file.php b/tests/lib/connector/sabre/file.php
index b4fdd91f512..6bb1b4e75d1 100644
--- a/tests/lib/connector/sabre/file.php
+++ b/tests/lib/connector/sabre/file.php
@@ -24,7 +24,7 @@ class Test_OC_Connector_Sabre_File extends \Test\TestCase {
$info = new \OC\Files\FileInfo('/test.txt', null, null, array(
'permissions'=>\OCP\Constants::PERMISSION_ALL
- ));
+ ), null);
$file = new OC_Connector_Sabre_File($view, $info);
@@ -59,7 +59,7 @@ class Test_OC_Connector_Sabre_File extends \Test\TestCase {
$info = new \OC\Files\FileInfo('/test.txt', null, null, array(
'permissions' => \OCP\Constants::PERMISSION_ALL
- ));
+ ), null);
$file = new OC_Connector_Sabre_File($view, $info);
@@ -83,7 +83,7 @@ class Test_OC_Connector_Sabre_File extends \Test\TestCase {
$info = new \OC\Files\FileInfo('/super*star.txt', null, null, array(
'permissions' => \OCP\Constants::PERMISSION_ALL
- ));
+ ), null);
$file = new OC_Connector_Sabre_File($view, $info);
// action
@@ -104,7 +104,7 @@ class Test_OC_Connector_Sabre_File extends \Test\TestCase {
$info = new \OC\Files\FileInfo('/super*star.txt', null, null, array(
'permissions' => \OCP\Constants::PERMISSION_ALL
- ));
+ ), null);
$file = new OC_Connector_Sabre_File($view, $info);
$file->setName('/super*star.txt');
}
@@ -136,7 +136,7 @@ class Test_OC_Connector_Sabre_File extends \Test\TestCase {
$info = new \OC\Files\FileInfo('/test.txt', null, null, array(
'permissions' => \OCP\Constants::PERMISSION_ALL
- ));
+ ), null);
$file = new OC_Connector_Sabre_File($view, $info);
@@ -158,7 +158,7 @@ class Test_OC_Connector_Sabre_File extends \Test\TestCase {
$info = new \OC\Files\FileInfo('/test.txt', null, null, array(
'permissions' => \OCP\Constants::PERMISSION_ALL
- ));
+ ), null);
$file = new OC_Connector_Sabre_File($view, $info);
@@ -176,7 +176,7 @@ class Test_OC_Connector_Sabre_File extends \Test\TestCase {
$info = new \OC\Files\FileInfo('/test.txt', null, null, array(
'permissions' => 0
- ));
+ ), null);
$file = new OC_Connector_Sabre_File($view, $info);
@@ -199,7 +199,7 @@ class Test_OC_Connector_Sabre_File extends \Test\TestCase {
$info = new \OC\Files\FileInfo('/test.txt', null, null, array(
'permissions' => \OCP\Constants::PERMISSION_ALL
- ));
+ ), null);
$file = new OC_Connector_Sabre_File($view, $info);
diff --git a/tests/lib/connector/sabre/objecttree.php b/tests/lib/connector/sabre/objecttree.php
index d1de46d2ee7..2548066214b 100644
--- a/tests/lib/connector/sabre/objecttree.php
+++ b/tests/lib/connector/sabre/objecttree.php
@@ -101,7 +101,7 @@ class ObjectTree extends \Test\TestCase {
private function moveTest($source, $dest, $updatables, $deletables) {
$view = new TestDoubleFileView($updatables, $deletables);
- $info = new FileInfo('', null, null, array());
+ $info = new FileInfo('', null, null, array(), null);
$rootDir = new OC_Connector_Sabre_Directory($view, $info);
$objectTree = $this->getMock('\OC\Connector\Sabre\ObjectTree',
diff --git a/tests/lib/files/node/file.php b/tests/lib/files/node/file.php
index a1d2266edf7..e3b8019b4ca 100644
--- a/tests/lib/files/node/file.php
+++ b/tests/lib/files/node/file.php
@@ -22,7 +22,7 @@ class File extends \Test\TestCase {
}
protected function getFileInfo($data) {
- return new FileInfo('', null, '', $data);
+ return new FileInfo('', null, '', $data, null);
}
public function testDelete() {
diff --git a/tests/lib/files/node/folder.php b/tests/lib/files/node/folder.php
index e69a2776979..bcd9cc93b5e 100644
--- a/tests/lib/files/node/folder.php
+++ b/tests/lib/files/node/folder.php
@@ -25,7 +25,7 @@ class Folder extends \Test\TestCase {
}
protected function getFileInfo($data) {
- return new FileInfo('', null, '', $data);
+ return new FileInfo('', null, '', $data, null);
}
public function testDelete() {
diff --git a/tests/lib/files/node/node.php b/tests/lib/files/node/node.php
index 4697479ba95..49a2006c767 100644
--- a/tests/lib/files/node/node.php
+++ b/tests/lib/files/node/node.php
@@ -19,7 +19,7 @@ class Node extends \Test\TestCase {
}
protected function getFileInfo($data) {
- return new FileInfo('', null, '', $data);
+ return new FileInfo('', null, '', $data, null);
}
public function testStat() {
diff --git a/tests/lib/files/node/root.php b/tests/lib/files/node/root.php
index 35bd462157e..a763428209c 100644
--- a/tests/lib/files/node/root.php
+++ b/tests/lib/files/node/root.php
@@ -21,7 +21,7 @@ class Root extends \Test\TestCase {
}
protected function getFileInfo($data) {
- return new FileInfo('', null, '', $data);
+ return new FileInfo('', null, '', $data, null);
}
public function testGet() {
diff --git a/tests/lib/memcache/redis.php b/tests/lib/memcache/redis.php
new file mode 100644
index 00000000000..c0bd18b46f9
--- /dev/null
+++ b/tests/lib/memcache/redis.php
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Memcache;
+
+class Redis extends Cache {
+ static public function setUpBeforeClass() {
+ parent::setUpBeforeClass();
+
+ if (!\OC\Memcache\Redis::isAvailable()) {
+ self::markTestSkipped('The redis extension is not available.');
+ }
+ $instance = new \OC\Memcache\Redis(self::getUniqueID());
+ if ($instance->set(self::getUniqueID(), self::getUniqueID()) === false) {
+ self::markTestSkipped('redis server seems to be down.');
+ }
+ }
+
+ protected function setUp() {
+ parent::setUp();
+ $this->instance = new \OC\Memcache\Redis($this->getUniqueID());
+ }
+}
diff --git a/tests/settings/controller/userscontrollertest.php b/tests/settings/controller/userscontrollertest.php
index 0ac6d3f0c01..207943c4c87 100644
--- a/tests/settings/controller/userscontrollertest.php
+++ b/tests/settings/controller/userscontrollertest.php
@@ -45,6 +45,16 @@ class UsersControllerTest extends \Test\TestCase {
->will($this->returnCallback(function($text, $parameters = array()) {
return vsprintf($text, $parameters);
}));
+ $this->container['Defaults'] = $this->getMockBuilder('\OC_Defaults')
+ ->disableOriginalConstructor()->getMock();
+ $this->container['Mail'] = $this->getMockBuilder('\OC_Mail')
+ ->disableOriginalConstructor()->getMock();
+ $this->container['DefaultMailAddress'] = 'no-reply@owncloud.com';
+ $this->container['Logger'] = $this->getMockBuilder('\OCP\ILogger')
+ ->disableOriginalConstructor()->getMock();
+ $this->container['URLGenerator'] = $this->getMockBuilder('\OCP\IURLGenerator')
+ ->disableOriginalConstructor()->getMock();
+
$this->usersController = $this->container['UsersController'];
}
@@ -473,4 +483,64 @@ class UsersControllerTest extends \Test\TestCase {
$this->assertEquals($expectedResponse, $response);
}
+ /**
+ * test if an invalid mail result in a failure response
+ */
+ public function testCreateUnsuccessfulWithInvalidEMail() {
+ /**
+ * FIXME: Disabled due to missing DI on mail class.
+ * TODO: Re-enable when https://github.com/owncloud/core/pull/12085 is merged.
+ */
+ $this->markTestSkipped('Disable test until OC_Mail is rewritten.');
+
+ $this->container['Mail']
+ ->expects($this->once())
+ ->method('validateAddress')
+ ->will($this->returnValue(false));
+
+ $expectedResponse = new DataResponse(
+ array(
+ 'message' => 'Invalid mail address'
+ ),
+ Http::STATUS_UNPROCESSABLE_ENTITY
+ );
+ $response = $this->usersController->create('foo', 'password', array(), 'invalidMailAdress');
+ $this->assertEquals($expectedResponse, $response);
+ }
+
+ /**
+ * test if a valid mail result in a successful mail send
+ */
+ public function testCreateSuccessfulWithValidEMail() {
+ /**
+ * FIXME: Disabled due to missing DI on mail class.
+ * TODO: Re-enable when https://github.com/owncloud/core/pull/12085 is merged.
+ */
+ $this->markTestSkipped('Disable test until OC_Mail is rewritten.');
+
+ $this->container['Mail']
+ ->expects($this->once())
+ ->method('validateAddress')
+ ->will($this->returnValue(true));
+ $this->container['Mail']
+ ->expects($this->once())
+ ->method('send')
+ ->with(
+ $this->equalTo('validMail@Adre.ss'),
+ $this->equalTo('foo'),
+ $this->anything(),
+ $this->anything(),
+ $this->anything(),
+ $this->equalTo('no-reply@owncloud.com'),
+ $this->equalTo(1),
+ $this->anything()
+ );
+ $this->container['Logger']
+ ->expects($this->never())
+ ->method('error');
+
+ $response = $this->usersController->create('foo', 'password', array(), 'validMail@Adre.ss');
+ $this->assertEquals(Http::STATUS_CREATED, $response->getStatus());
+ }
+
}