aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/encryption/lib/migration.php6
-rw-r--r--apps/encryption/tests/lib/MigrationTest.php34
-rw-r--r--apps/files/appinfo/remote.php56
-rw-r--r--apps/files/css/files.css123
-rw-r--r--apps/files/css/mobile.css22
-rw-r--r--apps/files/index.php1
-rw-r--r--apps/files/js/fileactions.js321
-rw-r--r--apps/files/js/fileactionsmenu.js132
-rw-r--r--apps/files/js/filelist.js56
-rw-r--r--apps/files/js/tagsplugin.js1
-rw-r--r--apps/files/lib/activity.php51
-rw-r--r--apps/files/tests/activitytest.php45
-rw-r--r--apps/files/tests/js/fileactionsSpec.js563
-rw-r--r--apps/files/tests/js/fileactionsmenuSpec.js273
-rw-r--r--apps/files/tests/js/filelistSpec.js79
-rw-r--r--apps/files_sharing/js/share.js96
-rw-r--r--apps/files_sharing/lib/activity.php2
-rw-r--r--apps/files_sharing/publicwebdav.php42
-rw-r--r--apps/files_sharing/templates/public.php1
-rw-r--r--apps/files_sharing/tests/js/shareSpec.js6
-rw-r--r--apps/files_trashbin/command/cleanup.php2
-rw-r--r--apps/files_trashbin/js/app.js1
-rw-r--r--apps/files_trashbin/tests/command/cleanuptest.php2
-rw-r--r--apps/provisioning_api/appinfo/routes.php57
-rw-r--r--apps/provisioning_api/lib/apps.php21
-rw-r--r--apps/provisioning_api/lib/groups.php69
-rw-r--r--apps/provisioning_api/lib/users.php209
-rw-r--r--apps/provisioning_api/tests/appstest.php29
-rw-r--r--apps/provisioning_api/tests/groupstest.php240
-rw-r--r--apps/provisioning_api/tests/testcase.php22
-rw-r--r--apps/provisioning_api/tests/userstest.php939
-rw-r--r--config/config.sample.php8
-rw-r--r--core/css/apps.css13
-rw-r--r--core/js/core.json4
-rw-r--r--core/js/js.js61
-rw-r--r--core/js/setupchecks.js10
-rw-r--r--core/js/share.js4
-rw-r--r--core/js/tests/specs/setupchecksSpec.js81
-rw-r--r--lib/private/activitymanager.php196
-rw-r--r--lib/private/app.php3
-rw-r--r--lib/private/appframework/dependencyinjection/dicontainer.php1
-rw-r--r--lib/private/appframework/http/request.php5
-rw-r--r--lib/private/appframework/utility/simplecontainer.php12
-rw-r--r--lib/private/connector/sabre/exceptionloggerplugin.php2
-rw-r--r--lib/private/connector/sabre/file.php2
-rw-r--r--lib/private/connector/sabre/objecttree.php6
-rw-r--r--lib/private/connector/sabre/serverfactory.php107
-rw-r--r--lib/private/db/querybuilder/querybuilder.php42
-rw-r--r--lib/private/defaults.php19
-rw-r--r--lib/private/files/view.php9
-rw-r--r--lib/private/server.php1
-rw-r--r--lib/private/share/share.php4
-rw-r--r--lib/public/activity/iextension.php9
-rw-r--r--lib/public/activity/imanager.php8
-rw-r--r--lib/public/appframework/http/contentsecuritypolicy.php1
-rw-r--r--lib/public/db/querybuilder/iquerybuilder.php9
-rw-r--r--lib/repair/cleantags.php12
-rw-r--r--lib/repair/filletags.php2
-rw-r--r--settings/controller/checksetupcontroller.php39
-rw-r--r--tests/lib/activitymanager.php43
-rw-r--r--tests/lib/appframework/controller/ControllerTest.php2
-rw-r--r--tests/lib/appframework/http/ContentSecurityPolicyTest.php106
-rw-r--r--tests/lib/appframework/http/DataResponseTest.php2
-rw-r--r--tests/lib/appframework/http/ResponseTest.php2
-rw-r--r--tests/lib/appframework/routing/RoutingTest.php30
-rw-r--r--tests/lib/appframework/utility/SimpleContainerTest.php48
-rw-r--r--tests/lib/connector/sabre/requesttest/auth.php69
-rw-r--r--tests/lib/connector/sabre/requesttest/exceptionplugin.php32
-rw-r--r--tests/lib/connector/sabre/requesttest/requesttest.php163
-rw-r--r--tests/lib/connector/sabre/requesttest/sapi.php53
-rw-r--r--tests/lib/connector/sabre/requesttest/uploadtest.php88
-rw-r--r--tests/lib/db/querybuilder/querybuildertest.php98
-rw-r--r--tests/lib/files/view.php4
-rw-r--r--tests/lib/repair/cleantags.php34
-rw-r--r--tests/lib/share/share.php4
-rw-r--r--tests/settings/controller/CheckSetupControllerTest.php92
-rw-r--r--themes/example/defaults.php6
-rw-r--r--version.php2
78 files changed, 3616 insertions, 1433 deletions
diff --git a/apps/encryption/lib/migration.php b/apps/encryption/lib/migration.php
index d22c571fd40..5396a7db627 100644
--- a/apps/encryption/lib/migration.php
+++ b/apps/encryption/lib/migration.php
@@ -72,7 +72,7 @@ class Migration {
// only update during the first run
if ($this->installedVersion !== '-1') {
$query = $this->connection->getQueryBuilder();
- $query->update('*PREFIX*filecache')
+ $query->update('filecache')
->set('size', 'unencrypted_size')
->where($query->expr()->eq('encrypted', $query->createParameter('encrypted')))
->setParameter('encrypted', 1);
@@ -163,7 +163,7 @@ class Migration {
$oldAppValues = $this->connection->getQueryBuilder();
$oldAppValues->select('*')
- ->from('*PREFIX*appconfig')
+ ->from('appconfig')
->where($oldAppValues->expr()->eq('appid', $oldAppValues->createParameter('appid')))
->setParameter('appid', 'files_encryption');
$appSettings = $oldAppValues->execute();
@@ -178,7 +178,7 @@ class Migration {
$oldPreferences = $this->connection->getQueryBuilder();
$oldPreferences->select('*')
- ->from('*PREFIX*preferences')
+ ->from('preferences')
->where($oldPreferences->expr()->eq('appid', $oldPreferences->createParameter('appid')))
->setParameter('appid', 'files_encryption');
$preferenceSettings = $oldPreferences->execute();
diff --git a/apps/encryption/tests/lib/MigrationTest.php b/apps/encryption/tests/lib/MigrationTest.php
index 5bc3b89b5b9..bb1f0a310a2 100644
--- a/apps/encryption/tests/lib/MigrationTest.php
+++ b/apps/encryption/tests/lib/MigrationTest.php
@@ -291,12 +291,12 @@ class MigrationTest extends \Test\TestCase {
/** @var \OCP\IDBConnection $connection */
$connection = \OC::$server->getDatabaseConnection();
$query = $connection->getQueryBuilder();
- $query->delete('*PREFIX*appconfig')
+ $query->delete('appconfig')
->where($query->expr()->eq('appid', $query->createParameter('appid')))
->setParameter('appid', 'encryption');
$query->execute();
$query = $connection->getQueryBuilder();
- $query->delete('*PREFIX*preferences')
+ $query->delete('preferences')
->where($query->expr()->eq('appid', $query->createParameter('appid')))
->setParameter('appid', 'encryption');
$query->execute();
@@ -309,10 +309,10 @@ class MigrationTest extends \Test\TestCase {
$this->invokePrivate($m, 'installedVersion', ['0.7']);
$m->updateDB();
- $this->verifyDB('*PREFIX*appconfig', 'files_encryption', 0);
- $this->verifyDB('*PREFIX*preferences', 'files_encryption', 0);
- $this->verifyDB('*PREFIX*appconfig', 'encryption', 3);
- $this->verifyDB('*PREFIX*preferences', 'encryption', 1);
+ $this->verifyDB('appconfig', 'files_encryption', 0);
+ $this->verifyDB('preferences', 'files_encryption', 0);
+ $this->verifyDB('appconfig', 'encryption', 3);
+ $this->verifyDB('preferences', 'encryption', 1);
}
@@ -329,17 +329,17 @@ class MigrationTest extends \Test\TestCase {
$this->invokePrivate($m, 'installedVersion', ['0.7']);
$m->updateDB();
- $this->verifyDB('*PREFIX*appconfig', 'files_encryption', 0);
- $this->verifyDB('*PREFIX*preferences', 'files_encryption', 0);
- $this->verifyDB('*PREFIX*appconfig', 'encryption', 3);
- $this->verifyDB('*PREFIX*preferences', 'encryption', 1);
+ $this->verifyDB('appconfig', 'files_encryption', 0);
+ $this->verifyDB('preferences', 'files_encryption', 0);
+ $this->verifyDB('appconfig', 'encryption', 3);
+ $this->verifyDB('preferences', 'encryption', 1);
// check if the existing values where overwritten correctly
/** @var \OC\DB\Connection $connection */
$connection = \OC::$server->getDatabaseConnection();
$query = $connection->getQueryBuilder();
$query->select('configvalue')
- ->from('*PREFIX*appconfig')
+ ->from('appconfig')
->where($query->expr()->andX(
$query->expr()->eq('appid', $query->createParameter('appid')),
$query->expr()->eq('configkey', $query->createParameter('configkey'))
@@ -353,7 +353,7 @@ class MigrationTest extends \Test\TestCase {
$query = $connection->getQueryBuilder();
$query->select('configvalue')
- ->from('*PREFIX*preferences')
+ ->from('preferences')
->where($query->expr()->andX(
$query->expr()->eq('appid', $query->createParameter('appid')),
$query->expr()->eq('configkey', $query->createParameter('configkey')),
@@ -399,7 +399,7 @@ class MigrationTest extends \Test\TestCase {
$connection = \OC::$server->getDatabaseConnection();
$query = $connection->getQueryBuilder();
$query->select('*')
- ->from('*PREFIX*filecache');
+ ->from('filecache');
$result = $query->execute();
$entries = $result->fetchAll();
foreach($entries as $entry) {
@@ -417,15 +417,15 @@ class MigrationTest extends \Test\TestCase {
/** @var \OCP\IDBConnection $connection */
$connection = \OC::$server->getDatabaseConnection();
$query = $connection->getQueryBuilder();
- $query->delete('*PREFIX*filecache');
+ $query->delete('filecache');
$query->execute();
$query = $connection->getQueryBuilder();
$result = $query->select('fileid')
- ->from('*PREFIX*filecache')
+ ->from('filecache')
->setMaxResults(1)->execute()->fetchAll();
$this->assertEmpty($result);
$query = $connection->getQueryBuilder();
- $query->insert('*PREFIX*filecache')
+ $query->insert('filecache')
->values(
array(
'storage' => $query->createParameter('storage'),
@@ -447,7 +447,7 @@ class MigrationTest extends \Test\TestCase {
}
$query = $connection->getQueryBuilder();
$result = $query->select('fileid')
- ->from('*PREFIX*filecache')
+ ->from('filecache')
->execute()->fetchAll();
$this->assertSame(19, count($result));
}
diff --git a/apps/files/appinfo/remote.php b/apps/files/appinfo/remote.php
index fff3332ef49..36479ae13d0 100644
--- a/apps/files/appinfo/remote.php
+++ b/apps/files/appinfo/remote.php
@@ -33,51 +33,23 @@ set_time_limit(0);
// Turn off output buffering to prevent memory problems
\OC_Util::obEnd();
+$serverFactory = new \OC\Connector\Sabre\ServerFactory(
+ \OC::$server->getConfig(),
+ \OC::$server->getLogger(),
+ \OC::$server->getDatabaseConnection(),
+ \OC::$server->getUserSession(),
+ \OC::$server->getMountManager(),
+ \OC::$server->getTagManager()
+);
+
// Backends
$authBackend = new \OC\Connector\Sabre\Auth();
+$requestUri = \OC::$server->getRequest()->getRequestUri();
-// Fire up server
-$objectTree = new \OC\Connector\Sabre\ObjectTree();
-$server = new \OC\Connector\Sabre\Server($objectTree);
-// Set URL explicitly due to reverse-proxy situations
-$server->httpRequest->setUrl(\OC::$server->getRequest()->getRequestUri());
-$server->setBaseUri($baseuri);
-
-// Load plugins
-$defaults = new OC_Defaults();
-$server->addPlugin(new \OC\Connector\Sabre\BlockLegacyClientPlugin(\OC::$server->getConfig()));
-$server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend, $defaults->getName()));
-// FIXME: The following line is a workaround for legacy components relying on being able to send a GET to /
-$server->addPlugin(new \OC\Connector\Sabre\DummyGetResponsePlugin());
-$server->addPlugin(new \OC\Connector\Sabre\FilesPlugin($objectTree));
-$server->addPlugin(new \OC\Connector\Sabre\MaintenancePlugin(\OC::$server->getConfig()));
-$server->addPlugin(new \OC\Connector\Sabre\ExceptionLoggerPlugin('webdav', \OC::$server->getLogger()));
-
-// wait with registering these until auth is handled and the filesystem is setup
-$server->on('beforeMethod', function () use ($server, $objectTree) {
- $view = \OC\Files\Filesystem::getView();
- $rootInfo = $view->getFileInfo('');
-
- // Create ownCloud Dir
- $mountManager = \OC\Files\Filesystem::getMountManager();
- $rootDir = new \OC\Connector\Sabre\Directory($view, $rootInfo);
- $objectTree->init($rootDir, $view, $mountManager);
-
- $server->addPlugin(new \OC\Connector\Sabre\TagsPlugin($objectTree, \OC::$server->getTagManager()));
- $server->addPlugin(new \OC\Connector\Sabre\QuotaPlugin($view));
-
- // custom properties plugin must be the last one
- $server->addPlugin(
- new \Sabre\DAV\PropertyStorage\Plugin(
- new \OC\Connector\Sabre\CustomPropertiesBackend(
- $objectTree,
- \OC::$server->getDatabaseConnection(),
- \OC::$server->getUserSession()->getUser()
- )
- )
- );
- $server->addPlugin(new \OC\Connector\Sabre\CopyEtagHeaderPlugin());
-}, 30); // priority 30: after auth (10) and acl(20), before lock(50) and handling the request
+$server = $serverFactory->createServer($baseuri, $requestUri, $authBackend, function() {
+ // use the view for the logged in user
+ return \OC\Files\Filesystem::getView();
+});
// And off we go!
$server->exec();
diff --git a/apps/files/css/files.css b/apps/files/css/files.css
index 7e3318a962b..26ba86b28c8 100644
--- a/apps/files/css/files.css
+++ b/apps/files/css/files.css
@@ -249,8 +249,8 @@ table th.column-last, table td.column-last {
box-sizing: border-box;
position: relative;
/* this can not be just width, both need to be set … table styling */
- min-width: 176px;
- max-width: 176px;
+ min-width: 130px;
+ max-width: 130px;
}
/* Multiselect bar */
@@ -326,14 +326,7 @@ table td.filename .nametext, .uploadtext, .modified, .column-last>span:first-chi
position: relative;
overflow: hidden;
text-overflow: ellipsis;
- width: 90%;
-}
-/* ellipsize long modified dates to make room for showing delete button */
-#fileList tr:hover .modified,
-#fileList tr:focus .modified,
-#fileList tr:hover .column-last>span:first-child,
-#fileList tr:focus .column-last>span:first-child {
- width: 75%;
+ width: 110px;
}
/* TODO fix usability bug (accidental file/folder selection) */
@@ -372,45 +365,27 @@ table td.filename .nametext .innernametext {
@media only screen and (min-width: 1366px) {
table td.filename .nametext .innernametext {
- max-width: 760px;
- }
-
- table tr:hover td.filename .nametext .innernametext,
- table tr:focus td.filename .nametext .innernametext {
- max-width: 480px;
+ max-width: 660px;
}
}
-
@media only screen and (min-width: 1200px) and (max-width: 1366px) {
table td.filename .nametext .innernametext {
- max-width: 600px;
- }
-
- table tr:hover td.filename .nametext .innernametext,
- table tr:focus td.filename .nametext .innernametext {
- max-width: 320px;
+ max-width: 500px;
}
}
-
-@media only screen and (min-width: 1000px) and (max-width: 1200px) {
+@media only screen and (min-width: 1100px) and (max-width: 1200px) {
table td.filename .nametext .innernametext {
max-width: 400px;
}
-
- table tr:hover td.filename .nametext .innernametext,
- table tr:focus td.filename .nametext .innernametext {
- max-width: 120px;
+}
+@media only screen and (min-width: 1000px) and (max-width: 1100px) {
+ table td.filename .nametext .innernametext {
+ max-width: 310px;
}
}
-
@media only screen and (min-width: 768px) and (max-width: 1000px) {
table td.filename .nametext .innernametext {
- max-width: 320px;
- }
-
- table tr:hover td.filename .nametext .innernametext,
- table tr:focus td.filename .nametext .innernametext {
- max-width: 40px;
+ max-width: 240px;
}
}
@@ -517,6 +492,23 @@ table td.filename .uploadtext {
font-size: 11px;
}
+.busy .fileactions, .busy .action {
+ visibility: hidden;
+}
+
+/* fix position of bubble pointer for Files app */
+.bubble,
+#app-navigation .app-navigation-entry-menu {
+ border-top-right-radius: 3px;
+}
+.bubble:after,
+#app-navigation .app-navigation-entry-menu:after {
+ right: 6px;
+}
+.bubble:before,
+#app-navigation .app-navigation-entry-menu:before {
+ right: 6px;
+}
/* force show the loading icon, not only on hover */
#fileList .icon-loading-small {
@@ -527,21 +519,15 @@ table td.filename .uploadtext {
}
#fileList img.move2trash { display:inline; margin:-8px 0; padding:16px 8px 16px 8px !important; float:right; }
-#fileList a.action.delete {
- position: absolute;
- right: 15px;
- padding: 17px 14px;
-}
#fileList .action.action-share-notification span, #fileList a.name {
cursor: default !important;
}
-a.action>img {
- max-height:16px;
- max-width:16px;
- vertical-align:text-bottom;
- margin-bottom: -1px;
+a.action > img {
+ max-height: 16px;
+ max-width: 16px;
+ vertical-align: text-bottom;
}
/* Actions for selected files */
@@ -578,10 +564,6 @@ a.action>img {
display:none;
}
-#fileList a.action[data-action="Rename"] {
- padding: 16px 14px 17px !important;
-}
-
.ie8 #fileList a.action img,
#fileList tr:hover a.action,
#fileList a.action.permanent,
@@ -693,3 +675,44 @@ table.dragshadow td.size {
.mask.transparent{
opacity: 0;
}
+
+.fileActionsMenu {
+ padding: 4px 12px;
+}
+.fileActionsMenu li {
+ padding: 5px 0;
+}
+#fileList .fileActionsMenu a.action img {
+ padding: initial;
+}
+#fileList .fileActionsMenu a.action {
+ padding: 10px;
+ margin: -10px;
+}
+
+.fileActionsMenu.hidden {
+ display: none;
+}
+
+#fileList .fileActionsMenu .action {
+ display: block;
+ line-height: 30px;
+ padding-left: 5px;
+ color: #000;
+ padding: 0;
+}
+
+.fileActionsMenu .action img,
+.fileActionsMenu .action .no-icon {
+ display: inline-block;
+ width: 16px;
+ margin-right: 5px;
+}
+
+.fileActionsMenu .action {
+ opacity: 0.5;
+}
+
+.fileActionsMenu li:hover .action {
+ opacity: 1;
+}
diff --git a/apps/files/css/mobile.css b/apps/files/css/mobile.css
index 4881f7c70e4..dd8244a2913 100644
--- a/apps/files/css/mobile.css
+++ b/apps/files/css/mobile.css
@@ -5,11 +5,6 @@
min-width: initial !important;
}
-/* do not show Deleted Files on mobile, not optimized yet and button too long */
-#controls #trash {
- display: none;
-}
-
/* hide size and date columns */
table th#headerSize,
table td.filesize,
@@ -38,7 +33,8 @@ table td.filename .nametext {
}
/* always show actions on mobile, not only on hover */
-#fileList a.action {
+#fileList a.action,
+#fileList a.action.action-menu.permanent {
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)" !important;
filter: alpha(opacity=20) !important;
opacity: .2 !important;
@@ -50,17 +46,19 @@ table td.filename .nametext {
filter: alpha(opacity=70) !important;
opacity: .7 !important;
}
-/* do not show Rename or Versions on mobile */
-#fileList .action.action-rename,
-#fileList .action.action-versions {
- display: none !important;
+#fileList a.action.action-menu img {
+ padding-left: 2px;
+}
+
+#fileList .fileActionsMenu {
+ margin-right: 5px;
}
/* some padding for better clickability */
#fileList a.action img {
padding: 0 6px 0 12px;
}
-/* hide text of the actions on mobile */
-#fileList a.action span {
+/* hide text of the share action on mobile */
+#fileList a.action-share span {
display: none;
}
diff --git a/apps/files/index.php b/apps/files/index.php
index dca3e5ae74d..a41ec059b55 100644
--- a/apps/files/index.php
+++ b/apps/files/index.php
@@ -138,6 +138,7 @@ foreach ($navItems as $item) {
}
OCP\Util::addscript('files', 'fileactions');
+OCP\Util::addscript('files', 'fileactionsmenu');
OCP\Util::addscript('files', 'files');
OCP\Util::addscript('files', 'navigation');
OCP\Util::addscript('files', 'keyboardshortcuts');
diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js
index 8dd26d71c3e..43f74c5816d 100644
--- a/apps/files/js/fileactions.js
+++ b/apps/files/js/fileactions.js
@@ -10,6 +10,12 @@
(function() {
+ var TEMPLATE_FILE_ACTION_TRIGGER =
+ '<a class="action action-{{nameLowerCase}}" href="#" data-action="{{name}}">' +
+ '{{#if icon}}<img class="svg" alt="{{altText}}" src="{{icon}}" />{{/if}}' +
+ '{{#if displayName}}<span> {{displayName}}</span>{{/if}}' +
+ '</a>';
+
/**
* Construct a new FileActions instance
* @constructs FileActions
@@ -18,6 +24,8 @@
var FileActions = function() {
this.initialize();
};
+ FileActions.TYPE_DROPDOWN = 0;
+ FileActions.TYPE_INLINE = 1;
FileActions.prototype = {
/** @lends FileActions.prototype */
actions: {},
@@ -38,6 +46,8 @@
*/
_updateListeners: {},
+ _fileActionTriggerTemplate: null,
+
/**
* @private
*/
@@ -46,6 +56,8 @@
// abusing jquery for events until we get a real event lib
this.$el = $('<div class="dummy-fileactions hidden"></div>');
$('body').append(this.$el);
+
+ this._showMenuClosure = _.bind(this._showMenu, this);
},
/**
@@ -111,6 +123,7 @@
displayName: displayName || name
});
},
+
/**
* Register action
*
@@ -125,15 +138,14 @@
displayName: action.displayName,
mime: mime,
icon: action.icon,
- permissions: action.permissions
+ permissions: action.permissions,
+ type: action.type || FileActions.TYPE_DROPDOWN
};
if (_.isUndefined(action.displayName)) {
actionSpec.displayName = t('files', name);
}
if (_.isFunction(action.render)) {
actionSpec.render = action.render;
- } else {
- actionSpec.render = _.bind(this._defaultRenderAction, this);
}
if (!this.actions[mime]) {
this.actions[mime] = {};
@@ -162,6 +174,16 @@
this.defaults[mime] = name;
this._notifyUpdateListeners('setDefault', {defaultAction: {mime: mime, name: name}});
},
+
+ /**
+ * Returns a map of file actions handlers matching the given conditions
+ *
+ * @param {string} mime mime type
+ * @param {string} type "dir" or "file"
+ * @param {int} permissions permissions
+ *
+ * @return {Object.<string,OCA.Files.FileActions~actionHandler>} map of action name to action spec
+ */
get: function (mime, type, permissions) {
var actions = this.getActions(mime, type, permissions);
var filteredActions = {};
@@ -170,6 +192,16 @@
});
return filteredActions;
},
+
+ /**
+ * Returns an array of file actions matching the given conditions
+ *
+ * @param {string} mime mime type
+ * @param {string} type "dir" or "file"
+ * @param {int} permissions permissions
+ *
+ * @return {Array.<OCA.Files.FileAction>} array of action specs
+ */
getActions: function (mime, type, permissions) {
var actions = {};
if (this.actions.all) {
@@ -197,7 +229,37 @@
});
return filteredActions;
},
+
+ /**
+ * Returns the default file action handler for the given conditions
+ *
+ * @param {string} mime mime type
+ * @param {string} type "dir" or "file"
+ * @param {int} permissions permissions
+ *
+ * @return {OCA.Files.FileActions~actionHandler} action handler
+ *
+ * @deprecated use getDefaultFileAction instead
+ */
getDefault: function (mime, type, permissions) {
+ var defaultActionSpec = this.getDefaultFileAction(mime, type, permissions);
+ if (defaultActionSpec) {
+ return defaultActionSpec.action;
+ }
+ return undefined;
+ },
+
+ /**
+ * Returns the default file action handler for the given conditions
+ *
+ * @param {string} mime mime type
+ * @param {string} type "dir" or "file"
+ * @param {int} permissions permissions
+ *
+ * @return {OCA.Files.FileActions~actionHandler} action handler
+ * @since 8.2
+ */
+ getDefaultFileAction: function(mime, type, permissions) {
var mimePart;
if (mime) {
mimePart = mime.substr(0, mime.indexOf('/'));
@@ -212,9 +274,10 @@
} else {
name = this.defaults.all;
}
- var actions = this.get(mime, type, permissions);
+ var actions = this.getActions(mime, type, permissions);
return actions[name];
},
+
/**
* Default function to render actions
*
@@ -224,87 +287,82 @@
* @param {OCA.Files.FileActionContext} context action context
*/
_defaultRenderAction: function(actionSpec, isDefault, context) {
- var name = actionSpec.name;
- if (name === 'Download' || !isDefault) {
- var $actionLink = this._makeActionLink(actionSpec, context);
+ if (!isDefault) {
+ var params = {
+ name: actionSpec.name,
+ nameLowerCase: actionSpec.name.toLowerCase(),
+ displayName: actionSpec.displayName,
+ icon: actionSpec.icon,
+ altText: actionSpec.altText,
+ };
+ if (_.isFunction(actionSpec.icon)) {
+ params.icon = actionSpec.icon(context.$file.attr('data-file'));
+ }
+
+ var $actionLink = this._makeActionLink(params, context);
context.$file.find('a.name>span.fileactions').append($actionLink);
+ $actionLink.addClass('permanent');
return $actionLink;
}
},
+
/**
* Renders the action link element
*
- * @param {OCA.Files.FileAction} actionSpec action object
- * @param {OCA.Files.FileActionContext} context action context
+ * @param {Object} params action params
*/
- _makeActionLink: function(actionSpec, context) {
- var img = actionSpec.icon;
- if (img && img.call) {
- img = img(context.$file.attr('data-file'));
- }
- var html = '<a href="#">';
- if (img) {
- html += '<img class="svg" alt="" src="' + img + '" />';
- }
- if (actionSpec.displayName) {
- html += '<span> ' + actionSpec.displayName + '</span>';
+ _makeActionLink: function(params) {
+ if (!this._fileActionTriggerTemplate) {
+ this._fileActionTriggerTemplate = Handlebars.compile(TEMPLATE_FILE_ACTION_TRIGGER);
}
- html += '</a>';
- return $(html);
+ return $(this._fileActionTriggerTemplate(params));
},
+
/**
- * Custom renderer for the "Rename" action.
- * Displays the rename action as an icon behind the file name.
+ * Displays the file actions dropdown menu
*
- * @param {OCA.Files.FileAction} actionSpec file action to render
- * @param {boolean} isDefault true if the action is a default action,
- * false otherwise
- * @param {OCAFiles.FileActionContext} context rendering context
+ * @param {string} fileName file name
+ * @param {OCA.Files.FileActionContext} context rendering context
*/
- _renderRenameAction: function(actionSpec, isDefault, context) {
- var $actionEl = this._makeActionLink(actionSpec, context);
- var $container = context.$file.find('a.name span.nametext');
- $actionEl.find('img').attr('alt', t('files', 'Rename'));
- $container.find('.action-rename').remove();
- $container.append($actionEl);
- return $actionEl;
+ _showMenu: function(fileName, context) {
+ var menu;
+ var $trigger = context.$file.closest('tr').find('.fileactions .action-menu');
+ $trigger.addClass('open');
+
+ menu = new OCA.Files.FileActionsMenu();
+ menu.$el.on('afterHide', function() {
+ context.$file.removeClass('mouseOver');
+ $trigger.removeClass('open');
+ menu.remove();
+ });
+
+ context.$file.addClass('mouseOver');
+ context.$file.find('td.filename').append(menu.$el);
+ menu.show(context);
},
+
/**
- * Custom renderer for the "Delete" action.
- * Displays the "Delete" action as a trash icon at the end of
- * the table row.
- *
- * @param {OCA.Files.FileAction} actionSpec file action to render
- * @param {boolean} isDefault true if the action is a default action,
- * false otherwise
- * @param {OCAFiles.FileActionContext} context rendering context
+ * Renders the menu trigger on the given file list row
+ *
+ * @param {Object} $tr file list row element
+ * @param {OCA.Files.FileActionContext} context rendering context
*/
- _renderDeleteAction: function(actionSpec, isDefault, context) {
- var mountType = context.$file.attr('data-mounttype');
- var deleteTitle = t('files', 'Delete');
- if (mountType === 'external-root') {
- deleteTitle = t('files', 'Disconnect storage');
- } 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="' +cssClasses + '">' +
- '<span class="hidden-visually">' + escapeHTML(deleteTitle) + '</span>' +
- '</a>'
- );
- var $container = context.$file.find('td:last');
- $container.find('.delete').remove();
- $container.append($actionLink);
- return $actionLink;
+ _renderMenuTrigger: function($tr, context) {
+ // remove previous
+ $tr.find('.action-menu').remove();
+
+ var $el = this._renderInlineAction({
+ name: 'menu',
+ displayName: '',
+ icon: OC.imagePath('core', 'actions/more'),
+ altText: t('files', 'Actions'),
+ action: this._showMenuClosure
+ }, false, context);
+
+ $el.addClass('permanent');
},
+
/**
* Renders the action element by calling actionSpec.render() and
* registers the click event to process the action.
@@ -312,25 +370,32 @@
* @param {OCA.Files.FileAction} actionSpec file action to render
* @param {boolean} isDefault true if the action is a default action,
* false otherwise
- * @param {OCAFiles.FileActionContext} context rendering context
+ * @param {OCA.Files.FileActionContext} context rendering context
*/
- _renderAction: function(actionSpec, isDefault, context) {
- var $actionEl = actionSpec.render(actionSpec, isDefault, context);
+ _renderInlineAction: function(actionSpec, isDefault, context) {
+ var renderFunc = actionSpec.render || _.bind(this._defaultRenderAction, this);
+ var $actionEl = renderFunc(actionSpec, isDefault, context);
if (!$actionEl || !$actionEl.length) {
return;
}
- $actionEl.addClass('action action-' + actionSpec.name.toLowerCase());
- $actionEl.attr('data-action', actionSpec.name);
$actionEl.on(
'click', {
a: null
},
function(event) {
+ event.stopPropagation();
+ event.preventDefault();
+
+ if ($actionEl.hasClass('open')) {
+ return;
+ }
+
var $file = $(event.target).closest('tr');
+ if ($file.hasClass('busy')) {
+ return;
+ }
var currentFile = $file.find('td.filename');
var fileName = $file.attr('data-file');
- event.stopPropagation();
- event.preventDefault();
context.fileActions.currentFile = currentFile;
// also set on global object for legacy apps
@@ -346,6 +411,7 @@
);
return $actionEl;
},
+
/**
* Display file actions for the given element
* @param parent "td" element of the file for which to display actions
@@ -376,36 +442,29 @@
nameLinks = parent.children('a.name');
nameLinks.find('.fileactions, .nametext .action').remove();
nameLinks.append('<span class="fileactions" />');
- var defaultAction = this.getDefault(
+ var defaultAction = this.getDefaultFileAction(
this.getCurrentMimeType(),
this.getCurrentType(),
this.getCurrentPermissions()
);
+ var context = {
+ $file: $tr,
+ fileActions: this,
+ fileList: fileList
+ };
+
$.each(actions, function (name, actionSpec) {
- if (name !== 'Share') {
- self._renderAction(
+ if (actionSpec.type === FileActions.TYPE_INLINE) {
+ self._renderInlineAction(
actionSpec,
- actionSpec.action === defaultAction, {
- $file: $tr,
- fileActions: this,
- fileList : fileList
- }
+ defaultAction && actionSpec.name === defaultAction.name,
+ context
);
}
});
- // added here to make sure it's always the last action
- var shareActionSpec = actions.Share;
- if (shareActionSpec){
- this._renderAction(
- shareActionSpec,
- shareActionSpec.action === defaultAction, {
- $file: $tr,
- fileActions: this,
- fileList: fileList
- }
- );
- }
+
+ this._renderMenuTrigger($tr, context);
if (triggerEvent){
fileList.$fileList.trigger(jQuery.Event("fileActionsReady", {fileList: fileList, $files: $tr}));
@@ -429,35 +488,42 @@
*/
registerDefaultActions: function() {
this.registerAction({
- name: 'Delete',
- displayName: '',
+ name: 'Download',
+ displayName: t('files', 'Download'),
mime: 'all',
- // 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');
+ icon: function () {
+ return OC.imagePath('core', 'actions/download');
},
- 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) {
+ actionHandler: function (filename, context) {
+ var dir = context.dir || context.fileList.getCurrentDirectory();
+ var url = context.fileList.getDownloadUrl(filename, dir);
+
+ var downloadFileaction = $(context.$file).find('.fileactions .action-download');
+
+ // don't allow a second click on the download action
+ if(downloadFileaction.hasClass('disabled')) {
return;
}
- context.fileList.do_delete(fileName, context.dir);
- $('.tipsy').remove();
+
+ if (url) {
+ var disableLoadingState = function() {
+ context.fileList.showFileBusyState(filename, false);
+ };
+
+ context.fileList.showFileBusyState(downloadFileaction, true);
+ OCA.Files.Files.handleDownload(url, disableLoadingState);
+ }
}
});
- // t('files', 'Rename')
this.registerAction({
name: 'Rename',
- displayName: '',
mime: 'all',
permissions: OC.PERMISSION_UPDATE,
icon: function() {
return OC.imagePath('core', 'actions/rename');
},
- render: _.bind(this._renderRenameAction, this),
actionHandler: function (filename, context) {
context.fileList.rename(filename);
}
@@ -471,30 +537,25 @@
context.fileList.changeDirectory(dir + filename);
});
- this.setDefault('dir', 'Open');
-
- this.register('all', 'Download', OC.PERMISSION_READ, function () {
- return OC.imagePath('core', 'actions/download');
- }, function (filename, context) {
- var dir = context.dir || context.fileList.getCurrentDirectory();
- var url = context.fileList.getDownloadUrl(filename, dir);
-
- var downloadFileaction = $(context.$file).find('.fileactions .action-download');
-
- // don't allow a second click on the download action
- if(downloadFileaction.hasClass('disabled')) {
- return;
+ this.registerAction({
+ name: 'Delete',
+ mime: 'all',
+ // 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');
+ },
+ 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();
}
+ });
- if (url) {
- var disableLoadingState = function(){
- OCA.Files.FileActions.updateFileActionSpinner(downloadFileaction, false);
- };
-
- OCA.Files.FileActions.updateFileActionSpinner(downloadFileaction, true);
- OCA.Files.Files.handleDownload(url, disableLoadingState);
- }
- }, t('files', 'Download'));
+ this.setDefault('dir', 'Open');
}
};
diff --git a/apps/files/js/fileactionsmenu.js b/apps/files/js/fileactionsmenu.js
new file mode 100644
index 00000000000..623ebde5442
--- /dev/null
+++ b/apps/files/js/fileactionsmenu.js
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2014
+ *
+ * This file is licensed under the Affero General Public License version 3
+ * or later.
+ *
+ * See the COPYING-README file.
+ *
+ */
+
+(function() {
+
+ var TEMPLATE_MENU =
+ '<ul>' +
+ '{{#each items}}' +
+ '<li>' +
+ '<a href="#" class="action action-{{nameLowerCase}} permanent" data-action="{{name}}">{{#if icon}}<img src="{{icon}}"/>{{else}}<span class="no-icon"></span>{{/if}}<span>{{displayName}}</span></a>' +
+ '</li>' +
+ '{{/each}}' +
+ '</ul>';
+
+ /**
+ * Construct a new FileActionsMenu instance
+ * @constructs FileActionsMenu
+ * @memberof OCA.Files
+ */
+ var FileActionsMenu = OC.Backbone.View.extend({
+ tagName: 'div',
+ className: 'fileActionsMenu bubble hidden open menu',
+
+ /**
+ * Current context
+ *
+ * @type OCA.Files.FileActionContext
+ */
+ _context: null,
+
+ events: {
+ 'click a.action': '_onClickAction'
+ },
+
+ template: function(data) {
+ if (!OCA.Files.FileActionsMenu._TEMPLATE) {
+ OCA.Files.FileActionsMenu._TEMPLATE = Handlebars.compile(TEMPLATE_MENU);
+ }
+ return OCA.Files.FileActionsMenu._TEMPLATE(data);
+ },
+
+ /**
+ * Event handler whenever an action has been clicked within the menu
+ *
+ * @param {Object} event event object
+ */
+ _onClickAction: function(event) {
+ var $target = $(event.target);
+ if (!$target.is('a')) {
+ $target = $target.closest('a');
+ }
+ var fileActions = this._context.fileActions;
+ var actionName = $target.attr('data-action');
+ var actions = fileActions.getActions(
+ fileActions.getCurrentMimeType(),
+ fileActions.getCurrentType(),
+ fileActions.getCurrentPermissions()
+ );
+ var actionSpec = actions[actionName];
+ var fileName = this._context.$file.attr('data-file');
+
+ event.stopPropagation();
+ event.preventDefault();
+
+ OC.hideMenus();
+
+ actionSpec.action(
+ fileName,
+ this._context
+ );
+ },
+
+ /**
+ * Renders the menu with the currently set items
+ */
+ render: function() {
+ var fileActions = this._context.fileActions;
+ var actions = fileActions.getActions(
+ fileActions.getCurrentMimeType(),
+ fileActions.getCurrentType(),
+ fileActions.getCurrentPermissions()
+ );
+
+ var defaultAction = fileActions.getDefaultFileAction(
+ fileActions.getCurrentMimeType(),
+ fileActions.getCurrentType(),
+ fileActions.getCurrentPermissions()
+ );
+
+ var items = _.filter(actions, function(actionSpec) {
+ return (
+ actionSpec.type === OCA.Files.FileActions.TYPE_DROPDOWN &&
+ (!defaultAction || actionSpec.name !== defaultAction.name)
+ );
+ });
+ items = _.map(items, function(item) {
+ item.nameLowerCase = item.name.toLowerCase();
+ return item;
+ });
+
+ this.$el.html(this.template({
+ items: items
+ }));
+ },
+
+ /**
+ * Displays the menu under the given element
+ *
+ * @param {OCA.Files.FileActionContext} context context
+ * @param {Object} $trigger trigger element
+ */
+ show: function(context) {
+ this._context = context;
+
+ this.render();
+ this.$el.removeClass('hidden');
+
+ OC.showMenu(null, this.$el);
+ }
+ });
+
+ OCA.Files.FileActionsMenu = FileActionsMenu;
+
+})();
+
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index f5629ecd2c3..e297edcf11b 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -1444,9 +1444,7 @@
}
_.each(fileNames, function(fileName) {
var $tr = self.findFileEl(fileName);
- var $thumbEl = $tr.find('.thumbnail');
- var oldBackgroundImage = $thumbEl.css('background-image');
- $thumbEl.css('background-image', 'url('+ OC.imagePath('core', 'loading.gif') + ')');
+ self.showFileBusyState($tr, true);
// TODO: improve performance by sending all file names in a single call
$.post(
OC.filePath('files', 'ajax', 'move.php'),
@@ -1488,7 +1486,7 @@
} else {
OC.dialogs.alert(t('files', 'Error moving file'), t('files', 'Error'));
}
- $thumbEl.css('background-image', oldBackgroundImage);
+ self.showFileBusyState($tr, false);
}
);
});
@@ -1549,14 +1547,13 @@
try {
var newName = input.val();
- var $thumbEl = tr.find('.thumbnail');
input.tipsy('hide');
form.remove();
if (newName !== oldname) {
checkInput();
// mark as loading (temp element)
- $thumbEl.css('background-image', 'url('+ OC.imagePath('core', 'loading.gif') + ')');
+ self.showFileBusyState(tr, true);
tr.attr('data-file', newName);
var basename = newName;
if (newName.indexOf('.') > 0 && tr.data('type') !== 'dir') {
@@ -1564,7 +1561,6 @@
}
td.find('a.name span.nametext').text(basename);
td.children('a.name').show();
- tr.find('.fileactions, .action').addClass('hidden');
$.ajax({
url: OC.filePath('files','ajax','rename.php'),
@@ -1636,6 +1632,44 @@
inList:function(file) {
return this.findFileEl(file).length;
},
+
+ /**
+ * Shows busy state on a given file row or multiple
+ *
+ * @param {string|Array.<string>} files file name or array of file names
+ * @param {bool} [busy=true] busy state, true for busy, false to remove busy state
+ *
+ * @since 8.2
+ */
+ showFileBusyState: function(files, state) {
+ var self = this;
+ if (!_.isArray(files)) {
+ files = [files];
+ }
+
+ if (_.isUndefined(state)) {
+ state = true;
+ }
+
+ _.each(files, function($tr) {
+ // jquery element already ?
+ if (!$tr.is) {
+ $tr = self.findFileEl($tr);
+ }
+
+ var $thumbEl = $tr.find('.thumbnail');
+ $tr.toggleClass('busy', state);
+
+ if (state) {
+ $thumbEl.attr('data-oldimage', $thumbEl.css('background-image'));
+ $thumbEl.css('background-image', 'url('+ OC.imagePath('core', 'loading.gif') + ')');
+ } else {
+ $thumbEl.css('background-image', $thumbEl.attr('data-oldimage'));
+ $thumbEl.removeAttr('data-oldimage');
+ }
+ });
+ },
+
/**
* Delete the given files from the given dir
* @param files file names list (without path)
@@ -1649,9 +1683,8 @@
files=[files];
}
if (files) {
+ this.showFileBusyState(files, true);
for (var i=0; i<files.length; i++) {
- var deleteAction = this.findFileEl(files[i]).children("td.date").children(".action.delete");
- deleteAction.removeClass('icon-delete').addClass('icon-loading-small');
}
}
// Finish any existing actions
@@ -1669,7 +1702,7 @@
// no files passed, delete all in current dir
params.allfiles = true;
// show spinner for all files
- this.$fileList.find('tr>td.date .action.delete').removeClass('icon-delete').addClass('icon-loading-small');
+ this.$fileList.find('tr').addClass('busy');
}
$.post(OC.filePath('files', 'ajax', 'delete.php'),
@@ -1712,8 +1745,7 @@
}
else {
$.each(files,function(index,file) {
- var deleteAction = self.findFileEl(file).find('.action.delete');
- deleteAction.removeClass('icon-loading-small').addClass('icon-delete');
+ self.$fileList.find('tr').removeClass('busy');
});
}
}
diff --git a/apps/files/js/tagsplugin.js b/apps/files/js/tagsplugin.js
index 293e25176f3..ec69ce4b965 100644
--- a/apps/files/js/tagsplugin.js
+++ b/apps/files/js/tagsplugin.js
@@ -81,6 +81,7 @@
displayName: 'Favorite',
mime: 'all',
permissions: OC.PERMISSION_READ,
+ type: OCA.Files.FileActions.TYPE_INLINE,
render: function(actionSpec, isDefault, context) {
var $file = context.$file;
var isFavorite = $file.data('favorite') === true;
diff --git a/apps/files/lib/activity.php b/apps/files/lib/activity.php
index fff49ea4ea5..bf80d0cfd7c 100644
--- a/apps/files/lib/activity.php
+++ b/apps/files/lib/activity.php
@@ -30,6 +30,7 @@ use OCP\IL10N;
use OCP\IURLGenerator;
class Activity implements IExtension {
+ const APP_FILES = 'files';
const FILTER_FILES = 'files';
const FILTER_FAVORITES = 'files_favorites';
@@ -78,7 +79,7 @@ class Activity implements IExtension {
* @return IL10N
*/
protected function getL10N($languageCode = null) {
- return $this->languageFactory->get('files', $languageCode);
+ return $this->languageFactory->get(self::APP_FILES, $languageCode);
}
/**
@@ -86,14 +87,21 @@ class Activity implements IExtension {
* If no additional types are to be added false is to be returned
*
* @param string $languageCode
- * @return array|false
+ * @return array|false Array "stringID of the type" => "translated string description for the setting"
+ * or Array "stringID of the type" => [
+ * 'desc' => "translated string description for the setting"
+ * 'methods' => [self::METHOD_*],
+ * ]
*/
public function getNotificationTypes($languageCode) {
$l = $this->getL10N($languageCode);
return [
self::TYPE_SHARE_CREATED => (string) $l->t('A new file or folder has been <strong>created</strong>'),
self::TYPE_SHARE_CHANGED => (string) $l->t('A file or folder has been <strong>changed</strong>'),
- self::TYPE_FAVORITES => (string) $l->t('Limit notifications about creation and changes to your <strong>favorite files</strong> <em>(Stream only)</em>'),
+ self::TYPE_FAVORITES => [
+ 'desc' => (string) $l->t('Limit notifications about creation and changes to your <strong>favorite files</strong> <em>(Stream only)</em>'),
+ 'methods' => [self::METHOD_STREAM],
+ ],
self::TYPE_SHARE_DELETED => (string) $l->t('A file or folder has been <strong>deleted</strong>'),
self::TYPE_SHARE_RESTORED => (string) $l->t('A file or folder has been <strong>restored</strong>'),
];
@@ -107,7 +115,7 @@ class Activity implements IExtension {
* @return array|false
*/
public function getDefaultTypes($method) {
- if ($method === 'stream') {
+ if ($method === self::METHOD_STREAM) {
$settings = array();
$settings[] = self::TYPE_SHARE_CREATED;
$settings[] = self::TYPE_SHARE_CHANGED;
@@ -132,29 +140,30 @@ class Activity implements IExtension {
* @return string|false
*/
public function translate($app, $text, $params, $stripPath, $highlightParams, $languageCode) {
- if ($app !== 'files') {
+ if ($app !== self::APP_FILES) {
return false;
}
+ $l = $this->getL10N($languageCode);
switch ($text) {
case 'created_self':
- return (string) $this->l->t('You created %1$s', $params);
+ return (string) $l->t('You created %1$s', $params);
case 'created_by':
- return (string) $this->l->t('%2$s created %1$s', $params);
+ return (string) $l->t('%2$s created %1$s', $params);
case 'created_public':
- return (string) $this->l->t('%1$s was created in a public folder', $params);
+ return (string) $l->t('%1$s was created in a public folder', $params);
case 'changed_self':
- return (string) $this->l->t('You changed %1$s', $params);
+ return (string) $l->t('You changed %1$s', $params);
case 'changed_by':
- return (string) $this->l->t('%2$s changed %1$s', $params);
+ return (string) $l->t('%2$s changed %1$s', $params);
case 'deleted_self':
- return (string) $this->l->t('You deleted %1$s', $params);
+ return (string) $l->t('You deleted %1$s', $params);
case 'deleted_by':
- return (string) $this->l->t('%2$s deleted %1$s', $params);
+ return (string) $l->t('%2$s deleted %1$s', $params);
case 'restored_self':
- return (string) $this->l->t('You restored %1$s', $params);
+ return (string) $l->t('You restored %1$s', $params);
case 'restored_by':
- return (string) $this->l->t('%2$s restored %1$s', $params);
+ return (string) $l->t('%2$s restored %1$s', $params);
default:
return false;
@@ -173,7 +182,7 @@ class Activity implements IExtension {
* @return array|false
*/
function getSpecialParameterList($app, $text) {
- if ($app === 'files') {
+ if ($app === self::APP_FILES) {
switch ($text) {
case 'created_self':
case 'created_by':
@@ -223,7 +232,7 @@ class Activity implements IExtension {
* @return integer|false
*/
public function getGroupParameter($activity) {
- if ($activity['app'] === 'files') {
+ if ($activity['app'] === self::APP_FILES) {
switch ($activity['subject']) {
case 'created_self':
case 'created_by':
@@ -309,7 +318,7 @@ class Activity implements IExtension {
$user = $this->activityManager->getCurrentUserId();
// Display actions from all files
if ($filter === self::FILTER_FILES) {
- return ['`app` = ?', ['files']];
+ return ['`app` = ?', [self::APP_FILES]];
}
if (!$user) {
@@ -323,7 +332,7 @@ class Activity implements IExtension {
$favorites = $this->helper->getFavoriteFilePaths($user);
} catch (\RuntimeException $e) {
// Too many favorites, can not put them into one query anymore...
- return ['`app` = ?', ['files']];
+ return ['`app` = ?', [self::APP_FILES]];
}
/*
@@ -331,7 +340,7 @@ class Activity implements IExtension {
* or `file` is a favorite or in a favorite folder
*/
$parameters = $fileQueryList = [];
- $parameters[] = 'files';
+ $parameters[] = self::APP_FILES;
$fileQueryList[] = '(`type` <> ? AND `type` <> ?)';
$parameters[] = self::TYPE_SHARE_CREATED;
@@ -346,7 +355,7 @@ class Activity implements IExtension {
$parameters[] = $favorite . '/%';
}
- $parameters[] = 'files';
+ $parameters[] = self::APP_FILES;
return [
' CASE WHEN `app` = ? THEN (' . implode(' OR ', $fileQueryList) . ') ELSE `app` <> ? END ',
@@ -363,6 +372,6 @@ class Activity implements IExtension {
* @return bool
*/
protected function userSettingFavoritesOnly($user) {
- return (bool) $this->config->getUserValue($user, 'activity', 'notify_stream_' . self::TYPE_FAVORITES, false);
+ return (bool) $this->config->getUserValue($user, 'activity', 'notify_' . self::METHOD_STREAM . '_' . self::TYPE_FAVORITES, false);
}
}
diff --git a/apps/files/tests/activitytest.php b/apps/files/tests/activitytest.php
index 4ab8ad11eae..cdb1d21bcd8 100644
--- a/apps/files/tests/activitytest.php
+++ b/apps/files/tests/activitytest.php
@@ -42,6 +42,9 @@ class ActivityTest extends TestCase {
/** @var \PHPUnit_Framework_MockObject_MockObject */
protected $activityHelper;
+ /** @var \PHPUnit_Framework_MockObject_MockObject */
+ protected $l10nFactory;
+
/** @var \OCA\Files\Activity */
protected $activityExtension;
@@ -67,8 +70,28 @@ class ActivityTest extends TestCase {
$this->config
);
+ $this->l10nFactory = $this->getMockBuilder('OC\L10N\Factory')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $deL10n = $this->getMockBuilder('OC_L10N')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $deL10n->expects($this->any())
+ ->method('t')
+ ->willReturnCallback(function ($argument) {
+ return 'translate(' . $argument . ')';
+ });
+
+ $this->l10nFactory->expects($this->any())
+ ->method('get')
+ ->willReturnMap([
+ ['files', null, new \OC_L10N('files', 'en')],
+ ['files', 'en', new \OC_L10N('files', 'en')],
+ ['files', 'de', $deL10n],
+ ]);
+
$this->activityExtension = $activityExtension = new Activity(
- new \OC\L10N\Factory(),
+ $this->l10nFactory,
$this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(),
$this->activityManager,
$this->activityHelper,
@@ -111,6 +134,26 @@ class ActivityTest extends TestCase {
$this->activityExtension->translate('files_sharing', '', [], false, false, 'en'),
'Asserting that no translations are set for files_sharing'
);
+
+ // Test english
+ $this->assertNotFalse(
+ $this->activityExtension->translate('files', 'deleted_self', ['file'], false, false, 'en'),
+ 'Asserting that translations are set for files.deleted_self'
+ );
+ $this->assertStringStartsWith(
+ 'You deleted ',
+ $this->activityExtension->translate('files', 'deleted_self', ['file'], false, false, 'en')
+ );
+
+ // Test translation
+ $this->assertNotFalse(
+ $this->activityExtension->translate('files', 'deleted_self', ['file'], false, false, 'de'),
+ 'Asserting that translations are set for files.deleted_self'
+ );
+ $this->assertStringStartsWith(
+ 'translate(You deleted ',
+ $this->activityExtension->translate('files', 'deleted_self', ['file'], false, false, 'de')
+ );
}
public function testGetSpecialParameterList() {
diff --git a/apps/files/tests/js/fileactionsSpec.js b/apps/files/tests/js/fileactionsSpec.js
index e420ab828af..236cff6cafd 100644
--- a/apps/files/tests/js/fileactionsSpec.js
+++ b/apps/files/tests/js/fileactionsSpec.js
@@ -20,8 +20,7 @@
*/
describe('OCA.Files.FileActions tests', function() {
- var $filesTable, fileList;
- var FileActions;
+ var fileList, fileActions;
beforeEach(function() {
// init horrible parameters
@@ -29,211 +28,191 @@ describe('OCA.Files.FileActions tests', function() {
$body.append('<input type="hidden" id="dir" value="/subdir"></input>');
$body.append('<input type="hidden" id="permissions" value="31"></input>');
// dummy files table
- $filesTable = $body.append('<table id="filestable"></table>');
- fileList = new OCA.Files.FileList($('#testArea'));
- FileActions = new OCA.Files.FileActions();
- FileActions.registerDefaultActions();
+ fileActions = new OCA.Files.FileActions();
+ fileActions.registerAction({
+ name: 'Testdropdown',
+ displayName: 'Testdropdowndisplay',
+ mime: 'all',
+ permissions: OC.PERMISSION_READ,
+ icon: function () {
+ return OC.imagePath('core', 'actions/download');
+ }
+ });
+
+ fileActions.registerAction({
+ name: 'Testinline',
+ displayName: 'Testinlinedisplay',
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ mime: 'all',
+ permissions: OC.PERMISSION_READ
+ });
+
+ fileActions.registerAction({
+ name: 'Testdefault',
+ displayName: 'Testdefaultdisplay',
+ mime: 'all',
+ permissions: OC.PERMISSION_READ
+ });
+ fileActions.setDefault('all', 'Testdefault');
+ fileList = new OCA.Files.FileList($body, {
+ fileActions: fileActions
+ });
});
afterEach(function() {
- FileActions = null;
+ fileActions = null;
fileList.destroy();
fileList = undefined;
$('#dir, #permissions, #filestable').remove();
});
it('calling clear() clears file actions', function() {
- FileActions.clear();
- expect(FileActions.actions).toEqual({});
- expect(FileActions.defaults).toEqual({});
- expect(FileActions.icons).toEqual({});
- expect(FileActions.currentFile).toBe(null);
+ fileActions.clear();
+ expect(fileActions.actions).toEqual({});
+ expect(fileActions.defaults).toEqual({});
+ expect(fileActions.icons).toEqual({});
+ expect(fileActions.currentFile).toBe(null);
});
- it('calling display() sets file actions', function() {
- var fileData = {
- id: 18,
- type: 'file',
- name: 'testName.txt',
- mimetype: 'text/plain',
- size: '1234',
- etag: 'a01234c',
- mtime: '123456'
- };
-
- // note: FileActions.display() is called implicitly
- var $tr = fileList.add(fileData);
-
- // actions defined after call
- expect($tr.find('.action.action-download').length).toEqual(1);
- expect($tr.find('.action.action-download').attr('data-action')).toEqual('Download');
- expect($tr.find('.nametext .action.action-rename').length).toEqual(1);
- expect($tr.find('.nametext .action.action-rename').attr('data-action')).toEqual('Rename');
- expect($tr.find('.action.delete').length).toEqual(1);
- });
- it('calling display() twice correctly replaces file actions', function() {
- var fileData = {
- id: 18,
- type: 'file',
- name: 'testName.txt',
- mimetype: 'text/plain',
- size: '1234',
- etag: 'a01234c',
- mtime: '123456'
- };
- var $tr = fileList.add(fileData);
-
- FileActions.display($tr.find('td.filename'), true, fileList);
- FileActions.display($tr.find('td.filename'), true, fileList);
-
- // actions defined after cal
- expect($tr.find('.action.action-download').length).toEqual(1);
- expect($tr.find('.nametext .action.action-rename').length).toEqual(1);
- expect($tr.find('.action.delete').length).toEqual(1);
- });
- it('redirects to download URL when clicking download', function() {
- var redirectStub = sinon.stub(OC, 'redirect');
- var fileData = {
- id: 18,
- type: 'file',
- name: 'testName.txt',
- mimetype: 'text/plain',
- size: '1234',
- etag: 'a01234c',
- mtime: '123456'
- };
- var $tr = fileList.add(fileData);
- FileActions.display($tr.find('td.filename'), true, fileList);
-
- $tr.find('.action-download').click();
-
- expect(redirectStub.calledOnce).toEqual(true);
- expect(redirectStub.getCall(0).args[0]).toContain(
- OC.webroot +
- '/index.php/apps/files/ajax/download.php' +
- '?dir=%2Fsubdir&files=testName.txt');
- redirectStub.restore();
- });
- it('takes the file\'s path into account when clicking download', function() {
- var redirectStub = sinon.stub(OC, 'redirect');
- var fileData = {
- id: 18,
- type: 'file',
- name: 'testName.txt',
- path: '/anotherpath/there',
- mimetype: 'text/plain',
- size: '1234',
- etag: 'a01234c',
- mtime: '123456'
- };
- var $tr = fileList.add(fileData);
- FileActions.display($tr.find('td.filename'), true, fileList);
-
- $tr.find('.action-download').click();
-
- expect(redirectStub.calledOnce).toEqual(true);
- expect(redirectStub.getCall(0).args[0]).toContain(
- OC.webroot + '/index.php/apps/files/ajax/download.php' +
- '?dir=%2Fanotherpath%2Fthere&files=testName.txt'
- );
- redirectStub.restore();
- });
- it('deletes file when clicking 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'
- };
- var $tr = fileList.add(fileData);
- FileActions.display($tr.find('td.filename'), true, fileList);
-
- $tr.find('.action.delete').click();
-
- expect(deleteStub.calledOnce).toEqual(true);
- expect(deleteStub.getCall(0).args[0]).toEqual('testName.txt');
- 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);
+ describe('displaying actions', function() {
+ var $tr;
- var $action = $tr.find('.action.delete');
+ beforeEach(function() {
+ var fileData = {
+ id: 18,
+ type: 'file',
+ name: 'testName.txt',
+ mimetype: 'text/plain',
+ size: '1234',
+ etag: 'a01234c',
+ mtime: '123456',
+ permissions: OC.PERMISSION_READ | OC.PERMISSION_UPDATE
+ };
- 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();
+ // note: FileActions.display() is called implicitly
+ $tr = fileList.add(fileData);
+ });
+ it('renders inline file actions', function() {
+ // actions defined after call
+ expect($tr.find('.action.action-testinline').length).toEqual(1);
+ expect($tr.find('.action.action-testinline').attr('data-action')).toEqual('Testinline');
+ });
+ it('does not render dropdown actions', function() {
+ expect($tr.find('.action.action-testdropdown').length).toEqual(0);
+ });
+ it('does not render default action', function() {
+ expect($tr.find('.action.action-testdefault').length).toEqual(0);
+ });
+ it('replaces file actions when displayed twice', function() {
+ fileActions.display($tr.find('td.filename'), true, fileList);
+ fileActions.display($tr.find('td.filename'), true, fileList);
+
+ expect($tr.find('.action.action-testinline').length).toEqual(1);
+ });
+ it('renders actions menu trigger', function() {
+ expect($tr.find('.action.action-menu').length).toEqual(1);
+ expect($tr.find('.action.action-menu').attr('data-action')).toEqual('menu');
+ });
+ it('only renders actions relevant to the mime type', function() {
+ fileActions.registerAction({
+ name: 'Match',
+ displayName: 'MatchDisplay',
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ mime: 'text/plain',
+ permissions: OC.PERMISSION_READ
+ });
+ fileActions.registerAction({
+ name: 'Nomatch',
+ displayName: 'NoMatchDisplay',
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ mime: 'application/octet-stream',
+ permissions: OC.PERMISSION_READ
+ });
+
+ fileActions.display($tr.find('td.filename'), true, fileList);
+ expect($tr.find('.action.action-match').length).toEqual(1);
+ expect($tr.find('.action.action-nomatch').length).toEqual(0);
+ });
+ it('only renders actions relevant to the permissions', function() {
+ fileActions.registerAction({
+ name: 'Match',
+ displayName: 'MatchDisplay',
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ mime: 'text/plain',
+ permissions: OC.PERMISSION_UPDATE
+ });
+ fileActions.registerAction({
+ name: 'Nomatch',
+ displayName: 'NoMatchDisplay',
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ mime: 'text/plain',
+ permissions: OC.PERMISSION_DELETE
+ });
+
+ fileActions.display($tr.find('td.filename'), true, fileList);
+ expect($tr.find('.action.action-match').length).toEqual(1);
+ expect($tr.find('.action.action-nomatch').length).toEqual(0);
+ });
});
- it('passes context to action handler', function() {
- var actionStub = sinon.stub();
- var fileData = {
- id: 18,
- type: 'file',
- name: 'testName.txt',
- mimetype: 'text/plain',
- size: '1234',
- etag: 'a01234c',
- mtime: '123456'
- };
- var $tr = fileList.add(fileData);
- FileActions.register(
- 'all',
- 'Test',
- OC.PERMISSION_READ,
- OC.imagePath('core', 'actions/test'),
- actionStub
- );
- FileActions.display($tr.find('td.filename'), true, fileList);
- $tr.find('.action-test').click();
- expect(actionStub.calledOnce).toEqual(true);
- expect(actionStub.getCall(0).args[0]).toEqual('testName.txt');
- var context = actionStub.getCall(0).args[1];
- expect(context.$file.is($tr)).toEqual(true);
- expect(context.fileList).toBeDefined();
- expect(context.fileActions).toBeDefined();
- expect(context.dir).toEqual('/subdir');
-
- // when data-path is defined
- actionStub.reset();
- $tr.attr('data-path', '/somepath');
- $tr.find('.action-test').click();
- context = actionStub.getCall(0).args[1];
- expect(context.dir).toEqual('/somepath');
+ describe('action handler', function() {
+ var actionStub, $tr;
+
+ beforeEach(function() {
+ var fileData = {
+ id: 18,
+ type: 'file',
+ name: 'testName.txt',
+ mimetype: 'text/plain',
+ size: '1234',
+ etag: 'a01234c',
+ mtime: '123456'
+ };
+ actionStub = sinon.stub();
+ fileActions.registerAction({
+ name: 'Test',
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ mime: 'all',
+ icon: OC.imagePath('core', 'actions/test'),
+ permissions: OC.PERMISSION_READ,
+ actionHandler: actionStub
+ });
+ $tr = fileList.add(fileData);
+ });
+ it('passes context to action handler', function() {
+ $tr.find('.action-test').click();
+ expect(actionStub.calledOnce).toEqual(true);
+ expect(actionStub.getCall(0).args[0]).toEqual('testName.txt');
+ var context = actionStub.getCall(0).args[1];
+ expect(context.$file.is($tr)).toEqual(true);
+ expect(context.fileList).toBeDefined();
+ expect(context.fileActions).toBeDefined();
+ expect(context.dir).toEqual('/subdir');
+
+ // when data-path is defined
+ actionStub.reset();
+ $tr.attr('data-path', '/somepath');
+ $tr.find('.action-test').click();
+ context = actionStub.getCall(0).args[1];
+ expect(context.dir).toEqual('/somepath');
+ });
+ describe('actions menu', function() {
+ it('shows actions menu inside row when clicking the menu trigger', function() {
+ expect($tr.find('td.filename .fileActionsMenu').length).toEqual(0);
+ $tr.find('.action-menu').click();
+ expect($tr.find('td.filename .fileActionsMenu').length).toEqual(1);
+ });
+ it('shows highlight on current row', function() {
+ $tr.find('.action-menu').click();
+ expect($tr.hasClass('mouseOver')).toEqual(true);
+ });
+ it('cleans up after hiding', function() {
+ var clock = sinon.useFakeTimers();
+ $tr.find('.action-menu').click();
+ expect($tr.find('.fileActionsMenu').length).toEqual(1);
+ OC.hideMenus();
+ // sliding animation
+ clock.tick(500);
+ expect($tr.hasClass('mouseOver')).toEqual(false);
+ expect($tr.find('.fileActionsMenu').length).toEqual(0);
+ });
+ });
});
describe('custom rendering', function() {
var $tr;
@@ -251,10 +230,11 @@ describe('OCA.Files.FileActions tests', function() {
});
it('regular function', function() {
var actionStub = sinon.stub();
- FileActions.registerAction({
+ fileActions.registerAction({
name: 'Test',
displayName: '',
mime: 'all',
+ type: OCA.Files.FileActions.TYPE_INLINE,
permissions: OC.PERMISSION_READ,
render: function(actionSpec, isDefault, context) {
expect(actionSpec.name).toEqual('Test');
@@ -266,13 +246,13 @@ describe('OCA.Files.FileActions tests', function() {
expect(context.fileList).toEqual(fileList);
expect(context.$file[0]).toEqual($tr[0]);
- var $customEl = $('<a href="#"><span>blabli</span><span>blabla</span></a>');
+ var $customEl = $('<a class="action action-test" href="#"><span>blabli</span><span>blabla</span></a>');
$tr.find('td:first').append($customEl);
return $customEl;
},
actionHandler: actionStub
});
- FileActions.display($tr.find('td.filename'), true, fileList);
+ fileActions.display($tr.find('td.filename'), true, fileList);
var $actionEl = $tr.find('td:first .action-test');
expect($actionEl.length).toEqual(1);
@@ -306,20 +286,22 @@ describe('OCA.Files.FileActions tests', function() {
var actions2 = new OCA.Files.FileActions();
var actionStub1 = sinon.stub();
var actionStub2 = sinon.stub();
- actions1.register(
- 'all',
- 'Test',
- OC.PERMISSION_READ,
- OC.imagePath('core', 'actions/test'),
- actionStub1
- );
- actions2.register(
- 'all',
- 'Test2',
- OC.PERMISSION_READ,
- OC.imagePath('core', 'actions/test'),
- actionStub2
- );
+ actions1.registerAction({
+ name: 'Test',
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ mime: 'all',
+ permissions: OC.PERMISSION_READ,
+ icon: OC.imagePath('core', 'actions/test'),
+ actionHandler: actionStub1
+ });
+ actions2.registerAction({
+ name: 'Test2',
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ mime: 'all',
+ permissions: OC.PERMISSION_READ,
+ icon: OC.imagePath('core', 'actions/test'),
+ actionHandler: actionStub2
+ });
actions2.merge(actions1);
actions2.display($tr.find('td.filename'), true, fileList);
@@ -342,20 +324,22 @@ describe('OCA.Files.FileActions tests', function() {
var actions2 = new OCA.Files.FileActions();
var actionStub1 = sinon.stub();
var actionStub2 = sinon.stub();
- actions1.register(
- 'all',
- 'Test',
- OC.PERMISSION_READ,
- OC.imagePath('core', 'actions/test'),
- actionStub1
- );
- actions2.register(
- 'all',
- 'Test', // override
- OC.PERMISSION_READ,
- OC.imagePath('core', 'actions/test'),
- actionStub2
- );
+ actions1.registerAction({
+ name: 'Test',
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ mime: 'all',
+ permissions: OC.PERMISSION_READ,
+ icon: OC.imagePath('core', 'actions/test'),
+ actionHandler: actionStub1
+ });
+ actions2.registerAction({
+ name: 'Test', // override
+ mime: 'all',
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ permissions: OC.PERMISSION_READ,
+ icon: OC.imagePath('core', 'actions/test'),
+ actionHandler: actionStub2
+ });
actions1.merge(actions2);
actions1.display($tr.find('td.filename'), true, fileList);
@@ -371,24 +355,26 @@ describe('OCA.Files.FileActions tests', function() {
var actions2 = new OCA.Files.FileActions();
var actionStub1 = sinon.stub();
var actionStub2 = sinon.stub();
- actions1.register(
- 'all',
- 'Test',
- OC.PERMISSION_READ,
- OC.imagePath('core', 'actions/test'),
- actionStub1
- );
+ actions1.registerAction({
+ mime: 'all',
+ name: 'Test',
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ permissions: OC.PERMISSION_READ,
+ icon: OC.imagePath('core', 'actions/test'),
+ actionHandler: actionStub1
+ });
actions1.merge(actions2);
// late override
- actions1.register(
- 'all',
- 'Test', // override
- OC.PERMISSION_READ,
- OC.imagePath('core', 'actions/test'),
- actionStub2
- );
+ actions1.registerAction({
+ mime: 'all',
+ name: 'Test', // override
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ permissions: OC.PERMISSION_READ,
+ icon: OC.imagePath('core', 'actions/test'),
+ actionHandler: actionStub2
+ });
actions1.display($tr.find('td.filename'), true, fileList);
@@ -403,25 +389,27 @@ describe('OCA.Files.FileActions tests', function() {
var actions2 = new OCA.Files.FileActions();
var actionStub1 = sinon.stub();
var actionStub2 = sinon.stub();
- actions1.register(
- 'all',
- 'Test',
- OC.PERMISSION_READ,
- OC.imagePath('core', 'actions/test'),
- actionStub1
- );
+ actions1.registerAction({
+ mime: 'all',
+ name: 'Test',
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ permissions: OC.PERMISSION_READ,
+ icon: OC.imagePath('core', 'actions/test'),
+ actionHandler: actionStub1
+ });
// copy the Test action to actions2
actions2.merge(actions1);
// late override
- actions2.register(
- 'all',
- 'Test', // override
- OC.PERMISSION_READ,
- OC.imagePath('core', 'actions/test'),
- actionStub2
- );
+ actions2.registerAction({
+ mime: 'all',
+ name: 'Test', // override
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ permissions: OC.PERMISSION_READ,
+ icon: OC.imagePath('core', 'actions/test'),
+ actionHandler: actionStub2
+ });
// check if original actions still call the correct handler
actions1.display($tr.find('td.filename'), true, fileList);
@@ -444,42 +432,45 @@ describe('OCA.Files.FileActions tests', function() {
it('notifies update event handlers once after multiple changes', function() {
var actionStub = sinon.stub();
var handler = sinon.stub();
- FileActions.on('registerAction', handler);
- FileActions.register(
- 'all',
- 'Test',
- OC.PERMISSION_READ,
- OC.imagePath('core', 'actions/test'),
- actionStub
- );
- FileActions.register(
- 'all',
- 'Test2',
- OC.PERMISSION_READ,
- OC.imagePath('core', 'actions/test'),
- actionStub
- );
+ fileActions.on('registerAction', handler);
+ fileActions.registerAction({
+ mime: 'all',
+ name: 'Test',
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ permissions: OC.PERMISSION_READ,
+ icon: OC.imagePath('core', 'actions/test'),
+ actionHandler: actionStub
+ });
+ fileActions.registerAction({
+ mime: 'all',
+ name: 'Test2',
+ permissions: OC.PERMISSION_READ,
+ icon: OC.imagePath('core', 'actions/test'),
+ actionHandler: actionStub
+ });
expect(handler.calledTwice).toEqual(true);
});
it('does not notifies update event handlers after unregistering', function() {
var actionStub = sinon.stub();
var handler = sinon.stub();
- FileActions.on('registerAction', handler);
- FileActions.off('registerAction', handler);
- FileActions.register(
- 'all',
- 'Test',
- OC.PERMISSION_READ,
- OC.imagePath('core', 'actions/test'),
- actionStub
- );
- FileActions.register(
- 'all',
- 'Test2',
- OC.PERMISSION_READ,
- OC.imagePath('core', 'actions/test'),
- actionStub
- );
+ fileActions.on('registerAction', handler);
+ fileActions.off('registerAction', handler);
+ fileActions.registerAction({
+ mime: 'all',
+ name: 'Test',
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ permissions: OC.PERMISSION_READ,
+ icon: OC.imagePath('core', 'actions/test'),
+ actionHandler: actionStub
+ });
+ fileActions.registerAction({
+ mime: 'all',
+ name: 'Test2',
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ permissions: OC.PERMISSION_READ,
+ icon: OC.imagePath('core', 'actions/test'),
+ actionHandler: actionStub
+ });
expect(handler.notCalled).toEqual(true);
});
});
diff --git a/apps/files/tests/js/fileactionsmenuSpec.js b/apps/files/tests/js/fileactionsmenuSpec.js
new file mode 100644
index 00000000000..0cfd12a2d04
--- /dev/null
+++ b/apps/files/tests/js/fileactionsmenuSpec.js
@@ -0,0 +1,273 @@
+/**
+* ownCloud
+*
+* @author Vincent Petry
+* @copyright 2015 Vincent Petry <pvince81@owncloud.com>
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*
+* You should have received a copy of the GNU Affero General Public
+* License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+describe('OCA.Files.FileActionsMenu tests', function() {
+ var fileList, fileActions, menu, actionStub, $tr;
+
+ beforeEach(function() {
+ // init horrible parameters
+ var $body = $('#testArea');
+ $body.append('<input type="hidden" id="dir" value="/subdir"></input>');
+ $body.append('<input type="hidden" id="permissions" value="31"></input>');
+ // dummy files table
+ actionStub = sinon.stub();
+ fileActions = new OCA.Files.FileActions();
+ fileList = new OCA.Files.FileList($body, {
+ fileActions: fileActions
+ });
+
+ fileActions.registerAction({
+ name: 'Testdropdown',
+ displayName: 'Testdropdowndisplay',
+ mime: 'all',
+ permissions: OC.PERMISSION_READ,
+ icon: function () {
+ return OC.imagePath('core', 'actions/download');
+ },
+ actionHandler: actionStub
+ });
+
+ fileActions.registerAction({
+ name: 'Testdropdownnoicon',
+ displayName: 'Testdropdowndisplaynoicon',
+ mime: 'all',
+ permissions: OC.PERMISSION_READ,
+ actionHandler: actionStub
+ });
+
+ fileActions.registerAction({
+ name: 'Testinline',
+ displayName: 'Testinlinedisplay',
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ mime: 'all',
+ permissions: OC.PERMISSION_READ
+ });
+
+ fileActions.registerAction({
+ name: 'Testdefault',
+ displayName: 'Testdefaultdisplay',
+ mime: 'all',
+ permissions: OC.PERMISSION_READ
+ });
+ fileActions.setDefault('all', 'Testdefault');
+
+ var fileData = {
+ id: 18,
+ type: 'file',
+ name: 'testName.txt',
+ mimetype: 'text/plain',
+ size: '1234',
+ etag: 'a01234c',
+ mtime: '123456'
+ };
+ $tr = fileList.add(fileData);
+
+ var menuContext = {
+ $file: $tr,
+ fileList: fileList,
+ fileActions: fileActions,
+ dir: fileList.getCurrentDirectory()
+ };
+ menu = new OCA.Files.FileActionsMenu();
+ menu.show(menuContext);
+ });
+ afterEach(function() {
+ fileActions = null;
+ fileList.destroy();
+ fileList = undefined;
+ menu.remove();
+ $('#dir, #permissions, #filestable').remove();
+ });
+
+ describe('rendering', function() {
+ it('renders dropdown actions in menu', function() {
+ var $action = menu.$el.find('a[data-action=Testdropdown]');
+ expect($action.length).toEqual(1);
+ expect($action.find('img').attr('src'))
+ .toEqual(OC.imagePath('core', 'actions/download'));
+ expect($action.find('.no-icon').length).toEqual(0);
+
+ $action = menu.$el.find('a[data-action=Testdropdownnoicon]');
+ expect($action.length).toEqual(1);
+ expect($action.find('img').length).toEqual(0);
+ expect($action.find('.no-icon').length).toEqual(1);
+ });
+ it('does not render default actions', function() {
+ expect(menu.$el.find('a[data-action=Testdefault]').length).toEqual(0);
+ });
+ it('does not render inline actions', function() {
+ expect(menu.$el.find('a[data-action=Testinline]').length).toEqual(0);
+ });
+ it('only renders actions relevant to the mime type', function() {
+ fileActions.registerAction({
+ name: 'Match',
+ displayName: 'MatchDisplay',
+ mime: 'text/plain',
+ permissions: OC.PERMISSION_READ
+ });
+ fileActions.registerAction({
+ name: 'Nomatch',
+ displayName: 'NoMatchDisplay',
+ mime: 'application/octet-stream',
+ permissions: OC.PERMISSION_READ
+ });
+
+ menu.render();
+ expect(menu.$el.find('a[data-action=Match]').length).toEqual(1);
+ expect(menu.$el.find('a[data-action=NoMatch]').length).toEqual(0);
+ });
+ it('only renders actions relevant to the permissions', function() {
+ fileActions.registerAction({
+ name: 'Match',
+ displayName: 'MatchDisplay',
+ mime: 'text/plain',
+ permissions: OC.PERMISSION_UPDATE
+ });
+ fileActions.registerAction({
+ name: 'Nomatch',
+ displayName: 'NoMatchDisplay',
+ mime: 'text/plain',
+ permissions: OC.PERMISSION_DELETE
+ });
+
+ menu.render();
+ expect(menu.$el.find('a[data-action=Match]').length).toEqual(1);
+ expect(menu.$el.find('a[data-action=NoMatch]').length).toEqual(0);
+ });
+ });
+
+ describe('action handler', function() {
+ it('calls action handler when clicking menu item', function() {
+ var $action = menu.$el.find('a[data-action=Testdropdown]');
+ $action.click();
+
+ expect(actionStub.calledOnce).toEqual(true);
+ expect(actionStub.getCall(0).args[0]).toEqual('testName.txt');
+ expect(actionStub.getCall(0).args[1].$file[0]).toEqual($tr[0]);
+ expect(actionStub.getCall(0).args[1].fileList).toEqual(fileList);
+ expect(actionStub.getCall(0).args[1].fileActions).toEqual(fileActions);
+ expect(actionStub.getCall(0).args[1].dir).toEqual('/subdir');
+ });
+ });
+ describe('default actions from registerDefaultActions', function() {
+ beforeEach(function() {
+ fileActions.clear();
+ fileActions.registerDefaultActions();
+ });
+ it('redirects to download URL when clicking download', function() {
+ var redirectStub = sinon.stub(OC, 'redirect');
+ var fileData = {
+ id: 18,
+ type: 'file',
+ name: 'testName.txt',
+ mimetype: 'text/plain',
+ size: '1234',
+ etag: 'a01234c',
+ mtime: '123456'
+ };
+ var $tr = fileList.add(fileData);
+ fileActions.display($tr.find('td.filename'), true, fileList);
+
+ var menuContext = {
+ $file: $tr,
+ fileList: fileList,
+ fileActions: fileActions,
+ dir: fileList.getCurrentDirectory()
+ };
+ menu = new OCA.Files.FileActionsMenu();
+ menu.show(menuContext);
+
+ menu.$el.find('.action-download').click();
+
+ expect(redirectStub.calledOnce).toEqual(true);
+ expect(redirectStub.getCall(0).args[0]).toContain(
+ OC.webroot +
+ '/index.php/apps/files/ajax/download.php' +
+ '?dir=%2Fsubdir&files=testName.txt');
+ redirectStub.restore();
+ });
+ it('takes the file\'s path into account when clicking download', function() {
+ var redirectStub = sinon.stub(OC, 'redirect');
+ var fileData = {
+ id: 18,
+ type: 'file',
+ name: 'testName.txt',
+ path: '/anotherpath/there',
+ mimetype: 'text/plain',
+ size: '1234',
+ etag: 'a01234c',
+ mtime: '123456'
+ };
+ var $tr = fileList.add(fileData);
+ fileActions.display($tr.find('td.filename'), true, fileList);
+
+ var menuContext = {
+ $file: $tr,
+ fileList: fileList,
+ fileActions: fileActions,
+ dir: '/anotherpath/there'
+ };
+ menu = new OCA.Files.FileActionsMenu();
+ menu.show(menuContext);
+
+ menu.$el.find('.action-download').click();
+
+ expect(redirectStub.calledOnce).toEqual(true);
+ expect(redirectStub.getCall(0).args[0]).toContain(
+ OC.webroot + '/index.php/apps/files/ajax/download.php' +
+ '?dir=%2Fanotherpath%2Fthere&files=testName.txt'
+ );
+ redirectStub.restore();
+ });
+ it('deletes file when clicking 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'
+ };
+ var $tr = fileList.add(fileData);
+ fileActions.display($tr.find('td.filename'), true, fileList);
+
+ var menuContext = {
+ $file: $tr,
+ fileList: fileList,
+ fileActions: fileActions,
+ dir: '/somepath/dir'
+ };
+ menu = new OCA.Files.FileActionsMenu();
+ menu.show(menuContext);
+
+ menu.$el.find('.action-delete').click();
+
+ expect(deleteStub.calledOnce).toEqual(true);
+ expect(deleteStub.getCall(0).args[0]).toEqual('testName.txt');
+ expect(deleteStub.getCall(0).args[1]).toEqual('/somepath/dir');
+ deleteStub.restore();
+ });
+ });
+});
+
diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js
index 5c0c8c96bc5..57e16626403 100644
--- a/apps/files/tests/js/filelistSpec.js
+++ b/apps/files/tests/js/filelistSpec.js
@@ -456,19 +456,19 @@ describe('OCA.Files.FileList tests', function() {
expect(notificationStub.notCalled).toEqual(true);
});
- it('shows spinner on files to be deleted', function() {
+ it('shows busy state on files to be deleted', function() {
fileList.setFiles(testFiles);
doDelete();
- expect(fileList.findFileEl('One.txt').find('.icon-loading-small:not(.icon-delete)').length).toEqual(1);
- expect(fileList.findFileEl('Three.pdf').find('.icon-delete:not(.icon-loading-small)').length).toEqual(1);
+ expect(fileList.findFileEl('One.txt').hasClass('busy')).toEqual(true);
+ expect(fileList.findFileEl('Three.pdf').hasClass('busy')).toEqual(false);
});
- it('shows spinner on all files when deleting all', function() {
+ it('shows busy state on all files when deleting all', function() {
fileList.setFiles(testFiles);
fileList.do_delete();
- expect(fileList.$fileList.find('tr .icon-loading-small:not(.icon-delete)').length).toEqual(4);
+ expect(fileList.$fileList.find('tr.busy').length).toEqual(4);
});
it('updates summary when deleting last file', function() {
var $summary;
@@ -625,7 +625,7 @@ describe('OCA.Files.FileList tests', function() {
doCancelRename();
expect($summary.find('.info').text()).toEqual('1 folder and 3 files');
});
- it('Hides actions while rename in progress', function() {
+ it('Shows busy state while rename in progress', function() {
var $tr;
doRename();
@@ -634,8 +634,7 @@ describe('OCA.Files.FileList tests', function() {
expect($tr.length).toEqual(1);
expect(fileList.findFileEl('One.txt').length).toEqual(0);
// file actions are hidden
- expect($tr.find('.action').hasClass('hidden')).toEqual(true);
- expect($tr.find('.fileactions').hasClass('hidden')).toEqual(true);
+ expect($tr.hasClass('busy')).toEqual(true);
// input and form are gone
expect(fileList.$fileList.find('input.filename').length).toEqual(0);
@@ -1918,16 +1917,17 @@ describe('OCA.Files.FileList tests', function() {
it('Clicking on a file name will trigger default action', function() {
var actionStub = sinon.stub();
fileList.setFiles(testFiles);
- fileList.fileActions.register(
- 'text/plain',
- 'Test',
- OC.PERMISSION_ALL,
- function() {
+ fileList.fileActions.registerAction({
+ mime: 'text/plain',
+ name: 'Test',
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ permissions: OC.PERMISSION_ALL,
+ icon: function() {
// Specify icon for hitory button
return OC.imagePath('core','actions/history');
},
- actionStub
- );
+ actionHandler: actionStub
+ });
fileList.fileActions.setDefault('text/plain', 'Test');
var $tr = fileList.findFileEl('One.txt');
$tr.find('td.filename .nametext').click();
@@ -1958,16 +1958,17 @@ describe('OCA.Files.FileList tests', function() {
fileList.$fileList.on('fileActionsReady', readyHandler);
- fileList.fileActions.register(
- 'text/plain',
- 'Test',
- OC.PERMISSION_ALL,
- function() {
+ fileList.fileActions.registerAction({
+ mime: 'text/plain',
+ name: 'Test',
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ permissions: OC.PERMISSION_ALL,
+ icon: function() {
// Specify icon for hitory button
return OC.imagePath('core','actions/history');
},
- actionStub
- );
+ actionHandler: actionStub
+ });
var $tr = fileList.findFileEl('One.txt');
expect($tr.find('.action-test').length).toEqual(0);
expect(readyHandler.notCalled).toEqual(true);
@@ -2256,6 +2257,8 @@ describe('OCA.Files.FileList tests', function() {
});
});
describe('Handeling errors', function () {
+ var redirectStub;
+
beforeEach(function () {
redirectStub = sinon.stub(OC, 'redirect');
@@ -2281,4 +2284,36 @@ describe('OCA.Files.FileList tests', function() {
expect(redirectStub.calledWith(OC.generateUrl('apps/files'))).toEqual(true);
});
});
+ describe('showFileBusyState', function() {
+ var $tr;
+
+ beforeEach(function() {
+ fileList.setFiles(testFiles);
+ $tr = fileList.findFileEl('Two.jpg');
+ });
+ it('shows spinner on busy rows', function() {
+ fileList.showFileBusyState('Two.jpg', true);
+ expect($tr.hasClass('busy')).toEqual(true);
+ expect(OC.TestUtil.getImageUrl($tr.find('.thumbnail')))
+ .toEqual(OC.imagePath('core', 'loading.gif'));
+
+ fileList.showFileBusyState('Two.jpg', false);
+ expect($tr.hasClass('busy')).toEqual(false);
+ expect(OC.TestUtil.getImageUrl($tr.find('.thumbnail')))
+ .toEqual(OC.imagePath('core', 'filetypes/image.svg'));
+ });
+ it('accepts multiple input formats', function() {
+ _.each([
+ 'Two.jpg',
+ ['Two.jpg'],
+ $tr,
+ [$tr]
+ ], function(testCase) {
+ fileList.showFileBusyState(testCase, true);
+ expect($tr.hasClass('busy')).toEqual(true);
+ fileList.showFileBusyState(testCase, false);
+ expect($tr.hasClass('busy')).toEqual(false);
+ });
+ });
+ });
});
diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js
index 12bec0e8c9a..04700b84011 100644
--- a/apps/files_sharing/js/share.js
+++ b/apps/files_sharing/js/share.js
@@ -89,57 +89,59 @@
}
});
- fileActions.register(
- 'all',
- 'Share',
- OC.PERMISSION_SHARE,
- OC.imagePath('core', 'actions/share'),
- function(filename, context) {
-
- var $tr = context.$file;
- var itemType = 'file';
- if ($tr.data('type') === 'dir') {
- itemType = 'folder';
- }
- var possiblePermissions = $tr.data('share-permissions');
- if (_.isUndefined(possiblePermissions)) {
- possiblePermissions = $tr.data('permissions');
- }
+ fileActions.registerAction({
+ name: 'Share',
+ displayName: '',
+ mime: 'all',
+ permissions: OC.PERMISSION_SHARE,
+ icon: OC.imagePath('core', 'actions/share'),
+ type: OCA.Files.FileActions.TYPE_INLINE,
+ actionHandler: function(filename, context) {
+ var $tr = context.$file;
+ var itemType = 'file';
+ if ($tr.data('type') === 'dir') {
+ itemType = 'folder';
+ }
+ var possiblePermissions = $tr.data('share-permissions');
+ if (_.isUndefined(possiblePermissions)) {
+ possiblePermissions = $tr.data('permissions');
+ }
- var appendTo = $tr.find('td.filename');
- // Check if drop down is already visible for a different file
- if (OC.Share.droppedDown) {
- if ($tr.attr('data-id') !== $('#dropdown').attr('data-item-source')) {
- OC.Share.hideDropDown(function () {
- $tr.addClass('mouseOver');
- OC.Share.showDropDown(itemType, $tr.data('id'), appendTo, true, possiblePermissions, filename);
- });
+ var appendTo = $tr.find('td.filename');
+ // Check if drop down is already visible for a different file
+ if (OC.Share.droppedDown) {
+ if ($tr.attr('data-id') !== $('#dropdown').attr('data-item-source')) {
+ OC.Share.hideDropDown(function () {
+ $tr.addClass('mouseOver');
+ OC.Share.showDropDown(itemType, $tr.data('id'), appendTo, true, possiblePermissions, filename);
+ });
+ } else {
+ OC.Share.hideDropDown();
+ }
} else {
- OC.Share.hideDropDown();
+ $tr.addClass('mouseOver');
+ OC.Share.showDropDown(itemType, $tr.data('id'), appendTo, true, possiblePermissions, filename);
}
- } else {
- $tr.addClass('mouseOver');
- OC.Share.showDropDown(itemType, $tr.data('id'), appendTo, true, possiblePermissions, filename);
+ $('#dropdown').on('sharesChanged', function(ev) {
+ // files app current cannot show recipients on load, so we don't update the
+ // icon when changed for consistency
+ if (context.fileList.$el.closest('#app-content-files').length) {
+ return;
+ }
+ var recipients = _.pluck(ev.shares[OC.Share.SHARE_TYPE_USER], 'share_with_displayname');
+ var groupRecipients = _.pluck(ev.shares[OC.Share.SHARE_TYPE_GROUP], 'share_with_displayname');
+ recipients = recipients.concat(groupRecipients);
+ // note: we only update the data attribute because updateIcon()
+ // is called automatically after this event
+ if (recipients.length) {
+ $tr.attr('data-share-recipients', OCA.Sharing.Util.formatRecipients(recipients));
+ }
+ else {
+ $tr.removeAttr('data-share-recipients');
+ }
+ });
}
- $('#dropdown').on('sharesChanged', function(ev) {
- // files app current cannot show recipients on load, so we don't update the
- // icon when changed for consistency
- if (context.fileList.$el.closest('#app-content-files').length) {
- return;
- }
- var recipients = _.pluck(ev.shares[OC.Share.SHARE_TYPE_USER], 'share_with_displayname');
- var groupRecipients = _.pluck(ev.shares[OC.Share.SHARE_TYPE_GROUP], 'share_with_displayname');
- recipients = recipients.concat(groupRecipients);
- // note: we only update the data attribute because updateIcon()
- // is called automatically after this event
- if (recipients.length) {
- $tr.attr('data-share-recipients', OCA.Sharing.Util.formatRecipients(recipients));
- }
- else {
- $tr.removeAttr('data-share-recipients');
- }
- });
- }, t('files_sharing', 'Share'));
+ });
OC.addScript('files_sharing', 'sharetabview').done(function() {
fileList.registerTabView(new OCA.Sharing.ShareTabView('shareTabView'));
diff --git a/apps/files_sharing/lib/activity.php b/apps/files_sharing/lib/activity.php
index e531674ddc2..204c0a037b9 100644
--- a/apps/files_sharing/lib/activity.php
+++ b/apps/files_sharing/lib/activity.php
@@ -106,7 +106,7 @@ class Activity implements IExtension {
self::TYPE_REMOTE_SHARE,
];
- if ($method === 'stream') {
+ if ($method === self::METHOD_STREAM) {
$defaultTypes[] = self::TYPE_PUBLIC_LINKS;
}
diff --git a/apps/files_sharing/publicwebdav.php b/apps/files_sharing/publicwebdav.php
index 5bde908109d..eec158dd4b6 100644
--- a/apps/files_sharing/publicwebdav.php
+++ b/apps/files_sharing/publicwebdav.php
@@ -33,24 +33,18 @@ OC_Util::obEnd();
// Backends
$authBackend = new OCA\Files_Sharing\Connector\PublicAuth(\OC::$server->getConfig());
-// Fire up server
-$objectTree = new \OC\Connector\Sabre\ObjectTree();
-$server = new \OC\Connector\Sabre\Server($objectTree);
-// Set URL explicitly due to reverse-proxy situations
-$server->httpRequest->setUrl(\OC::$server->getRequest()->getRequestUri());
-$server->setBaseUri($baseuri);
+$serverFactory = new \OC\Connector\Sabre\ServerFactory(
+ \OC::$server->getConfig(),
+ \OC::$server->getLogger(),
+ \OC::$server->getDatabaseConnection(),
+ \OC::$server->getUserSession(),
+ \OC::$server->getMountManager(),
+ \OC::$server->getTagManager()
+);
-// Load plugins
-$defaults = new OC_Defaults();
-$server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend, $defaults->getName()));
-// FIXME: The following line is a workaround for legacy components relying on being able to send a GET to /
-$server->addPlugin(new \OC\Connector\Sabre\DummyGetResponsePlugin());
-$server->addPlugin(new \OC\Connector\Sabre\FilesPlugin($objectTree, true));
-$server->addPlugin(new \OC\Connector\Sabre\MaintenancePlugin(\OC::$server->getConfig()));
-$server->addPlugin(new \OC\Connector\Sabre\ExceptionLoggerPlugin('webdav', \OC::$server->getLogger()));
+$requestUri = \OC::$server->getRequest()->getRequestUri();
-// wait with registering these until auth is handled and the filesystem is setup
-$server->on('beforeMethod', function () use ($server, $objectTree, $authBackend) {
+$server = $serverFactory->createServer($baseuri, $requestUri, $authBackend, function () use ($authBackend) {
if (OCA\Files_Sharing\Helper::isOutgoingServer2serverShareEnabled() === false) {
// this is what is thrown when trying to access a non-existing share
throw new \Sabre\DAV\Exception\NotAuthenticated();
@@ -72,20 +66,8 @@ $server->on('beforeMethod', function () use ($server, $objectTree, $authBackend)
$ownerView = \OC\Files\Filesystem::getView();
$path = $ownerView->getPath($fileId);
- $view = new \OC\Files\View($ownerView->getAbsolutePath($path));
- $rootInfo = $view->getFileInfo('');
-
- // Create ownCloud Dir
- if ($rootInfo->getType() === 'dir') {
- $root = new \OC\Connector\Sabre\Directory($view, $rootInfo);
- } else {
- $root = new \OC\Connector\Sabre\File($view, $rootInfo);
- }
- $mountManager = \OC\Files\Filesystem::getMountManager();
- $objectTree->init($root, $view, $mountManager);
-
- $server->addPlugin(new \OC\Connector\Sabre\QuotaPlugin($view));
-}, 30); // priority 30: after auth (10) and acl(20), before lock(50) and handling the request
+ return new \OC\Files\View($ownerView->getAbsolutePath($path));
+});
// And off we go!
$server->exec();
diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php
index ffe0472b2b1..2962f62520d 100644
--- a/apps/files_sharing/templates/public.php
+++ b/apps/files_sharing/templates/public.php
@@ -7,6 +7,7 @@ OCP\Util::addStyle('files_sharing', 'public');
OCP\Util::addStyle('files_sharing', 'mobile');
OCP\Util::addScript('files_sharing', 'public');
OCP\Util::addScript('files', 'fileactions');
+OCP\Util::addScript('files', 'fileactionsmenu');
OCP\Util::addScript('files', 'jquery.iframe-transport');
OCP\Util::addScript('files', 'jquery.fileupload');
diff --git a/apps/files_sharing/tests/js/shareSpec.js b/apps/files_sharing/tests/js/shareSpec.js
index aa409285ca4..581e15caf93 100644
--- a/apps/files_sharing/tests/js/shareSpec.js
+++ b/apps/files_sharing/tests/js/shareSpec.js
@@ -97,7 +97,7 @@ describe('OCA.Sharing.Util tests', function() {
}]);
$tr = fileList.$el.find('tbody tr:first');
$action = $tr.find('.action-share');
- expect($action.hasClass('permanent')).toEqual(false);
+ expect($action.hasClass('permanent')).toEqual(true);
expect(OC.basename($action.find('img').attr('src'))).toEqual('share.svg');
expect(OC.basename(getImageUrl($tr.find('.filename .thumbnail')))).toEqual('folder.svg');
expect($action.find('img').length).toEqual(1);
@@ -257,7 +257,7 @@ describe('OCA.Sharing.Util tests', function() {
$action = fileList.$el.find('tbody tr:first .action-share');
$tr = fileList.$el.find('tr:first');
- expect($action.hasClass('permanent')).toEqual(false);
+ expect($action.hasClass('permanent')).toEqual(true);
$tr.find('.action-share').click();
@@ -344,7 +344,7 @@ describe('OCA.Sharing.Util tests', function() {
expect($tr.attr('data-share-recipients')).not.toBeDefined();
OC.Share.updateIcon('file', 1);
- expect($action.hasClass('permanent')).toEqual(false);
+ expect($action.hasClass('permanent')).toEqual(true);
});
it('keep share text after updating reshare', function() {
var $action, $tr;
diff --git a/apps/files_trashbin/command/cleanup.php b/apps/files_trashbin/command/cleanup.php
index 0cc94912339..60717abac18 100644
--- a/apps/files_trashbin/command/cleanup.php
+++ b/apps/files_trashbin/command/cleanup.php
@@ -108,7 +108,7 @@ class CleanUp extends Command {
if ($this->rootFolder->nodeExists('/' . $uid . '/files_trashbin')) {
$this->rootFolder->get('/' . $uid . '/files_trashbin')->delete();
$query = $this->dbConnection->getQueryBuilder();
- $query->delete('*PREFIX*files_trash')
+ $query->delete('files_trash')
->where($query->expr()->eq('user', $query->createParameter('uid')))
->setParameter('uid', $uid);
$query->execute();
diff --git a/apps/files_trashbin/js/app.js b/apps/files_trashbin/js/app.js
index 315349d293c..473cce88a71 100644
--- a/apps/files_trashbin/js/app.js
+++ b/apps/files_trashbin/js/app.js
@@ -59,7 +59,6 @@ OCA.Trashbin.App = {
fileActions.registerAction({
name: 'Delete',
- displayName: '',
mime: 'all',
permissions: OC.PERMISSION_READ,
icon: function() {
diff --git a/apps/files_trashbin/tests/command/cleanuptest.php b/apps/files_trashbin/tests/command/cleanuptest.php
index a7400e901fa..d4cccee448e 100644
--- a/apps/files_trashbin/tests/command/cleanuptest.php
+++ b/apps/files_trashbin/tests/command/cleanuptest.php
@@ -43,7 +43,7 @@ class CleanUpTest extends TestCase {
protected $dbConnection;
/** @var string */
- protected $trashTable = '*PREFIX*files_trash';
+ protected $trashTable = 'files_trash';
/** @var string */
protected $user0 = 'user0';
diff --git a/apps/provisioning_api/appinfo/routes.php b/apps/provisioning_api/appinfo/routes.php
index 323c8d609c7..2ee3a185dae 100644
--- a/apps/provisioning_api/appinfo/routes.php
+++ b/apps/provisioning_api/appinfo/routes.php
@@ -21,30 +21,45 @@
*
*/
-// Users
+namespace OCA\Provisioning_API\AppInfo;
+
use OCP\API;
-API::register('get', '/cloud/users', array('OCA\Provisioning_API\Users', 'getUsers'), 'provisioning_api', API::ADMIN_AUTH);
-API::register('post', '/cloud/users', array('OCA\Provisioning_API\Users', 'addUser'), 'provisioning_api', API::ADMIN_AUTH);
-API::register('get', '/cloud/users/{userid}', array('OCA\Provisioning_API\Users', 'getUser'), 'provisioning_api', API::USER_AUTH);
-API::register('put', '/cloud/users/{userid}', array('OCA\Provisioning_API\Users', 'editUser'), 'provisioning_api', API::USER_AUTH);
-API::register('delete', '/cloud/users/{userid}', array('OCA\Provisioning_API\Users', 'deleteUser'), 'provisioning_api', API::SUBADMIN_AUTH);
-API::register('get', '/cloud/users/{userid}/groups', array('OCA\Provisioning_API\Users', 'getUsersGroups'), 'provisioning_api', API::USER_AUTH);
-API::register('post', '/cloud/users/{userid}/groups', array('OCA\Provisioning_API\Users', 'addToGroup'), 'provisioning_api', API::SUBADMIN_AUTH);
-API::register('delete', '/cloud/users/{userid}/groups', array('OCA\Provisioning_API\Users', 'removeFromGroup'), 'provisioning_api', API::SUBADMIN_AUTH);
-API::register('post', '/cloud/users/{userid}/subadmins', array('OCA\Provisioning_API\Users', 'addSubAdmin'), 'provisioning_api', API::ADMIN_AUTH);
-API::register('delete', '/cloud/users/{userid}/subadmins', array('OCA\Provisioning_API\Users', 'removeSubAdmin'), 'provisioning_api', API::ADMIN_AUTH);
-API::register('get', '/cloud/users/{userid}/subadmins', array('OCA\Provisioning_API\Users', 'getUserSubAdminGroups'), 'provisioning_api', API::ADMIN_AUTH);
+// Users
+$users = new \OCA\Provisioning_API\Users(
+ \OC::$server->getUserManager(),
+ \OC::$server->getConfig(),
+ \OC::$server->getGroupManager(),
+ \OC::$server->getUserSession()
+);
+API::register('get', '/cloud/users', [$users, 'getUsers'], 'provisioning_api', API::ADMIN_AUTH);
+API::register('post', '/cloud/users', [$users, 'addUser'], 'provisioning_api', API::ADMIN_AUTH);
+API::register('get', '/cloud/users/{userid}', [$users, 'getUser'], 'provisioning_api', API::USER_AUTH);
+API::register('put', '/cloud/users/{userid}', [$users, 'editUser'], 'provisioning_api', API::USER_AUTH);
+API::register('delete', '/cloud/users/{userid}', [$users, 'deleteUser'], 'provisioning_api', API::SUBADMIN_AUTH);
+API::register('get', '/cloud/users/{userid}/groups', [$users, 'getUsersGroups'], 'provisioning_api', API::USER_AUTH);
+API::register('post', '/cloud/users/{userid}/groups', [$users, 'addToGroup'], 'provisioning_api', API::SUBADMIN_AUTH);
+API::register('delete', '/cloud/users/{userid}/groups', [$users, 'removeFromGroup'], 'provisioning_api', API::SUBADMIN_AUTH);
+API::register('post', '/cloud/users/{userid}/subadmins', [$users, 'addSubAdmin'], 'provisioning_api', API::ADMIN_AUTH);
+API::register('delete', '/cloud/users/{userid}/subadmins', [$users, 'removeSubAdmin'], 'provisioning_api', API::ADMIN_AUTH);
+API::register('get', '/cloud/users/{userid}/subadmins', [$users, 'getUserSubAdminGroups'], 'provisioning_api', API::ADMIN_AUTH);
// Groups
-API::register('get', '/cloud/groups', array('OCA\Provisioning_API\Groups', 'getGroups'), 'provisioning_api', API::SUBADMIN_AUTH);
-API::register('post', '/cloud/groups', array('OCA\Provisioning_API\Groups', 'addGroup'), 'provisioning_api', API::SUBADMIN_AUTH);
-API::register('get', '/cloud/groups/{groupid}', array('OCA\Provisioning_API\Groups', 'getGroup'), 'provisioning_api', API::SUBADMIN_AUTH);
-API::register('delete', '/cloud/groups/{groupid}', array('OCA\Provisioning_API\Groups', 'deleteGroup'), 'provisioning_api', API::ADMIN_AUTH);
-API::register('get', '/cloud/groups/{groupid}/subadmins', array('OCA\Provisioning_API\Groups', 'getSubAdminsOfGroup'), 'provisioning_api', API::ADMIN_AUTH);
+$groups = new \OCA\Provisioning_API\Groups(
+ \OC::$server->getGroupManager(),
+ \OC::$server->getUserSession()
+);
+API::register('get', '/cloud/groups', [$groups, 'getGroups'], 'provisioning_api', API::SUBADMIN_AUTH);
+API::register('post', '/cloud/groups', [$groups, 'addGroup'], 'provisioning_api', API::SUBADMIN_AUTH);
+API::register('get', '/cloud/groups/{groupid}', [$groups, 'getGroup'], 'provisioning_api', API::SUBADMIN_AUTH);
+API::register('delete', '/cloud/groups/{groupid}', [$groups, 'deleteGroup'], 'provisioning_api', API::ADMIN_AUTH);
+API::register('get', '/cloud/groups/{groupid}/subadmins', [$groups, 'getSubAdminsOfGroup'], 'provisioning_api', API::ADMIN_AUTH);
// Apps
-API::register('get', '/cloud/apps', array('OCA\Provisioning_API\Apps', 'getApps'), 'provisioning_api', API::ADMIN_AUTH);
-API::register('get', '/cloud/apps/{appid}', array('OCA\Provisioning_API\Apps', 'getAppInfo'), 'provisioning_api', API::ADMIN_AUTH);
-API::register('post', '/cloud/apps/{appid}', array('OCA\Provisioning_API\Apps', 'enable'), 'provisioning_api', API::ADMIN_AUTH);
-API::register('delete', '/cloud/apps/{appid}', array('OCA\Provisioning_API\Apps', 'disable'), 'provisioning_api', API::ADMIN_AUTH);
+$apps = new \OCA\Provisioning_API\Apps(
+ \OC::$server->getAppManager()
+);
+API::register('get', '/cloud/apps', [$apps, 'getApps'], 'provisioning_api', API::ADMIN_AUTH);
+API::register('get', '/cloud/apps/{appid}', [$apps, 'getAppInfo'], 'provisioning_api', API::ADMIN_AUTH);
+API::register('post', '/cloud/apps/{appid}', [$apps, 'enable'], 'provisioning_api', API::ADMIN_AUTH);
+API::register('delete', '/cloud/apps/{appid}', [$apps, 'disable'], 'provisioning_api', API::ADMIN_AUTH);
diff --git a/apps/provisioning_api/lib/apps.php b/apps/provisioning_api/lib/apps.php
index 22713865c1e..168f6f3cad8 100644
--- a/apps/provisioning_api/lib/apps.php
+++ b/apps/provisioning_api/lib/apps.php
@@ -28,7 +28,14 @@ use \OC_App;
class Apps {
- public static function getApps($parameters){
+ /** @var \OCP\App\IAppManager */
+ private $appManager;
+
+ public function __construct(\OCP\App\IAppManager $appManager) {
+ $this->appManager = $appManager;
+ }
+
+ public function getApps($parameters){
$apps = OC_App::listAllApps();
$list = array();
foreach($apps as $app) {
@@ -55,9 +62,9 @@ class Apps {
}
}
- public static function getAppInfo($parameters){
+ public function getAppInfo($parameters){
$app = $parameters['appid'];
- $info = OC_App::getAppInfo($app);
+ $info = \OCP\App::getAppInfo($app);
if(!is_null($info)) {
return new OC_OCS_Result(OC_App::getAppInfo($app));
} else {
@@ -65,15 +72,15 @@ class Apps {
}
}
- public static function enable($parameters){
+ public function enable($parameters){
$app = $parameters['appid'];
- OC_App::enable($app);
+ $this->appManager->enableApp($app);
return new OC_OCS_Result(null, 100);
}
- public static function disable($parameters){
+ public function disable($parameters){
$app = $parameters['appid'];
- OC_App::disable($app);
+ $this->appManager->disableApp($app);
return new OC_OCS_Result(null, 100);
}
diff --git a/apps/provisioning_api/lib/groups.php b/apps/provisioning_api/lib/groups.php
index 81a5a6e5c30..91d0a1c6342 100644
--- a/apps/provisioning_api/lib/groups.php
+++ b/apps/provisioning_api/lib/groups.php
@@ -24,33 +24,65 @@
namespace OCA\Provisioning_API;
use \OC_OCS_Result;
-use \OC_Group;
use \OC_SubAdmin;
class Groups{
+ /** @var \OCP\IGroupManager */
+ private $groupManager;
+
+ /** @var \OCP\IUserSession */
+ private $userSession;
+
+ /**
+ * @param \OCP\IGroupManager $groupManager
+ * @param \OCP\IUserSession $userSession
+ */
+ public function __construct(\OCP\IGroupManager $groupManager,
+ \OCP\IUserSession $userSession) {
+ $this->groupManager = $groupManager;
+ $this->userSession = $userSession;
+ }
+
/**
* returns a list of groups
*/
- public static function getGroups($parameters){
+ public function getGroups($parameters){
$search = !empty($_GET['search']) ? $_GET['search'] : '';
$limit = !empty($_GET['limit']) ? $_GET['limit'] : null;
$offset = !empty($_GET['offset']) ? $_GET['offset'] : null;
- return new OC_OCS_Result(array('groups' => OC_Group::getGroups($search, $limit, $offset)));
+
+ $groups = $this->groupManager->search($search, $limit, $offset);
+ $groups = array_map(function($group) {
+ return $group->getGID();
+ }, $groups);
+
+ return new OC_OCS_Result(['groups' => $groups]);
}
/**
* returns an array of users in the group specified
*/
- public static function getGroup($parameters){
+ public function getGroup($parameters) {
+ // Check if user is logged in
+ $user = $this->userSession->getUser();
+ if ($user === null) {
+ return new OC_OCS_Result(null, \OCP\API::RESPOND_UNAUTHORISED);
+ }
+
// Check the group exists
- if(!OC_Group::groupExists($parameters['groupid'])){
+ if(!$this->groupManager->groupExists($parameters['groupid'])){
return new OC_OCS_Result(null, \OCP\API::RESPOND_NOT_FOUND, 'The requested group could not be found');
}
// Check subadmin has access to this group
- if(\OC_User::isAdminUser(\OC_User::getUser())
- || in_array($parameters['groupid'], \OC_SubAdmin::getSubAdminsGroups(\OC_User::getUser()))){
- return new OC_OCS_Result(array('users' => OC_Group::usersInGroup($parameters['groupid'])));
+ if($this->groupManager->isAdmin($user->getUID())
+ || in_array($parameters['groupid'], \OC_SubAdmin::getSubAdminsGroups($user->getUID()))){
+ $users = $this->groupManager->get($parameters['groupid'])->getUsers();
+ $users = array_map(function($user) {
+ return $user->getUID();
+ }, $users);
+ $users = array_values($users);
+ return new OC_OCS_Result(['users' => $users]);
} else {
return new OC_OCS_Result(null, \OCP\API::RESPOND_UNAUTHORISED, 'User does not have access to specified group');
}
@@ -59,7 +91,7 @@ class Groups{
/**
* creates a new group
*/
- public static function addGroup($parameters){
+ public function addGroup($parameters){
// Validate name
$groupid = isset($_POST['groupid']) ? $_POST['groupid'] : '';
if( preg_match( '/[^a-zA-Z0-9 _\.@\-]/', $groupid ) || empty($groupid)){
@@ -67,21 +99,18 @@ class Groups{
return new OC_OCS_Result(null, 101, 'Invalid group name');
}
// Check if it exists
- if(OC_Group::groupExists($groupid)){
+ if($this->groupManager->groupExists($groupid)){
return new OC_OCS_Result(null, 102);
}
- if(OC_Group::createGroup($groupid)){
- return new OC_OCS_Result(null, 100);
- } else {
- return new OC_OCS_Result(null, 103);
- }
+ $this->groupManager->createGroup($groupid);
+ return new OC_OCS_Result(null, 100);
}
- public static function deleteGroup($parameters){
+ public function deleteGroup($parameters){
// Check it exists
- if(!OC_Group::groupExists($parameters['groupid'])){
+ if(!$this->groupManager->groupExists($parameters['groupid'])){
return new OC_OCS_Result(null, 101);
- } else if($parameters['groupid'] == 'admin' || !OC_Group::deleteGroup($parameters['groupid'])){
+ } else if($parameters['groupid'] === 'admin' || !$this->groupManager->get($parameters['groupid'])->delete()){
// Cannot delete admin group
return new OC_OCS_Result(null, 102);
} else {
@@ -89,10 +118,10 @@ class Groups{
}
}
- public static function getSubAdminsOfGroup($parameters) {
+ public function getSubAdminsOfGroup($parameters) {
$group = $parameters['groupid'];
// Check group exists
- if(!OC_Group::groupExists($group)) {
+ if(!$this->groupManager->groupExists($group)) {
return new OC_OCS_Result(null, 101, 'Group does not exist');
}
// Go
diff --git a/apps/provisioning_api/lib/users.php b/apps/provisioning_api/lib/users.php
index fada85b293d..f5b201a55ea 100644
--- a/apps/provisioning_api/lib/users.php
+++ b/apps/provisioning_api/lib/users.php
@@ -27,32 +27,64 @@ namespace OCA\Provisioning_API;
use \OC_OCS_Result;
use \OC_SubAdmin;
-use \OC_User;
-use \OC_Group;
use \OC_Helper;
use OCP\Files\NotFoundException;
class Users {
+ /** @var \OCP\IUserManager */
+ private $userManager;
+
+ /** @var \OCP\IConfig */
+ private $config;
+
+ /** @var \OCP\IGroupManager */
+ private $groupManager;
+
+ /** @var \OCP\IUserSession */
+ private $userSession;
+
+ /**
+ * @param \OCP\IUserManager $userManager
+ * @param \OCP\IConfig $config
+ * @param \OCP\IGroupManager $groupManager
+ * @param \OCP\IUserSession $user
+ */
+ public function __construct(\OCP\IUserManager $userManager,
+ \OCP\IConfig $config,
+ \OCP\IGroupManager $groupManager,
+ \OCP\IUserSession $userSession) {
+ $this->userManager = $userManager;
+ $this->config = $config;
+ $this->groupManager = $groupManager;
+ $this->userSession = $userSession;
+ }
+
/**
* returns a list of users
*/
- public static function getUsers(){
+ public function getUsers(){
$search = !empty($_GET['search']) ? $_GET['search'] : '';
$limit = !empty($_GET['limit']) ? $_GET['limit'] : null;
$offset = !empty($_GET['offset']) ? $_GET['offset'] : null;
- return new OC_OCS_Result(array('users' => OC_User::getUsers($search, $limit, $offset)));
+
+ $users = $this->userManager->search($search, $limit, $offset);
+ $users = array_keys($users);
+
+ return new OC_OCS_Result([
+ 'users' => $users
+ ]);
}
- public static function addUser(){
+ public function addUser(){
$userId = isset($_POST['userid']) ? $_POST['userid'] : null;
$password = isset($_POST['password']) ? $_POST['password'] : null;
- if(OC_User::userExists($userId)) {
+ if($this->userManager->userExists($userId)) {
\OCP\Util::writeLog('ocs_api', 'Failed addUser attempt: User already exists.', \OCP\Util::ERROR);
return new OC_OCS_Result(null, 102, 'User already exists');
} else {
try {
- OC_User::createUser($userId, $password);
+ $this->userManager->createUser($userId, $password);
\OCP\Util::writeLog('ocs_api', 'Successful addUser call with userid: '.$_POST['userid'], \OCP\Util::INFO);
return new OC_OCS_Result(null, 100);
} catch (\Exception $e) {
@@ -65,25 +97,32 @@ class Users {
/**
* gets user info
*/
- public static function getUser($parameters){
+ public function getUser($parameters){
$userId = $parameters['userid'];
+
+ // Check if user is logged in
+ $user = $this->userSession->getUser();
+ if ($user === null) {
+ return new OC_OCS_Result(null, \OCP\API::RESPOND_UNAUTHORISED);
+ }
+
// Admin? Or SubAdmin?
- if(OC_User::isAdminUser(OC_User::getUser()) || OC_SubAdmin::isUserAccessible(OC_User::getUser(), $userId)) {
+ if($this->groupManager->isAdmin($user->getUID()) || OC_SubAdmin::isUserAccessible($user->getUID(), $userId)) {
// Check they exist
- if(!OC_User::userExists($userId)) {
+ if(!$this->userManager->userExists($userId)) {
return new OC_OCS_Result(null, \OCP\API::RESPOND_NOT_FOUND, 'The requested user could not be found');
}
// Show all
- $return = array(
+ $return = [
'email',
'enabled',
- );
- if(OC_User::getUser() != $userId) {
+ ];
+ if($user->getUID() !== $userId) {
$return[] = 'quota';
}
} else {
// Check they are looking up themselves
- if(OC_User::getUser() != $userId) {
+ if($user->getUID() !== $userId) {
return new OC_OCS_Result(null, \OCP\API::RESPOND_UNAUTHORISED);
}
// Return some additional information compared to the core route
@@ -93,14 +132,12 @@ class Users {
);
}
- $config = \OC::$server->getConfig();
-
// Find the data
$data = [];
$data = self::fillStorageInfo($userId, $data);
- $data['enabled'] = $config->getUserValue($userId, 'core', 'enabled', 'true');
- $data['email'] = $config->getUserValue($userId, 'settings', 'email');
- $data['displayname'] = OC_User::getDisplayName($parameters['userid']);
+ $data['enabled'] = $this->config->getUserValue($userId, 'core', 'enabled', 'true');
+ $data['email'] = $this->config->getUserValue($userId, 'settings', 'email');
+ $data['displayname'] = $this->userManager->get($parameters['userid'])->getDisplayName();
// Return the appropriate data
$responseData = array();
@@ -114,21 +151,28 @@ class Users {
/**
* edit users
*/
- public static function editUser($parameters){
+ public function editUser($parameters){
$userId = $parameters['userid'];
- if($userId === OC_User::getUser()) {
+
+ // Check if user is logged in
+ $user = $this->userSession->getUser();
+ if ($user === null) {
+ return new OC_OCS_Result(null, \OCP\API::RESPOND_UNAUTHORISED);
+ }
+
+ if($userId === $user->getUID()) {
// Editing self (display, email)
$permittedFields[] = 'display';
$permittedFields[] = 'email';
$permittedFields[] = 'password';
// If admin they can edit their own quota
- if(OC_User::isAdminUser(OC_User::getUser())) {
+ if($this->groupManager->isAdmin($user->getUID())) {
$permittedFields[] = 'quota';
}
} else {
// Check if admin / subadmin
- if(OC_SubAdmin::isUserAccessible(OC_User::getUser(), $userId)
- || OC_User::isAdminUser(OC_User::getUser())) {
+ if(OC_SubAdmin::isUserAccessible($user->getUID(), $userId)
+ || $this->groupManager->isAdmin($user->getUID())) {
// They have permissions over the user
$permittedFields[] = 'display';
$permittedFields[] = 'quota';
@@ -146,7 +190,7 @@ class Users {
// Process the edit
switch($parameters['_put']['key']){
case 'display':
- OC_User::setDisplayName($userId, $parameters['_put']['value']);
+ $this->userManager->get($userId)->setDisplayName($parameters['_put']['value']);
break;
case 'quota':
$quota = $parameters['_put']['value'];
@@ -154,27 +198,27 @@ class Users {
if (is_numeric($quota)) {
$quota = floatval($quota);
} else {
- $quota = OC_Helper::computerFileSize($quota);
+ $quota = \OCP\Util::computerFileSize($quota);
}
if ($quota === false) {
return new OC_OCS_Result(null, 103, "Invalid quota value {$parameters['_put']['value']}");
}
- if($quota == 0) {
+ if($quota === 0) {
$quota = 'default';
- }else if($quota == -1){
+ }else if($quota === -1){
$quota = 'none';
} else {
- $quota = OC_Helper::humanFileSize($quota);
+ $quota = \OCP\Util::humanFileSize($quota);
}
}
- \OC::$server->getConfig()->setUserValue($userId, 'files', 'quota', $quota);
+ $this->config->setUserValue($userId, 'files', 'quota', $quota);
break;
case 'password':
- OC_User::setPassword($userId, $parameters['_put']['value']);
+ $this->userManager->get($userId)->setPassword($parameters['_put']['value']);
break;
case 'email':
if(filter_var($parameters['_put']['value'], FILTER_VALIDATE_EMAIL)) {
- \OC::$server->getConfig()->setUserValue($userId, 'settings', 'email', $parameters['_put']['value']);
+ $this->config->setUserValue($userId, 'settings', 'email', $parameters['_put']['value']);
} else {
return new OC_OCS_Result(null, 102);
}
@@ -186,32 +230,53 @@ class Users {
return new OC_OCS_Result(null, 100);
}
- public static function deleteUser($parameters){
- if(!OC_User::userExists($parameters['userid'])
- || $parameters['userid'] === OC_User::getUser()) {
+ public function deleteUser($parameters){
+ // Check if user is logged in
+ $user = $this->userSession->getUser();
+ if ($user === null) {
+ return new OC_OCS_Result(null, \OCP\API::RESPOND_UNAUTHORISED);
+ }
+
+ if(!$this->userManager->userExists($parameters['userid'])
+ || $parameters['userid'] === $user->getUID()) {
return new OC_OCS_Result(null, 101);
}
// If not permitted
- if(!OC_User::isAdminUser(OC_User::getUser()) && !OC_SubAdmin::isUserAccessible(OC_User::getUser(), $parameters['userid'])) {
+ if(!$this->groupManager->isAdmin($user->getUID()) && !OC_SubAdmin::isUserAccessible($user->getUID(), $parameters['userid'])) {
return new OC_OCS_Result(null, 997);
}
// Go ahead with the delete
- if(OC_User::deleteUser($parameters['userid'])) {
+ if($this->userManager->get($parameters['userid'])->delete()) {
return new OC_OCS_Result(null, 100);
} else {
return new OC_OCS_Result(null, 101);
}
}
- public static function getUsersGroups($parameters){
- if($parameters['userid'] === OC_User::getUser() || OC_User::isAdminUser(OC_User::getUser())) {
+ public function getUsersGroups($parameters) {
+ // Check if user is logged in
+ $user = $this->userSession->getUser();
+ if ($user === null) {
+ return new OC_OCS_Result(null, \OCP\API::RESPOND_UNAUTHORISED);
+ }
+
+ if($parameters['userid'] === $user->getUID() || $this->groupManager->isAdmin($user->getUID())) {
// Self lookup or admin lookup
- return new OC_OCS_Result(array('groups' => OC_Group::getUserGroups($parameters['userid'])));
+ return new OC_OCS_Result([
+ 'groups' => $this->groupManager->getUserGroupIds(
+ $this->userManager->get($parameters['userid'])
+ )
+ ]);
} else {
// Looking up someone else
- if(OC_SubAdmin::isUserAccessible(OC_User::getUser(), $parameters['userid'])) {
+ if(OC_SubAdmin::isUserAccessible($user->getUID(), $parameters['userid'])) {
// Return the group that the method caller is subadmin of for the user in question
- $groups = array_intersect(OC_SubAdmin::getSubAdminsGroups(OC_User::getUser()), OC_Group::getUserGroups($parameters['userid']));
+ $groups = array_intersect(
+ OC_SubAdmin::getSubAdminsGroups($user->getUID()),
+ $this->groupManager->getUserGroupIds(
+ $this->userManager->get($parameters['userid'])
+ )
+ );
return new OC_OCS_Result(array('groups' => $groups));
} else {
// Not permitted
@@ -221,78 +286,96 @@ class Users {
}
- public static function addToGroup($parameters){
+ public function addToGroup($parameters){
+ // Check if user is logged in
+ $user = $this->userSession->getUser();
+ if ($user === null) {
+ return new OC_OCS_Result(null, \OCP\API::RESPOND_UNAUTHORISED);
+ }
+
$group = !empty($_POST['groupid']) ? $_POST['groupid'] : null;
if(is_null($group)){
return new OC_OCS_Result(null, 101);
}
// Check they're an admin
- if(!OC_Group::inGroup(OC_User::getUser(), 'admin')){
+ if(!$this->groupManager->isInGroup($user->getUID(), 'admin')){
// This user doesn't have rights to add a user to this group
return new OC_OCS_Result(null, \OCP\API::RESPOND_UNAUTHORISED);
}
// Check if the group exists
- if(!OC_Group::groupExists($group)){
+ if(!$this->groupManager->groupExists($group)){
return new OC_OCS_Result(null, 102);
}
// Check if the user exists
- if(!OC_User::userExists($parameters['userid'])){
+ if(!$this->userManager->userExists($parameters['userid'])){
return new OC_OCS_Result(null, 103);
}
// Add user to group
- return OC_Group::addToGroup($parameters['userid'], $group) ? new OC_OCS_Result(null, 100) : new OC_OCS_Result(null, 105);
+ $this->groupManager->get($group)->addUser(
+ $this->userManager->get($parameters['userid'])
+ );
+ return new OC_OCS_Result(null, 100);
}
- public static function removeFromGroup($parameters){
+ public function removeFromGroup($parameters) {
+ // Check if user is logged in
+ $user = $this->userSession->getUser();
+ if ($user === null) {
+ return new OC_OCS_Result(null, \OCP\API::RESPOND_UNAUTHORISED);
+ }
+
$group = !empty($parameters['_delete']['groupid']) ? $parameters['_delete']['groupid'] : null;
if(is_null($group)){
return new OC_OCS_Result(null, 101);
}
// If they're not an admin, check they are a subadmin of the group in question
- if(!OC_Group::inGroup(OC_User::getUser(), 'admin') && !OC_SubAdmin::isSubAdminofGroup(OC_User::getUser(), $group)){
+ if(!$this->groupManager->isInGroup($user->getUID(), 'admin') && !OC_SubAdmin::isSubAdminofGroup($user->getUID(), $group)){
return new OC_OCS_Result(null, 104);
}
// Check they aren't removing themselves from 'admin' or their 'subadmin; group
- if($parameters['userid'] === OC_User::getUser()){
- if(OC_Group::inGroup(OC_User::getUser(), 'admin')){
+ if($parameters['userid'] === $user->getUID()){
+ if($this->groupManager->isInGroup($user->getUID(), 'admin')){
if($group === 'admin'){
return new OC_OCS_Result(null, 105, 'Cannot remove yourself from the admin group');
}
} else {
// Not an admin, check they are not removing themself from their subadmin group
- if(in_array($group, OC_SubAdmin::getSubAdminsGroups(OC_User::getUser()))){
+ if(in_array($group, OC_SubAdmin::getSubAdminsGroups($user->getUID()))){
return new OC_OCS_Result(null, 105, 'Cannot remove yourself from this group as you are a SubAdmin');
}
}
}
// Check if the group exists
- if(!OC_Group::groupExists($group)){
+ if(!$this->groupManager->groupExists($group)){
return new OC_OCS_Result(null, 102);
}
// Check if the user exists
- if(!OC_User::userExists($parameters['userid'])){
+ if(!$this->userManager->userExists($parameters['userid'])){
return new OC_OCS_Result(null, 103);
}
// Remove user from group
- return OC_Group::removeFromGroup($parameters['userid'], $group) ? new OC_OCS_Result(null, 100) : new OC_OCS_Result(null, 105);
+ $this->groupManager->get($group)->removeUser(
+ $this->userManager->get($parameters['userid'])
+ );
+ return new OC_OCS_Result(null, 100);
}
/**
* Creates a subadmin
*/
- public static function addSubAdmin($parameters) {
+ public function addSubAdmin($parameters) {
$group = $_POST['groupid'];
$user = $parameters['userid'];
// Check if the user exists
- if(!OC_User::userExists($user)) {
+ if(!$this->userManager->userExists($user)) {
return new OC_OCS_Result(null, 101, 'User does not exist');
}
// Check if group exists
- if(!OC_Group::groupExists($group)) {
+ if(!$this->groupManager->groupExists($group)) {
return new OC_OCS_Result(null, 102, 'Group:'.$group.' does not exist');
}
// Check if trying to make subadmin of admin group
- if(strtolower($group) == 'admin') {
+ if(strtolower($group) === 'admin') {
return new OC_OCS_Result(null, 103, 'Cannot create subadmins for admin group');
}
// We cannot be subadmin twice
@@ -311,11 +394,11 @@ class Users {
/**
* Removes a subadmin from a group
*/
- public static function removeSubAdmin($parameters) {
+ public function removeSubAdmin($parameters) {
$group = $parameters['_delete']['groupid'];
$user = $parameters['userid'];
// Check if the user exists
- if(!OC_User::userExists($user)) {
+ if(!$this->userManager->userExists($user)) {
return new OC_OCS_Result(null, 101, 'User does not exist');
}
// Check if they are a subadmin of this said group
@@ -333,10 +416,10 @@ class Users {
/**
* @Get the groups a user is a subadmin of
*/
- public static function getUserSubAdminGroups($parameters) {
+ public function getUserSubAdminGroups($parameters) {
$user = $parameters['userid'];
// Check if the user exists
- if(!OC_User::userExists($user)) {
+ if(!$this->userManager->userExists($user)) {
return new OC_OCS_Result(null, 101, 'User does not exist');
}
// Get the subadmin groups
diff --git a/apps/provisioning_api/tests/appstest.php b/apps/provisioning_api/tests/appstest.php
index c4298f017fc..f2a3977eac4 100644
--- a/apps/provisioning_api/tests/appstest.php
+++ b/apps/provisioning_api/tests/appstest.php
@@ -25,8 +25,17 @@
namespace OCA\Provisioning_API\Tests;
class AppsTest extends TestCase {
+
+ public function setup() {
+ parent::setup();
+ $this->appManager = \OC::$server->getAppManager();
+ $this->groupManager = \OC::$server->getGroupManager();
+ $this->userSession = \OC::$server->getUserSession();
+ $this->api = new \OCA\Provisioning_API\Apps($this->appManager);
+ }
+
public function testGetAppInfo() {
- $result = \OCA\provisioning_API\Apps::getAppInfo(array('appid' => 'provisioning_api'));
+ $result = $this->api->getAppInfo(['appid' => 'provisioning_api']);
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
@@ -34,7 +43,7 @@ class AppsTest extends TestCase {
public function testGetAppInfoOnBadAppID() {
- $result = \OCA\provisioning_API\Apps::getAppInfo(array('appid' => 'not_provisioning_api'));
+ $result = $this->api->getAppInfo(['appid' => 'not_provisioning_api']);
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertFalse($result->succeeded());
$this->assertEquals(\OCP\API::RESPOND_NOT_FOUND, $result->getStatusCode());
@@ -44,10 +53,10 @@ class AppsTest extends TestCase {
public function testGetApps() {
$user = $this->generateUsers();
- \OC_Group::addToGroup($user, 'admin');
- self::loginAsUser($user);
+ $this->groupManager->get('admin')->addUser($user);
+ $this->userSession->setUser($user);
- $result = \OCA\provisioning_API\Apps::getApps(array());
+ $result = $this->api->getApps([]);
$this->assertTrue($result->succeeded());
$data = $result->getData();
@@ -58,7 +67,7 @@ class AppsTest extends TestCase {
public function testGetAppsEnabled() {
$_GET['filter'] = 'enabled';
- $result = \OCA\provisioning_API\Apps::getApps(array('filter' => 'enabled'));
+ $result = $this->api->getApps(['filter' => 'enabled']);
$this->assertTrue($result->succeeded());
$data = $result->getData();
$this->assertEquals(count(\OC_App::getEnabledApps()), count($data['apps']));
@@ -68,7 +77,7 @@ class AppsTest extends TestCase {
public function testGetAppsDisabled() {
$_GET['filter'] = 'disabled';
- $result = \OCA\provisioning_API\Apps::getApps(array('filter' => 'disabled'));
+ $result = $this->api->getApps(['filter' => 'disabled']);
$this->assertTrue($result->succeeded());
$data = $result->getData();
$apps = \OC_App::listAllApps();
@@ -78,6 +87,12 @@ class AppsTest extends TestCase {
}
$disabled = array_diff($list, \OC_App::getEnabledApps());
$this->assertEquals(count($disabled), count($data['apps']));
+ }
+ public function testGetAppsInvalidFilter() {
+ $_GET['filter'] = 'foo';
+ $result = $this->api->getApps([]);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(101, $result->getStatusCode());
}
}
diff --git a/apps/provisioning_api/tests/groupstest.php b/apps/provisioning_api/tests/groupstest.php
index b8b02790698..73044e33120 100644
--- a/apps/provisioning_api/tests/groupstest.php
+++ b/apps/provisioning_api/tests/groupstest.php
@@ -24,18 +24,79 @@
namespace OCA\Provisioning_API\Tests;
+use OCP\IUserManager;
+use OCP\IGroupManager;
+use OCP\IUserSession;
+
class GroupsTest extends TestCase {
+
+ /** @var IUserManager */
+ protected $userManager;
+
+ /** @var IGroupManager */
+ protected $groupManager;
+
+ /** @var IUserSession */
+ protected $userSession;
+
+ protected function setup() {
+ parent::setup();
+
+ $this->userManager = \OC::$server->getUserManager();
+ $this->groupManager = \OC::$server->getGroupManager();
+ $this->userSession = \OC::$server->getUserSession();
+ $this->api = new \OCA\Provisioning_API\Groups(
+ $this->groupManager,
+ $this->userSession
+ );
+ }
+
+ public function testGetGroups() {
+ $groups = [];
+ $id = $this->getUniqueID();
+
+ for ($i=0; $i < 10; $i++) {
+ $groups[] = $this->groupManager->createGroup($id . '_' . $i);
+ }
+
+ $_GET = [];
+ $result = $this->api->getGroups([]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertTrue($result->succeeded());
+ $this->assertCount(count($this->groupManager->search('')), $result->getData()['groups']);
+ $this->assertContains('admin', $result->getData()['groups']);
+ foreach ($groups as $group) {
+ $this->assertContains($group->getGID(), $result->getData()['groups']);
+ }
+
+ $_GET = [
+ 'search' => $id,
+ 'limit' => 5,
+ 'offset' => 2
+ ];
+ $result = $this->api->getGroups([]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertTrue($result->succeeded());
+ $this->assertCount(5, $result->getData()['groups']);
+ foreach (array_splice($groups, 2, 5) as $group) {
+ $this->assertContains($group->getGID(), $result->getData()['groups']);
+ }
+
+ foreach ($groups as $group) {
+ $group->delete();
+ }
+ }
+
public function testGetGroupAsUser() {
$users = $this->generateUsers(2);
- self::loginAsUser($users[0]);
+ $this->userSession->setUser($users[0]);
- $group = $this->getUniqueID();
- \OC_Group::createGroup($group);
- \OC_Group::addToGroup($users[1], $group);
+ $group = $this->groupManager->createGroup($this->getUniqueID());
+ $group->addUser($users[1]);
- $result = \OCA\provisioning_api\Groups::getGroup(array(
- 'groupid' => $group,
+ $result = $this->api->getGroup(array(
+ 'groupid' => $group->getGID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
@@ -47,18 +108,17 @@ class GroupsTest extends TestCase {
public function testGetGroupAsSubadmin() {
$users = $this->generateUsers(2);
- self::loginAsUser($users[0]);
+ $this->userSession->setUser($users[0]);
- $group = $this->getUniqueID();
- \OC_Group::createGroup($group);
- \OC_Group::addToGroup($users[0], $group);
- \OC_Group::addToGroup($users[1], $group);
+ $group = $this->groupManager->createGroup($this->getUniqueID());
+ $group->addUser($users[0]);
+ $group->addUser($users[1]);
- \OC_SubAdmin::createSubAdmin($users[0], $group);
+ \OC_SubAdmin::createSubAdmin($users[0]->getUID(), $group->getGID());
- $result = \OCA\provisioning_api\Groups::getGroup(array(
- 'groupid' => $group,
- ));
+ $result = $this->api->getGroup([
+ 'groupid' => $group->getGID(),
+ ]);
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
@@ -67,6 +127,10 @@ class GroupsTest extends TestCase {
$resultData = $result->getData();
$resultData = $resultData['users'];
+ $users = array_map(function($user) {
+ return $user->getUID();
+ }, $users);
+
sort($users);
sort($resultData);
$this->assertEquals($users, $resultData);
@@ -76,20 +140,18 @@ class GroupsTest extends TestCase {
public function testGetGroupAsIrrelevantSubadmin() {
$users = $this->generateUsers(2);
- self::loginAsUser($users[0]);
+ $this->userSession->setUser($users[0]);
- $group = $this->getUniqueID();
- \OC_Group::createGroup($group);
- $group2 = $this->getUniqueID();
- \OC_Group::createGroup($group2);
- \OC_Group::addToGroup($users[1], $group);
- \OC_Group::addToGroup($users[0], $group2);
+ $group1 = $this->groupManager->createGroup($this->getUniqueID());
+ $group2 = $this->groupManager->createGroup($this->getUniqueID());
+ $group1->addUser($users[1]);
+ $group2->addUser($users[0]);
- \OC_SubAdmin::createSubAdmin($users[0], $group2);
+ \OC_SubAdmin::createSubAdmin($users[0]->getUID(), $group2->getGID());
- $result = \OCA\provisioning_api\Groups::getGroup(array(
- 'groupid' => $group,
- ));
+ $result = $this->api->getGroup([
+ 'groupid' => $group1->getGID(),
+ ]);
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertFalse($result->succeeded());
@@ -100,49 +162,129 @@ class GroupsTest extends TestCase {
public function testGetGroupAsAdmin() {
$users = $this->generateUsers(2);
- self::loginAsUser($users[0]);
+ $this->userSession->setUser($users[0]);
- $group = $this->getUniqueID();
- \OC_Group::createGroup($group);
+ $group = $this->groupManager->createGroup($this->getUniqueID());
- \OC_Group::addToGroup($users[1], $group);
- \OC_Group::addToGroup($users[0], 'admin');
+ $group->addUser($users[1]);
+ $this->groupManager->get('admin')->addUser($users[0]);
- $result = \OCA\provisioning_api\Groups::getGroup(array(
- 'groupid' => $group,
- ));
+ $result = $this->api->getGroup([
+ 'groupid' => $group->getGID(),
+ ]);
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
- $this->assertEquals(array('users' => array($users[1])), $result->getData());
+ $this->assertEquals(['users' => [$users[1]->getUID()]], $result->getData());
+
+ }
+
+ public function testGetGroupNonExisting() {
+ $result = $this->api->getGroup([
+ 'groupid' => $this->getUniqueId()
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(\OCP\API::RESPOND_NOT_FOUND, $result->getStatusCode());
+ $this->assertEquals('The requested group could not be found', $result->getMeta()['message']);
}
public function testGetSubAdminsOfGroup() {
$user1 = $this->generateUsers();
$user2 = $this->generateUsers();
- self::loginAsUser($user1);
- \OC_Group::addToGroup($user1, 'admin');
- $group1 = $this->getUniqueID();
- \OC_Group::createGroup($group1);
- \OC_SubAdmin::createSubAdmin($user2, $group1);
- $result = \OCA\provisioning_api\Groups::getSubAdminsOfGroup(array(
- 'groupid' => $group1,
- ));
+ $this->userSession->setUser($user1);
+ $this->groupManager->get('admin')->addUser($user1);
+ $group1 = $this->groupManager->createGroup($this->getUniqueID());
+ \OC_SubAdmin::createSubAdmin($user2->getUID(), $group1->getGID());
+ $result = $this->api->getSubAdminsOfGroup([
+ 'groupid' => $group1->getGID(),
+ ]);
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
$data = $result->getData();
- $this->assertEquals($user2, reset($data));
- \OC_Group::deleteGroup($group1);
+ $this->assertEquals($user2->getUID(), reset($data));
+ $group1->delete();
$user1 = $this->generateUsers();
- self::loginAsUser($user1);
- \OC_Group::addToGroup($user1, 'admin');
- $result = \OCA\provisioning_api\Groups::getSubAdminsOfGroup(array(
+ $this->userSession->setUser($user1);
+ $this->groupManager->get('admin')->addUser($user1);
+ $result = $this->api->getSubAdminsOfGroup([
'groupid' => $this->getUniqueID(),
- ));
+ ]);
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertFalse($result->succeeded());
$this->assertEquals(101, $result->getStatusCode());
}
+
+ public function testAddGroupEmptyGroup() {
+ $_POST = [];
+ $result = $this->api->addGroup([]);
+
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(101, $result->getStatusCode());
+ $this->assertEquals('Invalid group name', $result->getMeta()['message']);
+ }
+
+ public function testAddGroupExistingGroup() {
+ $group = $this->groupManager->createGroup($this->getUniqueID());
+
+ $_POST = [
+ 'groupid' => $group->getGID()
+ ];
+ $result = $this->api->addGroup([]);
+
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(102, $result->getStatusCode());
+
+ $group->delete();
+ }
+
+ public function testAddGroup() {
+ $group = $this->getUniqueId();
+
+ $_POST = [
+ 'groupid' => $group
+ ];
+
+ $result = $this->api->addGroup([]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertTrue($result->succeeded());
+ $this->assertTrue($this->groupManager->groupExists($group));
+
+ $this->groupManager->get($group)->delete();
+ }
+
+ public function testDeleteGroupNonExisting() {
+ $group = $this->getUniqueId();
+
+ $result = $this->api->deleteGroup([
+ 'groupid' => $group
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(101, $result->getStatusCode());
+ }
+
+ public function testDeleteAdminGroup() {
+ $result = $this->api->deleteGroup([
+ 'groupid' => 'admin'
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(102, $result->getStatusCode());
+ }
+
+ public function testDeleteGroup() {
+ $group = $this->groupManager->createGroup($this->getUniqueId());
+
+ $result = $this->api->deleteGroup([
+ 'groupid' => $group->getGID()
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertTrue($result->succeeded());
+ $this->assertFalse($this->groupManager->groupExists($group->getGID()));
+ }
}
diff --git a/apps/provisioning_api/tests/testcase.php b/apps/provisioning_api/tests/testcase.php
index 3d0468daa12..ee7eb2a5a9a 100644
--- a/apps/provisioning_api/tests/testcase.php
+++ b/apps/provisioning_api/tests/testcase.php
@@ -22,12 +22,24 @@
namespace OCA\Provisioning_API\Tests;
+use OCP\IUserManager;
+use OCP\IGroupManager;
+
abstract class TestCase extends \Test\TestCase {
protected $users = array();
+ /** @var IUserManager */
+ protected $userManager;
+
+ /** @var IGroupManager */
+ protected $groupManager;
+
protected function setUp() {
parent::setUp();
- \OC_Group::createGroup('admin');
+
+ $this->userManager = \OC::$server->getUserManager();
+ $this->groupManager = \OC::$server->getGroupManager();
+ $this->groupManager->createGroup('admin');
}
/**
@@ -38,8 +50,7 @@ abstract class TestCase extends \Test\TestCase {
protected function generateUsers($num = 1) {
$users = array();
for ($i = 0; $i < $num; $i++) {
- $user = $this->getUniqueID();
- \OC_User::createUser($user, 'password');
+ $user = $this->userManager->createUser($this->getUniqueID(), 'password');
$this->users[] = $user;
$users[] = $user;
}
@@ -48,11 +59,10 @@ abstract class TestCase extends \Test\TestCase {
protected function tearDown() {
foreach($this->users as $user) {
- \OC_User::deleteUser($user);
+ $user->delete();
}
- \OC_Group::deleteGroup('admin');
-
+ $this->groupManager->get('admin')->delete();
parent::tearDown();
}
}
diff --git a/apps/provisioning_api/tests/userstest.php b/apps/provisioning_api/tests/userstest.php
index f2862565039..350586f8335 100644
--- a/apps/provisioning_api/tests/userstest.php
+++ b/apps/provisioning_api/tests/userstest.php
@@ -26,34 +26,67 @@
namespace OCA\Provisioning_API\Tests;
+use OCP\IUserManager;
+use OCP\IConfig;
+use OCP\IGroupManager;
+use OCP\IUserSession;
+
class UsersTest extends TestCase {
+
+ /** @var IUserManager */
+ protected $userManager;
+
+ /** @var IConfig */
+ protected $config;
+
+ /** @var IGroupManager */
+ protected $groupManager;
+
+ /** @var IUserSession */
+ protected $userSession;
+
protected function resetParams() {
$_GET = null;
$_POST = null;
}
+ protected function setup() {
+ parent::setup();
+
+ $this->userManager = \OC::$server->getUserManager();
+ $this->config = \OC::$server->getConfig();
+ $this->groupManager = \OC::$server->getGroupManager();
+ $this->userSession = \OC::$server->getUserSession();
+ $this->api = new \OCA\Provisioning_Api\Users(
+ $this->userManager,
+ $this->config,
+ $this->groupManager,
+ $this->userSession
+ );
+ }
+
// Test getting the list of users
public function testGetUsers() {
- $result = \OCA\provisioning_API\Users::getUsers(array());
+ $result = $this->api->getUsers();
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
$count = $result->getData();
$count = count($count['users']);
- $this->assertEquals(count(\OC_User::getUsers()), $count);
+ $this->assertEquals(count($this->userManager->search('', null, null)), $count);
$user = $this->generateUsers();
- $_GET['search'] = $user;
- $result = \OCA\provisioning_API\Users::getUsers(array());
+ $_GET['search'] = $user->getUID();
+ $result = $this->api->getUsers();
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
$data = $result->getData();
- $this->assertEquals($user, reset($data['users']));
+ $this->assertEquals($user->getUID(), reset($data['users']));
// Add several users
$this->generateUsers(10);
$this->resetParams();
$_GET['limit'] = 2;
- $result = \OCA\provisioning_API\Users::getUsers(array());
+ $result = $this->api->getUsers();
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
$count = $result->getData();
@@ -63,45 +96,93 @@ class UsersTest extends TestCase {
$this->resetParams();
$_GET['limit'] = 1;
$_GET['offset'] = 1;
- $result = \OCA\provisioning_API\Users::getUsers(array());
+ $result = $this->api->getUsers(array());
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
$data = $result->getData();
- $this->assertEquals(\OC_User::getUsers('', 1, 1), $data['users']);
+ $this->assertEquals(array_keys($this->userManager->search('', 1, 1)), $data['users']);
}
public function testAddUser() {
$this->resetParams();
$_POST['userid'] = $this->getUniqueID();
$_POST['password'] = 'password';
- $result = \OCA\provisioning_API\Users::addUser(array());
+ $result = $this->api->addUser();
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
- $this->assertTrue(\OC_User::userExists($_POST['userid']));
- $this->assertEquals($_POST['userid'], \OC_User::checkPassword($_POST['userid'], $_POST['password']));
- $this->users[] = $_POST['userid'];
+ $this->assertTrue($this->userManager->userExists($_POST['userid']));
+ $this->assertEquals($_POST['userid'], $this->userManager->checkPassword($_POST['userid'], $_POST['password'])->getUID());
+ $this->users[] = $this->userManager->get($_POST['userid']);
+ }
+
+ public function testAddUserTwice() {
+ $this->resetParams();
+ $_POST['userid'] = $this->getUniqueID();
+ $_POST['password'] = 'password';
+ $this->api->addUser();
+ $result = $this->api->addUser();
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(102, $result->getStatusCode());
+ $this->assertEquals('User already exists', $result->getMeta()['message']);
+ }
+
+ public function testAddUserFails() {
+ $uid = $this->getUniqueID();
+
+ $userManager = $this->getMockBuilder('\OCP\IUserManager')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $userManager->expects($this->once())
+ ->method('userExists')
+ ->with($uid)
+ ->willReturn(false);
+ $userManager->expects($this->once())
+ ->method('createUser')
+ ->with($uid, 'password')
+ ->will($this->throwException(new \Exception));
+
+ $api = new \OCA\Provisioning_Api\Users(
+ $userManager,
+ $this->config,
+ $this->groupManager,
+ $this->userSession
+ );
+
+ $this->resetParams();
+ $_POST['userid'] = $uid;
+ $_POST['password'] = 'password';
+ $result = $api->addUser();
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(101, $result->getStatusCode());
+ $this->assertEquals('Bad request', $result->getMeta()['message']);
}
public function testGetUserOnSelf() {
$user = $this->generateUsers();
- self::loginAsUser($user);
- $params['userid'] = $user;
- $result = \OCA\provisioning_API\Users::getUser($params);
+ $user->setDisplayName('foobar');
+ $this->userSession->setUser($user);
+ $params['userid'] = $user->getUID();
+ $result = $this->api->getUser($params);
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
$data = $result->getData();
+
+ $this->assertEquals('foobar', $data['displayname']);
}
public function testGetUserOnNonExistingUser() {
$user = $this->generateUsers();
- \OC_Group::addToGroup($user, 'admin');
- self::loginAsUser($user);
+ $this->groupManager->get('admin')->addUser($user);
+ $this->userSession->setUser($user);
$params = array();
$params['userid'] = $this->getUniqueID();
- while(\OC_User::userExists($params['userid'])) {
+ while($this->userManager->userExists($params['userid'])) {
$params['userid'] = $this->getUniqueID();
}
- $result = \OCA\provisioning_API\Users::getUser($params);
+ $result = $this->api->getUser($params);
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertFalse($result->succeeded());
$this->assertEquals(\OCP\API::RESPOND_NOT_FOUND, $result->getStatusCode());
@@ -111,33 +192,32 @@ class UsersTest extends TestCase {
public function testGetUserOnOtherUser() {
$users = $this->generateUsers(2);
$params['userid'] = $users[0];
- self::loginAsUser($users[1]);
- $result = \OCA\provisioning_API\Users::getUser($params);
+ $this->userSession->setUser($users[1]);
+ $result = $this->api->getUser($params);
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertFalse($result->succeeded());
// Now as as admin
$users = $this->generateUsers(2);
- $params['userid'] = $users[0];
+ $params['userid'] = $users[0]->getUID();
// login to generate home
- self::loginAsUser($users[0]);
- \OC_Group::addToGroup($users[1], 'admin');
- self::loginAsUser($users[1]);
- $result = \OCA\provisioning_API\Users::getUser($params);
+ $this->userSession->setUser($users[0]);
+ $this->groupManager->get('admin')->addUser($users[1]);
+ $this->userSession->setUser($users[1]);
+ $result = $this->api->getUser($params);
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
$data = $result->getData();
- $this->assertEquals(\OC::$server->getConfig()->getUserValue($users[0], 'core', 'enabled', 'true'), $data['enabled']);
+ $this->assertEquals(\OC::$server->getConfig()->getUserValue($users[0]->getUID(), 'core', 'enabled', 'true'), $data['enabled']);
}
public function testEditOwnDisplayName() {
-
// Test editing own name
$user = $this->generateUsers();
- self::loginAsUser($user);
- $result = \OCA\provisioning_API\Users::editUser(
+ $this->userSession->setUser($user);
+ $result = $this->api->editUser(
array(
- 'userid' => $user,
+ 'userid' => $user->getUID(),
'_put' => array(
'key' => 'display',
'value' => 'newname',
@@ -146,41 +226,39 @@ class UsersTest extends TestCase {
);
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
- $this->assertEquals('newname', \OC_User::getDisplayName($user));
+ $this->assertEquals('newname', $user->getDisplayName());
}
public function testAdminEditDisplayNameOfUser() {
-
// Test admin editing users name
$user = $this->generateUsers();
- \OC_Group::addToGroup($user, 'admin');
- self::loginAsUser($user);
+ $this->groupManager->get('admin')->addUser($user);
+ $this->userSession->setUser($user);
$user2 = $this->generateUsers();
- $result = \OCA\provisioning_API\Users::editUser(
- array(
- 'userid' => $user2,
- '_put' => array(
+ $result = $this->api->editUser(
+ [
+ 'userid' => $user2->getUID(),
+ '_put' => [
'key' => 'display',
'value' => 'newname',
- ),
- )
+ ],
+ ]
);
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
- $this->assertEquals('newname', \OC_User::getDisplayName($user2));
+ $this->assertEquals('newname', $user2->getDisplayName());
}
public function testUserEditOtherUserDisplayName() {
-
// Test editing other users name
$user = $this->generateUsers();
- self::loginAsUser($user);
+ $this->userSession->setUser($user);
$user2 = $this->generateUsers();
- $result = \OCA\provisioning_API\Users::editUser(
+ $result = $this->api->editUser(
array(
- 'userid' => $user2,
+ 'userid' => $user2->getUID(),
'_put' => array(
'key' => 'display',
'value' => 'newname',
@@ -199,11 +277,33 @@ class UsersTest extends TestCase {
*/
public function testEditOwnQuota($expected, $quota) {
$user = $this->generateUsers();
- \OC_Group::addToGroup($user, 'admin');
- self::loginAsUser($user);
- $result = \OCA\provisioning_API\Users::editUser(
+ $this->userSession->setUser($user);
+ $result = $this->api->editUser(
+ [
+ 'userid' => $user->getUID(),
+ '_put' => [
+ 'key' => 'quota',
+ 'value' => $quota,
+ ],
+ ]
+ );
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(997, $result->getStatusCode());
+ }
+
+ /**
+ * @dataProvider providesQuotas
+ * @param $expected
+ * @param $quota
+ */
+ public function testEditOwnQuotaAsAdmin($expected, $quota) {
+ $user = $this->generateUsers();
+ $this->groupManager->get('admin')->addUser($user);
+ $this->userSession->setUser($user);
+ $result = $this->api->editUser(
[
- 'userid' => $user,
+ 'userid' => $user->getUID(),
'_put' => [
'key' => 'quota',
'value' => $quota,
@@ -221,16 +321,18 @@ class UsersTest extends TestCase {
[true, 'none'],
[true, 'default'],
[false, 'qwertzu'],
+ [true, 0],
+ [true, -1]
];
}
public function testAdminEditOwnQuota() {
$user = $this->generateUsers();
- \OC_Group::addToGroup($user, 'admin');
- self::loginAsUser($user);
- $result = \OCA\provisioning_API\Users::editUser(
+ $this->groupManager->get('admin')->addUser($user);
+ $this->userSession->setUser($user);
+ $result = $this->api->editUser(
array(
- 'userid' => $user,
+ 'userid' => $user->getUID(),
'_put' => array(
'key' => 'quota',
'value' => '20G',
@@ -243,12 +345,12 @@ class UsersTest extends TestCase {
public function testAdminEditOtherUserQuota() {
$user = $this->generateUsers();
- \OC_Group::addToGroup($user, 'admin');
- self::loginAsUser($user);
+ $this->groupManager->get('admin')->addUser($user);
+ $this->userSession->setUser($user);
$user2 = $this->generateUsers();
- $result = \OCA\provisioning_API\Users::editUser(
+ $result = $this->api->editUser(
array(
- 'userid' => $user2,
+ 'userid' => $user2->getUID(),
'_put' => array(
'key' => 'quota',
'value' => '20G',
@@ -261,11 +363,11 @@ class UsersTest extends TestCase {
public function testUserEditOtherUserQuota() {
$user = $this->generateUsers();
- self::loginAsUser($user);
+ $this->userSession->setUser($user);
$user2 = $this->generateUsers();
- $result = \OCA\provisioning_API\Users::editUser(
+ $result = $this->api->editUser(
array(
- 'userid' => $user2,
+ 'userid' => $user2->getUID(),
'_put' => array(
'key' => 'quota',
'value' => '20G',
@@ -279,10 +381,10 @@ class UsersTest extends TestCase {
public function testUserEditOwnEmail() {
$user = $this->generateUsers();
$email = 'test@example.com';
- self::loginAsUser($user);
- $result = \OCA\provisioning_API\Users::editUser(
+ $this->userSession->setUser($user);
+ $result = $this->api->editUser(
array(
- 'userid' => $user,
+ 'userid' => $user->getUID(),
'_put' => array(
'key' => 'email',
'value' => $email,
@@ -291,16 +393,32 @@ class UsersTest extends TestCase {
);
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
- $this->assertEquals($email, \OC::$server->getConfig()->getUserValue($user, 'settings', 'email', null));
+ $this->assertEquals($email, \OC::$server->getConfig()->getUserValue($user->getUID(), 'settings', 'email', null));
+ }
+
+ public function testUserEditOwnEmailInvalid() {
+ $user = $this->generateUsers();
+ $email = 'test@example';
+ $this->userSession->setUser($user);
+ $result = $this->api->editUser([
+ 'userid' => $user->getUID(),
+ '_put' => [
+ 'key' => 'email',
+ 'value' => $email,
+ ],
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(102, $result->getStatusCode());
}
public function testUserEditOtherUserEmailAsUser() {
$users = $this->generateUsers(2);
$email = 'test@example.com';
- self::loginAsUser($users[0]);
- $result = \OCA\provisioning_API\Users::editUser(
+ $this->userSession->setUser($users[0]);
+ $result = $this->api->editUser(
array(
- 'userid' => $users[1],
+ 'userid' => $users[1]->getUID(),
'_put' => array(
'key' => 'email',
'value' => $email,
@@ -314,11 +432,11 @@ class UsersTest extends TestCase {
public function testUserEditOtherUserEmailAsAdmin() {
$users = $this->generateUsers(2);
$email = 'test@example.com';
- self::loginAsUser($users[0]);
- \OC_Group::addToGroup($users[0], 'admin');
- $result = \OCA\provisioning_API\Users::editUser(
+ $this->userSession->setUser($users[0]);
+ $this->groupManager->get('admin')->addUser($users[0]);
+ $result = $this->api->editUser(
array(
- 'userid' => $users[1],
+ 'userid' => $users[1]->getUID(),
'_put' => array(
'key' => 'email',
'value' => $email,
@@ -327,14 +445,60 @@ class UsersTest extends TestCase {
);
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
- $this->assertEquals($email, \OC::$server->getConfig()->getUserValue($users[1], 'settings', 'email', null));
+ $this->assertEquals($email, \OC::$server->getConfig()->getUserValue($users[1]->getUID(), 'settings', 'email', null));
+ }
+
+ public function testUserEditOwnPassword() {
+ $user = $this->generateUsers();
+ $password = 'foo';
+ $this->userSession->setUser($user);
+ $result = $this->api->editUser([
+ 'userid' => $user->getUID(),
+ '_put' => [
+ 'key' => 'password',
+ 'value' => $password,
+ ],
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertTrue($result->succeeded());
+ }
+
+ public function testUserEditOtherUserPasswordAsUser() {
+ $users = $this->generateUsers(2);
+ $password = 'foo';
+ $this->userSession->setUser($users[0]);
+ $result = $this->api->editUser([
+ 'userid' => $users[1]->getUID(),
+ '_put' => [
+ 'key' => 'password',
+ 'value' => $password,
+ ],
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ }
+
+ public function testUserEditOtherUserPasswordAsAdmin() {
+ $users = $this->generateUsers(2);
+ $password = 'foo';
+ $this->userSession->setUser($users[0]);
+ $this->groupManager->get('admin')->addUser($users[0]);
+ $result = $this->api->editUser([
+ 'userid' => $users[1]->getUID(),
+ '_put' => [
+ 'key' => 'password',
+ 'value' => $password,
+ ],
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertTrue($result->succeeded());
}
public function testDeleteSelf() {
$user = $this->generateUsers();
- self::loginAsUser($user);
- $result = \OCA\provisioning_API\Users::deleteUser(array(
- 'userid' => $user,
+ $this->userSession->setUser($user);
+ $result = $this->api->deleteUser(array(
+ 'userid' => $user->getUID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertFalse($result->succeeded());
@@ -342,10 +506,10 @@ class UsersTest extends TestCase {
public function testDeleteOtherAsUser() {
$user = $this->generateUsers();
- self::loginAsUser($user);
+ $this->userSession->setUser($user);
$user2 = $this->generateUsers();
- $result = \OCA\provisioning_API\Users::deleteUser(array(
- 'userid' => $user2,
+ $result = $this->api->deleteUser(array(
+ 'userid' => $user2->getUID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertFalse($result->succeeded());
@@ -353,48 +517,45 @@ class UsersTest extends TestCase {
public function testDeleteOtherAsSubAdmin() {
$user = $this->generateUsers();
- self::loginAsUser($user);
+ $this->userSession->setUser($user);
$user2 = $this->generateUsers();
- $group = $this->getUniqueID();
- \OC_Group::createGroup($group);
- \OC_Group::addToGroup($user, $group);
- \OC_Group::addToGroup($user2, $group);
- \OC_SubAdmin::createSubAdmin($user, $group);
- $result = \OCA\provisioning_API\Users::deleteUser(array(
- 'userid' => $user2,
+ $group = $this->groupManager->createGroup($this->getUniqueID());
+ $group->addUser($user);
+ $group->addUser($user2);
+ \OC_SubAdmin::createSubAdmin($user->getUID(), $group->getGID());
+ $result = $this->api->deleteUser(array(
+ 'userid' => $user2->getUID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
- \OC_Group::deleteGroup($group);
+ $group->delete();
}
public function testDeleteOtherAsIrelevantSubAdmin() {
$user = $this->generateUsers();
- self::loginAsUser($user);
+ $this->userSession->setUser($user);
$user2 = $this->generateUsers();
- $group = $this->getUniqueID();
- $group2 = $this->getUniqueID();
- \OC_Group::createGroup($group);
- \OC_Group::createGroup($group2);
- \OC_Group::addToGroup($user, $group);
- \OC_Group::addToGroup($user2, $group2);
- \OC_SubAdmin::createSubAdmin($user, $group);
- $result = \OCA\provisioning_API\Users::deleteUser(array(
- 'userid' => $user2,
- ));
+ $group = $this->groupManager->createGroup($this->getUniqueID());
+ $group2 = $this->groupManager->createGroup($this->getUniqueID());
+ $group->addUser($user);
+ $group2->addUser($user2);
+ \OC_SubAdmin::createSubAdmin($user->getUID(), $group->getGID());
+ $result = $this->api->deleteUser(array(
+ 'userid' => $user2->getUID(),
+ ));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertFalse($result->succeeded());
- \OC_Group::deleteGroup($group);
- \OC_Group::deleteGroup($group2);
+ $group->delete();
+ $group2->delete();
}
public function testDeleteOtherAsAdmin() {
$user = $this->generateUsers();
- \OC_Group::addToGroup($user, 'admin');
- self::loginAsUser($user);
+ $this->groupManager->get('admin')->addUser($user);
+ $this->userSession->setUser($user);
$user2 = $this->generateUsers();
- $result = \OCA\provisioning_API\Users::deleteUser(array(
- 'userid' => $user2,
+ $result = $this->api->deleteUser(array(
+ 'userid' => $user2->getUID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
@@ -402,288 +563,485 @@ class UsersTest extends TestCase {
public function testDeleteSelfAsAdmin() {
$user = $this->generateUsers();
- \OC_Group::addToGroup($user, 'admin');
- self::loginAsUser($user);
- $result = \OCA\provisioning_API\Users::deleteUser(array(
- 'userid' => $user,
+ $this->groupManager->get('admin')->addUser($user);
+ $this->userSession->setUser($user);
+ $result = $this->api->deleteUser(array(
+ 'userid' => $user->getUID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertFalse($result->succeeded());
}
+ public function testDeleteFails() {
+ $user = $this->getMockBuilder('\OCP\IUser')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $user->expects($this->once())
+ ->method('delete')
+ ->willReturn(false);
+
+ $user2 = $this->getMockBuilder('\OCP\IUser')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $user2->expects($this->any())
+ ->method('getUID')
+ ->willReturn('user2');
+
+ $userManager = $this->getMockBuilder('\OCP\IUserManager')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $userManager->expects($this->once())
+ ->method('userExists')
+ ->with('user')
+ ->willReturn(true);
+ $userManager->expects($this->once())
+ ->method('get')
+ ->with('user')
+ ->willReturn($user);
+
+ $userSession = $this->getMockBuilder('\OCP\IUserSession')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $userSession->expects($this->once())
+ ->method('getUser')
+ ->willReturn($user2);
+
+ $groupManager = $this->getMockBuilder('\OCP\IGroupManager')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $groupManager->expects($this->once())
+ ->method('isAdmin')
+ ->with('user2')
+ ->willReturn(true);
+
+ $api = new \OCA\Provisioning_Api\Users(
+ $userManager,
+ $this->config,
+ $groupManager,
+ $userSession
+ );
+
+ $result = $api->deleteUser([
+ 'userid' => 'user',
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(101, $result->getStatusCode());
+ }
+
public function testGetUsersGroupsOnSelf() {
$user = $this->generateUsers();
- self::loginAsUser($user);
+ $this->userSession->setUser($user);
$group = $this->getUniqueID();
- \OC_Group::createGroup($group);
- \OC_Group::addToGroup($user, $group);
- $result = \OCA\provisioning_API\Users::getUsersGroups(array(
- 'userid' => $user,
+ $group = $this->groupManager->createGroup($group);
+ $group->addUser($user);
+ $result = $this->api->getUsersGroups(array(
+ 'userid' => $user->getUID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
$data = $result->getData();
- $this->assertEquals($group, reset($data['groups']));
+ $this->assertEquals($group->getGID(), reset($data['groups']));
$this->assertEquals(1, count($data['groups']));
- \OC_Group::deleteGroup($group);
+ $group->delete();
}
public function testGetUsersGroupOnOther() {
$user1 = $this->generateUsers();
$user2 = $this->generateUsers();
- self::loginAsUser($user1);
+ $this->userSession->setUser($user1);
$group = $this->getUniqueID();
- \OC_Group::createGroup($group);
- \OC_Group::addToGroup($user2, $group);
- $result = \OCA\provisioning_API\Users::getUsersGroups(array(
- 'userid' => $user2,
+ $group = $this->groupManager->createGroup($group);
+ $group->addUser($user2);
+ $result = $this->api->getUsersGroups(array(
+ 'userid' => $user2->getUID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertFalse($result->succeeded());
- \OC_Group::deleteGroup($group);
+ $group->delete();
}
public function testGetUsersGroupOnOtherAsAdmin() {
$user1 = $this->generateUsers();
- \OC_Group::addToGroup($user1, 'admin');
+ $this->groupManager->get('admin')->addUser($user1);
$user2 = $this->generateUsers();
- self::loginAsUser($user1);
+ $this->userSession->setUser($user1);
$group = $this->getUniqueID();
- \OC_Group::createGroup($group);
- \OC_Group::addToGroup($user2, $group);
- $result = \OCA\provisioning_API\Users::getUsersGroups(array(
- 'userid' => $user2,
+ $group = $this->groupManager->createGroup($group);
+ $group->addUser($user2);
+ $result = $this->api->getUsersGroups(array(
+ 'userid' => $user2->getUID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
$data = $result->getData();
- $this->assertEquals($group, reset($data['groups']));
+ $this->assertEquals($group->getGID(), reset($data['groups']));
$this->assertEquals(1, count($data['groups']));
- \OC_Group::deleteGroup($group);
+ $group->delete();
}
public function testGetUsersGroupsOnOtherAsSubAdmin() {
$user1 = $this->generateUsers();
$user2 = $this->generateUsers();
- self::loginAsUser($user1);
+ $this->userSession->setUser($user1);
$group1 = $this->getUniqueID();
$group2 = $this->getUniqueID();
- \OC_Group::createGroup($group1);
- \OC_Group::createGroup($group2);
- \OC_Group::addToGroup($user2, $group1);
- \OC_Group::addToGroup($user2, $group2);
- \OC_Group::addToGroup($user1, $group1);
- \OC_SubAdmin::createSubAdmin($user1, $group1);
- $result = \OCA\provisioning_API\Users::getUsersGroups(array(
- 'userid' => $user2,
+ $group1 = $this->groupManager->createGroup($group1);
+ $group2 = $this->groupManager->createGroup($group2);
+ $group1->addUser($user2);
+ $group2->addUser($user2);
+ $group1->addUser($user1);
+ \OC_SubAdmin::createSubAdmin($user1->getUID(), $group1->getGID());
+ $result = $this->api->getUsersGroups(array(
+ 'userid' => $user2->getUID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
$data = $result->getData();
- $this->assertEquals($group1, reset($data['groups']));
+ $this->assertEquals($group1->getGID(), reset($data['groups']));
$this->assertEquals(1, count($data['groups']));
- \OC_Group::deleteGroup($group1);
- \OC_Group::deleteGroup($group2);
+ $group1->delete();
+ $group2->delete();
}
public function testGetUsersGroupsOnOtherAsIrelevantSubAdmin() {
$user1 = $this->generateUsers();
$user2 = $this->generateUsers();
- self::loginAsUser($user1);
+ $this->userSession->setUser($user1);
$group1 = $this->getUniqueID();
$group2 = $this->getUniqueID();
- \OC_Group::createGroup($group1);
- \OC_Group::createGroup($group2);
- \OC_Group::addToGroup($user2, $group2);
- \OC_Group::addToGroup($user1, $group1);
- \OC_SubAdmin::createSubAdmin($user1, $group1);
- $result = \OCA\provisioning_API\Users::getUsersGroups(array(
- 'userid' => $user2,
+ $group1 = $this->groupManager->createGroup($group1);
+ $group2 = $this->groupManager->createGroup($group2);
+ $group2->addUser($user2);
+ $group1->addUser($user1);
+ \OC_SubAdmin::createSubAdmin($user1->getUID(), $group1->getGID());
+ $result = $this->api->getUsersGroups(array(
+ 'userid' => $user2->getUID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertFalse($result->succeeded());
- \OC_Group::deleteGroup($group1);
- \OC_Group::deleteGroup($group2);
+ $group1->delete();
+ $group2->delete();
}
public function testAddToGroup() {
$user = $this->generateUsers();
$group = $this->getUniqueID();
- \OC_Group::createGroup($group);
- self::loginAsUser($user);
- $_POST['groupid'] = $group;
- $result = \OCA\provisioning_API\Users::addToGroup(array(
- 'userid' => $user,
+ $group = $this->groupManager->createGroup($group);
+ $this->userSession->setUser($user);
+ $_POST['groupid'] = $group->getGID();
+ $result = $this->api->addToGroup(array(
+ 'userid' => $user->getUID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertFalse($result->succeeded());
- $this->assertFalse(\OC_Group::inGroup($user, $group));
- \OC_Group::deleteGroup($group);
+ $this->assertFalse($group->inGroup($user));
+ $group->delete();
}
public function testAddToGroupAsAdmin() {
$user = $this->generateUsers();
- \OC_Group::addToGroup($user, 'admin');
+ $this->groupManager->get('admin')->addUser($user);
$group = $this->getUniqueID();
- \OC_Group::createGroup($group);
+ $group = $this->groupManager->createGroup($group);
$user2 = $this->generateUsers();
- self::loginAsUser($user);
- $_POST['groupid'] = $group;
- $result = \OCA\provisioning_API\Users::addToGroup(array(
- 'userid' => $user2,
+ $this->userSession->setUser($user);
+ $_POST['groupid'] = $group->getGID();
+ $result = $this->api->addToGroup(array(
+ 'userid' => $user2->getUID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
- $this->assertTrue(\OC_Group::inGroup($user2, $group));
- \OC_Group::deleteGroup($group);
+ $this->assertTrue($group->inGroup($user2));
+ $group->delete();
}
public function testAddToGroupAsSubAdmin() {
$user1 = $this->generateUsers();
$user2 = $this->generateUsers();
- self::loginAsUser($user1);
+ $this->userSession->setUser($user1);
$group1 = $this->getUniqueID();
- \OC_Group::createGroup($group1);
- \OC_SubAdmin::createSubAdmin($user1, $group1);
- $_POST['groupid'] = $group1;
- $result = \OCA\provisioning_API\Users::addToGroup(array(
- 'userid' => $user2,
+ $group1 = $this->groupManager->createGroup($group1);
+ \OC_SubAdmin::createSubAdmin($user1->getUID(), $group1->getGID());
+ $_POST['groupid'] = $group1->getGID();
+ $result = $this->api->addToGroup(array(
+ 'userid' => $user2->getUID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertFalse($result->succeeded());
- $this->assertFalse(\OC_Group::inGroup($user2, $group1));
- \OC_Group::deleteGroup($group1);
+ $this->assertFalse($group1->inGroup($user2));
+ $group1->delete();
}
public function testAddToGroupAsIrelevantSubAdmin() {
$user1 = $this->generateUsers();
$user2 = $this->generateUsers();
- self::loginAsUser($user1);
+ $this->userSession->setUser($user1);
$group1 = $this->getUniqueID();
$group2 = $this->getUniqueID();
- \OC_Group::createGroup($group1);
- \OC_Group::createGroup($group2);
- \OC_SubAdmin::createSubAdmin($user1, $group1);
- $_POST['groupid'] = $group2;
- $result = \OCA\provisioning_API\Users::addToGroup(array(
- 'userid' => $user2,
+ $group1 = $this->groupManager->createGroup($group1);
+ $group2 = $this->groupManager->createGroup($group2);
+ \OC_SubAdmin::createSubAdmin($user1->getUID(), $group1->getGID());
+ $_POST['groupid'] = $group2->getGID();
+ $result = $this->api->addToGroup(array(
+ 'userid' => $user2->getUID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertFalse($result->succeeded());
- $this->assertFalse(\OC_Group::inGroup($user2, $group2));
- \OC_Group::deleteGroup($group1);
- \OC_Group::deleteGroup($group2);
+ $this->assertFalse($group2->inGroup($user2));
+ $group1->delete();
+ $group2->delete();
+ }
+
+ public function testAddToGroupNoGroupId() {
+ $_POST['groupid'] = '';
+ $result = $this->api->addToGroup([
+ 'userid' => $this->getUniqueID(),
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(101, $result->getStatusCode());
+ }
+
+ public function testAddToNonExistingGroup() {
+ $user = $this->generateUsers();
+ $this->groupManager->get('admin')->addUser($user);
+ $this->userSession->setUser($user);
+
+ $group = $this->groupManager->createGroup($this->getUniqueID());
+ $_POST['groupid'] = $group->getGID();
+ $result = $this->api->addToGroup([
+ 'userid' => $this->getUniqueID(),
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(103, $result->getStatusCode());
+ }
+
+ public function testAddNonExistingUserToGroup() {
+ $user = $this->generateUsers();
+ $this->groupManager->get('admin')->addUser($user);
+ $this->userSession->setUser($user);
+
+ $_POST['groupid'] = $this->getUniqueID();
+ $result = $this->api->addToGroup([
+ 'userid' => $this->getUniqueID(),
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(102, $result->getStatusCode());
}
// test delete /cloud/users/{userid}/groups
public function testRemoveFromGroupAsSelf() {
$user1 = $this->generateUsers();
- self::loginAsUser($user1);
+ $this->userSession->setUser($user1);
$group1 = $this->getUniqueID();
- \OC_Group::createGroup($group1);
- \OC_Group::addToGroup($user1, $group1);
- $result = \OCA\provisioning_api\Users::removeFromGroup(array(
- 'userid' => $user1,
+ $group1 = $this->groupManager->createGroup($group1);
+ $group1->addUser($user1);
+ $result = $this->api->removeFromGroup(array(
+ 'userid' => $user1->getUID(),
'_delete' => array(
- 'groupid' => $group1,
+ 'groupid' => $group1->getGID(),
),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertFalse($result->succeeded());
- $this->assertTrue(\OC_Group::inGroup($user1, $group1));
- \OC_Group::deleteGroup($group1);
+ $this->assertTrue($group1->inGroup($user1));
+ $group1->delete();
}
public function testRemoveFromGroupAsAdmin() {
$user1 = $this->generateUsers();
$user2 = $this->generateUsers();
- self::loginAsUser($user1);
+ $this->userSession->setUser($user1);
$group1 = $this->getUniqueID();
- \OC_Group::createGroup($group1);
- \OC_Group::addToGroup($user2, $group1);
- \OC_Group::addToGroup($user1, 'admin');
- $result = \OCA\provisioning_api\Users::removeFromGroup(array(
- 'userid' => $user2,
+ $group1 = $this->groupManager->createGroup($group1);
+ $group1->addUser($user2);
+ $this->groupManager->get('admin')->addUser($user1);
+ $result = $this->api->removeFromGroup(array(
+ 'userid' => $user2->getUID(),
'_delete' => array(
- 'groupid' => $group1,
+ 'groupid' => $group1->getGID(),
),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
- $this->assertFalse(\OC_Group::inGroup($user2, $group1));
- \OC_Group::deleteGroup($group1);
+ $this->assertFalse($group1->inGroup($user2));
+ $group1->delete();
+ }
+
+ public function testRemoveSelfFromGroupAsAdmin() {
+ $user1 = $this->generateUsers();
+ $this->userSession->setUser($user1);
+ $group1 = $this->groupManager->createGroup($this->getUniqueID());
+ $group1->addUser($user1);
+ $this->groupManager->get('admin')->addUser($user1);
+ $result = $this->api->removeFromGroup([
+ 'userid' => $user1->getUID(),
+ '_delete' => [
+ 'groupid' => $group1->getGID(),
+ ],
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertTrue($result->succeeded());
+ $this->assertFalse($group1->inGroup($user1));
+ $group1->delete();
}
public function testRemoveFromGroupAsSubAdmin() {
$user1 = $this->generateUsers();
- self::loginAsUser($user1);
+ $this->userSession->setUser($user1);
$user2 = $this->generateUsers();
$group1 = $this->getUniqueID();
- \OC_Group::createGroup($group1);
- \OC_Group::addToGroup($user1, $group1);
- \OC_Group::addToGroup($user2, $group1);
- \OC_SubAdmin::createSubAdmin($user1, $group1);
- $result = \OCA\provisioning_api\Users::removeFromGroup(array(
- 'userid' => $user2,
+ $group1 = $this->groupManager->createGroup($group1);
+ $group1->addUser($user1);
+ $group1->addUser($user2);
+ \OC_SubAdmin::createSubAdmin($user1->getUID(), $group1->getGID());
+ $result = $this->api->removeFromGroup(array(
+ 'userid' => $user2->getUID(),
'_delete' => array(
- 'groupid' => $group1,
+ 'groupid' => $group1->getGID(),
),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
- $this->assertFalse(\OC_Group::inGroup($user2, $group1));
- \OC_Group::deleteGroup($group1);
+ $this->assertFalse($group1->inGroup($user2));
+ $group1->delete();
}
public function testRemoveFromGroupAsIrelevantSubAdmin() {
$user1 = $this->generateUsers();
- self::loginAsUser($user1);
+ $this->userSession->setUser($user1);
$user2 = $this->generateUsers();
$group1 = $this->getUniqueID();
$group2 = $this->getUniqueID();
- \OC_Group::createGroup($group1);
- \OC_Group::createGroup($group2);
- \OC_Group::addToGroup($user1, $group1);
- \OC_Group::addToGroup($user2, $group2);
- \OC_SubAdmin::createSubAdmin($user1, $group1);
- $result = \OCA\provisioning_api\Users::removeFromGroup(array(
- 'userid' => $user2,
+ $group1 = $this->groupManager->createGroup($group1);
+ $group2 = $this->groupManager->createGroup($group2);
+ $group1->addUser($user1);
+ $group2->addUser($user2);
+ \OC_SubAdmin::createSubAdmin($user1->getUID(), $group1->getGID());
+ $result = $this->api->removeFromGroup(array(
+ 'userid' => $user2->getUID(),
'_delete' => array(
- 'groupid' => $group2,
+ 'groupid' => $group2->getGID(),
),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertFalse($result->succeeded());
- $this->assertTrue(\OC_Group::inGroup($user2, $group2));
- \OC_Group::deleteGroup($group1);
- \OC_Group::deleteGroup($group2);
+ $this->assertTrue($group2->inGroup($user2));
+ $group1->delete();
+ $group2->delete();
+ }
+
+ public function testRemoveFromGroupNoGroupId() {
+ $result = $this->api->removeFromGroup([
+ '_delete' => [
+ 'groupid' => ''
+ ],
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(101, $result->getStatusCode());
}
+ public function testRemoveSelfFromAdminAsAdmin() {
+ $user = $this->generateUsers();
+ $this->userSession->setUser($user);
+ $this->groupManager->get('admin')->addUser($user);
+
+ $result = $this->api->removeFromGroup([
+ 'userid' => $user->getUID(),
+ '_delete' => [
+ 'groupid' => 'admin'
+ ],
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(105, $result->getStatusCode());
+ $this->assertEquals('Cannot remove yourself from the admin group', $result->getMeta()['message']);
+ }
+
+ public function testRemoveSelfFromSubAdminGroupAsSubAdmin() {
+ $user = $this->generateUsers();
+ $this->userSession->setUser($user);
+ $group = $this->groupManager->createGroup($this->getUniqueID());
+ \OC_SubAdmin::createSubAdmin($user->getUID(), $group->getGID());
+
+ $result = $this->api->removeFromGroup([
+ 'userid' => $user->getUID(),
+ '_delete' => [
+ 'groupid' => $group->getGID()
+ ],
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(105, $result->getStatusCode());
+ $this->assertEquals('Cannot remove yourself from this group as you are a SubAdmin', $result->getMeta()['message']);
+ $group->delete();
+ }
+
+ public function testRemoveFromNonExistingGroup() {
+ $user1 = $this->generateUsers();
+ $this->userSession->setUser($user1);
+ $this->groupManager->get('admin')->addUser($user1);
+
+ $user2 = $this->generateUsers();
+ $result = $this->api->removeFromGroup([
+ 'userid' => $user2->getUID(),
+ '_delete' => [
+ 'groupid' => $this->getUniqueID()
+ ],
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(102, $result->getStatusCode());
+ }
+
+ public function testRemoveFromNonGroupNonExistingUser() {
+ $user = $this->generateUsers();
+ $this->userSession->setUser($user);
+ $this->groupManager->get('admin')->addUser($user);
+
+ $group = $this->groupManager->createGroup($this->getUniqueID());
+
+ $result = $this->api->removeFromGroup([
+ 'userid' => $this->getUniqueID(),
+ '_delete' => [
+ 'groupid' => $group->getGID()
+ ],
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(103, $result->getStatusCode());
+ }
+
+
public function testCreateSubAdmin() {
$user1 = $this->generateUsers();
$user2 = $this->generateUsers();
- self::loginAsUser($user1);
- \OC_Group::addToGroup($user1, 'admin');
+ $this->userSession->setUser($user1);
+ $this->groupManager->get('admin')->addUser($user1);
$group1 = $this->getUniqueID();
- \OC_Group::createGroup($group1);
- $_POST['groupid'] = $group1;
- $result = \OCA\provisioning_api\Users::addSubAdmin(array(
- 'userid' => $user2,
+ $group1 = $this->groupManager->createGroup($group1);
+ $_POST['groupid'] = $group1->getGID();
+ $result = $this->api->addSubAdmin(array(
+ 'userid' => $user2->getUID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
- $this->assertTrue(\OC_SubAdmin::isSubAdminofGroup($user2, $group1));
- \OC_Group::deleteGroup($group1);
+ $this->assertTrue(\OC_SubAdmin::isSubAdminofGroup($user2->getUID(), $group1->getGID()));
+ $group1->delete();
$this->resetParams();
$user1 = $this->generateUsers();
$user2 = $this->generateUsers();
- self::loginAsUser($user1);
- \OC_Group::addToGroup($user1, 'admin');
+ $this->userSession->setUser($user1);
+ $this->groupManager->get('admin')->addUser($user1);
$_POST['groupid'] = 'admin';
- $result = \OCA\provisioning_api\Users::addSubAdmin(array(
- 'userid' => $user2,
+ $result = $this->api->addSubAdmin(array(
+ 'userid' => $user2->getUID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertEquals(103, $result->getStatusCode());
@@ -692,46 +1050,58 @@ class UsersTest extends TestCase {
$this->resetParams();
$user1 = $this->generateUsers();
- self::loginAsUser($user1);
- \OC_Group::addToGroup($user1, 'admin');
+ $this->userSession->setUser($user1);
+ $this->groupManager->get('admin')->addUser($user1);
$group1 = $this->getUniqueID();
- \OC_Group::createGroup($group1);
- $_POST['groupid'] = $group1;
- $result = \OCA\provisioning_api\Users::addSubAdmin(array(
+ $group1 = $this->groupManager->createGroup($group1);
+ $_POST['groupid'] = $group1->getGID();
+ $result = $this->api->addSubAdmin(array(
'userid' => $this->getUniqueID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertFalse($result->succeeded());
$this->assertEquals(101, $result->getStatusCode());
- \OC_Group::deleteGroup($group1);
+ $group1->delete();
+
+ $user1 = $this->generateUsers();
+ $this->userSession->setUser($user1);
+ $group = $this->getUniqueID();
+ $_POST['groupid'] = $group;
+ $result = $this->api->addSubAdmin([
+ 'userid' => $user1->getUID()
+ ]);
+ $this->assertInstanceOf('OC_OCS_Result', $result);
+ $this->assertFalse($result->succeeded());
+ $this->assertEquals(102, $result->getStatusCode());
+ $this->assertEquals('Group:'.$group.' does not exist', $result->getMeta()['message']);
}
public function testRemoveSubAdmin() {
$user1 = $this->generateUsers();
$user2 = $this->generateUsers();
- self::loginAsUser($user1);
- \OC_Group::addToGroup($user1, 'admin');
+ $this->userSession->setUser($user1);
+ $this->groupManager->get('admin')->addUser($user1);
$group1 = $this->getUniqueID();
- \OC_Group::createGroup($group1);
- \OC_SubAdmin::createSubAdmin($user2, $group1);
- $result = \OCA\provisioning_api\Users::removeSubAdmin(array(
- 'userid' => $user2,
+ $group1 = $this->groupManager->createGroup($group1);
+ \OC_SubAdmin::createSubAdmin($user2->getUID(), $group1->getGID());
+ $result = $this->api->removeSubAdmin(array(
+ 'userid' => $user2->getUID(),
'_delete' => array(
- 'groupid' => $group1,
+ 'groupid' => $group1->getGID(),
),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
- $this->assertTrue(!\OC_SubAdmin::isSubAdminofGroup($user2, $group1));
- \OC_Group::deleteGroup($group1);
+ $this->assertTrue(!\OC_SubAdmin::isSubAdminofGroup($user2->getUID(), $group1->getGID()));
+ $group1->delete();
$user1 = $this->generateUsers();
- self::loginAsUser($user1);
- \OC_Group::addToGroup($user1, 'admin');
- $result = \OCA\provisioning_api\Users::removeSubAdmin(array(
+ $this->userSession->setUser($user1);
+ $this->groupManager->get('admin')->addUser($user1);
+ $result = $this->api->removeSubAdmin(array(
'userid' => $this->getUniqueID(),
'_delete' => array(
- 'groupid' => $group1,
+ 'groupid' => $group1->getGID(),
),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
@@ -742,45 +1112,44 @@ class UsersTest extends TestCase {
$user1 = $this->generateUsers();
$user2 = $this->generateUsers();
- self::loginAsUser($user1);
- \OC_Group::addToGroup($user1, 'admin');
+ $this->userSession->setUser($user1);
+ $this->groupManager->get('admin')->addUser($user1);
$group1 = $this->getUniqueID();
- \OC_Group::createGroup($group1);
- $_POST['groupid'] = $group1;
- $result = \OCA\provisioning_api\Users::removeSubAdmin(array(
- 'userid' => $user2,
+ $group1 = $this->groupManager->createGroup($group1);
+ $_POST['groupid'] = $group1->getGID();
+ $result = $this->api->removeSubAdmin(array(
+ 'userid' => $user2->getUID(),
'_delete' => array(
- 'groupid' => $group1,
+ 'groupid' => $group1->getGID(),
),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertFalse($result->succeeded());
$this->assertEquals(102, $result->getStatusCode());
- \OC_Group::deleteGroup($group1);
+ $group1->delete();
}
public function testGetSubAdminGroups() {
$user1 = $this->generateUsers();
$user2 = $this->generateUsers();
- self::loginAsUser($user1);
- \OC_Group::addToGroup($user1, 'admin');
+ $this->userSession->setUser($user1);
+ $this->groupManager->get('admin')->addUser($user1);
$group1 = $this->getUniqueID();
- \OC_Group::createGroup($group1);
- \OC_SubAdmin::createSubAdmin($user2, $group1);
- $result = \OCA\provisioning_api\Users::getUserSubAdminGroups(array(
- 'userid' => $user2,
+ $group1 = $this->groupManager->createGroup($group1);
+ \OC_SubAdmin::createSubAdmin($user2->getUID(), $group1->getGID());
+ $result = $this->api->getUserSubAdminGroups(array(
+ 'userid' => $user2->getUID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
$data = $result->getData();
- $this->assertEquals($group1, reset($data));
- \OC_Group::deleteGroup($group1);
+ $this->assertEquals($group1->getGID(), reset($data));
+ $group1->delete();
$user1 = $this->generateUsers();
- self::loginAsUser($user1);
- \OC_Group::addToGroup($user1, 'admin');
- $group1 = $this->getUniqueID();
- $result = \OCA\provisioning_api\Users::getUserSubAdminGroups(array(
+ $this->userSession->setUser($user1);
+ $this->groupManager->get('admin')->addUser($user1);
+ $result = $this->api->getUserSubAdminGroups(array(
'userid' => $this->getUniqueID(),
));
$this->assertInstanceOf('OC_OCS_Result', $result);
@@ -791,25 +1160,25 @@ class UsersTest extends TestCase {
public function testSubAdminOfGroupAlreadySubAdmin() {
$user1 = $this->generateUsers();
$user2 = $this->generateUsers();
- self::loginAsUser($user1);
- \OC_Group::addToGroup($user1, 'admin');
- $group1 = $this->getUniqueID();
- \OC_Group::createGroup($group1);
+ $this->userSession->setUser($user1);
+ $this->groupManager->get('admin')->addUser($user1);
+ $group1 = $this->groupManager->createGroup($this->getUniqueID());
//Make user2 subadmin of group1
- $_POST['groupid'] = $group1;
- $result = \OCA\provisioning_api\Users::addSubAdmin([
- 'userid' => $user2,
+ $_POST['groupid'] = $group1->getGID();
+ $result = $this->api->addSubAdmin([
+ 'userid' => $user2->getUID(),
]);
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
//Make user2 subadmin of group1 again
- $_POST['groupid'] = $group1;
- $result = \OCA\provisioning_api\Users::addSubAdmin([
- 'userid' => $user2,
+ $_POST['groupid'] = $group1->getGID();
+ $result = $this->api->addSubAdmin([
+ 'userid' => $user2->getUID(),
]);
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
+ $group1->delete();
}
}
diff --git a/config/config.sample.php b/config/config.sample.php
index 7becf3c3dc4..047e7ccdd12 100644
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -1035,7 +1035,13 @@ $CONFIG = array(
/**
* Headers that should be trusted as client IP address in combination with
- * `trusted_proxies`
+ * `trusted_proxies`. If the HTTP header looks like 'X-Forwarded-For', then use
+ * 'HTTP_X_FORWARDED_FOR' here.
+ *
+ * If set incorrectly, a client can spoof their IP address as visible to
+ * ownCloud, bypassing access controls and making logs useless!
+ *
+ * Defaults to 'HTTP_X_FORWARED_FOR' if unset
*/
'forwarded_for_headers' => array('HTTP_X_FORWARDED', 'HTTP_FORWARDED_FOR'),
diff --git a/core/css/apps.css b/core/css/apps.css
index 5769120c5ed..300b186bba2 100644
--- a/core/css/apps.css
+++ b/core/css/apps.css
@@ -292,13 +292,13 @@
list-style-type: none;
}
+.bubble,
#app-navigation .app-navigation-entry-menu {
- display: none;
position: absolute;
background-color: #eee;
color: #333;
border-radius: 3px;
- border-top-right-radius: 0px;
+ border-top-right-radius: 0;
z-index: 110;
margin: -5px 14px 5px 10px;
right: 0;
@@ -310,11 +310,17 @@
filter: drop-shadow(0 0 5px rgba(150, 150, 150, 0.75));
}
+#app-navigation .app-navigation-entry-menu {
+ display: none;
+}
+
#app-navigation .app-navigation-entry-menu.open {
display: block;
}
/* miraculous border arrow stuff */
+.bubble:after,
+.bubble:before,
#app-navigation .app-navigation-entry-menu:after,
#app-navigation .app-navigation-entry-menu:before {
bottom: 100%;
@@ -327,12 +333,15 @@
pointer-events: none;
}
+.bubble:after,
#app-navigation .app-navigation-entry-menu:after {
border-color: rgba(238, 238, 238, 0);
border-bottom-color: #eee;
border-width: 10px;
margin-left: -10px;
}
+
+.bubble:before,
#app-navigation .app-navigation-entry-menu:before {
border-color: rgba(187, 187, 187, 0);
border-bottom-color: #bbb;
diff --git a/core/js/core.json b/core/js/core.json
index 1053debaa99..a67491c4a35 100644
--- a/core/js/core.json
+++ b/core/js/core.json
@@ -7,7 +7,8 @@
"moment/min/moment-with-locales.js",
"handlebars/handlebars.js",
"blueimp-md5/js/md5.js",
- "bootstrap/js/tooltip.js"
+ "bootstrap/js/tooltip.js",
+ "backbone/backbone.js"
],
"libraries": [
"jquery-showpassword.js",
@@ -19,6 +20,7 @@
"jquery.ocdialog.js",
"oc-dialogs.js",
"js.js",
+ "oc-backbone.js",
"l10n.js",
"apps.js",
"share.js",
diff --git a/core/js/js.js b/core/js/js.js
index 72d4edd28dd..89bb9a71430 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -571,21 +571,20 @@ var OC={
* @todo Write documentation
*/
registerMenu: function($toggle, $menuEl) {
+ var self = this;
$menuEl.addClass('menu');
$toggle.on('click.menu', function(event) {
// prevent the link event (append anchor to URL)
event.preventDefault();
if ($menuEl.is(OC._currentMenu)) {
- $menuEl.slideUp(OC.menuSpeed);
- OC._currentMenu = null;
- OC._currentMenuToggle = null;
+ self.hideMenus();
return;
}
// another menu was open?
else if (OC._currentMenu) {
// close it
- OC._currentMenu.hide();
+ self.hideMenus();
}
$menuEl.slideToggle(OC.menuSpeed);
OC._currentMenu = $menuEl;
@@ -599,15 +598,56 @@ var OC={
unregisterMenu: function($toggle, $menuEl) {
// close menu if opened
if ($menuEl.is(OC._currentMenu)) {
- $menuEl.slideUp(OC.menuSpeed);
- OC._currentMenu = null;
- OC._currentMenuToggle = null;
+ this.hideMenus();
}
$toggle.off('click.menu').removeClass('menutoggle');
$menuEl.removeClass('menu');
},
/**
+ * Hides any open menus
+ *
+ * @param {Function} complete callback when the hiding animation is done
+ */
+ hideMenus: function(complete) {
+ if (OC._currentMenu) {
+ var lastMenu = OC._currentMenu;
+ OC._currentMenu.trigger(new $.Event('beforeHide'));
+ OC._currentMenu.slideUp(OC.menuSpeed, function() {
+ lastMenu.trigger(new $.Event('afterHide'));
+ if (complete) {
+ complete.apply(this, arguments);
+ }
+ });
+ }
+ OC._currentMenu = null;
+ OC._currentMenuToggle = null;
+ },
+
+ /**
+ * Shows a given element as menu
+ *
+ * @param {Object} [$toggle=null] menu toggle
+ * @param {Object} $menuEl menu element
+ * @param {Function} complete callback when the showing animation is done
+ */
+ showMenu: function($toggle, $menuEl, complete) {
+ if ($menuEl.is(OC._currentMenu)) {
+ return;
+ }
+ this.hideMenus();
+ OC._currentMenu = $menuEl;
+ OC._currentMenuToggle = $toggle;
+ $menuEl.trigger(new $.Event('beforeShow'));
+ $menuEl.show();
+ $menuEl.trigger(new $.Event('afterShow'));
+ // no animation
+ if (_.isFunction()) {
+ complete();
+ }
+ },
+
+ /**
* Wrapper for matchMedia
*
* This is makes it possible for unit tests to
@@ -1256,11 +1296,8 @@ function initCore() {
// don't close when clicking on the menu directly or a menu toggle
return false;
}
- if (OC._currentMenu) {
- OC._currentMenu.slideUp(OC.menuSpeed);
- }
- OC._currentMenu = null;
- OC._currentMenuToggle = null;
+
+ OC.hideMenus();
});
diff --git a/core/js/setupchecks.js b/core/js/setupchecks.js
index 35f24b188fa..fd192e6563b 100644
--- a/core/js/setupchecks.js
+++ b/core/js/setupchecks.js
@@ -72,6 +72,16 @@
if(data.isUsedTlsLibOutdated) {
messages.push(data.isUsedTlsLibOutdated);
}
+ if(data.phpSupported && data.phpSupported.eol) {
+ messages.push(
+ t('core', 'Your PHP version ({version}) is no longer <a href="{phpLink}">supported by PHP</a>. We encourage you to upgrade your PHP version to take advantage of performance and security updates provided by PHP.', {version: data.phpSupported.version, phpLink: 'https://secure.php.net/supported-versions.php'})
+ );
+ }
+ if(!data.forwardedForHeadersWorking) {
+ messages.push(
+ t('core', 'The reverse proxy headers configuration is incorrect, or you are accessing ownCloud from a trusted proxy. If you are not accessing ownCloud from a trusted proxy, this is a security issue and can allow an attacker to spoof their IP address as visible to ownCloud. Further information can be found in our <a href="{docLink}">documentation</a>.', {docLink: data.reverseProxyDocs})
+ );
+ }
} else {
messages.push(t('core', 'Error occurred while checking server setup'));
}
diff --git a/core/js/share.js b/core/js/share.js
index 99fd08c6411..57dd0dd6553 100644
--- a/core/js/share.js
+++ b/core/js/share.js
@@ -266,7 +266,6 @@ OC.Share={
if (hasShares || owner) {
recipients = $tr.attr('data-share-recipients');
- action.addClass('permanent');
message = t('core', 'Shared');
// even if reshared, only show "Shared by"
if (owner) {
@@ -281,8 +280,7 @@ OC.Share={
}
}
else {
- action.removeClass('permanent');
- action.html(' <span>'+ escapeHTML(t('core', 'Share'))+'</span>').prepend(img);
+ action.html('<span></span>').prepend(img);
}
if (hasLink) {
image = OC.imagePath('core', 'actions/public');
diff --git a/core/js/tests/specs/setupchecksSpec.js b/core/js/tests/specs/setupchecksSpec.js
index ec8a732b4a1..d0efcf4b284 100644
--- a/core/js/tests/specs/setupchecksSpec.js
+++ b/core/js/tests/specs/setupchecksSpec.js
@@ -66,7 +66,12 @@ describe('OC.SetupChecks tests', function() {
{
'Content-Type': 'application/json'
},
- JSON.stringify({isUrandomAvailable: true, serverHasInternetConnection: false, memcacheDocs: 'https://doc.owncloud.org/server/go.php?to=admin-performance'})
+ JSON.stringify({
+ isUrandomAvailable: true,
+ serverHasInternetConnection: false,
+ memcacheDocs: 'https://doc.owncloud.org/server/go.php?to=admin-performance',
+ forwardedForHeadersWorking: true
+ })
);
async.done(function( data, s, x ){
@@ -83,7 +88,13 @@ describe('OC.SetupChecks tests', function() {
{
'Content-Type': 'application/json'
},
- JSON.stringify({isUrandomAvailable: true, serverHasInternetConnection: false, dataDirectoryProtected: false, memcacheDocs: 'https://doc.owncloud.org/server/go.php?to=admin-performance'})
+ JSON.stringify({
+ isUrandomAvailable: true,
+ serverHasInternetConnection: false,
+ dataDirectoryProtected: false,
+ memcacheDocs: 'https://doc.owncloud.org/server/go.php?to=admin-performance',
+ forwardedForHeadersWorking: true
+ })
);
async.done(function( data, s, x ){
@@ -100,7 +111,13 @@ describe('OC.SetupChecks tests', function() {
{
'Content-Type': 'application/json',
},
- JSON.stringify({isUrandomAvailable: true, serverHasInternetConnection: false, dataDirectoryProtected: false, isMemcacheConfigured: true})
+ JSON.stringify({
+ isUrandomAvailable: true,
+ serverHasInternetConnection: false,
+ dataDirectoryProtected: false,
+ isMemcacheConfigured: true,
+ forwardedForHeadersWorking: true
+ })
);
async.done(function( data, s, x ){
@@ -117,7 +134,14 @@ describe('OC.SetupChecks tests', function() {
{
'Content-Type': 'application/json',
},
- JSON.stringify({isUrandomAvailable: false, securityDocs: 'https://docs.owncloud.org/myDocs.html', serverHasInternetConnection: true, dataDirectoryProtected: true, isMemcacheConfigured: true})
+ JSON.stringify({
+ isUrandomAvailable: false,
+ securityDocs: 'https://docs.owncloud.org/myDocs.html',
+ serverHasInternetConnection: true,
+ dataDirectoryProtected: true,
+ isMemcacheConfigured: true,
+ forwardedForHeadersWorking: true
+ })
);
async.done(function( data, s, x ){
@@ -126,6 +150,30 @@ describe('OC.SetupChecks tests', function() {
});
});
+ it('should return an error if the forwarded for headers are not working', function(done) {
+ var async = OC.SetupChecks.checkSetup();
+
+ suite.server.requests[0].respond(
+ 200,
+ {
+ 'Content-Type': 'application/json',
+ },
+ JSON.stringify({
+ isUrandomAvailable: true,
+ serverHasInternetConnection: true,
+ dataDirectoryProtected: true,
+ isMemcacheConfigured: true,
+ forwardedForHeadersWorking: false,
+ reverseProxyDocs: 'https://docs.owncloud.org/foo/bar.html'
+ })
+ );
+
+ async.done(function( data, s, x ){
+ expect(data).toEqual(['The reverse proxy headers configuration is incorrect, or you are accessing ownCloud from a trusted proxy. If you are not accessing ownCloud from a trusted proxy, this is a security issue and can allow an attacker to spoof their IP address as visible to ownCloud. Further information can be found in our <a href="https://docs.owncloud.org/foo/bar.html">documentation</a>.']);
+ done();
+ });
+ });
+
it('should return an error if the response has no statuscode 200', function(done) {
var async = OC.SetupChecks.checkSetup();
@@ -142,6 +190,31 @@ describe('OC.SetupChecks tests', function() {
done();
});
});
+
+ it('should return an error if the php version is no longer supported', function(done) {
+ var async = OC.SetupChecks.checkSetup();
+
+ suite.server.requests[0].respond(
+ 200,
+ {
+ 'Content-Type': 'application/json',
+ },
+ JSON.stringify({
+ isUrandomAvailable: true,
+ securityDocs: 'https://docs.owncloud.org/myDocs.html',
+ serverHasInternetConnection: true,
+ dataDirectoryProtected: true,
+ isMemcacheConfigured: true,
+ forwardedForHeadersWorking: true,
+ phpSupported: {eol: true, version: '5.4.0'}
+ })
+ );
+
+ async.done(function( data, s, x ){
+ expect(data).toEqual(['Your PHP version (5.4.0) is no longer <a href="https://secure.php.net/supported-versions.php">supported by PHP</a>. We encourage you to upgrade your PHP version to take advantage of performance and security updates provided by PHP.']);
+ done();
+ });
+ });
});
describe('checkGeneric', function() {
diff --git a/lib/private/activitymanager.php b/lib/private/activitymanager.php
index 7b1d5d29f2e..938335a87e1 100644
--- a/lib/private/activitymanager.php
+++ b/lib/private/activitymanager.php
@@ -56,14 +56,16 @@ class ActivityManager implements IManager {
$this->config = $config;
}
- /**
- * @var \Closure[]
- */
+ /** @var \Closure[] */
+ private $consumersClosures = array();
+
+ /** @var IConsumer[] */
private $consumers = array();
- /**
- * @var \Closure[]
- */
+ /** @var \Closure[] */
+ private $extensionsClosures = array();
+
+ /** @var IExtension[] */
private $extensions = array();
/** @var array list of filters "name" => "is valid" */
@@ -80,6 +82,48 @@ class ActivityManager implements IManager {
protected $specialParameters = array();
/**
+ * @return \OCP\Activity\IConsumer[]
+ */
+ protected function getConsumers() {
+ if (!empty($this->consumers)) {
+ return $this->consumers;
+ }
+
+ $this->consumers = [];
+ foreach($this->consumersClosures as $consumer) {
+ $c = $consumer();
+ if ($c instanceof IConsumer) {
+ $this->consumers[] = $c;
+ } else {
+ throw new \InvalidArgumentException('The given consumer does not implement the \OCP\Activity\IConsumer interface');
+ }
+ }
+
+ return $this->consumers;
+ }
+
+ /**
+ * @return \OCP\Activity\IExtension[]
+ */
+ protected function getExtensions() {
+ if (!empty($this->extensions)) {
+ return $this->extensions;
+ }
+
+ $this->extensions = [];
+ foreach($this->extensionsClosures as $extension) {
+ $e = $extension();
+ if ($e instanceof IExtension) {
+ $this->extensions[] = $e;
+ } else {
+ throw new \InvalidArgumentException('The given extension does not implement the \OCP\Activity\IExtension interface');
+ }
+ }
+
+ return $this->extensions;
+ }
+
+ /**
* @param $app
* @param $subject
* @param $subjectParams
@@ -93,10 +137,8 @@ class ActivityManager implements IManager {
* @return mixed
*/
function publishActivity($app, $subject, $subjectParams, $message, $messageParams, $file, $link, $affectedUser, $type, $priority) {
- foreach($this->consumers as $consumer) {
- $c = $consumer();
- if ($c instanceof IConsumer) {
- try {
+ foreach($this->getConsumers() as $c) {
+ try {
$c->receive(
$app,
$subject,
@@ -108,11 +150,9 @@ class ActivityManager implements IManager {
$affectedUser,
$type,
$priority);
- } catch (\Exception $ex) {
- // TODO: log the exception
- }
+ } catch (\Exception $ex) {
+ // TODO: log the exception
}
-
}
}
@@ -125,7 +165,8 @@ class ActivityManager implements IManager {
* @param \Closure $callable
*/
function registerConsumer(\Closure $callable) {
- array_push($this->consumers, $callable);
+ array_push($this->consumersClosures, $callable);
+ $this->consumers = [];
}
/**
@@ -138,7 +179,8 @@ class ActivityManager implements IManager {
* @return void
*/
function registerExtension(\Closure $callable) {
- array_push($this->extensions, $callable);
+ array_push($this->extensionsClosures, $callable);
+ $this->extensions = [];
}
/**
@@ -149,13 +191,10 @@ class ActivityManager implements IManager {
*/
function getNotificationTypes($languageCode) {
$notificationTypes = array();
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- $result = $c->getNotificationTypes($languageCode);
- if (is_array($result)) {
- $notificationTypes = array_merge($notificationTypes, $result);
- }
+ foreach ($this->getExtensions() as $c) {
+ $result = $c->getNotificationTypes($languageCode);
+ if (is_array($result)) {
+ $notificationTypes = array_merge($notificationTypes, $result);
}
}
@@ -168,13 +207,10 @@ class ActivityManager implements IManager {
*/
function getDefaultTypes($method) {
$defaultTypes = array();
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- $types = $c->getDefaultTypes($method);
- if (is_array($types)) {
- $defaultTypes = array_merge($types, $defaultTypes);
- }
+ foreach ($this->getExtensions() as $c) {
+ $types = $c->getDefaultTypes($method);
+ if (is_array($types)) {
+ $defaultTypes = array_merge($types, $defaultTypes);
}
}
return $defaultTypes;
@@ -189,14 +225,11 @@ class ActivityManager implements IManager {
return $this->typeIcons[$type];
}
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- $icon = $c->getTypeIcon($type);
- if (is_string($icon)) {
- $this->typeIcons[$type] = $icon;
- return $icon;
- }
+ foreach ($this->getExtensions() as $c) {
+ $icon = $c->getTypeIcon($type);
+ if (is_string($icon)) {
+ $this->typeIcons[$type] = $icon;
+ return $icon;
}
}
@@ -214,13 +247,10 @@ class ActivityManager implements IManager {
* @return string|false
*/
function translate($app, $text, $params, $stripPath, $highlightParams, $languageCode) {
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- $translation = $c->translate($app, $text, $params, $stripPath, $highlightParams, $languageCode);
- if (is_string($translation)) {
- return $translation;
- }
+ foreach ($this->getExtensions() as $c) {
+ $translation = $c->translate($app, $text, $params, $stripPath, $highlightParams, $languageCode);
+ if (is_string($translation)) {
+ return $translation;
}
}
@@ -241,14 +271,11 @@ class ActivityManager implements IManager {
$this->specialParameters[$app] = array();
}
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- $specialParameter = $c->getSpecialParameterList($app, $text);
- if (is_array($specialParameter)) {
- $this->specialParameters[$app][$text] = $specialParameter;
- return $specialParameter;
- }
+ foreach ($this->getExtensions() as $c) {
+ $specialParameter = $c->getSpecialParameterList($app, $text);
+ if (is_array($specialParameter)) {
+ $this->specialParameters[$app][$text] = $specialParameter;
+ return $specialParameter;
}
}
@@ -261,13 +288,10 @@ class ActivityManager implements IManager {
* @return integer|false
*/
function getGroupParameter($activity) {
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- $parameter = $c->getGroupParameter($activity);
- if ($parameter !== false) {
- return $parameter;
- }
+ foreach ($this->getExtensions() as $c) {
+ $parameter = $c->getGroupParameter($activity);
+ if ($parameter !== false) {
+ return $parameter;
}
}
@@ -282,14 +306,11 @@ class ActivityManager implements IManager {
'apps' => array(),
'top' => array(),
);
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- $additionalEntries = $c->getNavigation();
- if (is_array($additionalEntries)) {
- $entries['apps'] = array_merge($entries['apps'], $additionalEntries['apps']);
- $entries['top'] = array_merge($entries['top'], $additionalEntries['top']);
- }
+ foreach ($this->getExtensions() as $c) {
+ $additionalEntries = $c->getNavigation();
+ if (is_array($additionalEntries)) {
+ $entries['apps'] = array_merge($entries['apps'], $additionalEntries['apps']);
+ $entries['top'] = array_merge($entries['top'], $additionalEntries['top']);
}
}
@@ -305,13 +326,10 @@ class ActivityManager implements IManager {
return $this->validFilters[$filterValue];
}
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- if ($c->isFilterValid($filterValue) === true) {
- $this->validFilters[$filterValue] = true;
- return true;
- }
+ foreach ($this->getExtensions() as $c) {
+ if ($c->isFilterValid($filterValue) === true) {
+ $this->validFilters[$filterValue] = true;
+ return true;
}
}
@@ -329,13 +347,10 @@ class ActivityManager implements IManager {
return $types;
}
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- $result = $c->filterNotificationTypes($types, $filter);
- if (is_array($result)) {
- $types = $result;
- }
+ foreach ($this->getExtensions() as $c) {
+ $result = $c->filterNotificationTypes($types, $filter);
+ if (is_array($result)) {
+ $types = $result;
}
}
return $types;
@@ -353,16 +368,13 @@ class ActivityManager implements IManager {
$conditions = array();
$parameters = array();
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- $result = $c->getQueryForFilter($filter);
- if (is_array($result)) {
- list($condition, $parameter) = $result;
- if ($condition && is_array($parameter)) {
- $conditions[] = $condition;
- $parameters = array_merge($parameters, $parameter);
- }
+ foreach ($this->getExtensions() as $c) {
+ $result = $c->getQueryForFilter($filter);
+ if (is_array($result)) {
+ list($condition, $parameter) = $result;
+ if ($condition && is_array($parameter)) {
+ $conditions[] = $condition;
+ $parameters = array_merge($parameters, $parameter);
}
}
}
diff --git a/lib/private/app.php b/lib/private/app.php
index 74b21b2b107..6c6f79dfa9d 100644
--- a/lib/private/app.php
+++ b/lib/private/app.php
@@ -421,7 +421,6 @@ class OC_App {
*/
public static function getSettingsNavigation() {
$l = \OC::$server->getL10N('lib');
- $defaults = new OC_Defaults();
$settings = array();
// by default, settings only contain the help menu
@@ -432,7 +431,7 @@ class OC_App {
array(
"id" => "help",
"order" => 1000,
- "href" => $defaults->getKnowledgeBaseUrl(),
+ "href" => OC_Helper::linkToRoute("settings_help"),
"name" => $l->t("Help"),
"icon" => OC_Helper::imagePath("settings", "help.svg")
)
diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/appframework/dependencyinjection/dicontainer.php
index c66b792064d..544da74a010 100644
--- a/lib/private/appframework/dependencyinjection/dicontainer.php
+++ b/lib/private/appframework/dependencyinjection/dicontainer.php
@@ -57,6 +57,7 @@ class DIContainer extends SimpleContainer implements IAppContainer {
* @param string $appName the name of the app
*/
public function __construct($appName, $urlParams = array()){
+ parent::__construct();
$this['AppName'] = $appName;
$this['urlParams'] = $urlParams;
diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php
index 43f01dfde3f..aaad286e843 100644
--- a/lib/private/appframework/http/request.php
+++ b/lib/private/appframework/http/request.php
@@ -452,7 +452,10 @@ class Request implements \ArrayAccess, \Countable, IRequest {
$trustedProxies = $this->config->getSystemValue('trusted_proxies', []);
if(is_array($trustedProxies) && in_array($remoteAddress, $trustedProxies)) {
- $forwardedForHeaders = $this->config->getSystemValue('forwarded_for_headers', []);
+ $forwardedForHeaders = $this->config->getSystemValue('forwarded_for_headers', [
+ 'HTTP_X_FORWARDED_FOR'
+ // only have one default, so we cannot ship an insecure product out of the box
+ ]);
foreach($forwardedForHeaders as $header) {
if(isset($this->server[$header])) {
diff --git a/lib/private/appframework/utility/simplecontainer.php b/lib/private/appframework/utility/simplecontainer.php
index c1fc96d1975..83a08acde26 100644
--- a/lib/private/appframework/utility/simplecontainer.php
+++ b/lib/private/appframework/utility/simplecontainer.php
@@ -99,6 +99,7 @@ class SimpleContainer extends Container implements IContainer {
* @throws QueryException if the query could not be resolved
*/
public function query($name) {
+ $name = $this->sanitizeName($name);
if ($this->offsetExists($name)) {
return $this->offsetGet($name);
} else {
@@ -128,6 +129,7 @@ class SimpleContainer extends Container implements IContainer {
* @param bool $shared
*/
public function registerService($name, Closure $closure, $shared = true) {
+ $name = $this->sanitizeName($name);
if (isset($this[$name])) {
unset($this[$name]);
}
@@ -148,7 +150,15 @@ class SimpleContainer extends Container implements IContainer {
public function registerAlias($alias, $target) {
$this->registerService($alias, function (IContainer $container) use ($target) {
return $container->query($target);
- });
+ }, false);
+ }
+
+ /*
+ * @param string $name
+ * @return string
+ */
+ protected function sanitizeName($name) {
+ return ltrim($name, '\\');
}
}
diff --git a/lib/private/connector/sabre/exceptionloggerplugin.php b/lib/private/connector/sabre/exceptionloggerplugin.php
index 741ba4d3e05..53a1f738ea6 100644
--- a/lib/private/connector/sabre/exceptionloggerplugin.php
+++ b/lib/private/connector/sabre/exceptionloggerplugin.php
@@ -28,7 +28,7 @@ use Sabre\DAV\Exception;
use Sabre\HTTP\Response;
class ExceptionLoggerPlugin extends \Sabre\DAV\ServerPlugin {
- private $nonFatalExceptions = array(
+ protected $nonFatalExceptions = array(
'Sabre\DAV\Exception\NotAuthenticated' => true,
// the sync client uses this to find out whether files exist,
// so it is not always an error, log it as debug
diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index fa2f5ce18d7..b7d0c547f24 100644
--- a/lib/private/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -332,7 +332,7 @@ class File extends Node implements IFile {
$info = \OC_FileChunking::decodeName($name);
if (empty($info)) {
- throw new NotImplemented();
+ throw new NotImplemented('Invalid chunk name');
}
$chunk_handler = new \OC_FileChunking($info);
$bytesWritten = $chunk_handler->store($info['index'], $data);
diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php
index 1e9b9ba59e2..18d3c1dcf23 100644
--- a/lib/private/connector/sabre/objecttree.php
+++ b/lib/private/connector/sabre/objecttree.php
@@ -41,7 +41,7 @@ class ObjectTree extends \Sabre\DAV\Tree {
protected $fileView;
/**
- * @var \OC\Files\Mount\Manager
+ * @var \OCP\Files\Mount\IMountManager
*/
protected $mountManager;
@@ -54,9 +54,9 @@ class ObjectTree extends \Sabre\DAV\Tree {
/**
* @param \Sabre\DAV\INode $rootNode
* @param \OC\Files\View $view
- * @param \OC\Files\Mount\Manager $mountManager
+ * @param \OCP\Files\Mount\IMountManager $mountManager
*/
- public function init(\Sabre\DAV\INode $rootNode, \OC\Files\View $view, \OC\Files\Mount\Manager $mountManager) {
+ public function init(\Sabre\DAV\INode $rootNode, \OC\Files\View $view, \OCP\Files\Mount\IMountManager $mountManager) {
$this->rootNode = $rootNode;
$this->fileView = $view;
$this->mountManager = $mountManager;
diff --git a/lib/private/connector/sabre/serverfactory.php b/lib/private/connector/sabre/serverfactory.php
new file mode 100644
index 00000000000..525ff0104cd
--- /dev/null
+++ b/lib/private/connector/sabre/serverfactory.php
@@ -0,0 +1,107 @@
+<?php
+/**
+ * @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 OC\Connector\Sabre;
+
+use OCP\Files\Mount\IMountManager;
+use OCP\IConfig;
+use OCP\IDBConnection;
+use OCP\ILogger;
+use OCP\ITagManager;
+use OCP\IUserSession;
+use Sabre\DAV\Auth\Backend\BackendInterface;
+
+class ServerFactory {
+ public function __construct(
+ IConfig $config,
+ ILogger $logger,
+ IDBConnection $databaseConnection,
+ IUserSession $userSession,
+ IMountManager $mountManager,
+ ITagManager $tagManager
+ ) {
+ $this->config = $config;
+ $this->logger = $logger;
+ $this->databaseConnection = $databaseConnection;
+ $this->userSession = $userSession;
+ $this->mountManager = $mountManager;
+ $this->tagManager = $tagManager;
+ }
+
+ /**
+ * @param string $baseUri
+ * @param string $requestUri
+ * @param BackendInterface $authBackend
+ * @param callable $viewCallBack callback that should return the view for the dav endpoint
+ * @return Server
+ */
+ public function createServer($baseUri, $requestUri, BackendInterface $authBackend, callable $viewCallBack) {
+ // Fire up server
+ $objectTree = new \OC\Connector\Sabre\ObjectTree();
+ $server = new \OC\Connector\Sabre\Server($objectTree);
+ // Set URL explicitly due to reverse-proxy situations
+ $server->httpRequest->setUrl($requestUri);
+ $server->setBaseUri($baseUri);
+
+ // Load plugins
+ $defaults = new \OC_Defaults();
+ $server->addPlugin(new \OC\Connector\Sabre\BlockLegacyClientPlugin($this->config));
+ $server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend, $defaults->getName()));
+ // FIXME: The following line is a workaround for legacy components relying on being able to send a GET to /
+ $server->addPlugin(new \OC\Connector\Sabre\DummyGetResponsePlugin());
+ $server->addPlugin(new \OC\Connector\Sabre\FilesPlugin($objectTree));
+ $server->addPlugin(new \OC\Connector\Sabre\MaintenancePlugin($this->config));
+ $server->addPlugin(new \OC\Connector\Sabre\ExceptionLoggerPlugin('webdav', $this->logger));
+
+ // wait with registering these until auth is handled and the filesystem is setup
+ $server->on('beforeMethod', function () use ($server, $objectTree, $viewCallBack) {
+ /** @var \OC\Files\View $view */
+ $view = $viewCallBack();
+ $rootInfo = $view->getFileInfo('');
+
+ // Create ownCloud Dir
+ if ($rootInfo->getType() === 'dir') {
+ $root = new \OC\Connector\Sabre\Directory($view, $rootInfo);
+ } else {
+ $root = new \OC\Connector\Sabre\File($view, $rootInfo);
+ }
+ $objectTree->init($root, $view, $this->mountManager);
+
+ $server->addPlugin(new \OC\Connector\Sabre\QuotaPlugin($view));
+
+ if($this->userSession->isLoggedIn()) {
+ $server->addPlugin(new \OC\Connector\Sabre\TagsPlugin($objectTree, $this->tagManager));
+ // custom properties plugin must be the last one
+ $server->addPlugin(
+ new \Sabre\DAV\PropertyStorage\Plugin(
+ new \OC\Connector\Sabre\CustomPropertiesBackend(
+ $objectTree,
+ $this->databaseConnection,
+ $this->userSession->getUser()
+ )
+ )
+ );
+ }
+ $server->addPlugin(new \OC\Connector\Sabre\CopyEtagHeaderPlugin());
+ }, 30); // priority 30: after auth (10) and acl(20), before lock(50) and handling the request
+ return $server;
+ }
+}
diff --git a/lib/private/db/querybuilder/querybuilder.php b/lib/private/db/querybuilder/querybuilder.php
index 1a1408876f1..1d97faf77cc 100644
--- a/lib/private/db/querybuilder/querybuilder.php
+++ b/lib/private/db/querybuilder/querybuilder.php
@@ -37,6 +37,9 @@ class QueryBuilder implements IQueryBuilder {
/** @var QuoteHelper */
private $helper;
+ /** @var bool */
+ private $automaticTablePrefix = true;
+
/**
* Initializes a new QueryBuilder.
*
@@ -49,6 +52,17 @@ class QueryBuilder implements IQueryBuilder {
}
/**
+ * Enable/disable automatic prefixing of table names with the oc_ prefix
+ *
+ * @param bool $enabled If set to true table names will be prefixed with the
+ * owncloud database prefix automatically.
+ * @since 8.2.0
+ */
+ public function automaticTablePrefix($enabled) {
+ $this->automaticTablePrefix = (bool) $enabled;
+ }
+
+ /**
* Gets an ExpressionBuilder used for object-oriented construction of query expressions.
* This producer method is intended for convenient inline usage. Example:
*
@@ -329,7 +343,7 @@ class QueryBuilder implements IQueryBuilder {
*/
public function delete($delete = null, $alias = null) {
$this->queryBuilder->delete(
- $this->helper->quoteColumnName($delete),
+ $this->getTableName($delete),
$alias
);
@@ -354,7 +368,7 @@ class QueryBuilder implements IQueryBuilder {
*/
public function update($update = null, $alias = null) {
$this->queryBuilder->update(
- $this->helper->quoteColumnName($update),
+ $this->getTableName($update),
$alias
);
@@ -382,7 +396,7 @@ class QueryBuilder implements IQueryBuilder {
*/
public function insert($insert = null) {
$this->queryBuilder->insert(
- $this->helper->quoteColumnName($insert)
+ $this->getTableName($insert)
);
return $this;
@@ -405,7 +419,7 @@ class QueryBuilder implements IQueryBuilder {
*/
public function from($from, $alias = null) {
$this->queryBuilder->from(
- $this->helper->quoteColumnName($from),
+ $this->getTableName($from),
$alias
);
@@ -432,7 +446,7 @@ class QueryBuilder implements IQueryBuilder {
public function join($fromAlias, $join, $alias, $condition = null) {
$this->queryBuilder->join(
$fromAlias,
- $this->helper->quoteColumnName($join),
+ $this->getTableName($join),
$alias,
$condition
);
@@ -460,7 +474,7 @@ class QueryBuilder implements IQueryBuilder {
public function innerJoin($fromAlias, $join, $alias, $condition = null) {
$this->queryBuilder->innerJoin(
$fromAlias,
- $this->helper->quoteColumnName($join),
+ $this->getTableName($join),
$alias,
$condition
);
@@ -488,7 +502,7 @@ class QueryBuilder implements IQueryBuilder {
public function leftJoin($fromAlias, $join, $alias, $condition = null) {
$this->queryBuilder->leftJoin(
$fromAlias,
- $this->helper->quoteColumnName($join),
+ $this->getTableName($join),
$alias,
$condition
);
@@ -516,7 +530,7 @@ class QueryBuilder implements IQueryBuilder {
public function rightJoin($fromAlias, $join, $alias, $condition = null) {
$this->queryBuilder->rightJoin(
$fromAlias,
- $this->helper->quoteColumnName($join),
+ $this->getTableName($join),
$alias,
$condition
);
@@ -984,4 +998,16 @@ class QueryBuilder implements IQueryBuilder {
public function createFunction($call) {
return new QueryFunction($call);
}
+
+ /**
+ * @param string $table
+ * @return string
+ */
+ private function getTableName($table) {
+ if ($this->automaticTablePrefix === false || strpos($table, '*PREFIX*') === 0) {
+ return $this->helper->quoteColumnName($table);
+ }
+
+ return $this->helper->quoteColumnName('*PREFIX*' . $table);
+ }
}
diff --git a/lib/private/defaults.php b/lib/private/defaults.php
index b86805357bd..16f45943f54 100644
--- a/lib/private/defaults.php
+++ b/lib/private/defaults.php
@@ -46,11 +46,9 @@ class OC_Defaults {
private $defaultSlogan;
private $defaultLogoClaim;
private $defaultMailHeaderColor;
- private $defaultKnowledgeBaseUrl;
function __construct() {
$this->l = \OC::$server->getL10N('lib');
- $urlGenerator = \OC::$server->getURLGenerator();
$version = OC_Util::getVersion();
$this->defaultEntity = 'ownCloud'; /* e.g. company name, used for footers and copyright notices */
@@ -66,7 +64,6 @@ class OC_Defaults {
$this->defaultSlogan = $this->l->t('web services under your control');
$this->defaultLogoClaim = '';
$this->defaultMailHeaderColor = '#1d2d44'; /* header color of mail notifications */
- $this->defaultKnowledgeBaseUrl = $urlGenerator->linkToRoute('settings_help');
$themePath = OC::$SERVERROOT . '/themes/' . OC_Util::getTheme() . '/defaults.php';
if (file_exists($themePath)) {
@@ -82,7 +79,6 @@ class OC_Defaults {
/**
* @param string $method
- * @return bool
*/
private function themeExist($method) {
if (isset($this->theme) && method_exists($this->theme, $method)) {
@@ -284,19 +280,4 @@ class OC_Defaults {
}
}
- /**
- * get knowledge base URL, will be used for the "Help"-Link in the top
- * right menu
- *
- * @return string
- */
- public function getKnowledgeBaseUrl() {
- if ($this->themeExist('getKnowledgeBaseUrl')) {
- return $this->theme->getKnowledgeBaseUrl();
- } else {
- return $this->defaultKnowledgeBaseUrl;
- }
-
- }
-
}
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index dc6e8aaa719..9afa9d40b20 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -642,10 +642,10 @@ class View {
}
$run = true;
- if ($this->shouldEmitHooks() && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2))) {
+ if ($this->shouldEmitHooks($path1) && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2))) {
// if it was a rename from a part file to a regular file it was a write and not a rename operation
$this->emit_file_hooks_pre($exists, $path2, $run);
- } elseif ($this->shouldEmitHooks()) {
+ } elseif ($this->shouldEmitHooks($path1)) {
\OC_Hook::emit(
Filesystem::CLASSNAME, Filesystem::signal_rename,
array(
@@ -1087,6 +1087,11 @@ class View {
return true;
}
$fullPath = $this->getAbsolutePath($path);
+
+ if ($fullPath === $defaultRoot) {
+ return true;
+ }
+
return (strlen($fullPath) > strlen($defaultRoot)) && (substr($fullPath, 0, strlen($defaultRoot) + 1) === $defaultRoot . '/');
}
diff --git a/lib/private/server.php b/lib/private/server.php
index 9503cf16ff7..618431ff2d4 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -75,6 +75,7 @@ class Server extends SimpleContainer implements IServerContainer {
* @param string $webRoot
*/
public function __construct($webRoot) {
+ parent::__construct();
$this->webRoot = $webRoot;
$this->registerService('ContactsManager', function ($c) {
diff --git a/lib/private/share/share.php b/lib/private/share/share.php
index 40fcc59f219..9aea4677b5b 100644
--- a/lib/private/share/share.php
+++ b/lib/private/share/share.php
@@ -1218,7 +1218,7 @@ class Share extends Constants {
$qb = $connection->getQueryBuilder();
$qb->select('uid_owner')
- ->from('*PREFIX*share')
+ ->from('share')
->where($qb->expr()->eq('id', $qb->createParameter('shareId')))
->setParameter(':shareId', $shareId);
$result = $qb->execute();
@@ -1269,7 +1269,7 @@ class Share extends Constants {
self::verifyPassword($password);
$qb = $connection->getQueryBuilder();
- $qb->update('*PREFIX*share')
+ $qb->update('share')
->set('share_with', $qb->createParameter('pass'))
->where($qb->expr()->eq('id', $qb->createParameter('shareId')))
->setParameter(':pass', is_null($password) ? null : \OC::$server->getHasher()->hash($password))
diff --git a/lib/public/activity/iextension.php b/lib/public/activity/iextension.php
index 19d1d2e83a0..5d9fe3329ef 100644
--- a/lib/public/activity/iextension.php
+++ b/lib/public/activity/iextension.php
@@ -38,6 +38,8 @@ namespace OCP\Activity;
* @since 8.0.0
*/
interface IExtension {
+ const METHOD_STREAM = 'stream';
+ const METHOD_MAIL = 'email';
const PRIORITY_VERYLOW = 10;
const PRIORITY_LOW = 20;
@@ -50,8 +52,13 @@ interface IExtension {
* If no additional types are to be added false is to be returned
*
* @param string $languageCode
- * @return array|false
+ * @return array|false Array "stringID of the type" => "translated string description for the setting"
+ * or Array "stringID of the type" => [
+ * 'desc' => "translated string description for the setting"
+ * 'methods' => [self::METHOD_*],
+ * ]
* @since 8.0.0
+ * @changed 8.2.0 - Added support to allow limiting notifications to certain methods
*/
public function getNotificationTypes($languageCode);
diff --git a/lib/public/activity/imanager.php b/lib/public/activity/imanager.php
index cadb37da03b..0f5dccd8ba1 100644
--- a/lib/public/activity/imanager.php
+++ b/lib/public/activity/imanager.php
@@ -81,9 +81,15 @@ interface IManager {
/**
* Will return additional notification types as specified by other apps
+ *
* @param string $languageCode
- * @return array
+ * @return array Array "stringID of the type" => "translated string description for the setting"
+ * or Array "stringID of the type" => [
+ * 'desc' => "translated string description for the setting"
+ * 'methods' => [\OCP\Activity\IExtension::METHOD_*],
+ * ]
* @since 8.0.0
+ * @changed 8.2.0 - Added support to allow limiting notifications to certain methods
*/
function getNotificationTypes($languageCode);
diff --git a/lib/public/appframework/http/contentsecuritypolicy.php b/lib/public/appframework/http/contentsecuritypolicy.php
index 9c7218dc8ba..ee36f7aac17 100644
--- a/lib/public/appframework/http/contentsecuritypolicy.php
+++ b/lib/public/appframework/http/contentsecuritypolicy.php
@@ -63,6 +63,7 @@ class ContentSecurityPolicy {
/** @var array Domains from which images can get loaded */
private $allowedImageDomains = [
'\'self\'',
+ 'data:',
];
/** @var array Domains to which connections can be done */
private $allowedConnectDomains = [
diff --git a/lib/public/db/querybuilder/iquerybuilder.php b/lib/public/db/querybuilder/iquerybuilder.php
index 09d5d199bef..3fc07af1a47 100644
--- a/lib/public/db/querybuilder/iquerybuilder.php
+++ b/lib/public/db/querybuilder/iquerybuilder.php
@@ -27,6 +27,15 @@ namespace OCP\DB\QueryBuilder;
*/
interface IQueryBuilder {
/**
+ * Enable/disable automatic prefixing of table names with the oc_ prefix
+ *
+ * @param bool $enabled If set to true table names will be prefixed with the
+ * owncloud database prefix automatically.
+ * @since 8.2.0
+ */
+ public function automaticTablePrefix($enabled);
+
+ /**
* Gets an ExpressionBuilder used for object-oriented construction of query expressions.
* This producer method is intended for convenient inline usage. Example:
*
diff --git a/lib/repair/cleantags.php b/lib/repair/cleantags.php
index 2bda1047081..d16a49fbca7 100644
--- a/lib/repair/cleantags.php
+++ b/lib/repair/cleantags.php
@@ -65,8 +65,8 @@ class CleanTags extends BasicEmitter implements RepairStep {
protected function deleteOrphanFileEntries() {
$this->deleteOrphanEntries(
'%d tags for delete files have been removed.',
- '*PREFIX*vcategory_to_object', 'objid',
- '*PREFIX*filecache', 'fileid', 'path_hash'
+ 'vcategory_to_object', 'objid',
+ 'filecache', 'fileid', 'path_hash'
);
}
@@ -76,8 +76,8 @@ class CleanTags extends BasicEmitter implements RepairStep {
protected function deleteOrphanTagEntries() {
$this->deleteOrphanEntries(
'%d tag entries for deleted tags have been removed.',
- '*PREFIX*vcategory_to_object', 'categoryid',
- '*PREFIX*vcategory', 'id', 'uid'
+ 'vcategory_to_object', 'categoryid',
+ 'vcategory', 'id', 'uid'
);
}
@@ -87,8 +87,8 @@ class CleanTags extends BasicEmitter implements RepairStep {
protected function deleteOrphanCategoryEntries() {
$this->deleteOrphanEntries(
'%d tags with no entries have been removed.',
- '*PREFIX*vcategory', 'id',
- '*PREFIX*vcategory_to_object', 'categoryid', 'type'
+ 'vcategory', 'id',
+ 'vcategory_to_object', 'categoryid', 'type'
);
}
diff --git a/lib/repair/filletags.php b/lib/repair/filletags.php
index f1bb2c896c4..40072209982 100644
--- a/lib/repair/filletags.php
+++ b/lib/repair/filletags.php
@@ -42,7 +42,7 @@ class FillETags extends BasicEmitter implements \OC\RepairStep {
public function run() {
$qb = $this->connection->getQueryBuilder();
- $qb->update('*PREFIX*filecache')
+ $qb->update('filecache')
->set('etag', $qb->expr()->literal('xxx'))
->where($qb->expr()->eq('etag', $qb->expr()->literal('')))
->orWhere($qb->expr()->isNull('etag'));
diff --git a/settings/controller/checksetupcontroller.php b/settings/controller/checksetupcontroller.php
index f849e3ed565..33f94fe4238 100644
--- a/settings/controller/checksetupcontroller.php
+++ b/settings/controller/checksetupcontroller.php
@@ -128,7 +128,7 @@ class CheckSetupController extends Controller {
/**
* Check if the used SSL lib is outdated. Older OpenSSL and NSS versions do
* have multiple bugs which likely lead to problems in combination with
- * functionalities required by ownCloud such as SNI.
+ * functionality required by ownCloud such as SNI.
*
* @link https://github.com/owncloud/core/issues/17446#issuecomment-122877546
* @link https://bugzilla.redhat.com/show_bug.cgi?id=1241172
@@ -175,6 +175,40 @@ class CheckSetupController extends Controller {
return '';
}
+
+ /*
+ * Whether the php version is still supported (at time of release)
+ * according to: https://secure.php.net/supported-versions.php
+ *
+ * @return array
+ */
+ private function isPhpSupported() {
+ $eol = false;
+
+ //PHP 5.4 is EOL on 14 Sep 2015
+ if (version_compare(PHP_VERSION, '5.5.0') === -1) {
+ $eol = true;
+ }
+
+ return ['eol' => $eol, 'version' => PHP_VERSION];
+ }
+
+ /*
+ * Check if the reverse proxy configuration is working as expected
+ *
+ * @return bool
+ */
+ private function forwardedForHeadersWorking() {
+ $trustedProxies = $this->config->getSystemValue('trusted_proxies', []);
+ $remoteAddress = $this->request->getRemoteAddress();
+
+ if (is_array($trustedProxies) && in_array($remoteAddress, $trustedProxies)) {
+ return false;
+ }
+
+ // either not enabled or working correctly
+ return true;
+ }
/**
* @return DataResponse
@@ -189,6 +223,9 @@ class CheckSetupController extends Controller {
'isUrandomAvailable' => $this->isUrandomAvailable(),
'securityDocs' => $this->urlGenerator->linkToDocs('admin-security'),
'isUsedTlsLibOutdated' => $this->isUsedTlsLibOutdated(),
+ 'phpSupported' => $this->isPhpSupported(),
+ 'forwardedForHeadersWorking' => $this->forwardedForHeadersWorking(),
+ 'reverseProxyDocs' => $this->urlGenerator->linkToDocs('admin-reverse-proxy'),
]
);
}
diff --git a/tests/lib/activitymanager.php b/tests/lib/activitymanager.php
index a35daeaf494..28caf575948 100644
--- a/tests/lib/activitymanager.php
+++ b/tests/lib/activitymanager.php
@@ -41,6 +41,9 @@ class Test_ActivityManager extends \Test\TestCase {
$this->config
);
+ $this->activityManager->registerConsumer(function() {
+ return new NoOpConsumer();
+ });
$this->activityManager->registerExtension(function() {
return new NoOpExtension();
});
@@ -49,6 +52,40 @@ class Test_ActivityManager extends \Test\TestCase {
});
}
+ public function testGetConsumers() {
+ $consumers = $this->invokePrivate($this->activityManager, 'getConsumers');
+
+ $this->assertNotEmpty($consumers);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testGetConsumersInvalidConsumer() {
+ $this->activityManager->registerConsumer(function() {
+ return new StdClass();
+ });
+
+ $this->invokePrivate($this->activityManager, 'getConsumers');
+ }
+
+ public function testGetExtensions() {
+ $extensions = $this->invokePrivate($this->activityManager, 'getExtensions');
+
+ $this->assertNotEmpty($extensions);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testGetExtensionsInvalidExtension() {
+ $this->activityManager->registerExtension(function() {
+ return new StdClass();
+ });
+
+ $this->invokePrivate($this->activityManager, 'getExtensions');
+ }
+
public function testNotificationTypes() {
$result = $this->activityManager->getNotificationTypes('en');
$this->assertTrue(is_array($result));
@@ -328,3 +365,9 @@ class NoOpExtension implements \OCP\Activity\IExtension {
return false;
}
}
+
+class NoOpConsumer implements \OCP\Activity\IConsumer {
+
+ public function receive($app, $subject, $subjectParams, $message, $messageParams, $file, $link, $affectedUser, $type, $priority) {
+ }
+}
diff --git a/tests/lib/appframework/controller/ControllerTest.php b/tests/lib/appframework/controller/ControllerTest.php
index ccc373f4d59..0d7716da411 100644
--- a/tests/lib/appframework/controller/ControllerTest.php
+++ b/tests/lib/appframework/controller/ControllerTest.php
@@ -177,7 +177,7 @@ class ControllerTest extends \Test\TestCase {
'test' => 'something',
'Cache-Control' => 'no-cache, must-revalidate',
'Content-Type' => 'application/json; charset=utf-8',
- 'Content-Security-Policy' => "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'",
+ 'Content-Security-Policy' => "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'",
];
$response = $this->controller->customDataResponse(array('hi'));
diff --git a/tests/lib/appframework/http/ContentSecurityPolicyTest.php b/tests/lib/appframework/http/ContentSecurityPolicyTest.php
index 18d71df483f..082c032a420 100644
--- a/tests/lib/appframework/http/ContentSecurityPolicyTest.php
+++ b/tests/lib/appframework/http/ContentSecurityPolicyTest.php
@@ -28,19 +28,19 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDefault() {
- $defaultPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $defaultPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->assertSame($defaultPolicy, $this->contentSecurityPolicy->buildPolicy());
}
public function testGetPolicyScriptDomainValid() {
- $expectedPolicy = "default-src 'none';script-src 'self' www.owncloud.com 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' www.owncloud.com 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedScriptDomain('www.owncloud.com');
$this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy());
}
public function testGetPolicyScriptDomainValidMultiple() {
- $expectedPolicy = "default-src 'none';script-src 'self' www.owncloud.com www.owncloud.org 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' www.owncloud.com www.owncloud.org 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedScriptDomain('www.owncloud.com');
$this->contentSecurityPolicy->addAllowedScriptDomain('www.owncloud.org');
@@ -48,7 +48,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowScriptDomain() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedScriptDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowScriptDomain('www.owncloud.com');
@@ -56,7 +56,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowScriptDomainMultiple() {
- $expectedPolicy = "default-src 'none';script-src 'self' www.owncloud.com 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' www.owncloud.com 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedScriptDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowScriptDomain('www.owncloud.org');
@@ -64,7 +64,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowScriptDomainMultipleStacked() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedScriptDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowScriptDomain('www.owncloud.org')->disallowScriptDomain('www.owncloud.com');
@@ -72,14 +72,14 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyScriptAllowInline() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-inline' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-inline' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->allowInlineScript(true);
$this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy());
}
public function testGetPolicyScriptAllowInlineWithDomain() {
- $expectedPolicy = "default-src 'none';script-src 'self' www.owncloud.com 'unsafe-inline' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' www.owncloud.com 'unsafe-inline' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedScriptDomain('www.owncloud.com');
$this->contentSecurityPolicy->allowInlineScript(true);
@@ -87,7 +87,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyScriptDisallowInlineAndEval() {
- $expectedPolicy = "default-src 'none';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->allowInlineScript(false);
$this->contentSecurityPolicy->allowEvalScript(false);
@@ -95,14 +95,14 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyStyleDomainValid() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' www.owncloud.com 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' www.owncloud.com 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedStyleDomain('www.owncloud.com');
$this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy());
}
public function testGetPolicyStyleDomainValidMultiple() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' www.owncloud.com www.owncloud.org 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' www.owncloud.com www.owncloud.org 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedStyleDomain('www.owncloud.com');
$this->contentSecurityPolicy->addAllowedStyleDomain('www.owncloud.org');
@@ -110,7 +110,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowStyleDomain() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedStyleDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowStyleDomain('www.owncloud.com');
@@ -118,7 +118,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowStyleDomainMultiple() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' www.owncloud.com 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' www.owncloud.com 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedStyleDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowStyleDomain('www.owncloud.org');
@@ -126,7 +126,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowStyleDomainMultipleStacked() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedStyleDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowStyleDomain('www.owncloud.org')->disallowStyleDomain('www.owncloud.com');
@@ -134,35 +134,35 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyStyleAllowInline() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->allowInlineStyle(true);
$this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy());
}
public function testGetPolicyStyleAllowInlineWithDomain() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' www.owncloud.com 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' www.owncloud.com 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedStyleDomain('www.owncloud.com');
$this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy());
}
public function testGetPolicyStyleDisallowInline() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->allowInlineStyle(false);
$this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy());
}
public function testGetPolicyImageDomainValid() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' www.owncloud.com;font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: www.owncloud.com;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedImageDomain('www.owncloud.com');
$this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy());
}
public function testGetPolicyImageDomainValidMultiple() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' www.owncloud.com www.owncloud.org;font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: www.owncloud.com www.owncloud.org;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedImageDomain('www.owncloud.com');
$this->contentSecurityPolicy->addAllowedImageDomain('www.owncloud.org');
@@ -170,7 +170,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowImageDomain() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedImageDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowImageDomain('www.owncloud.com');
@@ -178,7 +178,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowImageDomainMultiple() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' www.owncloud.com;font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: www.owncloud.com;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedImageDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowImageDomain('www.owncloud.org');
@@ -186,7 +186,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowImageDomainMultipleStakes() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedImageDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowImageDomain('www.owncloud.org')->disallowImageDomain('www.owncloud.com');
@@ -194,14 +194,14 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyFontDomainValid() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self' www.owncloud.com;connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self' www.owncloud.com;connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedFontDomain('www.owncloud.com');
$this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy());
}
public function testGetPolicyFontDomainValidMultiple() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self' www.owncloud.com www.owncloud.org;connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self' www.owncloud.com www.owncloud.org;connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedFontDomain('www.owncloud.com');
$this->contentSecurityPolicy->addAllowedFontDomain('www.owncloud.org');
@@ -209,7 +209,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowFontDomain() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedFontDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowFontDomain('www.owncloud.com');
@@ -217,7 +217,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowFontDomainMultiple() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self' www.owncloud.com;connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self' www.owncloud.com;connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedFontDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowFontDomain('www.owncloud.org');
@@ -225,7 +225,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowFontDomainMultipleStakes() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedFontDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowFontDomain('www.owncloud.org')->disallowFontDomain('www.owncloud.com');
@@ -233,14 +233,14 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyConnectDomainValid() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self' www.owncloud.com;media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self' www.owncloud.com;media-src 'self'";
$this->contentSecurityPolicy->addAllowedConnectDomain('www.owncloud.com');
$this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy());
}
public function testGetPolicyConnectDomainValidMultiple() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self' www.owncloud.com www.owncloud.org;media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self' www.owncloud.com www.owncloud.org;media-src 'self'";
$this->contentSecurityPolicy->addAllowedConnectDomain('www.owncloud.com');
$this->contentSecurityPolicy->addAllowedConnectDomain('www.owncloud.org');
@@ -248,7 +248,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowConnectDomain() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedConnectDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowConnectDomain('www.owncloud.com');
@@ -256,7 +256,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowConnectDomainMultiple() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self' www.owncloud.com;media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self' www.owncloud.com;media-src 'self'";
$this->contentSecurityPolicy->addAllowedConnectDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowConnectDomain('www.owncloud.org');
@@ -264,7 +264,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowConnectDomainMultipleStakes() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedConnectDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowConnectDomain('www.owncloud.org')->disallowConnectDomain('www.owncloud.com');
@@ -272,14 +272,14 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyMediaDomainValid() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self' www.owncloud.com";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self' www.owncloud.com";
$this->contentSecurityPolicy->addAllowedMediaDomain('www.owncloud.com');
$this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy());
}
public function testGetPolicyMediaDomainValidMultiple() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self' www.owncloud.com www.owncloud.org";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self' www.owncloud.com www.owncloud.org";
$this->contentSecurityPolicy->addAllowedMediaDomain('www.owncloud.com');
$this->contentSecurityPolicy->addAllowedMediaDomain('www.owncloud.org');
@@ -287,7 +287,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowMediaDomain() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedMediaDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowMediaDomain('www.owncloud.com');
@@ -295,7 +295,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowMediaDomainMultiple() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self' www.owncloud.com";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self' www.owncloud.com";
$this->contentSecurityPolicy->addAllowedMediaDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowMediaDomain('www.owncloud.org');
@@ -303,7 +303,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowMediaDomainMultipleStakes() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedMediaDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowMediaDomain('www.owncloud.org')->disallowMediaDomain('www.owncloud.com');
@@ -311,14 +311,14 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyObjectDomainValid() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self';object-src www.owncloud.com";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self';object-src www.owncloud.com";
$this->contentSecurityPolicy->addAllowedObjectDomain('www.owncloud.com');
$this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy());
}
public function testGetPolicyObjectDomainValidMultiple() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self';object-src www.owncloud.com www.owncloud.org";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self';object-src www.owncloud.com www.owncloud.org";
$this->contentSecurityPolicy->addAllowedObjectDomain('www.owncloud.com');
$this->contentSecurityPolicy->addAllowedObjectDomain('www.owncloud.org');
@@ -326,7 +326,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowObjectDomain() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedObjectDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowObjectDomain('www.owncloud.com');
@@ -334,7 +334,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowObjectDomainMultiple() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self';object-src www.owncloud.com";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self';object-src www.owncloud.com";
$this->contentSecurityPolicy->addAllowedObjectDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowObjectDomain('www.owncloud.org');
@@ -342,7 +342,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowObjectDomainMultipleStakes() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedObjectDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowObjectDomain('www.owncloud.org')->disallowObjectDomain('www.owncloud.com');
@@ -350,14 +350,14 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetAllowedFrameDomain() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self';frame-src www.owncloud.com";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self';frame-src www.owncloud.com";
$this->contentSecurityPolicy->addAllowedFrameDomain('www.owncloud.com');
$this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy());
}
public function testGetPolicyFrameDomainValidMultiple() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self';frame-src www.owncloud.com www.owncloud.org";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self';frame-src www.owncloud.com www.owncloud.org";
$this->contentSecurityPolicy->addAllowedFrameDomain('www.owncloud.com');
$this->contentSecurityPolicy->addAllowedFrameDomain('www.owncloud.org');
@@ -365,7 +365,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowFrameDomain() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedFrameDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowFrameDomain('www.owncloud.com');
@@ -373,7 +373,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowFrameDomainMultiple() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self';frame-src www.owncloud.com";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self';frame-src www.owncloud.com";
$this->contentSecurityPolicy->addAllowedFrameDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowFrameDomain('www.owncloud.org');
@@ -381,7 +381,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowFrameDomainMultipleStakes() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedFrameDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowFrameDomain('www.owncloud.org')->disallowFrameDomain('www.owncloud.com');
@@ -389,14 +389,14 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetAllowedChildSrcDomain() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self';child-src child.owncloud.com";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self';child-src child.owncloud.com";
$this->contentSecurityPolicy->addAllowedChildSrcDomain('child.owncloud.com');
$this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy());
}
public function testGetPolicyChildSrcValidMultiple() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self';child-src child.owncloud.com child.owncloud.org";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self';child-src child.owncloud.com child.owncloud.org";
$this->contentSecurityPolicy->addAllowedChildSrcDomain('child.owncloud.com');
$this->contentSecurityPolicy->addAllowedChildSrcDomain('child.owncloud.org');
@@ -404,7 +404,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowChildSrcDomain() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedChildSrcDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowChildSrcDomain('www.owncloud.com');
@@ -412,7 +412,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowChildSrcDomainMultiple() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self';child-src www.owncloud.com";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self';child-src www.owncloud.com";
$this->contentSecurityPolicy->addAllowedChildSrcDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowChildSrcDomain('www.owncloud.org');
@@ -420,7 +420,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testGetPolicyDisallowChildSrcDomainMultipleStakes() {
- $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->contentSecurityPolicy->addAllowedChildSrcDomain('www.owncloud.com');
$this->contentSecurityPolicy->disallowChildSrcDomain('www.owncloud.org')->disallowChildSrcDomain('www.owncloud.com');
@@ -428,7 +428,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
}
public function testConfigureStacked() {
- $expectedPolicy = "default-src 'none';script-src 'self' script.owncloud.org;style-src 'self' style.owncloud.org;img-src 'self' img.owncloud.org;font-src 'self' font.owncloud.org;connect-src 'self' connect.owncloud.org;media-src 'self' media.owncloud.org;object-src objects.owncloud.org;frame-src frame.owncloud.org;child-src child.owncloud.org";
+ $expectedPolicy = "default-src 'none';script-src 'self' script.owncloud.org;style-src 'self' style.owncloud.org;img-src 'self' data: img.owncloud.org;font-src 'self' font.owncloud.org;connect-src 'self' connect.owncloud.org;media-src 'self' media.owncloud.org;object-src objects.owncloud.org;frame-src frame.owncloud.org;child-src child.owncloud.org";
$this->contentSecurityPolicy->allowInlineStyle(false)
->allowEvalScript(false)
diff --git a/tests/lib/appframework/http/DataResponseTest.php b/tests/lib/appframework/http/DataResponseTest.php
index ca0582e10e5..2b7817c28e9 100644
--- a/tests/lib/appframework/http/DataResponseTest.php
+++ b/tests/lib/appframework/http/DataResponseTest.php
@@ -68,7 +68,7 @@ class DataResponseTest extends \Test\TestCase {
$expectedHeaders = [
'Cache-Control' => 'no-cache, must-revalidate',
- 'Content-Security-Policy' => "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'",
+ 'Content-Security-Policy' => "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'",
];
$expectedHeaders = array_merge($expectedHeaders, $headers);
diff --git a/tests/lib/appframework/http/ResponseTest.php b/tests/lib/appframework/http/ResponseTest.php
index c8b79fbd8b6..61dd95e5948 100644
--- a/tests/lib/appframework/http/ResponseTest.php
+++ b/tests/lib/appframework/http/ResponseTest.php
@@ -58,7 +58,7 @@ class ResponseTest extends \Test\TestCase {
$this->childResponse->setHeaders($expected);
$headers = $this->childResponse->getHeaders();
- $expected['Content-Security-Policy'] = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self'";
+ $expected['Content-Security-Policy'] = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data:;font-src 'self';connect-src 'self';media-src 'self'";
$this->assertEquals($expected, $headers);
}
diff --git a/tests/lib/appframework/routing/RoutingTest.php b/tests/lib/appframework/routing/RoutingTest.php
index 4ee3ed58807..51c191fdfb7 100644
--- a/tests/lib/appframework/routing/RoutingTest.php
+++ b/tests/lib/appframework/routing/RoutingTest.php
@@ -120,7 +120,8 @@ class RoutingTest extends \Test\TestCase
}
// route mocks
- $route = $this->mockRoute($verb, $controllerName, $actionName, $requirements, $defaults);
+ $container = new DIContainer('app1');
+ $route = $this->mockRoute($container, $verb, $controllerName, $actionName, $requirements, $defaults);
// router mock
$router = $this->getMock("\OC\Route\Router", array('create'));
@@ -133,7 +134,6 @@ class RoutingTest extends \Test\TestCase
->will($this->returnValue($route));
// load route configuration
- $container = new DIContainer('app1');
$config = new RouteConfig($container, $router, $routes);
$config->register();
@@ -151,11 +151,12 @@ class RoutingTest extends \Test\TestCase
$router = $this->getMock("\OC\Route\Router", array('create'));
// route mocks
- $indexRoute = $this->mockRoute('GET', $controllerName, 'index');
- $showRoute = $this->mockRoute('GET', $controllerName, 'show');
- $createRoute = $this->mockRoute('POST', $controllerName, 'create');
- $updateRoute = $this->mockRoute('PUT', $controllerName, 'update');
- $destroyRoute = $this->mockRoute('DELETE', $controllerName, 'destroy');
+ $container = new DIContainer('app1');
+ $indexRoute = $this->mockRoute($container, 'GET', $controllerName, 'index');
+ $showRoute = $this->mockRoute($container, 'GET', $controllerName, 'show');
+ $createRoute = $this->mockRoute($container, 'POST', $controllerName, 'create');
+ $updateRoute = $this->mockRoute($container, 'PUT', $controllerName, 'update');
+ $destroyRoute = $this->mockRoute($container, 'DELETE', $controllerName, 'destroy');
$urlWithParam = $url . '/{' . $paramName . '}';
@@ -191,21 +192,28 @@ class RoutingTest extends \Test\TestCase
->will($this->returnValue($destroyRoute));
// load route configuration
- $container = new DIContainer('app1');
$config = new RouteConfig($container, $router, $yaml);
$config->register();
}
/**
+ * @param DIContainer $container
* @param string $verb
* @param string $controllerName
* @param string $actionName
+ * @param array $requirements
+ * @param array $defaults
* @return \PHPUnit_Framework_MockObject_MockObject
*/
- private function mockRoute($verb, $controllerName, $actionName, array $requirements=array(), array $defaults=array())
- {
- $container = new DIContainer('app1');
+ private function mockRoute(
+ DIContainer $container,
+ $verb,
+ $controllerName,
+ $actionName,
+ array $requirements=array(),
+ array $defaults=array()
+ ) {
$route = $this->getMock("\OC\Route\Route", array('method', 'action', 'requirements', 'defaults'), array(), '', false);
$route
->expects($this->exactly(1))
diff --git a/tests/lib/appframework/utility/SimpleContainerTest.php b/tests/lib/appframework/utility/SimpleContainerTest.php
index 7ff579a85fc..e21e0ca13f2 100644
--- a/tests/lib/appframework/utility/SimpleContainerTest.php
+++ b/tests/lib/appframework/utility/SimpleContainerTest.php
@@ -159,10 +159,34 @@ class SimpleContainerTest extends \Test\TestCase {
public function testRegisterAliasService() {
$this->container->registerService('test', function() {
+ return new \StdClass;
+ }, true);
+ $this->container->registerAlias('test1', 'test');
+ $this->assertSame(
+ $this->container->query('test'), $this->container->query('test'));
+ $this->assertSame(
+ $this->container->query('test1'), $this->container->query('test1'));
+ $this->assertSame(
+ $this->container->query('test'), $this->container->query('test1'));
+ }
+
+ public function sanitizeNameProvider() {
+ return [
+ ['ABC\\Foo', 'ABC\\Foo'],
+ ['\\ABC\\Foo', '\\ABC\\Foo'],
+ ['\\ABC\\Foo', 'ABC\\Foo'],
+ ['ABC\\Foo', '\\ABC\\Foo'],
+ ];
+ }
+
+ /**
+ * @dataProvider sanitizeNameProvider
+ */
+ public function testSanitizeName($register, $query) {
+ $this->container->registerService($register, function() {
return 'abc';
});
- $this->container->registerAlias('test1', 'test');
- $this->assertEquals('abc', $this->container->query('test1'));
+ $this->assertEquals('abc', $this->container->query($query));
}
/**
@@ -174,5 +198,25 @@ class SimpleContainerTest extends \Test\TestCase {
);
}
+ public function testRegisterFactory() {
+ $this->container->registerService('test', function() {
+ return new \StdClass();
+ }, false);
+ $this->assertNotSame(
+ $this->container->query('test'), $this->container->query('test'));
+ }
+
+ public function testRegisterAliasFactory() {
+ $this->container->registerService('test', function() {
+ return new \StdClass();
+ }, false);
+ $this->container->registerAlias('test1', 'test');
+ $this->assertNotSame(
+ $this->container->query('test'), $this->container->query('test'));
+ $this->assertNotSame(
+ $this->container->query('test1'), $this->container->query('test1'));
+ $this->assertNotSame(
+ $this->container->query('test'), $this->container->query('test1'));
+ }
}
diff --git a/tests/lib/connector/sabre/requesttest/auth.php b/tests/lib/connector/sabre/requesttest/auth.php
new file mode 100644
index 00000000000..7cab4da5264
--- /dev/null
+++ b/tests/lib/connector/sabre/requesttest/auth.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Copyright (c) 2015 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\Connector\Sabre\RequestTest;
+
+use Sabre\DAV\Auth\Backend\BackendInterface;
+
+class Auth implements BackendInterface {
+ /**
+ * @var string
+ */
+ private $user;
+
+ /**
+ * @var string
+ */
+ private $password;
+
+ /**
+ * Auth constructor.
+ *
+ * @param string $user
+ * @param string $password
+ */
+ public function __construct($user, $password) {
+ $this->user = $user;
+ $this->password = $password;
+ }
+
+
+ /**
+ * Authenticates the user based on the current request.
+ *
+ * If authentication is successful, true must be returned.
+ * If authentication fails, an exception must be thrown.
+ *
+ * @param \Sabre\DAV\Server $server
+ * @param string $realm
+ * @return bool
+ */
+ function authenticate(\Sabre\DAV\Server $server, $realm) {
+ $userSession = \OC::$server->getUserSession();
+ $result = $userSession->login($this->user, $this->password);
+ if ($result) {
+ //we need to pass the user name, which may differ from login name
+ $user = $userSession->getUser()->getUID();
+ \OC_Util::setupFS($user);
+ //trigger creation of user home and /files folder
+ \OC::$server->getUserFolder($user);
+ }
+ return $result;
+ }
+
+ /**
+ * Returns information about the currently logged in username.
+ *
+ * If nobody is currently logged in, this method should return null.
+ *
+ * @return string|null
+ */
+ function getCurrentUser() {
+ return $this->user;
+ }
+}
diff --git a/tests/lib/connector/sabre/requesttest/exceptionplugin.php b/tests/lib/connector/sabre/requesttest/exceptionplugin.php
new file mode 100644
index 00000000000..2b9e5d6d46d
--- /dev/null
+++ b/tests/lib/connector/sabre/requesttest/exceptionplugin.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Copyright (c) 2015 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\Connector\Sabre\RequestTest;
+
+use Sabre\DAV\Exception;
+
+class ExceptionPlugin extends \OC\Connector\Sabre\ExceptionLoggerPlugin {
+ /**
+ * @var \Exception[]
+ */
+ protected $exceptions = [];
+
+ public function logException(\Exception $ex) {
+ $exceptionClass = get_class($ex);
+ if (!isset($this->nonFatalExceptions[$exceptionClass])) {
+ $this->exceptions[] = $ex;
+ }
+ }
+
+ /**
+ * @return \Exception[]
+ */
+ public function getExceptions() {
+ return $this->exceptions;
+ }
+}
diff --git a/tests/lib/connector/sabre/requesttest/requesttest.php b/tests/lib/connector/sabre/requesttest/requesttest.php
new file mode 100644
index 00000000000..c7739aefcd7
--- /dev/null
+++ b/tests/lib/connector/sabre/requesttest/requesttest.php
@@ -0,0 +1,163 @@
+<?php
+/**
+ * Copyright (c) 2015 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\Connector\Sabre\RequestTest;
+
+use OC\Connector\Sabre\Server;
+use OC\Connector\Sabre\ServerFactory;
+use OC\Files\Mount\MountPoint;
+use OC\Files\Storage\Temporary;
+use OC\Files\View;
+use OCP\IUser;
+use Sabre\HTTP\Request;
+use Test\TestCase;
+
+abstract class RequestTest extends TestCase {
+ /**
+ * @var \OC_User_Dummy
+ */
+ protected $userBackend;
+
+ /**
+ * @var \OCP\Files\Config\IMountProvider[]
+ */
+ protected $mountProviders;
+
+ /**
+ * @var \OC\Connector\Sabre\ServerFactory
+ */
+ protected $serverFactory;
+
+ protected function getStream($string) {
+ $stream = fopen('php://temp', 'r+');
+ fwrite($stream, $string);
+ fseek($stream, 0);
+ return $stream;
+ }
+
+ /**
+ * @param $userId
+ * @param $storages
+ * @return \OCP\Files\Config\IMountProvider
+ */
+ protected function getMountProvider($userId, $storages) {
+ $mounts = [];
+ foreach ($storages as $mountPoint => $storage) {
+ $mounts[] = new MountPoint($storage, $mountPoint);
+ }
+ $provider = $this->getMock('\OCP\Files\Config\IMountProvider');
+ $provider->expects($this->any())
+ ->method('getMountsForUser')
+ ->will($this->returnCallback(function (IUser $user) use ($userId, $mounts) {
+ if ($user->getUID() === $userId) {
+ return $mounts;
+ } else {
+ return [];
+ }
+ }));
+ return $provider;
+ }
+
+ protected function setUp() {
+ parent::setUp();
+ $this->userBackend = new \OC_User_Dummy();
+ \OC::$server->getUserManager()->registerBackend($this->userBackend);
+
+ $this->serverFactory = new ServerFactory(
+ \OC::$server->getConfig(),
+ \OC::$server->getLogger(),
+ \OC::$server->getDatabaseConnection(),
+ \OC::$server->getUserSession(),
+ \OC::$server->getMountManager(),
+ \OC::$server->getTagManager()
+ );
+ }
+
+ protected function tearDown() {
+ parent::tearDown();
+ \OC::$server->getUserManager()->removeBackend($this->userBackend);
+ }
+
+ protected function setupUser($name, $password) {
+ $this->userBackend->createUser($name, $password);
+ \OC::$server->getMountProviderCollection()->registerProvider($this->getMountProvider($name, [
+ '/' . $name => new Temporary()
+ ]));
+ $this->loginAsUser($name);
+ return new View('/' . $name . '/files');
+ }
+
+ /**
+ * @param \OC\Files\View $view the view to run the webdav server against
+ * @param string $user
+ * @param string $password
+ * @param string $method
+ * @param string $url
+ * @param resource|string|null $body
+ * @param array|null $headers
+ * @return \Sabre\HTTP\Response
+ */
+ protected function request($view, $user, $password, $method, $url, $body = null, $headers = null) {
+ if (is_string($body)) {
+ $body = $this->getStream($body);
+ }
+ $this->logout();
+ $exceptionPlugin = new ExceptionPlugin('webdav', null);
+ $server = $this->getSabreServer($view, $user, $password, $exceptionPlugin);
+ $request = new Request($method, $url, $headers, $body);
+
+ // since sabre catches all exceptions we need to save them and throw them from outside the sabre server
+
+ $originalServer = $_SERVER;
+
+ if (is_array($headers)) {
+ foreach ($headers as $header => $value) {
+ $_SERVER['HTTP_' . strtoupper(str_replace('-', '_', $header))] = $value;
+ }
+ }
+
+ $result = $this->makeRequest($server, $request);
+
+ foreach ($exceptionPlugin->getExceptions() as $exception) {
+ throw $exception;
+ }
+ $_SERVER = $originalServer;
+ return $result;
+ }
+
+ /**
+ * @param Server $server
+ * @param Request $request
+ * @return \Sabre\HTTP\Response
+ */
+ protected function makeRequest(Server $server, Request $request) {
+ $sapi = new Sapi($request);
+ $server->sapi = $sapi;
+ $server->httpRequest = $request;
+ $server->exec();
+ return $sapi->getResponse();
+ }
+
+ /**
+ * @param View $view
+ * @param string $user
+ * @param string $password
+ * @param ExceptionPlugin $exceptionPlugin
+ * @return Server
+ */
+ protected function getSabreServer(View $view, $user, $password, ExceptionPlugin $exceptionPlugin) {
+ $authBackend = new Auth($user, $password);
+
+ $server = $this->serverFactory->createServer('/', 'dummy', $authBackend, function () use ($view) {
+ return $view;
+ });
+ $server->addPlugin($exceptionPlugin);
+
+ return $server;
+ }
+}
diff --git a/tests/lib/connector/sabre/requesttest/sapi.php b/tests/lib/connector/sabre/requesttest/sapi.php
new file mode 100644
index 00000000000..7072b8bd286
--- /dev/null
+++ b/tests/lib/connector/sabre/requesttest/sapi.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Copyright (c) 2015 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\Connector\Sabre\RequestTest;
+
+use Sabre\HTTP\Request;
+use Sabre\HTTP\Response;
+
+class Sapi {
+ /**
+ * @var \Sabre\HTTP\Request
+ */
+ private $request;
+
+ /**
+ * @var \Sabre\HTTP\Response
+ */
+ private $response;
+
+ /**
+ * This static method will create a new Request object, based on the
+ * current PHP request.
+ *
+ * @return \Sabre\HTTP\Request
+ */
+ public function getRequest() {
+ return $this->request;
+ }
+
+ public function __construct(Request $request) {
+ $this->request = $request;
+ }
+
+ /**
+ * @param \Sabre\HTTP\Response $response
+ * @return void
+ */
+ public function sendResponse(Response $response) {
+ $this->response = $response;
+ }
+
+ /**
+ * @return \Sabre\HTTP\Response
+ */
+ public function getResponse() {
+ return $this->response;
+ }
+}
diff --git a/tests/lib/connector/sabre/requesttest/uploadtest.php b/tests/lib/connector/sabre/requesttest/uploadtest.php
new file mode 100644
index 00000000000..2cc912d07f2
--- /dev/null
+++ b/tests/lib/connector/sabre/requesttest/uploadtest.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Copyright (c) 2015 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\Connector\Sabre\RequestTest;
+
+class UploadTest extends RequestTest {
+ public function testBasicUpload() {
+ $user = $this->getUniqueID();
+ $view = $this->setupUser($user, 'pass');
+
+ $this->assertFalse($view->file_exists('foo.txt'));
+ $response = $this->request($view, $user, 'pass', 'PUT', '/foo.txt', 'asd');
+
+ $this->assertEquals(201, $response->getStatus());
+ $this->assertTrue($view->file_exists('foo.txt'));
+ $this->assertEquals('asd', $view->file_get_contents('foo.txt'));
+ }
+
+ public function testUploadOverWrite() {
+ $user = $this->getUniqueID();
+ $view = $this->setupUser($user, 'pass');
+
+ $view->file_put_contents('foo.txt', 'bar');
+
+ $response = $this->request($view, $user, 'pass', 'PUT', '/foo.txt', 'asd');
+
+ $this->assertEquals(204, $response->getStatus());
+ $this->assertEquals('asd', $view->file_get_contents('foo.txt'));
+ }
+
+ public function testChunkedUpload() {
+ $user = $this->getUniqueID();
+ $view = $this->setupUser($user, 'pass');
+
+ $this->assertFalse($view->file_exists('foo.txt'));
+ $response = $this->request($view, $user, 'pass', 'PUT', '/foo.txt-chunking-123-2-0', 'asd', ['OC-Chunked' => '1']);
+
+ $this->assertEquals(201, $response->getStatus());
+ $this->assertFalse($view->file_exists('foo.txt'));
+
+ $response = $this->request($view, $user, 'pass', 'PUT', '/foo.txt-chunking-123-2-1', 'bar', ['OC-Chunked' => '1']);
+
+ $this->assertEquals(201, $response->getStatus());
+ $this->assertTrue($view->file_exists('foo.txt'));
+
+ $this->assertEquals('asdbar', $view->file_get_contents('foo.txt'));
+ }
+
+ public function testChunkedUploadOverWrite() {
+ $user = $this->getUniqueID();
+ $view = $this->setupUser($user, 'pass');
+
+ $view->file_put_contents('foo.txt', 'bar');
+ $response = $this->request($view, $user, 'pass', 'PUT', '/foo.txt-chunking-123-2-0', 'asd', ['OC-Chunked' => '1']);
+
+ $this->assertEquals(201, $response->getStatus());
+ $this->assertEquals('bar', $view->file_get_contents('foo.txt'));
+
+ $response = $this->request($view, $user, 'pass', 'PUT', '/foo.txt-chunking-123-2-1', 'bar', ['OC-Chunked' => '1']);
+
+ $this->assertEquals(201, $response->getStatus());
+
+ $this->assertEquals('asdbar', $view->file_get_contents('foo.txt'));
+ }
+
+ public function testChunkedUploadOutOfOrder() {
+ $user = $this->getUniqueID();
+ $view = $this->setupUser($user, 'pass');
+
+ $this->assertFalse($view->file_exists('foo.txt'));
+ $response = $this->request($view, $user, 'pass', 'PUT', '/foo.txt-chunking-123-2-1', 'bar', ['OC-Chunked' => '1']);
+
+ $this->assertEquals(201, $response->getStatus());
+ $this->assertFalse($view->file_exists('foo.txt'));
+
+ $response = $this->request($view, $user, 'pass', 'PUT', '/foo.txt-chunking-123-2-0', 'asd', ['OC-Chunked' => '1']);
+
+ $this->assertEquals(201, $response->getStatus());
+ $this->assertTrue($view->file_exists('foo.txt'));
+
+ $this->assertEquals('asdbar', $view->file_get_contents('foo.txt'));
+ }
+}
diff --git a/tests/lib/db/querybuilder/querybuildertest.php b/tests/lib/db/querybuilder/querybuildertest.php
index 02e516b7386..75e62ba944e 100644
--- a/tests/lib/db/querybuilder/querybuildertest.php
+++ b/tests/lib/db/querybuilder/querybuildertest.php
@@ -253,8 +253,8 @@ class QueryBuilderTest extends \Test\TestCase {
public function dataDelete() {
return [
- ['data', null, ['table' => '`data`', 'alias' => null], '`data`'],
- ['data', 't', ['table' => '`data`', 'alias' => 't'], '`data` t'],
+ ['data', null, ['table' => '`*PREFIX*data`', 'alias' => null], '`*PREFIX*data`'],
+ ['data', 't', ['table' => '`*PREFIX*data`', 'alias' => 't'], '`*PREFIX*data` t'],
];
}
@@ -282,8 +282,8 @@ class QueryBuilderTest extends \Test\TestCase {
public function dataUpdate() {
return [
- ['data', null, ['table' => '`data`', 'alias' => null], '`data`'],
- ['data', 't', ['table' => '`data`', 'alias' => 't'], '`data` t'],
+ ['data', null, ['table' => '`*PREFIX*data`', 'alias' => null], '`*PREFIX*data`'],
+ ['data', 't', ['table' => '`*PREFIX*data`', 'alias' => 't'], '`*PREFIX*data` t'],
];
}
@@ -311,7 +311,7 @@ class QueryBuilderTest extends \Test\TestCase {
public function dataInsert() {
return [
- ['data', ['table' => '`data`'], '`data`'],
+ ['data', ['table' => '`*PREFIX*data`'], '`*PREFIX*data`'],
];
}
@@ -338,16 +338,16 @@ class QueryBuilderTest extends \Test\TestCase {
public function dataFrom() {
return [
- ['data', null, null, null, [['table' => '`data`', 'alias' => null]], '`data`'],
- ['data', 't', null, null, [['table' => '`data`', 'alias' => 't']], '`data` t'],
+ ['data', null, null, null, [['table' => '`*PREFIX*data`', 'alias' => null]], '`*PREFIX*data`'],
+ ['data', 't', null, null, [['table' => '`*PREFIX*data`', 'alias' => 't']], '`*PREFIX*data` t'],
['data1', null, 'data2', null, [
- ['table' => '`data1`', 'alias' => null],
- ['table' => '`data2`', 'alias' => null]
- ], '`data1`, `data2`'],
+ ['table' => '`*PREFIX*data1`', 'alias' => null],
+ ['table' => '`*PREFIX*data2`', 'alias' => null]
+ ], '`*PREFIX*data1`, `*PREFIX*data2`'],
['data', 't1', 'data', 't2', [
- ['table' => '`data`', 'alias' => 't1'],
- ['table' => '`data`', 'alias' => 't2']
- ], '`data` t1, `data` t2'],
+ ['table' => '`*PREFIX*data`', 'alias' => 't1'],
+ ['table' => '`*PREFIX*data`', 'alias' => 't2']
+ ], '`*PREFIX*data` t1, `*PREFIX*data` t2'],
];
}
@@ -382,18 +382,18 @@ class QueryBuilderTest extends \Test\TestCase {
return [
[
'd1', 'data2', null, null,
- ['d1' => [['joinType' => 'inner', 'joinTable' => '`data2`', 'joinAlias' => null, 'joinCondition' => null]]],
- '`data1` d1 INNER JOIN `data2` ON '
+ ['d1' => [['joinType' => 'inner', 'joinTable' => '`*PREFIX*data2`', 'joinAlias' => null, 'joinCondition' => null]]],
+ '`*PREFIX*data1` d1 INNER JOIN `*PREFIX*data2` ON '
],
[
'd1', 'data2', 'd2', null,
- ['d1' => [['joinType' => 'inner', 'joinTable' => '`data2`', 'joinAlias' => 'd2', 'joinCondition' => null]]],
- '`data1` d1 INNER JOIN `data2` d2 ON '
+ ['d1' => [['joinType' => 'inner', 'joinTable' => '`*PREFIX*data2`', 'joinAlias' => 'd2', 'joinCondition' => null]]],
+ '`*PREFIX*data1` d1 INNER JOIN `*PREFIX*data2` d2 ON '
],
[
'd1', 'data2', 'd2', 'd1.`field1` = d2.`field2`',
- ['d1' => [['joinType' => 'inner', 'joinTable' => '`data2`', 'joinAlias' => 'd2', 'joinCondition' => 'd1.`field1` = d2.`field2`']]],
- '`data1` d1 INNER JOIN `data2` d2 ON d1.`field1` = d2.`field2`'
+ ['d1' => [['joinType' => 'inner', 'joinTable' => '`*PREFIX*data2`', 'joinAlias' => 'd2', 'joinCondition' => 'd1.`field1` = d2.`field2`']]],
+ '`*PREFIX*data1` d1 INNER JOIN `*PREFIX*data2` d2 ON d1.`field1` = d2.`field2`'
],
];
@@ -463,18 +463,18 @@ class QueryBuilderTest extends \Test\TestCase {
return [
[
'd1', 'data2', null, null,
- ['d1' => [['joinType' => 'left', 'joinTable' => '`data2`', 'joinAlias' => null, 'joinCondition' => null]]],
- '`data1` d1 LEFT JOIN `data2` ON '
+ ['d1' => [['joinType' => 'left', 'joinTable' => '`*PREFIX*data2`', 'joinAlias' => null, 'joinCondition' => null]]],
+ '`*PREFIX*data1` d1 LEFT JOIN `*PREFIX*data2` ON '
],
[
'd1', 'data2', 'd2', null,
- ['d1' => [['joinType' => 'left', 'joinTable' => '`data2`', 'joinAlias' => 'd2', 'joinCondition' => null]]],
- '`data1` d1 LEFT JOIN `data2` d2 ON '
+ ['d1' => [['joinType' => 'left', 'joinTable' => '`*PREFIX*data2`', 'joinAlias' => 'd2', 'joinCondition' => null]]],
+ '`*PREFIX*data1` d1 LEFT JOIN `*PREFIX*data2` d2 ON '
],
[
'd1', 'data2', 'd2', 'd1.`field1` = d2.`field2`',
- ['d1' => [['joinType' => 'left', 'joinTable' => '`data2`', 'joinAlias' => 'd2', 'joinCondition' => 'd1.`field1` = d2.`field2`']]],
- '`data1` d1 LEFT JOIN `data2` d2 ON d1.`field1` = d2.`field2`'
+ ['d1' => [['joinType' => 'left', 'joinTable' => '`*PREFIX*data2`', 'joinAlias' => 'd2', 'joinCondition' => 'd1.`field1` = d2.`field2`']]],
+ '`*PREFIX*data1` d1 LEFT JOIN `*PREFIX*data2` d2 ON d1.`field1` = d2.`field2`'
],
];
}
@@ -513,18 +513,18 @@ class QueryBuilderTest extends \Test\TestCase {
return [
[
'd1', 'data2', null, null,
- ['d1' => [['joinType' => 'right', 'joinTable' => '`data2`', 'joinAlias' => null, 'joinCondition' => null]]],
- '`data1` d1 RIGHT JOIN `data2` ON '
+ ['d1' => [['joinType' => 'right', 'joinTable' => '`*PREFIX*data2`', 'joinAlias' => null, 'joinCondition' => null]]],
+ '`*PREFIX*data1` d1 RIGHT JOIN `*PREFIX*data2` ON '
],
[
'd1', 'data2', 'd2', null,
- ['d1' => [['joinType' => 'right', 'joinTable' => '`data2`', 'joinAlias' => 'd2', 'joinCondition' => null]]],
- '`data1` d1 RIGHT JOIN `data2` d2 ON '
+ ['d1' => [['joinType' => 'right', 'joinTable' => '`*PREFIX*data2`', 'joinAlias' => 'd2', 'joinCondition' => null]]],
+ '`*PREFIX*data1` d1 RIGHT JOIN `*PREFIX*data2` d2 ON '
],
[
'd1', 'data2', 'd2', 'd1.`field1` = d2.`field2`',
- ['d1' => [['joinType' => 'right', 'joinTable' => '`data2`', 'joinAlias' => 'd2', 'joinCondition' => 'd1.`field1` = d2.`field2`']]],
- '`data1` d1 RIGHT JOIN `data2` d2 ON d1.`field1` = d2.`field2`'
+ ['d1' => [['joinType' => 'right', 'joinTable' => '`*PREFIX*data2`', 'joinAlias' => 'd2', 'joinCondition' => 'd1.`field1` = d2.`field2`']]],
+ '`*PREFIX*data1` d1 RIGHT JOIN `*PREFIX*data2` d2 ON d1.`field1` = d2.`field2`'
],
];
}
@@ -591,7 +591,7 @@ class QueryBuilderTest extends \Test\TestCase {
);
$this->assertSame(
- 'UPDATE `data` SET ' . $expectedQuery,
+ 'UPDATE `*PREFIX*data` SET ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
@@ -774,7 +774,7 @@ class QueryBuilderTest extends \Test\TestCase {
);
$this->assertSame(
- 'INSERT INTO `data` ' . $expectedQuery,
+ 'INSERT INTO `*PREFIX*data` ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
@@ -799,7 +799,7 @@ class QueryBuilderTest extends \Test\TestCase {
);
$this->assertSame(
- 'INSERT INTO `data` ' . $expectedQuery,
+ 'INSERT INTO `*PREFIX*data` ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
@@ -996,4 +996,34 @@ class QueryBuilderTest extends \Test\TestCase {
$this->queryBuilder->getSQL()
);
}
+
+ public function dataGetTableName() {
+ return [
+ ['*PREFIX*table', null, '`*PREFIX*table`'],
+ ['*PREFIX*table', true, '`*PREFIX*table`'],
+ ['*PREFIX*table', false, '`*PREFIX*table`'],
+
+ ['table', null, '`*PREFIX*table`'],
+ ['table', true, '`*PREFIX*table`'],
+ ['table', false, '`table`'],
+ ];
+ }
+
+ /**
+ * @dataProvider dataGetTableName
+ *
+ * @param string $tableName
+ * @param bool $automatic
+ * @param string $expected
+ */
+ public function testGetTableName($tableName, $automatic, $expected) {
+ if ($automatic !== null) {
+ $this->queryBuilder->automaticTablePrefix($automatic);
+ }
+
+ $this->assertSame(
+ $expected,
+ $this->invokePrivate($this->queryBuilder, 'getTableName', [$tableName])
+ );
+ }
}
diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php
index bf99a582117..bb42f385fc5 100644
--- a/tests/lib/files/view.php
+++ b/tests/lib/files/view.php
@@ -1386,7 +1386,9 @@ class View extends \Test\TestCase {
['/foo/files/bar', '/foo', true],
['/foo', '/foo', false],
['/foo', '/files/foo', true],
- ['/foo', 'filesfoo', false]
+ ['/foo', 'filesfoo', false],
+ ['', '/foo/files', true],
+ ['', '/foo/files/bar.txt', true]
];
}
diff --git a/tests/lib/repair/cleantags.php b/tests/lib/repair/cleantags.php
index 2f6d0879642..a511daa03d6 100644
--- a/tests/lib/repair/cleantags.php
+++ b/tests/lib/repair/cleantags.php
@@ -40,13 +40,13 @@ class CleanTags extends \Test\TestCase {
protected function cleanUpTables() {
$qb = $this->connection->getQueryBuilder();
- $qb->delete('*PREFIX*vcategory')
+ $qb->delete('vcategory')
->execute();
- $qb->delete('*PREFIX*vcategory_to_object')
+ $qb->delete('vcategory_to_object')
->execute();
- $qb->delete('*PREFIX*filecache')
+ $qb->delete('filecache')
->execute();
}
@@ -61,20 +61,20 @@ class CleanTags extends \Test\TestCase {
$this->addTagEntry(9999999, $cat3, 'contacts'); // Retained
$this->addTagEntry($this->getFileID(), $cat3 + 1, 'files'); // Deleted: Category is NULL
- $this->assertEntryCount('*PREFIX*vcategory_to_object', 4, 'Assert tag entries count before repair step');
- $this->assertEntryCount('*PREFIX*vcategory', 4, 'Assert tag categories count before repair step');
+ $this->assertEntryCount('vcategory_to_object', 4, 'Assert tag entries count before repair step');
+ $this->assertEntryCount('vcategory', 4, 'Assert tag categories count before repair step');
self::invokePrivate($this->repair, 'deleteOrphanFileEntries');
- $this->assertEntryCount('*PREFIX*vcategory_to_object', 3, 'Assert tag entries count after cleaning file entries');
- $this->assertEntryCount('*PREFIX*vcategory', 4, 'Assert tag categories count after cleaning file entries');
+ $this->assertEntryCount('vcategory_to_object', 3, 'Assert tag entries count after cleaning file entries');
+ $this->assertEntryCount('vcategory', 4, 'Assert tag categories count after cleaning file entries');
self::invokePrivate($this->repair, 'deleteOrphanTagEntries');
- $this->assertEntryCount('*PREFIX*vcategory_to_object', 2, 'Assert tag entries count after cleaning tag entries');
- $this->assertEntryCount('*PREFIX*vcategory', 4, 'Assert tag categories count after cleaning tag entries');
+ $this->assertEntryCount('vcategory_to_object', 2, 'Assert tag entries count after cleaning tag entries');
+ $this->assertEntryCount('vcategory', 4, 'Assert tag categories count after cleaning tag entries');
self::invokePrivate($this->repair, 'deleteOrphanCategoryEntries');
- $this->assertEntryCount('*PREFIX*vcategory_to_object', 2, 'Assert tag entries count after cleaning category entries');
- $this->assertEntryCount('*PREFIX*vcategory', 2, 'Assert tag categories count after cleaning category entries');
+ $this->assertEntryCount('vcategory_to_object', 2, 'Assert tag entries count after cleaning category entries');
+ $this->assertEntryCount('vcategory', 2, 'Assert tag categories count after cleaning category entries');
}
/**
@@ -100,7 +100,7 @@ class CleanTags extends \Test\TestCase {
*/
protected function addTagCategory($category, $type) {
$qb = $this->connection->getQueryBuilder();
- $qb->insert('*PREFIX*vcategory')
+ $qb->insert('vcategory')
->values([
'uid' => $qb->createNamedParameter('TestRepairCleanTags'),
'category' => $qb->createNamedParameter($category),
@@ -108,7 +108,7 @@ class CleanTags extends \Test\TestCase {
])
->execute();
- return (int) $this->getLastInsertID('*PREFIX*vcategory', 'id');
+ return (int) $this->getLastInsertID('vcategory', 'id');
}
/**
@@ -119,7 +119,7 @@ class CleanTags extends \Test\TestCase {
*/
protected function addTagEntry($objectId, $category, $type) {
$qb = $this->connection->getQueryBuilder();
- $qb->insert('*PREFIX*vcategory_to_object')
+ $qb->insert('vcategory_to_object')
->values([
'objid' => $qb->createNamedParameter($objectId, \PDO::PARAM_INT),
'categoryid' => $qb->createNamedParameter($category, \PDO::PARAM_INT),
@@ -141,21 +141,21 @@ class CleanTags extends \Test\TestCase {
// We create a new file entry and delete it after the test again
$fileName = $this->getUniqueID('TestRepairCleanTags', 12);
- $qb->insert('*PREFIX*filecache')
+ $qb->insert('filecache')
->values([
'path' => $qb->createNamedParameter($fileName),
'path_hash' => $qb->createNamedParameter(md5($fileName)),
])
->execute();
$fileName = $this->getUniqueID('TestRepairCleanTags', 12);
- $qb->insert('*PREFIX*filecache')
+ $qb->insert('filecache')
->values([
'path' => $qb->createNamedParameter($fileName),
'path_hash' => $qb->createNamedParameter(md5($fileName)),
])
->execute();
- $this->createdFile = (int) $this->getLastInsertID('*PREFIX*filecache', 'fileid');
+ $this->createdFile = (int) $this->getLastInsertID('filecache', 'fileid');
return $this->createdFile;
}
diff --git a/tests/lib/share/share.php b/tests/lib/share/share.php
index b6d3e16826d..ef0d9822085 100644
--- a/tests/lib/share/share.php
+++ b/tests/lib/share/share.php
@@ -1288,7 +1288,7 @@ class Test_Share extends \Test\TestCase {
// Find the share ID in the db
$qb = $connection->getQueryBuilder();
$qb->select('id')
- ->from('*PREFIX*share')
+ ->from('share')
->where($qb->expr()->eq('item_type', $qb->createParameter('type')))
->andWhere($qb->expr()->eq('item_source', $qb->createParameter('source')))
->andWhere($qb->expr()->eq('uid_owner', $qb->createParameter('owner')))
@@ -1309,7 +1309,7 @@ class Test_Share extends \Test\TestCase {
// Fetch the hash from the database
$qb = $connection->getQueryBuilder();
$qb->select('share_with')
- ->from('*PREFIX*share')
+ ->from('share')
->where($qb->expr()->eq('id', $qb->createParameter('id')))
->setParameter('id', $id);
$hash = $qb->execute()->fetch()['share_with'];
diff --git a/tests/settings/controller/CheckSetupControllerTest.php b/tests/settings/controller/CheckSetupControllerTest.php
index 6096aae8652..414b1b91e17 100644
--- a/tests/settings/controller/CheckSetupControllerTest.php
+++ b/tests/settings/controller/CheckSetupControllerTest.php
@@ -31,11 +31,24 @@ use OC_Util;
use Test\TestCase;
/**
+ * Mock version_compare
+ * @param string $version1
+ * @param string $version2
+ * @return int
+ */
+function version_compare($version1, $version2) {
+ return CheckSetupControllerTest::$version_compare;
+}
+
+/**
* Class CheckSetupControllerTest
*
* @package OC\Settings\Controller
*/
class CheckSetupControllerTest extends TestCase {
+ /** @var int */
+ public static $version_compare;
+
/** @var CheckSetupController */
private $checkSetupController;
/** @var IRequest */
@@ -209,6 +222,66 @@ class CheckSetupControllerTest extends TestCase {
);
}
+ public function testIsPhpSupportedFalse() {
+ self::$version_compare = -1;
+
+ $this->assertEquals(
+ ['eol' => true, 'version' => PHP_VERSION],
+ self::invokePrivate($this->checkSetupController, 'isPhpSupported')
+ );
+ }
+
+ public function testIsPhpSupportedTrue() {
+ self::$version_compare = 0;
+
+ $this->assertEquals(
+ ['eol' => false, 'version' => PHP_VERSION],
+ self::invokePrivate($this->checkSetupController, 'isPhpSupported')
+ );
+
+
+ self::$version_compare = 1;
+
+ $this->assertEquals(
+ ['eol' => false, 'version' => PHP_VERSION],
+ self::invokePrivate($this->checkSetupController, 'isPhpSupported')
+ );
+ }
+
+ public function testForwardedForHeadersWorkingFalse() {
+ $this->config->expects($this->once())
+ ->method('getSystemValue')
+ ->with('trusted_proxies', [])
+ ->willReturn(['1.2.3.4']);
+ $this->request->expects($this->once())
+ ->method('getRemoteAddress')
+ ->willReturn('1.2.3.4');
+
+ $this->assertFalse(
+ self::invokePrivate(
+ $this->checkSetupController,
+ 'forwardedForHeadersWorking'
+ )
+ );
+ }
+
+ public function testForwardedForHeadersWorkingTrue() {
+ $this->config->expects($this->once())
+ ->method('getSystemValue')
+ ->with('trusted_proxies', [])
+ ->willReturn(['1.2.3.4']);
+ $this->request->expects($this->once())
+ ->method('getRemoteAddress')
+ ->willReturn('4.3.2.1');
+
+ $this->assertTrue(
+ self::invokePrivate(
+ $this->checkSetupController,
+ 'forwardedForHeadersWorking'
+ )
+ );
+ }
+
public function testCheck() {
$this->config->expects($this->at(0))
->method('getSystemValue')
@@ -218,6 +291,14 @@ class CheckSetupControllerTest extends TestCase {
->method('getSystemValue')
->with('memcache.local', null)
->will($this->returnValue('SomeProvider'));
+ $this->config->expects($this->at(2))
+ ->method('getSystemValue')
+ ->with('trusted_proxies', [])
+ ->willReturn(['1.2.3.4']);
+
+ $this->request->expects($this->once())
+ ->method('getRemoteAddress')
+ ->willReturn('4.3.2.1');
$client = $this->getMockBuilder('\OCP\Http\Client\IClient')
->disableOriginalConstructor()->getMock();
@@ -244,6 +325,11 @@ class CheckSetupControllerTest extends TestCase {
->method('linkToDocs')
->with('admin-security')
->willReturn('https://doc.owncloud.org/server/8.1/admin_manual/configuration_server/hardening.html');
+ self::$version_compare = -1;
+ $this->urlGenerator->expects($this->at(2))
+ ->method('linkToDocs')
+ ->with('admin-reverse-proxy')
+ ->willReturn('reverse-proxy-doc-link');
$expected = new DataResponse(
[
@@ -254,6 +340,12 @@ class CheckSetupControllerTest extends TestCase {
'isUrandomAvailable' => self::invokePrivate($this->checkSetupController, 'isUrandomAvailable'),
'securityDocs' => 'https://doc.owncloud.org/server/8.1/admin_manual/configuration_server/hardening.html',
'isUsedTlsLibOutdated' => '',
+ 'phpSupported' => [
+ 'eol' => true,
+ 'version' => PHP_VERSION
+ ],
+ 'forwardedForHeadersWorking' => true,
+ 'reverseProxyDocs' => 'reverse-proxy-doc-link',
]
);
$this->assertEquals($expected, $this->checkSetupController->check());
diff --git a/themes/example/defaults.php b/themes/example/defaults.php
index 21d80416e12..0dd0d46bd9c 100644
--- a/themes/example/defaults.php
+++ b/themes/example/defaults.php
@@ -28,7 +28,6 @@ class OC_Theme {
private $themeSyncClientUrl;
private $themeSlogan;
private $themeMailHeaderColor;
- private $themeKnowledgeBaseUrl;
/* put your custom text in these variables */
function __construct() {
@@ -40,7 +39,6 @@ class OC_Theme {
$this->themeSyncClientUrl = 'https://owncloud.org/install';
$this->themeSlogan = 'Your custom cloud, personalized for you!';
$this->themeMailHeaderColor = '#745bca';
- $this->themeKnowledgeBaseUrl = 'https://doc.owncloud.org';
}
/* nothing after this needs to be adjusted */
@@ -94,8 +92,4 @@ class OC_Theme {
return $this->themeMailHeaderColor;
}
- public function getKnowledgeBaseUrl() {
- return $this->themeKnowledgeBaseUrl;
- }
-
}
diff --git a/version.php b/version.php
index 7ccd2e6b548..a115f4b26be 100644
--- a/version.php
+++ b/version.php
@@ -22,7 +22,7 @@
// We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel
// when updating major/minor version number.
-$OC_Version=array(8, 2, 0, 3);
+$OC_Version=array(8, 2, 0, 4);
// The human readable string
$OC_VersionString='8.2 pre alpha';