aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/encryption/js/encryption.js2
-rw-r--r--apps/files/css/files.css4
-rw-r--r--apps/files/js/fileactions.js15
-rw-r--r--apps/files/tests/js/fileactionsSpec.js42
-rw-r--r--apps/files_external/3rdparty/composer.json2
-rw-r--r--apps/files_external/3rdparty/composer.lock14
-rw-r--r--apps/files_external/3rdparty/composer/installed.json14
-rw-r--r--apps/files_external/3rdparty/icewind/smb/composer.json2
-rw-r--r--apps/files_external/3rdparty/icewind/smb/src/Parser.php1
-rw-r--r--apps/files_external/l10n/fr.js2
-rw-r--r--apps/files_external/l10n/fr.json2
-rw-r--r--apps/files_external/tests/js/mountsfilelistSpec.js2
-rw-r--r--apps/files_sharing/l10n/fr.js2
-rw-r--r--apps/files_sharing/l10n/fr.json2
-rw-r--r--apps/files_sharing/l10n/gl.js2
-rw-r--r--apps/files_sharing/l10n/gl.json2
-rw-r--r--apps/files_sharing/lib/readonlycache.php44
-rw-r--r--apps/files_sharing/lib/readonlywrapper.php5
-rw-r--r--apps/files_sharing/publicwebdav.php3
-rw-r--r--apps/files_sharing/tests/readonlycache.php93
-rw-r--r--apps/files_trashbin/command/expire.php1
-rw-r--r--core/command/user/add.php2
-rw-r--r--core/command/user/delete.php19
-rw-r--r--core/command/user/lastseen.php17
-rw-r--r--core/command/user/report.php16
-rw-r--r--core/command/user/resetpassword.php9
-rw-r--r--core/css/icons.css4
-rw-r--r--core/register_command.php8
-rw-r--r--lib/private/app/codechecker.php2
-rw-r--r--settings/admin.php3
-rw-r--r--settings/js/apps.js2
-rw-r--r--settings/templates/admin.php10
-rw-r--r--tests/core/command/user/deletetest.php106
-rw-r--r--tests/core/command/user/lastseentest.php105
-rw-r--r--tests/lib/files/stream/encryption.php6
35 files changed, 376 insertions, 189 deletions
diff --git a/apps/encryption/js/encryption.js b/apps/encryption/js/encryption.js
index 7ed49f77311..ea6a5596f24 100644
--- a/apps/encryption/js/encryption.js
+++ b/apps/encryption/js/encryption.js
@@ -15,7 +15,7 @@ if (!OC.Encryption) {
*/
OC.Encryption = {
displayEncryptionWarning: function () {
- if (!OC.Notification.isHidden()) {
+ if (!OC.currentUser || !OC.Notification.isHidden()) {
return;
}
diff --git a/apps/files/css/files.css b/apps/files/css/files.css
index 9e55e428057..e4bf791761d 100644
--- a/apps/files/css/files.css
+++ b/apps/files/css/files.css
@@ -581,7 +581,9 @@ a.action>img {
#fileList tr:hover a.action,
#fileList a.action.permanent,
#fileList tr:focus a.action,
-#fileList a.action.permanent
+#fileList a.action.permanent,
+#fileList tr:hover a.action.no-permission:hover,
+#fileList tr:focus a.action.no-permission:focus
/*#fileList .name:focus .action*/ {
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
filter: alpha(opacity=50);
diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js
index b335f1f6432..1956fda0077 100644
--- a/apps/files/js/fileactions.js
+++ b/apps/files/js/fileactions.js
@@ -288,9 +288,15 @@
} else if (mountType === 'shared-root') {
deleteTitle = t('files', 'Unshare');
}
+ var cssClasses = 'action delete icon-delete';
+ if((context.$file.data('permissions') & OC.PERMISSION_DELETE) === 0) {
+ // add css class no-permission to delete icon
+ cssClasses += ' no-permission';
+ deleteTitle = t('files', 'No permission to delete');
+ }
var $actionLink = $('<a href="#" original-title="' +
escapeHTML(deleteTitle) +
- '" class="action delete icon-delete">' +
+ '" class="' +cssClasses + '">' +
'<span class="hidden-visually">' + escapeHTML(deleteTitle) + '</span>' +
'</a>'
);
@@ -426,12 +432,17 @@
name: 'Delete',
displayName: '',
mime: 'all',
- permissions: OC.PERMISSION_DELETE,
+ // permission is READ because we show a hint instead if there is no permission
+ permissions: OC.PERMISSION_READ,
icon: function() {
return OC.imagePath('core', 'actions/delete');
},
render: _.bind(this._renderDeleteAction, this),
actionHandler: function(fileName, context) {
+ // if there is no permission to delete do nothing
+ if((context.$file.data('permissions') & OC.PERMISSION_DELETE) === 0) {
+ return;
+ }
context.fileList.do_delete(fileName, context.dir);
$('.tipsy').remove();
}
diff --git a/apps/files/tests/js/fileactionsSpec.js b/apps/files/tests/js/fileactionsSpec.js
index 828aec9b6b9..53fa8707674 100644
--- a/apps/files/tests/js/fileactionsSpec.js
+++ b/apps/files/tests/js/fileactionsSpec.js
@@ -157,6 +157,48 @@ describe('OCA.Files.FileActions tests', function() {
expect(deleteStub.getCall(0).args[1]).toEqual('/somepath/dir');
deleteStub.restore();
});
+ it('shows delete hint when no permission to delete', function() {
+ var deleteStub = sinon.stub(fileList, 'do_delete');
+ var fileData = {
+ id: 18,
+ type: 'file',
+ name: 'testName.txt',
+ path: '/somepath/dir',
+ mimetype: 'text/plain',
+ size: '1234',
+ etag: 'a01234c',
+ mtime: '123456',
+ permissions: OC.PERMISSION_READ
+ };
+ var $tr = fileList.add(fileData);
+ FileActions.display($tr.find('td.filename'), true, fileList);
+
+ var $action = $tr.find('.action.delete');
+
+ expect($action.hasClass('no-permission')).toEqual(true);
+ deleteStub.restore();
+ });
+ it('shows delete hint not when permission to delete', function() {
+ var deleteStub = sinon.stub(fileList, 'do_delete');
+ var fileData = {
+ id: 18,
+ type: 'file',
+ name: 'testName.txt',
+ path: '/somepath/dir',
+ mimetype: 'text/plain',
+ size: '1234',
+ etag: 'a01234c',
+ mtime: '123456',
+ permissions: OC.PERMISSION_DELETE
+ };
+ var $tr = fileList.add(fileData);
+ FileActions.display($tr.find('td.filename'), true, fileList);
+
+ var $action = $tr.find('.action.delete');
+
+ expect($action.hasClass('no-permission')).toEqual(false);
+ deleteStub.restore();
+ });
it('passes context to action handler', function() {
var actionStub = sinon.stub();
var fileData = {
diff --git a/apps/files_external/3rdparty/composer.json b/apps/files_external/3rdparty/composer.json
index 8992220d843..9680d92e548 100644
--- a/apps/files_external/3rdparty/composer.json
+++ b/apps/files_external/3rdparty/composer.json
@@ -6,7 +6,7 @@
"vendor-dir": "."
},
"require": {
- "icewind/smb": "1.0.0",
+ "icewind/smb": "1.0.1",
"icewind/streams": "0.2"
}
}
diff --git a/apps/files_external/3rdparty/composer.lock b/apps/files_external/3rdparty/composer.lock
index ffd5c7c3c65..84fbb046d5a 100644
--- a/apps/files_external/3rdparty/composer.lock
+++ b/apps/files_external/3rdparty/composer.lock
@@ -4,24 +4,24 @@
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "2554253c9f91c67cd0db753a69105bc0",
+ "hash": "7b46d64e33feb600c5f0ec830b211e6f",
"packages": [
{
"name": "icewind/smb",
- "version": "v1.0.0",
+ "version": "v1.0.1",
"source": {
"type": "git",
"url": "https://github.com/icewind1991/SMB.git",
- "reference": "4f5d9db3a9397e30476f92eb753751b54d6d4fa5"
+ "reference": "8041bc1960bf2da94e60b88b34e5c78300eac476"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/icewind1991/SMB/zipball/4f5d9db3a9397e30476f92eb753751b54d6d4fa5",
- "reference": "4f5d9db3a9397e30476f92eb753751b54d6d4fa5",
+ "url": "https://api.github.com/repos/icewind1991/SMB/zipball/8041bc1960bf2da94e60b88b34e5c78300eac476",
+ "reference": "8041bc1960bf2da94e60b88b34e5c78300eac476",
"shasum": ""
},
"require": {
- "icewind/streams": "0.2.x",
+ "icewind/streams": "0.2.*",
"php": ">=5.3"
},
"require-dev": {
@@ -45,7 +45,7 @@
}
],
"description": "php wrapper for smbclient and libsmbclient-php",
- "time": "2015-04-10 12:10:08"
+ "time": "2015-04-20 11:16:24"
},
{
"name": "icewind/streams",
diff --git a/apps/files_external/3rdparty/composer/installed.json b/apps/files_external/3rdparty/composer/installed.json
index 441ed1f14fa..42e8fdd29db 100644
--- a/apps/files_external/3rdparty/composer/installed.json
+++ b/apps/files_external/3rdparty/composer/installed.json
@@ -43,27 +43,27 @@
},
{
"name": "icewind/smb",
- "version": "v1.0.0",
- "version_normalized": "1.0.0.0",
+ "version": "v1.0.1",
+ "version_normalized": "1.0.1.0",
"source": {
"type": "git",
"url": "https://github.com/icewind1991/SMB.git",
- "reference": "4f5d9db3a9397e30476f92eb753751b54d6d4fa5"
+ "reference": "8041bc1960bf2da94e60b88b34e5c78300eac476"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/icewind1991/SMB/zipball/4f5d9db3a9397e30476f92eb753751b54d6d4fa5",
- "reference": "4f5d9db3a9397e30476f92eb753751b54d6d4fa5",
+ "url": "https://api.github.com/repos/icewind1991/SMB/zipball/8041bc1960bf2da94e60b88b34e5c78300eac476",
+ "reference": "8041bc1960bf2da94e60b88b34e5c78300eac476",
"shasum": ""
},
"require": {
- "icewind/streams": "0.2.x",
+ "icewind/streams": "0.2.*",
"php": ">=5.3"
},
"require-dev": {
"satooshi/php-coveralls": "dev-master"
},
- "time": "2015-04-10 12:10:08",
+ "time": "2015-04-20 11:16:24",
"type": "library",
"installation-source": "source",
"autoload": {
diff --git a/apps/files_external/3rdparty/icewind/smb/composer.json b/apps/files_external/3rdparty/icewind/smb/composer.json
index 92f4280d775..593eb728716 100644
--- a/apps/files_external/3rdparty/icewind/smb/composer.json
+++ b/apps/files_external/3rdparty/icewind/smb/composer.json
@@ -10,7 +10,7 @@
],
"require" : {
"php": ">=5.3",
- "icewind/streams": "0.2.x"
+ "icewind/streams": "0.2.*"
},
"require-dev": {
"satooshi/php-coveralls" : "dev-master"
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Parser.php b/apps/files_external/3rdparty/icewind/smb/src/Parser.php
index 8b4de7825e4..6af70143c52 100644
--- a/apps/files_external/3rdparty/icewind/smb/src/Parser.php
+++ b/apps/files_external/3rdparty/icewind/smb/src/Parser.php
@@ -91,7 +91,6 @@ class Parser {
$mode = 0;
$size = 0;
foreach ($output as $line) {
- list($name, $value) = explode(':', $line, 2);
// A line = explode statement may not fill all array elements
// properly. May happen when accessing non Windows Fileservers
$words = explode(':', $line, 2);
diff --git a/apps/files_external/l10n/fr.js b/apps/files_external/l10n/fr.js
index f63553fe50a..4b6b3b7d305 100644
--- a/apps/files_external/l10n/fr.js
+++ b/apps/files_external/l10n/fr.js
@@ -37,7 +37,7 @@ OC.L10N.register(
"Password (required for OpenStack Object Storage)" : "Mot de passe (requis pour OpenStack Object Storage)",
"Service Name (required for OpenStack Object Storage)" : "Nom du service (requis pour le stockage OpenStack)",
"URL of identity endpoint (required for OpenStack Object Storage)" : "URL du point d'accès d'identité (requis pour le stockage OpenStack)",
- "Timeout of HTTP requests in seconds" : "Temps maximal de requête HTTP en seconde",
+ "Timeout of HTTP requests in seconds" : "Délai d'attente maximal des requêtes HTTP en secondes",
"Share" : "Partager",
"SMB / CIFS using OC login" : "SMB / CIFS en utilisant les identifiants OC",
"Username as share" : "Nom d'utilisateur comme nom de partage",
diff --git a/apps/files_external/l10n/fr.json b/apps/files_external/l10n/fr.json
index af99c2c935a..add46dd3021 100644
--- a/apps/files_external/l10n/fr.json
+++ b/apps/files_external/l10n/fr.json
@@ -35,7 +35,7 @@
"Password (required for OpenStack Object Storage)" : "Mot de passe (requis pour OpenStack Object Storage)",
"Service Name (required for OpenStack Object Storage)" : "Nom du service (requis pour le stockage OpenStack)",
"URL of identity endpoint (required for OpenStack Object Storage)" : "URL du point d'accès d'identité (requis pour le stockage OpenStack)",
- "Timeout of HTTP requests in seconds" : "Temps maximal de requête HTTP en seconde",
+ "Timeout of HTTP requests in seconds" : "Délai d'attente maximal des requêtes HTTP en secondes",
"Share" : "Partager",
"SMB / CIFS using OC login" : "SMB / CIFS en utilisant les identifiants OC",
"Username as share" : "Nom d'utilisateur comme nom de partage",
diff --git a/apps/files_external/tests/js/mountsfilelistSpec.js b/apps/files_external/tests/js/mountsfilelistSpec.js
index a4e4fec1177..c7ea819d2fe 100644
--- a/apps/files_external/tests/js/mountsfilelistSpec.js
+++ b/apps/files_external/tests/js/mountsfilelistSpec.js
@@ -128,7 +128,7 @@ describe('OCA.External.FileList tests', function() {
'?dir=/another%20mount%20points/sftp%20mount'
);
expect($tr.find('.nametext').text().trim()).toEqual('sftp mount');
- expect($tr.find('.column-scope').text().trim()).toEqual('System');
+ expect($tr.find('.column-scope > span').text().trim()).toEqual('System');
expect($tr.find('.column-backend').text().trim()).toEqual('SFTP');
$tr = $rows.eq(1);
diff --git a/apps/files_sharing/l10n/fr.js b/apps/files_sharing/l10n/fr.js
index 74f31dba7cf..6fd7bf4a9d9 100644
--- a/apps/files_sharing/l10n/fr.js
+++ b/apps/files_sharing/l10n/fr.js
@@ -28,7 +28,7 @@ OC.L10N.register(
"Shared by" : "Partagé par",
"A file or folder has been <strong>shared</strong>" : "Un fichier ou un répertoire a été <strong>partagé</strong>",
"A file or folder was shared from <strong>another server</strong>" : "Un fichier ou un répertoire a été partagé depuis <strong>un autre serveur</strong>",
- "A public shared file or folder was <strong>downloaded</strong>" : "Un fichier ou un répertoire partagé a été <strong>téléchargé</strong>",
+ "A public shared file or folder was <strong>downloaded</strong>" : "Un fichier ou un répertoire partagé publiquement a été <strong>téléchargé</strong>",
"You received a new remote share from %s" : "Vous avez reçu un partage distant de %s",
"%1$s accepted remote share %2$s" : "%1$s a accepté le partage distant %2$s",
"%1$s declined remote share %2$s" : "%1$s a refusé le partage distant %2$s",
diff --git a/apps/files_sharing/l10n/fr.json b/apps/files_sharing/l10n/fr.json
index d7ed1692d6f..07629def1d3 100644
--- a/apps/files_sharing/l10n/fr.json
+++ b/apps/files_sharing/l10n/fr.json
@@ -26,7 +26,7 @@
"Shared by" : "Partagé par",
"A file or folder has been <strong>shared</strong>" : "Un fichier ou un répertoire a été <strong>partagé</strong>",
"A file or folder was shared from <strong>another server</strong>" : "Un fichier ou un répertoire a été partagé depuis <strong>un autre serveur</strong>",
- "A public shared file or folder was <strong>downloaded</strong>" : "Un fichier ou un répertoire partagé a été <strong>téléchargé</strong>",
+ "A public shared file or folder was <strong>downloaded</strong>" : "Un fichier ou un répertoire partagé publiquement a été <strong>téléchargé</strong>",
"You received a new remote share from %s" : "Vous avez reçu un partage distant de %s",
"%1$s accepted remote share %2$s" : "%1$s a accepté le partage distant %2$s",
"%1$s declined remote share %2$s" : "%1$s a refusé le partage distant %2$s",
diff --git a/apps/files_sharing/l10n/gl.js b/apps/files_sharing/l10n/gl.js
index 9eeb97cde86..11cc0348f34 100644
--- a/apps/files_sharing/l10n/gl.js
+++ b/apps/files_sharing/l10n/gl.js
@@ -21,7 +21,7 @@ OC.L10N.register(
"Remote share password" : "Contrasinal da compartición remota",
"Cancel" : "Cancelar",
"Add remote share" : "Engadir unha compartición remota",
- "You can upload into this folder" : "Pode envialo envialo a este cartafol",
+ "You can upload into this folder" : "Pode envialo a este cartafol",
"No ownCloud installation (7 or higher) found at {remote}" : "Non se atopa unha instalación de ownCloud (7 ou superior) en {remote}",
"Invalid ownCloud url" : "URL incorrecto do ownCloud",
"Share" : "Compartir",
diff --git a/apps/files_sharing/l10n/gl.json b/apps/files_sharing/l10n/gl.json
index 4b222329227..01972ddee16 100644
--- a/apps/files_sharing/l10n/gl.json
+++ b/apps/files_sharing/l10n/gl.json
@@ -19,7 +19,7 @@
"Remote share password" : "Contrasinal da compartición remota",
"Cancel" : "Cancelar",
"Add remote share" : "Engadir unha compartición remota",
- "You can upload into this folder" : "Pode envialo envialo a este cartafol",
+ "You can upload into this folder" : "Pode envialo a este cartafol",
"No ownCloud installation (7 or higher) found at {remote}" : "Non se atopa unha instalación de ownCloud (7 ou superior) en {remote}",
"Invalid ownCloud url" : "URL incorrecto do ownCloud",
"Share" : "Compartir",
diff --git a/apps/files_sharing/lib/readonlycache.php b/apps/files_sharing/lib/readonlycache.php
deleted file mode 100644
index c7640f896f4..00000000000
--- a/apps/files_sharing/lib/readonlycache.php
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-/**
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@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\Files_Sharing;
-
-use OC\Files\Cache\Cache;
-
-class ReadOnlyCache extends Cache {
- public function get($path) {
- $data = parent::get($path);
- if ($data !== false) {
- $data['permissions'] &= (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_SHARE);
- }
- return $data;
- }
-
- public function getFolderContents($path) {
- $content = parent::getFolderContents($path);
- foreach ($content as &$data) {
- $data['permissions'] &= (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_SHARE);
- }
- return $content;
- }
-}
diff --git a/apps/files_sharing/lib/readonlywrapper.php b/apps/files_sharing/lib/readonlywrapper.php
index 067000ff47c..a5d84f7f5a2 100644
--- a/apps/files_sharing/lib/readonlywrapper.php
+++ b/apps/files_sharing/lib/readonlywrapper.php
@@ -23,7 +23,9 @@
namespace OCA\Files_Sharing;
+use OC\Files\Cache\Wrapper\CachePermissionsMask;
use OC\Files\Storage\Wrapper\Wrapper;
+use OCP\Constants;
class ReadOnlyWrapper extends Wrapper {
public function isUpdatable($path) {
@@ -66,6 +68,7 @@ class ReadOnlyWrapper extends Wrapper {
if (!$storage) {
$storage = $this;
}
- return new ReadOnlyCache($storage);
+ $sourceCache = $this->storage->getCache($path, $storage);
+ return new CachePermissionsMask($sourceCache, Constants::PERMISSION_READ | Constants::PERMISSION_SHARE);
}
}
diff --git a/apps/files_sharing/publicwebdav.php b/apps/files_sharing/publicwebdav.php
index 3a961f5d757..3be464c64f0 100644
--- a/apps/files_sharing/publicwebdav.php
+++ b/apps/files_sharing/publicwebdav.php
@@ -56,7 +56,8 @@ $server->addPlugin(new \OC\Connector\Sabre\ExceptionLoggerPlugin('webdav', \OC::
// wait with registering these until auth is handled and the filesystem is setup
$server->on('beforeMethod', function () use ($server, $objectTree, $authBackend) {
$share = $authBackend->getShare();
- $owner = $share['uid_owner'];
+ $rootShare = \OCP\Share::resolveReShare($share);
+ $owner = $rootShare['uid_owner'];
$isWritable = $share['permissions'] & (\OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_CREATE);
$fileId = $share['file_source'];
diff --git a/apps/files_sharing/tests/readonlycache.php b/apps/files_sharing/tests/readonlycache.php
deleted file mode 100644
index 5da200fa78f..00000000000
--- a/apps/files_sharing/tests/readonlycache.php
+++ /dev/null
@@ -1,93 +0,0 @@
-<?php
-/**
- * @author Olivier Paroz <owncloud@interfasys.ch>
- *
- * @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\Files_Sharing\Tests;
-
-class ReadOnlyCache extends TestCase {
-
- /** @var \OC\Files\Storage\Storage */
- protected $storage;
-
- /** @var \OC\Files\Storage\StorageFactory */
- protected $loader;
-
- /** @var \OC\Files\Mount\MountPoint */
- protected $readOnlyMount;
-
- /** @var \OCA\Files_Sharing\ReadOnlyWrapper */
- protected $readOnlyStorage;
-
- /** @var \OC\Files\Cache\Cache */
- protected $readOnlyCache;
-
- protected function setUp() {
- parent::setUp();
-
- $this->view->mkdir('readonly');
- $this->view->file_put_contents('readonly/foo.txt', 'foo');
- $this->view->file_put_contents('readonly/bar.txt', 'bar');
-
- list($this->storage) = $this->view->resolvePath('');
- $this->loader = new \OC\Files\Storage\StorageFactory();
- $this->readOnlyMount = new \OC\Files\Mount\MountPoint($this->storage,
- '/readonly', [[]], $this->loader);
- $this->readOnlyStorage = $this->loader->getInstance($this->readOnlyMount,
- '\OCA\Files_Sharing\ReadOnlyWrapper', ['storage' => $this->storage]);
-
- $this->readOnlyCache = $this->readOnlyStorage->getCache();
- }
-
- public function testSetup() {
- $this->assertTrue($this->view->file_exists('/readonly/foo.txt'));
-
- $perms = $this->readOnlyStorage->getPermissions('files/readonly/foo.txt');
- $this->assertEquals(17, $perms);
-
- $this->assertFalse($this->readOnlyStorage->unlink('files/readonly/foo.txt'));
- $this->assertTrue($this->readOnlyStorage->file_exists('files/readonly/foo.txt'));
-
- $this->assertInstanceOf('\OCA\Files_Sharing\ReadOnlyCache', $this->readOnlyCache);
- }
-
- public function testGetWhenFileExists() {
- $result = $this->readOnlyCache->get('files/readonly/foo.txt');
- $this->assertNotEmpty($result);
- }
-
- public function testGetWhenFileDoesNotExist() {
- $result = $this->readOnlyCache->get('files/readonly/proof does not exist.md');
- $this->assertFalse($result);
- }
-
- public function testGetFolderContentsWhenFolderExists() {
- $results = $this->readOnlyCache->getFolderContents('files/readonly');
- $this->assertNotEmpty($results);
-
- foreach ($results as $result) {
- $this->assertNotEmpty($result);
- }
- }
-
- public function testGetFolderContentsWhenFolderDoesNotExist() {
- $results = $this->readOnlyCache->getFolderContents('files/iamaghost');
- $this->assertEmpty($results);
- }
-
-}
diff --git a/apps/files_trashbin/command/expire.php b/apps/files_trashbin/command/expire.php
index f0526d42830..e617fa47c90 100644
--- a/apps/files_trashbin/command/expire.php
+++ b/apps/files_trashbin/command/expire.php
@@ -52,5 +52,6 @@ class Expire implements ICommand {
\OC_Util::tearDownFS();
\OC_Util::setupFS($this->user);
Trashbin::expire($this->trashBinSize, $this->user);
+ \OC_Util::tearDownFS();
}
}
diff --git a/core/command/user/add.php b/core/command/user/add.php
index 60c70bf13dd..c52ec4d0090 100644
--- a/core/command/user/add.php
+++ b/core/command/user/add.php
@@ -119,7 +119,7 @@ class Add extends Command {
);
if ($user instanceof IUser) {
- $output->writeln('The user "' . $user->getUID() . '" was created successfully');
+ $output->writeln('<info>The user "' . $user->getUID() . '" was created successfully</info>');
} else {
$output->writeln('<error>An error occurred while creating the user</error>');
return 1;
diff --git a/core/command/user/delete.php b/core/command/user/delete.php
index 53952ceb9e1..8cac03157eb 100644
--- a/core/command/user/delete.php
+++ b/core/command/user/delete.php
@@ -22,19 +22,20 @@
namespace OC\Core\Command\User;
+use OCP\IUserManager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
class Delete extends Command {
- /** @var \OC\User\Manager */
+ /** @var IUserManager */
protected $userManager;
/**
- * @param \OC\User\Manager $userManager
+ * @param IUserManager $userManager
*/
- public function __construct(\OC\User\Manager $userManager) {
+ public function __construct(IUserManager $userManager) {
$this->userManager = $userManager;
parent::__construct();
}
@@ -51,11 +52,17 @@ class Delete extends Command {
}
protected function execute(InputInterface $input, OutputInterface $output) {
- $wasSuccessful = $this->userManager->get($input->getArgument('uid'))->delete();
- if($wasSuccessful === true) {
- $output->writeln('The specified user was deleted');
+ $user = $this->userManager->get($input->getArgument('uid'));
+ if (is_null($user)) {
+ $output->writeln('<error>User does not exist</error>');
return;
}
+
+ if ($user->delete()) {
+ $output->writeln('<info>The specified user was deleted</info>');
+ return;
+ }
+
$output->writeln('<error>The specified could not be deleted. Please check the logs.</error>');
}
}
diff --git a/core/command/user/lastseen.php b/core/command/user/lastseen.php
index 308b3c67ddb..92fcb1d449b 100644
--- a/core/command/user/lastseen.php
+++ b/core/command/user/lastseen.php
@@ -22,12 +22,24 @@
namespace OC\Core\Command\User;
+use OCP\IUserManager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
class LastSeen extends Command {
+ /** @var IUserManager */
+ protected $userManager;
+
+ /**
+ * @param IUserManager $userManager
+ */
+ public function __construct(IUserManager $userManager) {
+ $this->userManager = $userManager;
+ parent::__construct();
+ }
+
protected function configure() {
$this
->setName('user:lastseen')
@@ -40,10 +52,9 @@ class LastSeen extends Command {
}
protected function execute(InputInterface $input, OutputInterface $output) {
- $userManager = \OC::$server->getUserManager();
- $user = $userManager->get($input->getArgument('uid'));
+ $user = $this->userManager->get($input->getArgument('uid'));
if(is_null($user)) {
- $output->writeln('User does not exist');
+ $output->writeln('<error>User does not exist</error>');
return;
}
diff --git a/core/command/user/report.php b/core/command/user/report.php
index 13bb5df69f8..5d89c0ae549 100644
--- a/core/command/user/report.php
+++ b/core/command/user/report.php
@@ -23,11 +23,23 @@
namespace OC\Core\Command\User;
+use OCP\IUserManager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class Report extends Command {
+ /** @var IUserManager */
+ protected $userManager;
+
+ /**
+ * @param IUserManager $userManager
+ */
+ public function __construct(IUserManager $userManager) {
+ $this->userManager = $userManager;
+ parent::__construct();
+ }
+
protected function configure() {
$this
->setName('user:report')
@@ -35,6 +47,7 @@ class Report extends Command {
}
protected function execute(InputInterface $input, OutputInterface $output) {
+ /** @var \Symfony\Component\Console\Helper\TableHelper $table */
$table = $this->getHelperSet()->get('table');
$table->setHeaders(array('User Report', ''));
$userCountArray = $this->countUsers();
@@ -61,8 +74,7 @@ class Report extends Command {
}
private function countUsers() {
- $userManager = \OC::$server->getUserManager();
- return $userManager->countUsers();
+ return $this->userManager->countUsers();
}
private function countUserDirectories() {
diff --git a/core/command/user/resetpassword.php b/core/command/user/resetpassword.php
index 3e16c8f79a5..7c405592114 100644
--- a/core/command/user/resetpassword.php
+++ b/core/command/user/resetpassword.php
@@ -23,6 +23,7 @@
namespace OC\Core\Command\User;
+use OCP\IUserManager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
@@ -31,10 +32,10 @@ use Symfony\Component\Console\Output\OutputInterface;
class ResetPassword extends Command {
- /** @var \OC\User\Manager */
+ /** @var IUserManager */
protected $userManager;
- public function __construct(\OC\User\Manager $userManager) {
+ public function __construct(IUserManager $userManager) {
$this->userManager = $userManager;
parent::__construct();
}
@@ -60,10 +61,10 @@ class ResetPassword extends Command {
protected function execute(InputInterface $input, OutputInterface $output) {
$username = $input->getArgument('user');
- /** @var $user \OC\User\User */
+ /** @var $user \OCP\IUser */
$user = $this->userManager->get($username);
if (is_null($user)) {
- $output->writeln("<error>There is no user called " . $username . "</error>");
+ $output->writeln('<error>User does not exist</error>');
return 1;
}
diff --git a/core/css/icons.css b/core/css/icons.css
index 0f602515883..e44f9880052 100644
--- a/core/css/icons.css
+++ b/core/css/icons.css
@@ -56,7 +56,9 @@
background-image: url('../img/actions/confirm.svg');
}
-.icon-delete {
+.icon-delete,
+.icon-delete.no-permission:hover,
+.icon-delete.no-permission:focus {
background-image: url('../img/actions/delete.svg');
}
.icon-delete:hover,
diff --git a/core/register_command.php b/core/register_command.php
index 701fb10d1ba..75c0245a924 100644
--- a/core/register_command.php
+++ b/core/register_command.php
@@ -42,11 +42,11 @@ if (\OC::$server->getConfig()->getSystemValue('installed', false)) {
$application->add(new OC\Core\Command\App\Enable());
$application->add(new OC\Core\Command\App\ListApps());
$application->add(new OC\Core\Command\Maintenance\Repair($repair, \OC::$server->getConfig()));
- $application->add(new OC\Core\Command\User\Report());
- $application->add(new OC\Core\Command\User\ResetPassword(\OC::$server->getUserManager()));
- $application->add(new OC\Core\Command\User\LastSeen());
- $application->add(new OC\Core\Command\User\Delete(\OC::$server->getUserManager()));
$application->add(new OC\Core\Command\User\Add(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
+ $application->add(new OC\Core\Command\User\Delete(\OC::$server->getUserManager()));
+ $application->add(new OC\Core\Command\User\LastSeen(\OC::$server->getUserManager()));
+ $application->add(new OC\Core\Command\User\Report(\OC::$server->getUserManager()));
+ $application->add(new OC\Core\Command\User\ResetPassword(\OC::$server->getUserManager()));
$application->add(new OC\Core\Command\Background\Cron(\OC::$server->getConfig()));
$application->add(new OC\Core\Command\Background\WebCron(\OC::$server->getConfig()));
$application->add(new OC\Core\Command\Background\Ajax(\OC::$server->getConfig()));
diff --git a/lib/private/app/codechecker.php b/lib/private/app/codechecker.php
index c8c66d6dcab..75db9ab3560 100644
--- a/lib/private/app/codechecker.php
+++ b/lib/private/app/codechecker.php
@@ -99,7 +99,7 @@ class CodeChecker extends BasicEmitter {
$excludes = array_map(function($item) use ($folder) {
return $folder . '/' . $item;
- }, ['vendor', '3rdparty', '.git', 'l10n']);
+ }, ['vendor', '3rdparty', '.git', 'l10n', 'tests', 'test']);
$iterator = new RecursiveDirectoryIterator($folder, RecursiveDirectoryIterator::SKIP_DOTS);
$iterator = new RecursiveCallbackFilterIterator($iterator, function($item) use ($folder, $excludes){
diff --git a/settings/admin.php b/settings/admin.php
index 94e48aab14e..f08c3cd53b6 100644
--- a/settings/admin.php
+++ b/settings/admin.php
@@ -123,6 +123,9 @@ $databaseOverload = (strpos(\OCP\Config::getSystemValue('dbtype'), 'sqlite') !==
$template->assign('databaseOverload', $databaseOverload);
$template->assign('cronErrors', $appConfig->getValue('core', 'cronErrors'));
+// warn if php is not setup properly to get system variables with getenv
+$template->assign('getenvServerNotWorking', empty(getenv('PATH')));
+
// warn if Windows is used
$template->assign('WindowsWarning', OC_Util::runningOnWindows());
diff --git a/settings/js/apps.js b/settings/js/apps.js
index 1bd7ffdf790..58a0a31ccd8 100644
--- a/settings/js/apps.js
+++ b/settings/js/apps.js
@@ -321,8 +321,10 @@ OC.Settings.Apps = OC.Settings.Apps || {
var img= $('<img class="app-icon"/>').attr({ src: entry.icon});
var a=$('<a></a>').attr('href', entry.href);
var filename=$('<span></span>');
+ var loading = $('<div class="icon-loading-dark"></div>').css('display', 'none');
filename.text(entry.name);
a.prepend(filename);
+ a.prepend(loading);
a.prepend(img);
li.append(a);
diff --git a/settings/templates/admin.php b/settings/templates/admin.php
index 4f60f7c16d9..587a3b6c66b 100644
--- a/settings/templates/admin.php
+++ b/settings/templates/admin.php
@@ -67,6 +67,16 @@ if ($_['mail_smtpmode'] == 'qmail') {
<h2><?php p($l->t('Security & setup warnings'));?></h2>
<ul>
<?php
+// is php setup properly to query system environment variables like getenv('PATH')
+if ($_['getenvServerNotWorking']) {
+?>
+ <li>
+ <?php p($l->t('php does not seem to be setup properly to query system environment variables. The test with getenv("PATH") only returns an empty response.')); ?><br>
+ <?php p($l->t('Please check the installation documentation for php configuration notes and the php configuration of your server, especially when using php-fpm.')); ?>
+ </li>
+<?php
+}
+
// is read only config enabled
if ($_['readOnlyConfigEnabled']) {
?>
diff --git a/tests/core/command/user/deletetest.php b/tests/core/command/user/deletetest.php
new file mode 100644
index 00000000000..bfcf031b719
--- /dev/null
+++ b/tests/core/command/user/deletetest.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@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 Tests\Core\Command\User;
+
+
+use OC\Core\Command\User\Delete;
+use Test\TestCase;
+
+class DeleteTest extends TestCase {
+ /** @var \PHPUnit_Framework_MockObject_MockObject */
+ protected $userManager;
+ /** @var \PHPUnit_Framework_MockObject_MockObject */
+ protected $consoleInput;
+ /** @var \PHPUnit_Framework_MockObject_MockObject */
+ protected $consoleOutput;
+
+ /** @var \Symfony\Component\Console\Command\Command */
+ protected $command;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $userManager = $this->userManager = $this->getMockBuilder('OCP\IUserManager')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->consoleInput = $this->getMock('Symfony\Component\Console\Input\InputInterface');
+ $this->consoleOutput = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
+
+ /** @var \OCP\IUserManager $userManager */
+ $this->command = new Delete($userManager);
+ }
+
+
+ public function validUserLastSeen() {
+ return [
+ [true, 'The specified user was deleted'],
+ [false, 'The specified could not be deleted'],
+ ];
+ }
+
+ /**
+ * @dataProvider validUserLastSeen
+ *
+ * @param bool $deleteSuccess
+ * @param string $expectedString
+ */
+ public function testValidUser($deleteSuccess, $expectedString) {
+ $user = $this->getMock('OCP\IUser');
+ $user->expects($this->once())
+ ->method('delete')
+ ->willReturn($deleteSuccess);
+
+ $this->userManager->expects($this->once())
+ ->method('get')
+ ->with('user')
+ ->willReturn($user);
+
+ $this->consoleInput->expects($this->once())
+ ->method('getArgument')
+ ->with('uid')
+ ->willReturn('user');
+
+ $this->consoleOutput->expects($this->once())
+ ->method('writeln')
+ ->with($this->stringContains($expectedString));
+
+ \Test_Helper::invokePrivate($this->command, 'execute', [$this->consoleInput, $this->consoleOutput]);
+ }
+
+ public function testInvalidUser() {
+ $this->userManager->expects($this->once())
+ ->method('get')
+ ->with('user')
+ ->willReturn(null);
+
+ $this->consoleInput->expects($this->once())
+ ->method('getArgument')
+ ->with('uid')
+ ->willReturn('user');
+
+ $this->consoleOutput->expects($this->once())
+ ->method('writeln')
+ ->with($this->stringContains('User does not exist'));
+
+ \Test_Helper::invokePrivate($this->command, 'execute', [$this->consoleInput, $this->consoleOutput]);
+ }
+}
diff --git a/tests/core/command/user/lastseentest.php b/tests/core/command/user/lastseentest.php
new file mode 100644
index 00000000000..7eda6fb27ed
--- /dev/null
+++ b/tests/core/command/user/lastseentest.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@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 Tests\Core\Command\User;
+
+
+use OC\Core\Command\User\LastSeen;
+use Test\TestCase;
+
+class LastSeenTest extends TestCase {
+ /** @var \PHPUnit_Framework_MockObject_MockObject */
+ protected $userManager;
+ /** @var \PHPUnit_Framework_MockObject_MockObject */
+ protected $consoleInput;
+ /** @var \PHPUnit_Framework_MockObject_MockObject */
+ protected $consoleOutput;
+
+ /** @var \Symfony\Component\Console\Command\Command */
+ protected $command;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $userManager = $this->userManager = $this->getMockBuilder('OCP\IUserManager')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->consoleInput = $this->getMock('Symfony\Component\Console\Input\InputInterface');
+ $this->consoleOutput = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
+
+ /** @var \OCP\IUserManager $userManager */
+ $this->command = new LastSeen($userManager);
+ }
+
+ public function validUserLastSeen() {
+ return [
+ [0, 'never logged in'],
+ [time(), 'last login'],
+ ];
+ }
+
+ /**
+ * @dataProvider validUserLastSeen
+ *
+ * @param int $lastSeen
+ * @param string $expectedString
+ */
+ public function testValidUser($lastSeen, $expectedString) {
+ $user = $this->getMock('OCP\IUser');
+ $user->expects($this->once())
+ ->method('getLastLogin')
+ ->willReturn($lastSeen);
+
+ $this->userManager->expects($this->once())
+ ->method('get')
+ ->with('user')
+ ->willReturn($user);
+
+ $this->consoleInput->expects($this->once())
+ ->method('getArgument')
+ ->with('uid')
+ ->willReturn('user');
+
+ $this->consoleOutput->expects($this->once())
+ ->method('writeln')
+ ->with($this->stringContains($expectedString));
+
+ \Test_Helper::invokePrivate($this->command, 'execute', [$this->consoleInput, $this->consoleOutput]);
+ }
+
+ public function testInvalidUser() {
+ $this->userManager->expects($this->once())
+ ->method('get')
+ ->with('user')
+ ->willReturn(null);
+
+ $this->consoleInput->expects($this->once())
+ ->method('getArgument')
+ ->with('uid')
+ ->willReturn('user');
+
+ $this->consoleOutput->expects($this->once())
+ ->method('writeln')
+ ->with($this->stringContains('User does not exist'));
+
+ \Test_Helper::invokePrivate($this->command, 'execute', [$this->consoleInput, $this->consoleOutput]);
+ }
+}
diff --git a/tests/lib/files/stream/encryption.php b/tests/lib/files/stream/encryption.php
index 25e7e54335e..1da208282e6 100644
--- a/tests/lib/files/stream/encryption.php
+++ b/tests/lib/files/stream/encryption.php
@@ -148,6 +148,8 @@ class Encryption extends \Test\TestCase {
$stream = $this->getStream($fileName, 'r', 6);
$this->assertEquals('foobar', fread($stream, 100));
fclose($stream);
+
+ unlink($fileName);
}
public function testSeek() {
@@ -161,6 +163,8 @@ class Encryption extends \Test\TestCase {
$stream = $this->getStream($fileName, 'r', 9);
$this->assertEquals('foofoobar', fread($stream, 100));
fclose($stream);
+
+ unlink($fileName);
}
function dataFilesProvider() {
@@ -198,6 +202,8 @@ class Encryption extends \Test\TestCase {
fclose($stream);
$this->assertEquals($expectedData, $data);
+
+ unlink($fileName);
}
/**