summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
m---------3rdparty0
-rw-r--r--README.md4
-rw-r--r--apps/dav/appinfo/info.xml1
-rw-r--r--apps/files/js/file-upload.js44
-rw-r--r--apps/files/js/filelist.js9
-rw-r--r--apps/files/tests/js/fileUploadSpec.js96
-rw-r--r--apps/files_external/l10n/fi_FI.js1
-rw-r--r--apps/files_external/l10n/fi_FI.json1
-rw-r--r--apps/files_external/l10n/it.js3
-rw-r--r--apps/files_external/l10n/it.json3
-rw-r--r--apps/files_external/l10n/oc.js25
-rw-r--r--apps/files_external/l10n/oc.json25
-rw-r--r--apps/files_external/l10n/pt_BR.js1
-rw-r--r--apps/files_external/l10n/pt_BR.json1
-rw-r--r--apps/files_external/l10n/sq.js1
-rw-r--r--apps/files_external/l10n/sq.json1
-rw-r--r--apps/provisioning_api/tests/userstest.php15
-rw-r--r--build/integration/config/behat.yml1
-rw-r--r--build/integration/features/bootstrap/FeatureContext.php128
-rw-r--r--build/integration/features/provisioning-v1.feature338
-rw-r--r--core/ajax/update.php27
-rw-r--r--core/command/upgrade.php12
-rw-r--r--core/js/js.js28
-rw-r--r--core/js/tests/specs/sharedialogviewSpec.js78
-rw-r--r--core/l10n/bg_BG.js1
-rw-r--r--core/l10n/bg_BG.json1
-rw-r--r--core/l10n/ca.js1
-rw-r--r--core/l10n/ca.json1
-rw-r--r--core/l10n/cs_CZ.js1
-rw-r--r--core/l10n/cs_CZ.json1
-rw-r--r--core/l10n/da.js1
-rw-r--r--core/l10n/da.json1
-rw-r--r--core/l10n/de.js1
-rw-r--r--core/l10n/de.json1
-rw-r--r--core/l10n/de_DE.js1
-rw-r--r--core/l10n/de_DE.json1
-rw-r--r--core/l10n/el.js1
-rw-r--r--core/l10n/el.json1
-rw-r--r--core/l10n/en_GB.js1
-rw-r--r--core/l10n/en_GB.json1
-rw-r--r--core/l10n/es.js1
-rw-r--r--core/l10n/es.json1
-rw-r--r--core/l10n/et_EE.js1
-rw-r--r--core/l10n/et_EE.json1
-rw-r--r--core/l10n/fi_FI.js2
-rw-r--r--core/l10n/fi_FI.json2
-rw-r--r--core/l10n/fr.js1
-rw-r--r--core/l10n/fr.json1
-rw-r--r--core/l10n/gl.js1
-rw-r--r--core/l10n/gl.json1
-rw-r--r--core/l10n/hu_HU.js1
-rw-r--r--core/l10n/hu_HU.json1
-rw-r--r--core/l10n/id.js1
-rw-r--r--core/l10n/id.json1
-rw-r--r--core/l10n/is.js1
-rw-r--r--core/l10n/is.json1
-rw-r--r--core/l10n/it.js2
-rw-r--r--core/l10n/it.json2
-rw-r--r--core/l10n/ja.js1
-rw-r--r--core/l10n/ja.json1
-rw-r--r--core/l10n/ko.js1
-rw-r--r--core/l10n/ko.json1
-rw-r--r--core/l10n/lt_LT.js1
-rw-r--r--core/l10n/lt_LT.json1
-rw-r--r--core/l10n/mk.js1
-rw-r--r--core/l10n/mk.json1
-rw-r--r--core/l10n/nb_NO.js1
-rw-r--r--core/l10n/nb_NO.json1
-rw-r--r--core/l10n/nds.js1
-rw-r--r--core/l10n/nds.json1
-rw-r--r--core/l10n/nl.js1
-rw-r--r--core/l10n/nl.json1
-rw-r--r--core/l10n/oc.js1
-rw-r--r--core/l10n/oc.json1
-rw-r--r--core/l10n/pl.js1
-rw-r--r--core/l10n/pl.json1
-rw-r--r--core/l10n/pt_BR.js2
-rw-r--r--core/l10n/pt_BR.json2
-rw-r--r--core/l10n/pt_PT.js1
-rw-r--r--core/l10n/pt_PT.json1
-rw-r--r--core/l10n/ro.js1
-rw-r--r--core/l10n/ro.json1
-rw-r--r--core/l10n/ru.js1
-rw-r--r--core/l10n/ru.json1
-rw-r--r--core/l10n/sk_SK.js1
-rw-r--r--core/l10n/sk_SK.json1
-rw-r--r--core/l10n/sl.js1
-rw-r--r--core/l10n/sl.json1
-rw-r--r--core/l10n/sq.js5
-rw-r--r--core/l10n/sq.json5
-rw-r--r--core/l10n/sr.js1
-rw-r--r--core/l10n/sr.json1
-rw-r--r--core/l10n/th_TH.js1
-rw-r--r--core/l10n/th_TH.json1
-rw-r--r--core/l10n/tr.js1
-rw-r--r--core/l10n/tr.json1
-rw-r--r--core/l10n/uk.js1
-rw-r--r--core/l10n/uk.json1
-rw-r--r--core/l10n/zh_CN.js1
-rw-r--r--core/l10n/zh_CN.json1
-rw-r--r--core/l10n/zh_TW.js1
-rw-r--r--core/l10n/zh_TW.json1
-rw-r--r--core/shipped.json1
-rw-r--r--indie.json92
-rw-r--r--lib/base.php14
-rw-r--r--lib/private/api.php18
-rw-r--r--lib/private/appframework/dependencyinjection/dicontainer.php4
-rw-r--r--lib/private/appframework/http/request.php15
-rw-r--r--lib/private/group/manager.php19
-rw-r--r--lib/private/legacy/subadmin.php172
-rw-r--r--lib/private/ocs/result.php4
-rw-r--r--lib/private/server.php2
-rw-r--r--lib/private/subadmin.php251
-rw-r--r--lib/private/updater.php9
-rw-r--r--lib/private/util.php19
-rw-r--r--settings/controller/checksetupcontroller.php4
-rw-r--r--settings/controller/userscontroller.php2
-rw-r--r--settings/js/apps.js4
-rw-r--r--tests/lib/api.php62
-rw-r--r--tests/lib/appframework/controller/ApiControllerTest.php1
-rw-r--r--tests/lib/appframework/controller/ControllerTest.php1
-rw-r--r--tests/lib/appframework/controller/OCSControllerTest.php4
-rw-r--r--tests/lib/appframework/dependencyinjection/DIContainerTest.php1
-rw-r--r--tests/lib/appframework/http/DispatcherTest.php6
-rw-r--r--tests/lib/appframework/http/RequestTest.php84
-rw-r--r--tests/lib/appframework/middleware/MiddlewareDispatcherTest.php1
-rw-r--r--tests/lib/appframework/middleware/MiddlewareTest.php1
-rw-r--r--tests/lib/appframework/middleware/security/CORSMiddlewareTest.php10
-rw-r--r--tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php1
-rw-r--r--tests/lib/appframework/middleware/sessionmiddlewaretest.php1
-rw-r--r--tests/lib/subadmin.php264
-rw-r--r--tests/lib/util.php2
-rw-r--r--tests/settings/controller/userscontrollertest.php108
-rw-r--r--version.php2
134 files changed, 1513 insertions, 601 deletions
diff --git a/3rdparty b/3rdparty
-Subproject 1914e923a4589e619b930e1ca587041d6fd3a1f
+Subproject 40dfc0121ec2a4940a62fdbc86b2a9a300658c5
diff --git a/README.md b/README.md
index 1085d516263..7e1a9fbc78b 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ Dependencies:
[![Dependency Status](https://www.versioneye.com/user/projects/54d1f76f3ca0840b190000c0/badge.svg?style=flat)](https://www.versioneye.com/user/projects/54d1f76f3ca0840b190000c0)
### Installation instructions
-https://doc.owncloud.org/server/8.2/developer_manual/app/index.html
+https://doc.owncloud.org/server/9.0/developer_manual/app/index.html
### Contribution Guidelines
https://owncloud.org/contribute/
@@ -35,4 +35,4 @@ https://www.transifex.com/projects/p/owncloud/
[![Transifex](https://www.transifex.com/projects/p/owncloud/resource/core/chart/image_png)](https://www.transifex.com/projects/p/owncloud/)
For more detailed information about translations:
-http://doc.owncloud.org/server/8.2/developer_manual/core/translation.html
+http://doc.owncloud.org/server/9.0/developer_manual/core/translation.html
diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml
index c80af15a29b..38878ec27f2 100644
--- a/apps/dav/appinfo/info.xml
+++ b/apps/dav/appinfo/info.xml
@@ -5,6 +5,7 @@
<description>ownCloud WebDAV endpoint</description>
<licence>AGPL</licence>
<author>owncloud.org</author>
+ <version>0.1</version>
<requiremin>9.0</requiremin>
<shipped>true</shipped>
<standalone/>
diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js
index 77b85ecd7da..d419cb3a2c0 100644
--- a/apps/files/js/file-upload.js
+++ b/apps/files/js/file-upload.js
@@ -18,7 +18,7 @@
* - TODO music upload button
*/
-/* global jQuery, oc_requesttoken, humanFileSize */
+/* global jQuery, oc_requesttoken, humanFileSize, FileList */
/**
* Function that will allow us to know if Ajax uploads are supported
@@ -48,6 +48,26 @@ function supportAjaxUploadWithProgress() {
}
/**
+ * Add form data into the given form data
+ *
+ * @param {Array|Object} formData form data which can either be an array or an object
+ * @param {Object} newData key-values to add to the form data
+ *
+ * @return updated form data
+ */
+function addFormData(formData, newData) {
+ // in IE8, formData is an array instead of object
+ if (_.isArray(formData)) {
+ _.each(newData, function(value, key) {
+ formData.push({name: key, value: value});
+ });
+ } else {
+ formData = _.extend(formData, newData);
+ }
+ return formData;
+}
+
+/**
* keeps track of uploads in progress and implements callbacks for the conflicts dialog
* @namespace
*/
@@ -143,9 +163,9 @@ OC.Upload = {
data.data.append('resolution', 'replace');
} else {
if (!data.formData) {
- data.formData = [];
+ data.formData = {};
}
- data.formData.push({name:'resolution', value:'replace'}); //hack for ie8
+ addFormData(data.formData, {resolution: 'replace'});
}
data.submit();
},
@@ -159,9 +179,9 @@ OC.Upload = {
data.data.append('resolution', 'autorename');
} else {
if (!data.formData) {
- data.formData = [];
+ data.formData = {};
}
- data.formData.push({name:'resolution', value:'autorename'}); //hack for ie8
+ addFormData(data.formData, {resolution: 'autorename'});
}
data.submit();
},
@@ -185,7 +205,7 @@ OC.Upload = {
* @param {function} callbacks.onCancel
*/
checkExistingFiles: function (selection, callbacks) {
- var fileList = OCA.Files.App.fileList;
+ var fileList = FileList;
var conflicts = [];
// only keep non-conflicting uploads
selection.uploads = _.filter(selection.uploads, function(upload) {
@@ -402,17 +422,19 @@ OC.Upload = {
submit: function(e, data) {
OC.Upload.rememberUpload(data);
if (!data.formData) {
- data.formData = [];
+ data.formData = {};
}
var fileDirectory = '';
if(typeof data.files[0].relativePath !== 'undefined') {
fileDirectory = data.files[0].relativePath;
}
- // FIXME: prevent re-adding the same
- data.formData.push({name: 'requesttoken', value: oc_requesttoken});
- data.formData.push({name: 'dir', value: data.targetDir || FileList.getCurrentDirectory()});
- data.formData.push({name: 'file_directory', value: fileDirectory});
+
+ addFormData(data.formData, {
+ requesttoken: oc_requesttoken,
+ dir: data.targetDir || FileList.getCurrentDirectory(),
+ file_directory: fileDirectory
+ });
},
fail: function(e, data) {
OC.Upload.log('fail', e, data);
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 4f5fdf242d9..c84d6c3c47d 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -390,12 +390,15 @@
* Update the details view to display the given file
*
* @param {string} fileName file name from the current list
+ * @param {boolean} [show=true] whether to open the sidebar if it was closed
*/
- _updateDetailsView: function(fileName) {
+ _updateDetailsView: function(fileName, show) {
if (!this._detailsView) {
return;
}
+ // show defaults to true
+ show = _.isUndefined(show) || !!show;
var oldFileInfo = this._detailsView.getFileInfo();
if (oldFileInfo) {
// TODO: use more efficient way, maybe track the highlight
@@ -413,7 +416,7 @@
return;
}
- if (this._detailsView.$el.hasClass('disappear')) {
+ if (show && this._detailsView.$el.hasClass('disappear')) {
OC.Apps.showAppSidebar(this._detailsView.$el);
}
@@ -1771,7 +1774,7 @@
tr.remove();
tr = self.add(fileInfo, {updateSummary: false, silent: true});
self.$fileList.trigger($.Event('fileActionsReady', {fileList: self, $files: $(tr)}));
- self._updateDetailsView(fileInfo.name);
+ self._updateDetailsView(fileInfo.name, false);
}
});
} else {
diff --git a/apps/files/tests/js/fileUploadSpec.js b/apps/files/tests/js/fileUploadSpec.js
index cad8468d1c8..a49a5d4e2e0 100644
--- a/apps/files/tests/js/fileUploadSpec.js
+++ b/apps/files/tests/js/fileUploadSpec.js
@@ -117,4 +117,100 @@ describe('OC.Upload tests', function() {
);
});
});
+ describe('Upload conflicts', function() {
+ var oldFileList;
+ var conflictDialogStub;
+ var callbacks;
+
+ beforeEach(function() {
+ oldFileList = FileList;
+ $('#testArea').append(
+ '<div id="tableContainer">' +
+ '<table id="filestable">' +
+ '<thead><tr>' +
+ '<th id="headerName" class="hidden column-name">' +
+ '<input type="checkbox" id="select_all_files" class="select-all">' +
+ '<a class="name columntitle" data-sort="name"><span>Name</span><span class="sort-indicator"></span></a>' +
+ '<span id="selectedActionsList" class="selectedActions hidden">' +
+ '<a href class="download"><img src="actions/download.svg">Download</a>' +
+ '<a href class="delete-selected">Delete</a></span>' +
+ '</th>' +
+ '<th class="hidden column-size"><a class="columntitle" data-sort="size"><span class="sort-indicator"></span></a></th>' +
+ '<th class="hidden column-mtime"><a class="columntitle" data-sort="mtime"><span class="sort-indicator"></span></a></th>' +
+ '</tr></thead>' +
+ '<tbody id="fileList"></tbody>' +
+ '<tfoot></tfoot>' +
+ '</table>' +
+ '</div>'
+ );
+ FileList = new OCA.Files.FileList($('#tableContainer'));
+
+ FileList.add({name: 'conflict.txt', mimetype: 'text/plain'});
+ FileList.add({name: 'conflict2.txt', mimetype: 'text/plain'});
+
+ conflictDialogStub = sinon.stub(OC.dialogs, 'fileexists');
+ callbacks = {
+ onNoConflicts: sinon.stub()
+ };
+ });
+ afterEach(function() {
+ conflictDialogStub.restore();
+
+ FileList.destroy();
+ FileList = oldFileList;
+ });
+ it('does not show conflict dialog when no client side conflict', function() {
+ var selection = {
+ // yes, the format of uploads is weird...
+ uploads: [
+ {files: [{name: 'noconflict.txt'}]},
+ {files: [{name: 'noconflict2.txt'}]}
+ ]
+ };
+
+ OC.Upload.checkExistingFiles(selection, callbacks);
+
+ expect(conflictDialogStub.notCalled).toEqual(true);
+ expect(callbacks.onNoConflicts.calledOnce).toEqual(true);
+ expect(callbacks.onNoConflicts.calledWith(selection)).toEqual(true);
+ });
+ it('shows conflict dialog when no client side conflict', function() {
+ var selection = {
+ // yes, the format of uploads is weird...
+ uploads: [
+ {files: [{name: 'conflict.txt'}]},
+ {files: [{name: 'conflict2.txt'}]},
+ {files: [{name: 'noconflict.txt'}]}
+ ]
+ };
+
+ var deferred = $.Deferred();
+ conflictDialogStub.returns(deferred.promise());
+ deferred.resolve();
+
+ OC.Upload.checkExistingFiles(selection, callbacks);
+
+ expect(conflictDialogStub.callCount).toEqual(3);
+ expect(conflictDialogStub.getCall(1).args[0])
+ .toEqual({files: [ { name: 'conflict.txt' } ]});
+ expect(conflictDialogStub.getCall(1).args[1])
+ .toEqual({ name: 'conflict.txt', mimetype: 'text/plain', directory: '/' });
+ expect(conflictDialogStub.getCall(1).args[2]).toEqual({ name: 'conflict.txt' });
+
+ // yes, the dialog must be called several times...
+ expect(conflictDialogStub.getCall(2).args[0]).toEqual({
+ files: [ { name: 'conflict2.txt' } ]
+ });
+ expect(conflictDialogStub.getCall(2).args[1])
+ .toEqual({ name: 'conflict2.txt', mimetype: 'text/plain', directory: '/' });
+ expect(conflictDialogStub.getCall(2).args[2]).toEqual({ name: 'conflict2.txt' });
+
+ expect(callbacks.onNoConflicts.calledOnce).toEqual(true);
+ expect(callbacks.onNoConflicts.calledWith({
+ uploads: [
+ {files: [{name: 'noconflict.txt'}]}
+ ]
+ })).toEqual(true);
+ });
+ });
});
diff --git a/apps/files_external/l10n/fi_FI.js b/apps/files_external/l10n/fi_FI.js
index b65dad2e321..18e4db069de 100644
--- a/apps/files_external/l10n/fi_FI.js
+++ b/apps/files_external/l10n/fi_FI.js
@@ -78,6 +78,7 @@ OC.L10N.register(
"Advanced settings" : "Lisäasetukset",
"Delete" : "Poista",
"Add storage" : "Lisää tallennustila",
+ "Allow users to mount external storages" : "Salli käyttäjien liittää erillisiä tallennustiloja",
"Allow users to mount the following external storage" : "Salli käyttäjien liittää seuraavat erilliset tallennusvälineet"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_external/l10n/fi_FI.json b/apps/files_external/l10n/fi_FI.json
index edf5c7c13b1..d879826f901 100644
--- a/apps/files_external/l10n/fi_FI.json
+++ b/apps/files_external/l10n/fi_FI.json
@@ -76,6 +76,7 @@
"Advanced settings" : "Lisäasetukset",
"Delete" : "Poista",
"Add storage" : "Lisää tallennustila",
+ "Allow users to mount external storages" : "Salli käyttäjien liittää erillisiä tallennustiloja",
"Allow users to mount the following external storage" : "Salli käyttäjien liittää seuraavat erilliset tallennusvälineet"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_external/l10n/it.js b/apps/files_external/l10n/it.js
index 860429080bc..a5f8afb474b 100644
--- a/apps/files_external/l10n/it.js
+++ b/apps/files_external/l10n/it.js
@@ -101,6 +101,7 @@ OC.L10N.register(
"Advanced settings" : "Impostazioni avanzate",
"Delete" : "Elimina",
"Add storage" : "Aggiungi archiviazione",
- "Allow users to mount the following external storage" : "Consenti agli utenti di montare la seguente memoria esterna"
+ "Allow users to mount external storages" : "Consenti agli utenti di montare archiviazioni esterne",
+ "Allow users to mount the following external storage" : "Consenti agli utenti di montare la seguente archiviazione esterna"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_external/l10n/it.json b/apps/files_external/l10n/it.json
index e277e9e8604..2f6dad37d7c 100644
--- a/apps/files_external/l10n/it.json
+++ b/apps/files_external/l10n/it.json
@@ -99,6 +99,7 @@
"Advanced settings" : "Impostazioni avanzate",
"Delete" : "Elimina",
"Add storage" : "Aggiungi archiviazione",
- "Allow users to mount the following external storage" : "Consenti agli utenti di montare la seguente memoria esterna"
+ "Allow users to mount external storages" : "Consenti agli utenti di montare archiviazioni esterne",
+ "Allow users to mount the following external storage" : "Consenti agli utenti di montare la seguente archiviazione esterna"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_external/l10n/oc.js b/apps/files_external/l10n/oc.js
index 049016b595d..4771b564edb 100644
--- a/apps/files_external/l10n/oc.js
+++ b/apps/files_external/l10n/oc.js
@@ -1,25 +1,41 @@
OC.L10N.register(
"files_external",
{
+ "Fetching request tokens failed. Verify that your app key and secret are correct." : "L'obtencion dels getons de requèsta a fracassat. Verificatz que vòstra clau d'aplicacion e vòstre senhal son corrèctes.",
+ "Fetching access tokens failed. Verify that your app key and secret are correct." : "L'obtencion dels getons d'aacès a fracassat. Verificatz que vòstra clau d'aplicacion e vòstre senhal son corrèctes.",
+ "Please provide a valid app key and secret." : "Provesissètz una clau d'aplicacion e un senhal valids.",
"Step 1 failed. Exception: %s" : "L’etapa 1 a fracassat. Error : %s",
"Step 2 failed. Exception: %s" : "L’etapa 2 a fracassat. Error : %s",
"External storage" : "Emmagazinatge extèrne",
"Storage with id \"%i\" not found" : "Emmagazinatge amb l'id \"%i\" pas trobat",
+ "Invalid backend or authentication mechanism class" : "Servici o metòde d'autentificacion pas valable",
"Invalid mount point" : "Punt de montatge invalid",
+ "Objectstore forbidden" : "\"Objectstore\" interdich",
"Invalid storage backend \"%s\"" : "Servici d'emmagazinatge invalid : \"%s\"",
+ "Not permitted to use backend \"%s\"" : "Pas autorizat a utilizar lo servici \"%s\"",
+ "Not permitted to use authentication mechanism \"%s\"" : "Pas autorizat a utilizar lo mecanisme d'autentificacion \"%s\"",
+ "Unsatisfied backend parameters" : "Paramètres mancants pel servici",
+ "Unsatisfied authentication mechanism parameters" : "Paramètres mancants pel metòde d'autentificacion",
"Personal" : "Personal",
"System" : "Sistèma",
"Grant access" : "Autorizar l'accès",
"Access granted" : "Accès autorizat",
+ "Error configuring OAuth1" : "Error al moment de la configuracion d'OAuth1",
+ "Error configuring OAuth2" : "Error al moment de la configuracion d'OAuth2",
"Generate keys" : "Generar de claus",
"Error generating key pair" : "Error al moment de la generacion de las claus",
"Enable encryption" : "Activar lo chiframent",
"Enable previews" : "Activar las previsualizacions",
+ "Check for changes" : "Recercar las modificacions",
"Never" : "Pas jamai",
+ "Once every direct access" : "Un còp a cada accès dirècte",
+ "Every time the filesystem is used" : "A cada còp que lo sistèma de fichièrs es utilizat",
+ "All users. Type to select user or group." : "Totes los utilizaires. Clicatz aicí per restrénher.",
"(group)" : "(grop)",
"Saved" : "Enregistrat",
"Access key" : "Clau d'accès",
"Secret key" : "Clau secreta",
+ "Builtin" : "Integrat",
"None" : "Pas cap",
"OAuth1" : "OAuth1",
"App key" : "App key",
@@ -27,9 +43,15 @@ OC.L10N.register(
"OAuth2" : "OAuth2",
"Client ID" : "ID Client",
"Client secret" : "Secret client",
+ "OpenStack" : "OpenStack",
"Username" : "Nom d'utilizaire",
"Password" : "Senhal",
+ "Tenant name" : "Tenant name",
+ "Identity endpoint URL" : "Identity endpoint URL",
+ "Rackspace" : "Rackspace",
"API key" : "Clau API",
+ "Username and password" : "Nom d'utilizaire e senhal",
+ "Session credentials" : "Informacions d'identificacion de session",
"RSA public key" : "Clau publica RSA",
"Public key" : "Clau publica",
"Amazon S3" : "Amazon S3",
@@ -52,6 +74,7 @@ OC.L10N.register(
"Location" : "Emplaçament",
"ownCloud" : "ownCloud",
"SFTP" : "SFTP",
+ "Root" : "Raiç",
"SFTP with secret key login" : "SFTP amb un identificant secret",
"SMB / CIFS" : "SMB / CIFS",
"Share" : "Partejar",
@@ -60,6 +83,7 @@ OC.L10N.register(
"Username as share" : "Nom d'utilizaire coma nom de partiment",
"OpenStack Object Storage" : "OpenStack Object Storage",
"Service name" : "Nom del servici",
+ "Request timeout (seconds)" : "Timeout de las requèstas (en segondas)",
"<b>Note:</b> " : "<b>Atencion :</b>",
"<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Atencion :</b> La presa en carga de cURL per PHP es pas activada o installada. Lo montatge de %s es pas possible. Contactatz vòstre administrator sistèma per l'installar.",
"<b>Note:</b> The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Atencion : </b> La presa en carga del FTP per PHP es pas activada o installada. Lo montatge de %s es pas possible. Contactatz vòstre administrator sistèma per l'installar.",
@@ -77,6 +101,7 @@ OC.L10N.register(
"Advanced settings" : "Paramètres avançats",
"Delete" : "Suprimir",
"Add storage" : "Apondre un supòrt d'emmagazinatge",
+ "Allow users to mount external storages" : "Autorizar los utilizaires a montar los emmagazinatges extèrnes",
"Allow users to mount the following external storage" : "Autorizar los utilizaires a montar los emmagazinatges extèrnes seguents"
},
"nplurals=2; plural=(n > 1);");
diff --git a/apps/files_external/l10n/oc.json b/apps/files_external/l10n/oc.json
index d90aa481fdc..f89691dddde 100644
--- a/apps/files_external/l10n/oc.json
+++ b/apps/files_external/l10n/oc.json
@@ -1,23 +1,39 @@
{ "translations": {
+ "Fetching request tokens failed. Verify that your app key and secret are correct." : "L'obtencion dels getons de requèsta a fracassat. Verificatz que vòstra clau d'aplicacion e vòstre senhal son corrèctes.",
+ "Fetching access tokens failed. Verify that your app key and secret are correct." : "L'obtencion dels getons d'aacès a fracassat. Verificatz que vòstra clau d'aplicacion e vòstre senhal son corrèctes.",
+ "Please provide a valid app key and secret." : "Provesissètz una clau d'aplicacion e un senhal valids.",
"Step 1 failed. Exception: %s" : "L’etapa 1 a fracassat. Error : %s",
"Step 2 failed. Exception: %s" : "L’etapa 2 a fracassat. Error : %s",
"External storage" : "Emmagazinatge extèrne",
"Storage with id \"%i\" not found" : "Emmagazinatge amb l'id \"%i\" pas trobat",
+ "Invalid backend or authentication mechanism class" : "Servici o metòde d'autentificacion pas valable",
"Invalid mount point" : "Punt de montatge invalid",
+ "Objectstore forbidden" : "\"Objectstore\" interdich",
"Invalid storage backend \"%s\"" : "Servici d'emmagazinatge invalid : \"%s\"",
+ "Not permitted to use backend \"%s\"" : "Pas autorizat a utilizar lo servici \"%s\"",
+ "Not permitted to use authentication mechanism \"%s\"" : "Pas autorizat a utilizar lo mecanisme d'autentificacion \"%s\"",
+ "Unsatisfied backend parameters" : "Paramètres mancants pel servici",
+ "Unsatisfied authentication mechanism parameters" : "Paramètres mancants pel metòde d'autentificacion",
"Personal" : "Personal",
"System" : "Sistèma",
"Grant access" : "Autorizar l'accès",
"Access granted" : "Accès autorizat",
+ "Error configuring OAuth1" : "Error al moment de la configuracion d'OAuth1",
+ "Error configuring OAuth2" : "Error al moment de la configuracion d'OAuth2",
"Generate keys" : "Generar de claus",
"Error generating key pair" : "Error al moment de la generacion de las claus",
"Enable encryption" : "Activar lo chiframent",
"Enable previews" : "Activar las previsualizacions",
+ "Check for changes" : "Recercar las modificacions",
"Never" : "Pas jamai",
+ "Once every direct access" : "Un còp a cada accès dirècte",
+ "Every time the filesystem is used" : "A cada còp que lo sistèma de fichièrs es utilizat",
+ "All users. Type to select user or group." : "Totes los utilizaires. Clicatz aicí per restrénher.",
"(group)" : "(grop)",
"Saved" : "Enregistrat",
"Access key" : "Clau d'accès",
"Secret key" : "Clau secreta",
+ "Builtin" : "Integrat",
"None" : "Pas cap",
"OAuth1" : "OAuth1",
"App key" : "App key",
@@ -25,9 +41,15 @@
"OAuth2" : "OAuth2",
"Client ID" : "ID Client",
"Client secret" : "Secret client",
+ "OpenStack" : "OpenStack",
"Username" : "Nom d'utilizaire",
"Password" : "Senhal",
+ "Tenant name" : "Tenant name",
+ "Identity endpoint URL" : "Identity endpoint URL",
+ "Rackspace" : "Rackspace",
"API key" : "Clau API",
+ "Username and password" : "Nom d'utilizaire e senhal",
+ "Session credentials" : "Informacions d'identificacion de session",
"RSA public key" : "Clau publica RSA",
"Public key" : "Clau publica",
"Amazon S3" : "Amazon S3",
@@ -50,6 +72,7 @@
"Location" : "Emplaçament",
"ownCloud" : "ownCloud",
"SFTP" : "SFTP",
+ "Root" : "Raiç",
"SFTP with secret key login" : "SFTP amb un identificant secret",
"SMB / CIFS" : "SMB / CIFS",
"Share" : "Partejar",
@@ -58,6 +81,7 @@
"Username as share" : "Nom d'utilizaire coma nom de partiment",
"OpenStack Object Storage" : "OpenStack Object Storage",
"Service name" : "Nom del servici",
+ "Request timeout (seconds)" : "Timeout de las requèstas (en segondas)",
"<b>Note:</b> " : "<b>Atencion :</b>",
"<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Atencion :</b> La presa en carga de cURL per PHP es pas activada o installada. Lo montatge de %s es pas possible. Contactatz vòstre administrator sistèma per l'installar.",
"<b>Note:</b> The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Atencion : </b> La presa en carga del FTP per PHP es pas activada o installada. Lo montatge de %s es pas possible. Contactatz vòstre administrator sistèma per l'installar.",
@@ -75,6 +99,7 @@
"Advanced settings" : "Paramètres avançats",
"Delete" : "Suprimir",
"Add storage" : "Apondre un supòrt d'emmagazinatge",
+ "Allow users to mount external storages" : "Autorizar los utilizaires a montar los emmagazinatges extèrnes",
"Allow users to mount the following external storage" : "Autorizar los utilizaires a montar los emmagazinatges extèrnes seguents"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/apps/files_external/l10n/pt_BR.js b/apps/files_external/l10n/pt_BR.js
index 58de3eb8386..3abc6d280d9 100644
--- a/apps/files_external/l10n/pt_BR.js
+++ b/apps/files_external/l10n/pt_BR.js
@@ -101,6 +101,7 @@ OC.L10N.register(
"Advanced settings" : "Configurações avançadas",
"Delete" : "Excluir",
"Add storage" : "Adicionar Armazenamento",
+ "Allow users to mount external storages" : "Permitir que usuários possam realizar armazenamentos externos",
"Allow users to mount the following external storage" : "Permitir que usuários montem o seguinte armazenamento externo"
},
"nplurals=2; plural=(n > 1);");
diff --git a/apps/files_external/l10n/pt_BR.json b/apps/files_external/l10n/pt_BR.json
index 50aabd17abb..31f71df8be9 100644
--- a/apps/files_external/l10n/pt_BR.json
+++ b/apps/files_external/l10n/pt_BR.json
@@ -99,6 +99,7 @@
"Advanced settings" : "Configurações avançadas",
"Delete" : "Excluir",
"Add storage" : "Adicionar Armazenamento",
+ "Allow users to mount external storages" : "Permitir que usuários possam realizar armazenamentos externos",
"Allow users to mount the following external storage" : "Permitir que usuários montem o seguinte armazenamento externo"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/apps/files_external/l10n/sq.js b/apps/files_external/l10n/sq.js
index 9885f7143e0..7edf0b5e67b 100644
--- a/apps/files_external/l10n/sq.js
+++ b/apps/files_external/l10n/sq.js
@@ -99,6 +99,7 @@ OC.L10N.register(
"Advanced settings" : "Rregullime të mëtejshme",
"Delete" : "Fshije",
"Add storage" : "Shtoni depozitë",
+ "Allow users to mount external storages" : "Lejoju përdoruesve të montojnë depozita të jashtme",
"Allow users to mount the following external storage" : "Lejoju përdoruesve të montojnë depozitën e jashtme vijuese"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_external/l10n/sq.json b/apps/files_external/l10n/sq.json
index 1dbebd0fb5c..3d597974f48 100644
--- a/apps/files_external/l10n/sq.json
+++ b/apps/files_external/l10n/sq.json
@@ -97,6 +97,7 @@
"Advanced settings" : "Rregullime të mëtejshme",
"Delete" : "Fshije",
"Add storage" : "Shtoni depozitë",
+ "Allow users to mount external storages" : "Lejoju përdoruesve të montojnë depozita të jashtme",
"Allow users to mount the following external storage" : "Lejoju përdoruesve të montojnë depozitën e jashtme vijuese"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/provisioning_api/tests/userstest.php b/apps/provisioning_api/tests/userstest.php
index 673383edae6..b43041bbbf9 100644
--- a/apps/provisioning_api/tests/userstest.php
+++ b/apps/provisioning_api/tests/userstest.php
@@ -151,7 +151,20 @@ class UsersTest extends TestCase {
$this->assertInstanceOf('OC_OCS_Result', $result);
$this->assertTrue($result->succeeded());
- $this->assertEquals(['users' => array_slice($uids, 1, 2)], $result->getData());
+
+ // Disable this test for now since sorting is not done the same on all backends
+ //$this->assertEquals(['users' => array_slice($uids, 1, 2)], $result->getData());
+
+ $this->assertCount(2, $result->getData()['users']);
+
+ $counter = 0;
+ foreach ($uids as $uid) {
+ if (in_array($uid, $result->getData()['users'], true)) {
+ $counter += 1;
+ }
+ }
+
+ $this->assertEquals(2, $counter);
}
public function testGetUsersNoUser() {
diff --git a/build/integration/config/behat.yml b/build/integration/config/behat.yml
index 01ca0d18790..8b6699cb086 100644
--- a/build/integration/config/behat.yml
+++ b/build/integration/config/behat.yml
@@ -9,6 +9,7 @@ default:
admin:
- admin
- admin
+ regular_user_password: 123456
ci:
formatter:
diff --git a/build/integration/features/bootstrap/FeatureContext.php b/build/integration/features/bootstrap/FeatureContext.php
index caff517a16d..e05015301f3 100644
--- a/build/integration/features/bootstrap/FeatureContext.php
+++ b/build/integration/features/bootstrap/FeatureContext.php
@@ -34,6 +34,7 @@ class FeatureContext extends BehatContext {
// Initialize your context here
$this->baseUrl = $parameters['baseUrl'];
$this->adminUser = $parameters['admin'];
+ $this->regularUser = $parameters['regular_user_password'];
// in case of ci deployment we take the server url from the environment
$testServerUrl = getenv('TEST_SERVER_URL');
@@ -76,14 +77,32 @@ class FeatureContext extends BehatContext {
}
/**
+ * Parses the xml answer to get the array of subadmins returned.
+ */
+ public function getArrayOfSubadminsResponded($resp) {
+ $listCheckedElements = $resp->xml()->data[0]->element;
+ $extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
+ return $extractedElementsArray;
+ }
+
+ /**
+ * This function is needed to use a vertical fashion in the gherkin tables.
+ */
+ public function simplifyArray($arrayOfArrays){
+ $a = array_map(function($subArray) { return $subArray[0]; }, $arrayOfArrays);
+ return $a;
+ }
+
+ /**
* @Then /^users returned are$/
* @param \Behat\Gherkin\Node\TableNode|null $formData
*/
public function theUsersShouldBe($usersList) {
if ($usersList instanceof \Behat\Gherkin\Node\TableNode) {
- $users = $usersList->getRows()[0];
+ $users = $usersList->getRows();
+ $usersSimplified = $this->simplifyArray($users);
$respondedArray = $this->getArrayOfUsersResponded($this->response);
- PHPUnit_Framework_Assert::assertEquals(asort($users), asort($respondedArray));
+ PHPUnit_Framework_Assert::assertEquals($usersSimplified, $respondedArray, "", 0.0, 10, true);
}
}
@@ -94,14 +113,37 @@ class FeatureContext extends BehatContext {
*/
public function theGroupsShouldBe($groupsList) {
if ($groupsList instanceof \Behat\Gherkin\Node\TableNode) {
- $groups = $groupsList->getRows()[0];
+ $groups = $groupsList->getRows();
+ $groupsSimplified = $this->simplifyArray($groups);
$respondedArray = $this->getArrayOfGroupsResponded($this->response);
- PHPUnit_Framework_Assert::assertEquals(asort($groups), asort($respondedArray));
+ PHPUnit_Framework_Assert::assertEquals($groupsSimplified, $respondedArray, "", 0.0, 10, true);
}
}
/**
+ * @Then /^subadmin groups returned are$/
+ * @param \Behat\Gherkin\Node\TableNode|null $formData
+ */
+ public function theSubadminGroupsShouldBe($groupsList) {
+ if ($groupsList instanceof \Behat\Gherkin\Node\TableNode) {
+ $groups = $groupsList->getRows();
+ $groupsSimplified = $this->simplifyArray($groups);
+ $respondedArray = $this->getArrayOfSubadminsResponded($this->response);
+ PHPUnit_Framework_Assert::assertEquals($groupsSimplified, $respondedArray, "", 0.0, 10, true);
+ }
+
+ }
+
+ /**
+ * @Then /^subadmin users returned are$/
+ * @param \Behat\Gherkin\Node\TableNode|null $formData
+ */
+ public function theSubadminUsersShouldBe($groupsList) {
+ $this->theSubadminGroupsShouldBe($groupsList);
+ }
+
+ /**
* @Then /^the OCS status code should be "([^"]*)"$/
*/
public function theOCSStatusCodeShouldBe($statusCode) {
@@ -145,6 +187,82 @@ class FeatureContext extends BehatContext {
}
/**
+ * @Given /^user "([^"]*)" belongs to group "([^"]*)"$/
+ */
+ public function userBelongsToGroup($user, $group) {
+ $fullUrl = $this->baseUrl . "v2.php/cloud/users/$user/groups";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->get($fullUrl, $options);
+ $groups = array($group);
+ $respondedArray = $this->getArrayOfGroupsResponded($this->response);
+ PHPUnit_Framework_Assert::assertEquals($groups, $respondedArray, "", 0.0, 10, true);
+ PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
+ }
+
+ /**
+ * @Given /^user "([^"]*)" does not belong to group "([^"]*)"$/
+ */
+ public function userDoesNotBelongToGroup($user, $group) {
+ $fullUrl = $this->baseUrl . "v2.php/cloud/users/$user/groups";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->get($fullUrl, $options);
+ $groups = array($group);
+ $respondedArray = $this->getArrayOfGroupsResponded($this->response);
+ PHPUnit_Framework_Assert::assertNotEquals($groups, $respondedArray, "", 0.0, 10, true);
+ PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
+ }
+
+
+ /**
+ * @Given /^user "([^"]*)" is subadmin of group "([^"]*)"$/
+ */
+ public function userIsSubadminOfGroup($user, $group) {
+ $fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group/subadmins";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->get($fullUrl, $options);
+ $subadmins = array($user);
+ $respondedArray = $this->getArrayOfSubadminsResponded($this->response);
+ sort($respondedArray);
+ PHPUnit_Framework_Assert::assertContains($user, $respondedArray);
+ PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
+ }
+
+ /**
+ * @Given /^user "([^"]*)" is not a subadmin of group "([^"]*)"$/
+ */
+ public function userIsNotSubadminOfGroup($user, $group) {
+ $fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group/subadmins";
+ $client = new Client();
+ $options = [];
+ if ($this->currentUser === 'admin') {
+ $options['auth'] = $this->adminUser;
+ }
+
+ $this->response = $client->get($fullUrl, $options);
+ $subadmins = array($user);
+ $respondedArray = $this->getArrayOfSubadminsResponded($this->response);
+ sort($respondedArray);
+ PHPUnit_Framework_Assert::assertNotContains($user, $respondedArray);
+ PHPUnit_Framework_Assert::assertEquals(200, $this->response->getStatusCode());
+ }
+
+
+ /**
* @Given /^user "([^"]*)" does not exist$/
*/
public function userDoesNotExist($user) {
@@ -233,6 +351,8 @@ class FeatureContext extends BehatContext {
$options = [];
if ($this->currentUser === 'admin') {
$options['auth'] = $this->adminUser;
+ } else {
+ $options['auth'] = $this->regularUser;
}
if ($body instanceof \Behat\Gherkin\Node\TableNode) {
$fd = $body->getRowsHash();
diff --git a/build/integration/features/provisioning-v1.feature b/build/integration/features/provisioning-v1.feature
index d865ee687ed..53fd70ee999 100644
--- a/build/integration/features/provisioning-v1.feature
+++ b/build/integration/features/provisioning-v1.feature
@@ -1,106 +1,240 @@
Feature: provisioning
- Background:
- Given using api version "1"
-
- Scenario: Getting an not existing user
- Given As an "admin"
- When sending "GET" to "/cloud/users/test"
- Then the OCS status code should be "998"
- And the HTTP status code should be "200"
-
- Scenario: Listing all users
- Given As an "admin"
- When sending "GET" to "/cloud/users"
- Then the OCS status code should be "100"
- And the HTTP status code should be "200"
-
- Scenario: Create a user
- Given As an "admin"
- And user "brand-new-user" does not exist
- When sending "POST" to "/cloud/users" with
- | userid | brand-new-user |
- | password | 123456 |
- Then the OCS status code should be "100"
- And the HTTP status code should be "200"
- And user "brand-new-user" exists
-
- Scenario: Create an existing user
- Given As an "admin"
- And user "brand-new-user" exists
- When sending "POST" to "/cloud/users" with
- | userid | brand-new-user |
- | password | 123456 |
- Then the OCS status code should be "102"
- And the HTTP status code should be "200"
-
- Scenario: Get an existing user
- Given As an "admin"
- When sending "GET" to "/cloud/users/brand-new-user"
- Then the OCS status code should be "100"
- And the HTTP status code should be "200"
-
-
- Scenario: Getting all users
- Given As an "admin"
- And user "brand-new-user" exists
- And user "admin" exists
- When sending "GET" to "/cloud/users"
- And users returned are
- | brand-new-user |
- | admin |
-
-
- Scenario: Edit a user
- Given As an "admin"
- And user "brand-new-user" exists
- When sending "PUT" to "/cloud/users/brand-new-user" with
- | key | quota |
- | value | 12MB |
- | key | email |
- | value | brand-new-user@gmail.com |
- Then the OCS status code should be "100"
- And the HTTP status code should be "200"
- And user "brand-new-user" exists
-
-
- Scenario: Delete a user
- Given As an "admin"
- And user "brand-new-user" exists
- When sending "DELETE" to "/cloud/users/brand-new-user"
- Then the OCS status code should be "100"
- And the HTTP status code should be "200"
- And user "brand-new-user" does not exist
-
-
- Scenario: Create a group
- Given As an "admin"
- And group "new-group" does not exist
- When sending "POST" to "/cloud/groups" with
- | groupid | new-group |
- | password | 123456 |
-
- Then the OCS status code should be "100"
- And the HTTP status code should be "200"
- And group "new-group" exists
-
-
- Scenario: Getting all groups
- Given As an "admin"
- And group "new-group" exists
- And group "admin" exists
- When sending "GET" to "/cloud/groups"
- And groups returned are
- | admin |
- | new-group |
-
-
- Scenario: Delete a group
- Given As an "admin"
- And group "new-group" exists
- When sending "DELETE" to "/cloud/groups/new-group"
- Then the OCS status code should be "100"
- And the HTTP status code should be "200"
- And group "new-group" does not exist
+ Background:
+ Given using api version "1"
+
+ Scenario: Getting an not existing user
+ Given As an "admin"
+ When sending "GET" to "/cloud/users/test"
+ Then the OCS status code should be "998"
+ And the HTTP status code should be "200"
+
+ Scenario: Listing all users
+ Given As an "admin"
+ When sending "GET" to "/cloud/users"
+ Then the OCS status code should be "100"
+ And the HTTP status code should be "200"
+
+ Scenario: Create a user
+ Given As an "admin"
+ And user "brand-new-user" does not exist
+ When sending "POST" to "/cloud/users" with
+ | userid | brand-new-user |
+ | password | 123456 |
+ Then the OCS status code should be "100"
+ And the HTTP status code should be "200"
+ And user "brand-new-user" exists
+
+ Scenario: Create an existing user
+ Given As an "admin"
+ And user "brand-new-user" exists
+ When sending "POST" to "/cloud/users" with
+ | userid | brand-new-user |
+ | password | 123456 |
+ Then the OCS status code should be "102"
+ And the HTTP status code should be "200"
+
+ Scenario: Get an existing user
+ Given As an "admin"
+ When sending "GET" to "/cloud/users/brand-new-user"
+ Then the OCS status code should be "100"
+ And the HTTP status code should be "200"
+
+ Scenario: Getting all users
+ Given As an "admin"
+ And user "brand-new-user" exists
+ And user "admin" exists
+ When sending "GET" to "/cloud/users"
+ Then users returned are
+ | brand-new-user |
+ | admin |
+
+ Scenario: Edit a user
+ Given As an "admin"
+ And user "brand-new-user" exists
+ When sending "PUT" to "/cloud/users/brand-new-user" with
+ | key | quota |
+ | value | 12MB |
+ | key | email |
+ | value | brand-new-user@gmail.com |
+ Then the OCS status code should be "100"
+ And the HTTP status code should be "200"
+ And user "brand-new-user" exists
+
+ Scenario: Create a group
+ Given As an "admin"
+ And group "new-group" does not exist
+ When sending "POST" to "/cloud/groups" with
+ | groupid | new-group |
+ | password | 123456 |
+ Then the OCS status code should be "100"
+ And the HTTP status code should be "200"
+ And group "new-group" exists
+
+ Scenario: adding user to a group without sending the group
+ Given As an "admin"
+ And user "brand-new-user" exists
+ When sending "POST" to "/cloud/users/brand-new-user/groups" with
+ | groupid | |
+ Then the OCS status code should be "101"
+ And the HTTP status code should be "200"
+
+ Scenario: adding user to a group which doesn't exist
+ Given As an "admin"
+ And user "brand-new-user" exists
+ And group "not-group" does not exist
+ When sending "POST" to "/cloud/users/brand-new-user/groups" with
+ | groupid | not-group |
+ Then the OCS status code should be "102"
+ And the HTTP status code should be "200"
+
+ Scenario: adding user to a group without privileges
+ Given As an "brand-new-user"
+ When sending "POST" to "/cloud/users/brand-new-user/groups" with
+ | groupid | new-group |
+ Then the OCS status code should be "997"
+ And the HTTP status code should be "401"
+
+ Scenario: adding user to a group
+ Given As an "admin"
+ And user "brand-new-user" exists
+ And group "new-group" exists
+ When sending "POST" to "/cloud/users/brand-new-user/groups" with
+ | groupid | new-group |
+ Then the OCS status code should be "100"
+ And the HTTP status code should be "200"
+
+ Scenario: getting groups of an user
+ Given As an "admin"
+ And user "brand-new-user" exists
+ And group "new-group" exists
+ When sending "GET" to "/cloud/users/brand-new-user/groups"
+ Then groups returned are
+ | new-group |
+ And the OCS status code should be "100"
+
+ Scenario: removing a user from a group
+ Given As an "admin"
+ And user "brand-new-user" exists
+ And group "new-group" exists
+ And user "brand-new-user" belongs to group "new-group"
+ When sending "DELETE" to "/cloud/users/brand-new-user/groups" with
+ | groupid | new-group |
+ Then the OCS status code should be "100"
+ And user "brand-new-user" does not belong to group "new-group"
+
+ Scenario: adding a user which doesn't exist to a group
+ Given As an "admin"
+ And user "not-user" does not exist
+ And group "new-group" exists
+ When sending "POST" to "/cloud/users/not-user/groups" with
+ | groupid | new-group |
+ Then the OCS status code should be "103"
+ And the HTTP status code should be "200"
+
+ Scenario: getting a group
+ Given As an "admin"
+ And group "new-group" exists
+ When sending "GET" to "/cloud/groups/new-group"
+ Then the OCS status code should be "100"
+ And the HTTP status code should be "200"
+
+ Scenario: Getting all groups
+ Given As an "admin"
+ And group "new-group" exists
+ And group "admin" exists
+ When sending "GET" to "/cloud/groups"
+ Then groups returned are
+ | admin |
+ | new-group |
+
+ Scenario: create a subadmin
+ Given As an "admin"
+ And user "brand-new-user" exists
+ And group "new-group" exists
+ When sending "POST" to "/cloud/users/brand-new-user/subadmins" with
+ | groupid | new-group |
+ Then the OCS status code should be "100"
+ And the HTTP status code should be "200"
+
+ Scenario: create a subadmin using a user which not exist
+ Given As an "admin"
+ And user "not-user" does not exist
+ And group "new-group" exists
+ When sending "POST" to "/cloud/users/not-user/subadmins" with
+ | groupid | new-group |
+ Then the OCS status code should be "101"
+ And the HTTP status code should be "200"
+
+ Scenario: create a subadmin using a group which not exist
+ Given As an "admin"
+ And user "brand-new-user" exists
+ And group "not-group" does not exist
+ When sending "POST" to "/cloud/users/brand-new-user/subadmins" with
+ | groupid | not-group |
+ Then the OCS status code should be "102"
+ And the HTTP status code should be "200"
+
+ Scenario: Getting subadmin groups
+ Given As an "admin"
+ And user "brand-new-user" exists
+ And group "new-group" exists
+ When sending "GET" to "/cloud/users/brand-new-user/subadmins"
+ Then subadmin groups returned are
+ | new-group |
+ Then the OCS status code should be "100"
+ And the HTTP status code should be "200"
+
+ Scenario: Getting subadmin groups of a user which not exist
+ Given As an "admin"
+ And user "not-user" does not exist
+ And group "new-group" exists
+ When sending "GET" to "/cloud/users/not-user/subadmins"
+ Then the OCS status code should be "101"
+ And the HTTP status code should be "200"
+
+ Scenario: Getting subadmin users of a group
+ Given As an "admin"
+ And user "brand-new-user" exists
+ And group "new-group" exists
+ When sending "GET" to "/cloud/groups/new-group/subadmins"
+ Then subadmin users returned are
+ | brand-new-user |
+ And the OCS status code should be "100"
+ And the HTTP status code should be "200"
+
+ Scenario: Getting subadmin users of a group which doesn't exist
+ Given As an "admin"
+ And user "brand-new-user" exists
+ And group "not-group" does not exist
+ When sending "GET" to "/cloud/groups/not-group/subadmins"
+ Then the OCS status code should be "101"
+ And the HTTP status code should be "200"
+
+ Scenario: Removing subadmin from a group
+ Given As an "admin"
+ And user "brand-new-user" exists
+ And group "new-group" exists
+ And user "brand-new-user" is subadmin of group "new-group"
+ When sending "DELETE" to "/cloud/users/brand-new-user/subadmins" with
+ | groupid | new-group |
+ And the OCS status code should be "100"
+ And the HTTP status code should be "200"
+
+ Scenario: Delete a user
+ Given As an "admin"
+ And user "brand-new-user" exists
+ When sending "DELETE" to "/cloud/users/brand-new-user"
+ Then the OCS status code should be "100"
+ And the HTTP status code should be "200"
+ And user "brand-new-user" does not exist
+
+ Scenario: Delete a group
+ Given As an "admin"
+ And group "new-group" exists
+ When sending "DELETE" to "/cloud/groups/new-group"
+ Then the OCS status code should be "100"
+ And the HTTP status code should be "200"
+ And group "new-group" does not exist
diff --git a/core/ajax/update.php b/core/ajax/update.php
index 11d159f15d1..42f7f14bbdd 100644
--- a/core/ajax/update.php
+++ b/core/ajax/update.php
@@ -68,12 +68,24 @@ if (OC::checkUpgrade(false)) {
$updater->listen('\OC\Updater', 'maintenanceActive', function () use ($eventSource, $l) {
$eventSource->send('success', (string)$l->t('Maintenance mode is kept active'));
});
+ $updater->listen('\OC\Updater', 'dbUpgradeBefore', function () use($eventSource, $l) {
+ $eventSource->send('success', (string)$l->t('Updating database schema'));
+ });
$updater->listen('\OC\Updater', 'dbUpgrade', function () use ($eventSource, $l) {
$eventSource->send('success', (string)$l->t('Updated database'));
});
+ $updater->listen('\OC\Updater', 'dbSimulateUpgradeBefore', function () use($eventSource, $l) {
+ $eventSource->send('success', (string)$l->t('Checking whether the database schema can be updated (this can take a long time depending on the database size)'));
+ });
$updater->listen('\OC\Updater', 'dbSimulateUpgrade', function () use ($eventSource, $l) {
$eventSource->send('success', (string)$l->t('Checked database schema update'));
});
+ $updater->listen('\OC\Updater', 'appUpgradeCheckBefore', function () use ($eventSource, $l) {
+ $eventSource->send('success', (string)$l->t('Checking updates of apps'));
+ });
+ $updater->listen('\OC\Updater', 'appSimulateUpdate', function ($app) use ($eventSource, $l) {
+ $eventSource->send('success', (string)$l->t('Checking whether the database schema for %s can be updated (this can take a long time depending on the database size)', [$app]));
+ });
$updater->listen('\OC\Updater', 'appUpgradeCheck', function () use ($eventSource, $l) {
$eventSource->send('success', (string)$l->t('Checked database schema update for apps'));
});
@@ -112,15 +124,18 @@ if (OC::checkUpgrade(false)) {
exit();
}
- if (!empty($incompatibleApps)) {
- $eventSource->send('notice',
- (string)$l->t('Following incompatible apps have been disabled: %s', implode(', ', $incompatibleApps)));
+ $disabledApps = [];
+ foreach ($disabledThirdPartyApps as $app) {
+ $disabledApps[$app] = (string) $l->t('%s (3rdparty)', [$app]);
}
- if (!empty($disabledThirdPartyApps)) {
- $eventSource->send('notice',
- (string)$l->t('Following apps have been disabled: %s', implode(', ', $disabledThirdPartyApps)));
+ foreach ($incompatibleApps as $app) {
+ $disabledApps[$app] = (string) $l->t('%s (incompatible)', [$app]);
}
+ if (!empty($disabledApps)) {
+ $eventSource->send('notice',
+ (string)$l->t('Following apps have been disabled: %s', implode(', ', $disabledApps)));
+ }
} else {
$eventSource->send('notice', (string)$l->t('Already up to date'));
}
diff --git a/core/command/upgrade.php b/core/command/upgrade.php
index 5d4819f6baf..9c313f83e14 100644
--- a/core/command/upgrade.php
+++ b/core/command/upgrade.php
@@ -155,9 +155,15 @@ class Upgrade extends Command {
}
$output->writeln($message);
});
+ $updater->listen('\OC\Updater', 'dbUpgradeBefore', function () use($output) {
+ $output->writeln('<info>Updating database schema</info>');
+ });
$updater->listen('\OC\Updater', 'dbUpgrade', function () use($output) {
$output->writeln('<info>Updated database</info>');
});
+ $updater->listen('\OC\Updater', 'dbSimulateUpgradeBefore', function () use($output) {
+ $output->writeln('<info>Checking whether the database schema can be updated (this can take a long time depending on the database size)</info>');
+ });
$updater->listen('\OC\Updater', 'dbSimulateUpgrade', function () use($output) {
$output->writeln('<info>Checked database schema update</info>');
});
@@ -176,6 +182,12 @@ class Upgrade extends Command {
$updater->listen('\OC\Updater', 'repairError', function ($app) use($output) {
$output->writeln('<error>Repair error: ' . $app . '</error>');
});
+ $updater->listen('\OC\Updater', 'appUpgradeCheckBefore', function () use ($output) {
+ $output->writeln('<info>Checking updates of apps</info>');
+ });
+ $updater->listen('\OC\Updater', 'appSimulateUpdate', function ($app) use ($output) {
+ $output->writeln("<info>Checking whether the database schema for <$app> can be updated (this can take a long time depending on the database size)</info>");
+ });
$updater->listen('\OC\Updater', 'appUpgradeCheck', function () use ($output) {
$output->writeln('<info>Checked database schema update for apps</info>');
});
diff --git a/core/js/js.js b/core/js/js.js
index 00a775b8027..9daca1f8469 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -1275,23 +1275,7 @@ function initCore() {
SVGSupport.checkMimeType();
}
- // user menu
- $('#settings #expand').keydown(function(event) {
- if (event.which === 13 || event.which === 32) {
- $('#expand').click();
- }
- });
- $('#settings #expand').click(function(event) {
- $('#settings #expanddiv').slideToggle(OC.menuSpeed);
- event.stopPropagation();
- });
- $('#settings #expanddiv').click(function(event){
- event.stopPropagation();
- });
- //hide the user menu when clicking outside it
- $(document).click(function(){
- $('#settings #expanddiv').slideUp(OC.menuSpeed);
- });
+ OC.registerMenu($('#expand'), $('#expanddiv'));
// toggle for menus
$(document).on('mouseup.closemenus', function(event) {
@@ -1304,7 +1288,6 @@ function initCore() {
OC.hideMenus();
});
-
/**
* Set up the main menu toggle to react to media query changes.
* If the screen is small enough, the main menu becomes a toggle.
@@ -1633,6 +1616,15 @@ OC.Util = {
},
/**
+ * Returns whether this is IE
+ *
+ * @return {bool} true if this is IE, false otherwise
+ */
+ isIE: function() {
+ return $('html').hasClass('ie');
+ },
+
+ /**
* Returns whether this is IE8
*
* @return {bool} true if this is IE8, false otherwise
diff --git a/core/js/tests/specs/sharedialogviewSpec.js b/core/js/tests/specs/sharedialogviewSpec.js
index 55aa0541bd0..0117f517d4c 100644
--- a/core/js/tests/specs/sharedialogviewSpec.js
+++ b/core/js/tests/specs/sharedialogviewSpec.js
@@ -676,5 +676,83 @@ describe('OC.Share.ShareDialogView', function() {
});
});
});
+ describe('remote sharing', function() {
+ it('shows remote share info when allows', function() {
+ configModel.set({
+ isRemoteShareAllowed: true
+ });
+ dialog.render();
+ expect(dialog.$el.find('.shareWithRemoteInfo').length).toEqual(1);
+ });
+ it('does not show remote share info when not allowed', function() {
+ configModel.set({
+ isRemoteShareAllowed: false
+ });
+ dialog.render();
+ expect(dialog.$el.find('.shareWithRemoteInfo').length).toEqual(0);
+ });
+ });
+ describe('autocompeltion of users', function() {
+ it('triggers autocomplete display and focus with data when ajax search succeeds', function () {
+ dialog.render();
+ var response = sinon.stub();
+ dialog.autocompleteHandler({term: 'bob'}, response);
+ var jsonData = JSON.stringify({
+ "data": [{"label": "bob", "value": {"shareType": 0, "shareWith": "test"}}],
+ "status": "success"
+ });
+ fakeServer.requests[0].respond(
+ 200,
+ {'Content-Type': 'application/json'},
+ jsonData
+ );
+ expect(response.calledWithExactly(JSON.parse(jsonData).data)).toEqual(true);
+ expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true);
+ });
+
+ it('gracefully handles successful ajax call with failure content', function () {
+ dialog.render();
+ var response = sinon.stub();
+ dialog.autocompleteHandler({term: 'bob'}, response);
+ var jsonData = JSON.stringify({"status": "failure"});
+ fakeServer.requests[0].respond(
+ 200,
+ {'Content-Type': 'application/json'},
+ jsonData
+ );
+ expect(response.calledWithExactly()).toEqual(true);
+ });
+
+ it('throws a notification when the ajax search lookup fails', function () {
+ notificationStub = sinon.stub(OC.Notification, 'show');
+ dialog.render();
+ dialog.autocompleteHandler({term: 'bob'}, sinon.stub());
+ fakeServer.requests[0].respond(500);
+ expect(notificationStub.calledOnce).toEqual(true);
+ notificationStub.restore();
+ });
+
+ describe('renders the autocomplete elements', function() {
+ it('renders a group element', function() {
+ dialog.render();
+ var el = dialog.autocompleteRenderItem(
+ $("<ul></ul>"),
+ {label: "1", value: { shareType: OC.Share.SHARE_TYPE_GROUP }}
+ );
+ expect(el.is('li')).toEqual(true);
+ expect(el.hasClass('group')).toEqual(true);
+ });
+
+ it('renders a remote element', function() {
+ dialog.render();
+ var el = dialog.autocompleteRenderItem(
+ $("<ul></ul>"),
+ {label: "1", value: { shareType: OC.Share.SHARE_TYPE_REMOTE }}
+ );
+ expect(el.is('li')).toEqual(true);
+ expect(el.hasClass('user')).toEqual(true);
+ });
+ });
+ });
});
diff --git a/core/l10n/bg_BG.js b/core/l10n/bg_BG.js
index f8d2e44204a..47af1b28d94 100644
--- a/core/l10n/bg_BG.js
+++ b/core/l10n/bg_BG.js
@@ -10,7 +10,6 @@ OC.L10N.register(
"Updated \"%s\" to %s" : "Обновен \"%s\" до %s",
"Repair warning: " : "Предупреждение при поправка:",
"Repair error: " : "Грешка при поправка:",
- "Following incompatible apps have been disabled: %s" : "Следните несъвместими приложения бяха изключени: %s",
"Invalid file provided" : "Предоставен е невалиден файл",
"No image or file provided" : "Не бяха доставени картинка или файл",
"Unknown filetype" : "Непознат файлов тип",
diff --git a/core/l10n/bg_BG.json b/core/l10n/bg_BG.json
index 4709830c087..43b5d5dbe21 100644
--- a/core/l10n/bg_BG.json
+++ b/core/l10n/bg_BG.json
@@ -8,7 +8,6 @@
"Updated \"%s\" to %s" : "Обновен \"%s\" до %s",
"Repair warning: " : "Предупреждение при поправка:",
"Repair error: " : "Грешка при поправка:",
- "Following incompatible apps have been disabled: %s" : "Следните несъвместими приложения бяха изключени: %s",
"Invalid file provided" : "Предоставен е невалиден файл",
"No image or file provided" : "Не бяха доставени картинка или файл",
"Unknown filetype" : "Непознат файлов тип",
diff --git a/core/l10n/ca.js b/core/l10n/ca.js
index 9d397d03408..b32aac7cf1d 100644
--- a/core/l10n/ca.js
+++ b/core/l10n/ca.js
@@ -12,7 +12,6 @@ OC.L10N.register(
"Updated \"%s\" to %s" : "Actualitzat \"%s\" a %s",
"Repair warning: " : "Advertiment de reparació:",
"Repair error: " : "Error de reparació:",
- "Following incompatible apps have been disabled: %s" : "Les següents apps incompatibles s'han deshabilitat: %s",
"Following apps have been disabled: %s" : "Les aplicacions següents s'han deshabilitat: %s",
"Already up to date" : "Ja actualitzat",
"File is too big" : "El fitxer és massa gran",
diff --git a/core/l10n/ca.json b/core/l10n/ca.json
index 52de7a322b4..04a0e7232d9 100644
--- a/core/l10n/ca.json
+++ b/core/l10n/ca.json
@@ -10,7 +10,6 @@
"Updated \"%s\" to %s" : "Actualitzat \"%s\" a %s",
"Repair warning: " : "Advertiment de reparació:",
"Repair error: " : "Error de reparació:",
- "Following incompatible apps have been disabled: %s" : "Les següents apps incompatibles s'han deshabilitat: %s",
"Following apps have been disabled: %s" : "Les aplicacions següents s'han deshabilitat: %s",
"Already up to date" : "Ja actualitzat",
"File is too big" : "El fitxer és massa gran",
diff --git a/core/l10n/cs_CZ.js b/core/l10n/cs_CZ.js
index f48b1f54d2b..047023401d7 100644
--- a/core/l10n/cs_CZ.js
+++ b/core/l10n/cs_CZ.js
@@ -15,7 +15,6 @@ OC.L10N.register(
"Repair error: " : "Chyba opravy:",
"Set log level to debug - current level: \"%s\"" : "Nastavit úroveň logování na debug - aktuální úroveň: \"%s\"",
"Reset log level to \"%s\"" : "Vrátit úroveň logování na \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Následující nekompatibilní aplikace byly zakázány: %s",
"Following apps have been disabled: %s" : "Následující aplikace byly vypnuty: %s",
"Already up to date" : "Je již aktuální",
"File is too big" : "Soubor je příliš velký",
diff --git a/core/l10n/cs_CZ.json b/core/l10n/cs_CZ.json
index e83942a8922..aa0228f8568 100644
--- a/core/l10n/cs_CZ.json
+++ b/core/l10n/cs_CZ.json
@@ -13,7 +13,6 @@
"Repair error: " : "Chyba opravy:",
"Set log level to debug - current level: \"%s\"" : "Nastavit úroveň logování na debug - aktuální úroveň: \"%s\"",
"Reset log level to \"%s\"" : "Vrátit úroveň logování na \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Následující nekompatibilní aplikace byly zakázány: %s",
"Following apps have been disabled: %s" : "Následující aplikace byly vypnuty: %s",
"Already up to date" : "Je již aktuální",
"File is too big" : "Soubor je příliš velký",
diff --git a/core/l10n/da.js b/core/l10n/da.js
index 3d90b55836c..3eef4d31c1e 100644
--- a/core/l10n/da.js
+++ b/core/l10n/da.js
@@ -14,7 +14,6 @@ OC.L10N.register(
"Repair error: " : "Reparationsfejl:",
"Set log level to debug - current level: \"%s\"" : "Sæt log niveau til fejlfinding - nuværende niveau: \"%s\"",
"Reset log level to \"%s\"" : "Nulstil log niveau til \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Følgende inkompatible apps er blevet deaktiveret: %s",
"Following apps have been disabled: %s" : "Følgende apps er blevet deaktiveret: %s",
"Already up to date" : "Allerede opdateret",
"File is too big" : "Filen er for stor",
diff --git a/core/l10n/da.json b/core/l10n/da.json
index 53182aeab70..a5e0912e774 100644
--- a/core/l10n/da.json
+++ b/core/l10n/da.json
@@ -12,7 +12,6 @@
"Repair error: " : "Reparationsfejl:",
"Set log level to debug - current level: \"%s\"" : "Sæt log niveau til fejlfinding - nuværende niveau: \"%s\"",
"Reset log level to \"%s\"" : "Nulstil log niveau til \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Følgende inkompatible apps er blevet deaktiveret: %s",
"Following apps have been disabled: %s" : "Følgende apps er blevet deaktiveret: %s",
"Already up to date" : "Allerede opdateret",
"File is too big" : "Filen er for stor",
diff --git a/core/l10n/de.js b/core/l10n/de.js
index ff0176b6d94..07f436c8510 100644
--- a/core/l10n/de.js
+++ b/core/l10n/de.js
@@ -15,7 +15,6 @@ OC.L10N.register(
"Repair error: " : "Reperaturfehler:",
"Set log level to debug - current level: \"%s\"" : "Log-Level auf Debug gesetzt - aktuelles Level: \"%s\"",
"Reset log level to \"%s\"" : "Log-Level auf \"%s\" zurückgesetzt",
- "Following incompatible apps have been disabled: %s" : "Die folgenden inkompatiblen Apps sind deaktiviert worden: %s",
"Following apps have been disabled: %s" : "Die folgenden Apps sind deaktiviert worden: %s",
"Already up to date" : "Bereits aktuell",
"File is too big" : "Datei ist zu groß",
diff --git a/core/l10n/de.json b/core/l10n/de.json
index 94df2d559fc..be36f78d567 100644
--- a/core/l10n/de.json
+++ b/core/l10n/de.json
@@ -13,7 +13,6 @@
"Repair error: " : "Reperaturfehler:",
"Set log level to debug - current level: \"%s\"" : "Log-Level auf Debug gesetzt - aktuelles Level: \"%s\"",
"Reset log level to \"%s\"" : "Log-Level auf \"%s\" zurückgesetzt",
- "Following incompatible apps have been disabled: %s" : "Die folgenden inkompatiblen Apps sind deaktiviert worden: %s",
"Following apps have been disabled: %s" : "Die folgenden Apps sind deaktiviert worden: %s",
"Already up to date" : "Bereits aktuell",
"File is too big" : "Datei ist zu groß",
diff --git a/core/l10n/de_DE.js b/core/l10n/de_DE.js
index b593fc452ae..2980331c651 100644
--- a/core/l10n/de_DE.js
+++ b/core/l10n/de_DE.js
@@ -15,7 +15,6 @@ OC.L10N.register(
"Repair error: " : "Reperaturfehler:",
"Set log level to debug - current level: \"%s\"" : "Log-Level auf Debug gesetzt - aktuelles Level: \"%s\"",
"Reset log level to \"%s\"" : "Log-Level auf \"%s\" zurückgesetzt",
- "Following incompatible apps have been disabled: %s" : "Die folgenden inkompatiblen Apps sind deaktiviert worden: %s",
"Following apps have been disabled: %s" : "Die folgenden Apps sind deaktiviert worden: %s",
"Already up to date" : "Bereits aktuell",
"File is too big" : "Datei ist zu groß",
diff --git a/core/l10n/de_DE.json b/core/l10n/de_DE.json
index c7fa1e368a9..68ab793889e 100644
--- a/core/l10n/de_DE.json
+++ b/core/l10n/de_DE.json
@@ -13,7 +13,6 @@
"Repair error: " : "Reperaturfehler:",
"Set log level to debug - current level: \"%s\"" : "Log-Level auf Debug gesetzt - aktuelles Level: \"%s\"",
"Reset log level to \"%s\"" : "Log-Level auf \"%s\" zurückgesetzt",
- "Following incompatible apps have been disabled: %s" : "Die folgenden inkompatiblen Apps sind deaktiviert worden: %s",
"Following apps have been disabled: %s" : "Die folgenden Apps sind deaktiviert worden: %s",
"Already up to date" : "Bereits aktuell",
"File is too big" : "Datei ist zu groß",
diff --git a/core/l10n/el.js b/core/l10n/el.js
index 975f3895b46..e6e798db3eb 100644
--- a/core/l10n/el.js
+++ b/core/l10n/el.js
@@ -15,7 +15,6 @@ OC.L10N.register(
"Repair error: " : "Σφάλμα διόρθωσης:",
"Set log level to debug - current level: \"%s\"" : "Καθορισμός του επιπέδου καταγραφής σε αποσφαλμάτωση - τρέχον επίπεδο: \"%s\"",
"Reset log level to \"%s\"" : "Επαναφορά επιπέδου καταγραφής σε \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Οι παρακάτω εφαρμογές έχουν απενεργοποιηθεί: %s",
"Following apps have been disabled: %s" : "Οι ακόλουθες εφαρμογές έχουν απενεργοποιηθεί: %s",
"Already up to date" : "Ήδη ενημερωμένο",
"File is too big" : "Το αρχείο είναι πολύ μεγάλο",
diff --git a/core/l10n/el.json b/core/l10n/el.json
index 21901440ecc..5e398ac086a 100644
--- a/core/l10n/el.json
+++ b/core/l10n/el.json
@@ -13,7 +13,6 @@
"Repair error: " : "Σφάλμα διόρθωσης:",
"Set log level to debug - current level: \"%s\"" : "Καθορισμός του επιπέδου καταγραφής σε αποσφαλμάτωση - τρέχον επίπεδο: \"%s\"",
"Reset log level to \"%s\"" : "Επαναφορά επιπέδου καταγραφής σε \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Οι παρακάτω εφαρμογές έχουν απενεργοποιηθεί: %s",
"Following apps have been disabled: %s" : "Οι ακόλουθες εφαρμογές έχουν απενεργοποιηθεί: %s",
"Already up to date" : "Ήδη ενημερωμένο",
"File is too big" : "Το αρχείο είναι πολύ μεγάλο",
diff --git a/core/l10n/en_GB.js b/core/l10n/en_GB.js
index d2f3ce77c73..b669829f061 100644
--- a/core/l10n/en_GB.js
+++ b/core/l10n/en_GB.js
@@ -10,7 +10,6 @@ OC.L10N.register(
"Updated \"%s\" to %s" : "Updated \"%s\" to %s",
"Repair warning: " : "Repair warning: ",
"Repair error: " : "Repair error: ",
- "Following incompatible apps have been disabled: %s" : "Following incompatible apps have been disabled: %s",
"Invalid file provided" : "Invalid file provided",
"No image or file provided" : "No image or file provided",
"Unknown filetype" : "Unknown filetype",
diff --git a/core/l10n/en_GB.json b/core/l10n/en_GB.json
index 75e8e30d594..5514abe5c44 100644
--- a/core/l10n/en_GB.json
+++ b/core/l10n/en_GB.json
@@ -8,7 +8,6 @@
"Updated \"%s\" to %s" : "Updated \"%s\" to %s",
"Repair warning: " : "Repair warning: ",
"Repair error: " : "Repair error: ",
- "Following incompatible apps have been disabled: %s" : "Following incompatible apps have been disabled: %s",
"Invalid file provided" : "Invalid file provided",
"No image or file provided" : "No image or file provided",
"Unknown filetype" : "Unknown filetype",
diff --git a/core/l10n/es.js b/core/l10n/es.js
index 4ee9dac0760..a9ee8ede55e 100644
--- a/core/l10n/es.js
+++ b/core/l10n/es.js
@@ -15,7 +15,6 @@ OC.L10N.register(
"Repair error: " : "Error que reparar:",
"Set log level to debug - current level: \"%s\"" : "Establecer nivel de registro para depurar - nivel actual: \"%s\"",
"Reset log level to \"%s\"" : "Restablecer nivel de registro a \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Las siguientes apps incompatibles se han deshabilitado: %s",
"Following apps have been disabled: %s" : "Siguiendo aplicaciones ha sido deshabilitado: %s",
"Already up to date" : "Ya actualizado",
"File is too big" : "El archivo es demasiado grande",
diff --git a/core/l10n/es.json b/core/l10n/es.json
index 8a598d505e5..ccd38613554 100644
--- a/core/l10n/es.json
+++ b/core/l10n/es.json
@@ -13,7 +13,6 @@
"Repair error: " : "Error que reparar:",
"Set log level to debug - current level: \"%s\"" : "Establecer nivel de registro para depurar - nivel actual: \"%s\"",
"Reset log level to \"%s\"" : "Restablecer nivel de registro a \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Las siguientes apps incompatibles se han deshabilitado: %s",
"Following apps have been disabled: %s" : "Siguiendo aplicaciones ha sido deshabilitado: %s",
"Already up to date" : "Ya actualizado",
"File is too big" : "El archivo es demasiado grande",
diff --git a/core/l10n/et_EE.js b/core/l10n/et_EE.js
index a55e1c04ccd..48fc8219653 100644
--- a/core/l10n/et_EE.js
+++ b/core/l10n/et_EE.js
@@ -11,7 +11,6 @@ OC.L10N.register(
"Updated \"%s\" to %s" : "Uuendatud \"%s\" -> %s",
"Repair warning: " : "Paranda hoiatus:",
"Repair error: " : "Paranda viga:",
- "Following incompatible apps have been disabled: %s" : "Järgnevad mitteühilduvad rakendused on välja lülitatud: %s",
"Following apps have been disabled: %s" : "Järgnevad rakendused on välja lülitatud: %s",
"Already up to date" : "On juba ajakohane",
"File is too big" : "Fail on liiga suur",
diff --git a/core/l10n/et_EE.json b/core/l10n/et_EE.json
index ee32aba5690..0c56d74d091 100644
--- a/core/l10n/et_EE.json
+++ b/core/l10n/et_EE.json
@@ -9,7 +9,6 @@
"Updated \"%s\" to %s" : "Uuendatud \"%s\" -> %s",
"Repair warning: " : "Paranda hoiatus:",
"Repair error: " : "Paranda viga:",
- "Following incompatible apps have been disabled: %s" : "Järgnevad mitteühilduvad rakendused on välja lülitatud: %s",
"Following apps have been disabled: %s" : "Järgnevad rakendused on välja lülitatud: %s",
"Already up to date" : "On juba ajakohane",
"File is too big" : "Fail on liiga suur",
diff --git a/core/l10n/fi_FI.js b/core/l10n/fi_FI.js
index c0f89d5899d..206c6d2632a 100644
--- a/core/l10n/fi_FI.js
+++ b/core/l10n/fi_FI.js
@@ -15,7 +15,6 @@ OC.L10N.register(
"Repair error: " : "Korjausvirhe:",
"Set log level to debug - current level: \"%s\"" : "Aseta lokitasoksi vianjäljitys - nykyinen taso: \"%s\"",
"Reset log level to \"%s\"" : "Palauta lokitasoksi \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Seuraavat yhteensopimattomat sovellukset on poistettu käytöstä: %s",
"Following apps have been disabled: %s" : "Seuraavat sovellukset on poistettu käytöstä: %s",
"Already up to date" : "Kaikki on jo ajan tasalla",
"File is too big" : "Tiedosto on liian suuri",
@@ -173,6 +172,7 @@ OC.L10N.register(
"Hello {name}" : "Hei {name}",
"_download %n file_::_download %n files_" : ["lataa %n tiedosto","lataa %n tiedostoa"],
"{version} is available. Get more information on how to update." : "{version} on saatavilla. Tarjolla on lisätietoja päivittämisestä.",
+ "The upgrade is in progress, leaving this page might interrupt the process in some environments." : "Päivitys on meneillään. Poistuminen tältä sivulta saattaa keskeyttää toimenpiteen joissain käyttöympäristöissä.",
"Updating {productName} to version {version}, this may take a while." : "Päivitetään {productName} versioon {version}, tämä saattaa kestää hetken.",
"An error occurred." : "Tapahtui virhe.",
"Please reload the page." : "Päivitä sivu.",
diff --git a/core/l10n/fi_FI.json b/core/l10n/fi_FI.json
index 52c1c5553b3..0f9f8d3ca5e 100644
--- a/core/l10n/fi_FI.json
+++ b/core/l10n/fi_FI.json
@@ -13,7 +13,6 @@
"Repair error: " : "Korjausvirhe:",
"Set log level to debug - current level: \"%s\"" : "Aseta lokitasoksi vianjäljitys - nykyinen taso: \"%s\"",
"Reset log level to \"%s\"" : "Palauta lokitasoksi \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Seuraavat yhteensopimattomat sovellukset on poistettu käytöstä: %s",
"Following apps have been disabled: %s" : "Seuraavat sovellukset on poistettu käytöstä: %s",
"Already up to date" : "Kaikki on jo ajan tasalla",
"File is too big" : "Tiedosto on liian suuri",
@@ -171,6 +170,7 @@
"Hello {name}" : "Hei {name}",
"_download %n file_::_download %n files_" : ["lataa %n tiedosto","lataa %n tiedostoa"],
"{version} is available. Get more information on how to update." : "{version} on saatavilla. Tarjolla on lisätietoja päivittämisestä.",
+ "The upgrade is in progress, leaving this page might interrupt the process in some environments." : "Päivitys on meneillään. Poistuminen tältä sivulta saattaa keskeyttää toimenpiteen joissain käyttöympäristöissä.",
"Updating {productName} to version {version}, this may take a while." : "Päivitetään {productName} versioon {version}, tämä saattaa kestää hetken.",
"An error occurred." : "Tapahtui virhe.",
"Please reload the page." : "Päivitä sivu.",
diff --git a/core/l10n/fr.js b/core/l10n/fr.js
index 905e9943c3f..976051f105a 100644
--- a/core/l10n/fr.js
+++ b/core/l10n/fr.js
@@ -15,7 +15,6 @@ OC.L10N.register(
"Repair error: " : "Erreur de réparation :",
"Set log level to debug - current level: \"%s\"" : "Réglage du niveau de log à \"debug\" - niveau actuel: \"%s\"",
"Reset log level to \"%s\"" : "Réglage du niveau de log à \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Les applications incompatibles suivantes ont été désactivées : %s",
"Following apps have been disabled: %s" : "Les applications suivantes ont été désactivées : %s",
"Already up to date" : "Déjà à jour",
"File is too big" : "Fichier trop volumineux",
diff --git a/core/l10n/fr.json b/core/l10n/fr.json
index 9cfa4af12c1..82078d9c0c8 100644
--- a/core/l10n/fr.json
+++ b/core/l10n/fr.json
@@ -13,7 +13,6 @@
"Repair error: " : "Erreur de réparation :",
"Set log level to debug - current level: \"%s\"" : "Réglage du niveau de log à \"debug\" - niveau actuel: \"%s\"",
"Reset log level to \"%s\"" : "Réglage du niveau de log à \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Les applications incompatibles suivantes ont été désactivées : %s",
"Following apps have been disabled: %s" : "Les applications suivantes ont été désactivées : %s",
"Already up to date" : "Déjà à jour",
"File is too big" : "Fichier trop volumineux",
diff --git a/core/l10n/gl.js b/core/l10n/gl.js
index 5ac505ab535..bf1b9fceb39 100644
--- a/core/l10n/gl.js
+++ b/core/l10n/gl.js
@@ -11,7 +11,6 @@ OC.L10N.register(
"Updated \"%s\" to %s" : "Actualizado «%s» a %s",
"Repair warning: " : "Aviso de arranxo:",
"Repair error: " : "Arranxar o erro:",
- "Following incompatible apps have been disabled: %s" : "As seguintes aplicacións incompatíbeis foron desactivadas: %s",
"Following apps have been disabled: %s" : "As seguintes aplicacións foron desactivadas: %s",
"File is too big" : "O ficheiro é grande de máis",
"Invalid file provided" : "O ficheiro fornecido non é válido",
diff --git a/core/l10n/gl.json b/core/l10n/gl.json
index d9b28a5a86f..2c8864fb13c 100644
--- a/core/l10n/gl.json
+++ b/core/l10n/gl.json
@@ -9,7 +9,6 @@
"Updated \"%s\" to %s" : "Actualizado «%s» a %s",
"Repair warning: " : "Aviso de arranxo:",
"Repair error: " : "Arranxar o erro:",
- "Following incompatible apps have been disabled: %s" : "As seguintes aplicacións incompatíbeis foron desactivadas: %s",
"Following apps have been disabled: %s" : "As seguintes aplicacións foron desactivadas: %s",
"File is too big" : "O ficheiro é grande de máis",
"Invalid file provided" : "O ficheiro fornecido non é válido",
diff --git a/core/l10n/hu_HU.js b/core/l10n/hu_HU.js
index 05b34ef23e3..cbf6eae1820 100644
--- a/core/l10n/hu_HU.js
+++ b/core/l10n/hu_HU.js
@@ -15,7 +15,6 @@ OC.L10N.register(
"Repair error: " : "Javítás hiba:",
"Set log level to debug - current level: \"%s\"" : "Hibakeresési naplózási szint beállítása - jelenlegi szint: \"%s\"",
"Reset log level to \"%s\"" : "Naplózási szint visszaállítása \"%s\"-re",
- "Following incompatible apps have been disabled: %s" : "A következő nem kompatibilis applikációk lettek tiltva: %s",
"Following apps have been disabled: %s" : "A következő applikációk lettek tiltva: %s",
"Already up to date" : "Már a legfrissebb változat",
"File is too big" : "A fájl túl nagy",
diff --git a/core/l10n/hu_HU.json b/core/l10n/hu_HU.json
index c32ed57c5a2..3d57204bb4d 100644
--- a/core/l10n/hu_HU.json
+++ b/core/l10n/hu_HU.json
@@ -13,7 +13,6 @@
"Repair error: " : "Javítás hiba:",
"Set log level to debug - current level: \"%s\"" : "Hibakeresési naplózási szint beállítása - jelenlegi szint: \"%s\"",
"Reset log level to \"%s\"" : "Naplózási szint visszaállítása \"%s\"-re",
- "Following incompatible apps have been disabled: %s" : "A következő nem kompatibilis applikációk lettek tiltva: %s",
"Following apps have been disabled: %s" : "A következő applikációk lettek tiltva: %s",
"Already up to date" : "Már a legfrissebb változat",
"File is too big" : "A fájl túl nagy",
diff --git a/core/l10n/id.js b/core/l10n/id.js
index 7213844072f..8e3b71651cd 100644
--- a/core/l10n/id.js
+++ b/core/l10n/id.js
@@ -15,7 +15,6 @@ OC.L10N.register(
"Repair error: " : "Kesalahan perbaikan:",
"Set log level to debug - current level: \"%s\"" : "Atur level log untuk debug - level saat ini: \"%s\"",
"Reset log level to \"%s\"" : "Atur ulang level log menjadi \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Aplikasi tidak kompatibel berikut telah dinonaktifkan: %s",
"Following apps have been disabled: %s" : "Aplikasi berikut telah dinonaktifkan: %s",
"Already up to date" : "Sudah yang terbaru",
"File is too big" : "Berkas terlalu besar",
diff --git a/core/l10n/id.json b/core/l10n/id.json
index 1c71260efec..918d095ba8e 100644
--- a/core/l10n/id.json
+++ b/core/l10n/id.json
@@ -13,7 +13,6 @@
"Repair error: " : "Kesalahan perbaikan:",
"Set log level to debug - current level: \"%s\"" : "Atur level log untuk debug - level saat ini: \"%s\"",
"Reset log level to \"%s\"" : "Atur ulang level log menjadi \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Aplikasi tidak kompatibel berikut telah dinonaktifkan: %s",
"Following apps have been disabled: %s" : "Aplikasi berikut telah dinonaktifkan: %s",
"Already up to date" : "Sudah yang terbaru",
"File is too big" : "Berkas terlalu besar",
diff --git a/core/l10n/is.js b/core/l10n/is.js
index bc3b13aaf4e..cfacb5640bc 100644
--- a/core/l10n/is.js
+++ b/core/l10n/is.js
@@ -12,7 +12,6 @@ OC.L10N.register(
"Updated \"%s\" to %s" : "Uppfært \\\"%s\\\" to %s",
"Repair warning: " : "Viðgerðar viðvörun:",
"Repair error: " : "Viðgerðar villa:",
- "Following incompatible apps have been disabled: %s" : "Eftirfarandi forrit eru ósamhæfð hafa verið gerð óvirk: %s",
"Following apps have been disabled: %s" : "Eftirfarandi forrit hafa verið gerð óvirk: %s",
"Already up to date" : "Allt uppfært nú þegar",
"File is too big" : "Skrá er of stór",
diff --git a/core/l10n/is.json b/core/l10n/is.json
index c46572fd129..527703e476b 100644
--- a/core/l10n/is.json
+++ b/core/l10n/is.json
@@ -10,7 +10,6 @@
"Updated \"%s\" to %s" : "Uppfært \\\"%s\\\" to %s",
"Repair warning: " : "Viðgerðar viðvörun:",
"Repair error: " : "Viðgerðar villa:",
- "Following incompatible apps have been disabled: %s" : "Eftirfarandi forrit eru ósamhæfð hafa verið gerð óvirk: %s",
"Following apps have been disabled: %s" : "Eftirfarandi forrit hafa verið gerð óvirk: %s",
"Already up to date" : "Allt uppfært nú þegar",
"File is too big" : "Skrá er of stór",
diff --git a/core/l10n/it.js b/core/l10n/it.js
index d3ac7cfa40d..584b67c59f1 100644
--- a/core/l10n/it.js
+++ b/core/l10n/it.js
@@ -15,7 +15,6 @@ OC.L10N.register(
"Repair error: " : "Errore di riparazione:",
"Set log level to debug - current level: \"%s\"" : "Imposta il livello del log a debug - livello attuale: \"%s\"",
"Reset log level to \"%s\"" : "Ripristina il livello del log a \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Le seguenti applicazioni incompatibili sono state disabilitate: %s",
"Following apps have been disabled: %s" : "Le seguenti applicazioni sono state disabilitate: %s",
"Already up to date" : "Già aggiornato",
"File is too big" : "Il file è troppo grande",
@@ -173,6 +172,7 @@ OC.L10N.register(
"Hello {name}" : "Ciao {name}",
"_download %n file_::_download %n files_" : ["scarica %n file","scarica %s file"],
"{version} is available. Get more information on how to update." : "{version} è disponibile. Ottieni ulteriori informazioni su come eseguire l'aggiornamento.",
+ "The upgrade is in progress, leaving this page might interrupt the process in some environments." : "L'aggiornamento è in corso, l'abbandono di questa pagina potrebbe interrompere il processo in alcuni ambienti.",
"Updating {productName} to version {version}, this may take a while." : "Aggiornamento di {productName} alla versione {version}, potrebbe richiedere del tempo.",
"An error occurred." : "Si è verificato un errore.",
"Please reload the page." : "Ricarica la pagina.",
diff --git a/core/l10n/it.json b/core/l10n/it.json
index 4862e2b5efe..889e325fbbc 100644
--- a/core/l10n/it.json
+++ b/core/l10n/it.json
@@ -13,7 +13,6 @@
"Repair error: " : "Errore di riparazione:",
"Set log level to debug - current level: \"%s\"" : "Imposta il livello del log a debug - livello attuale: \"%s\"",
"Reset log level to \"%s\"" : "Ripristina il livello del log a \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Le seguenti applicazioni incompatibili sono state disabilitate: %s",
"Following apps have been disabled: %s" : "Le seguenti applicazioni sono state disabilitate: %s",
"Already up to date" : "Già aggiornato",
"File is too big" : "Il file è troppo grande",
@@ -171,6 +170,7 @@
"Hello {name}" : "Ciao {name}",
"_download %n file_::_download %n files_" : ["scarica %n file","scarica %s file"],
"{version} is available. Get more information on how to update." : "{version} è disponibile. Ottieni ulteriori informazioni su come eseguire l'aggiornamento.",
+ "The upgrade is in progress, leaving this page might interrupt the process in some environments." : "L'aggiornamento è in corso, l'abbandono di questa pagina potrebbe interrompere il processo in alcuni ambienti.",
"Updating {productName} to version {version}, this may take a while." : "Aggiornamento di {productName} alla versione {version}, potrebbe richiedere del tempo.",
"An error occurred." : "Si è verificato un errore.",
"Please reload the page." : "Ricarica la pagina.",
diff --git a/core/l10n/ja.js b/core/l10n/ja.js
index 3f3b3714b03..c13d8548bc1 100644
--- a/core/l10n/ja.js
+++ b/core/l10n/ja.js
@@ -12,7 +12,6 @@ OC.L10N.register(
"Updated \"%s\" to %s" : "\"%s\" を %s にアップデートしました。",
"Repair warning: " : "修復警告:",
"Repair error: " : "修復エラー:",
- "Following incompatible apps have been disabled: %s" : "次の互換性のないアプリは無効にされています: %s",
"Following apps have been disabled: %s" : "以下のアプリが無効にされています: %s",
"File is too big" : "ファイルが大きすぎます",
"Invalid file provided" : "無効なファイルが提供されました",
diff --git a/core/l10n/ja.json b/core/l10n/ja.json
index 6daf6329e5a..7134e2aecb7 100644
--- a/core/l10n/ja.json
+++ b/core/l10n/ja.json
@@ -10,7 +10,6 @@
"Updated \"%s\" to %s" : "\"%s\" を %s にアップデートしました。",
"Repair warning: " : "修復警告:",
"Repair error: " : "修復エラー:",
- "Following incompatible apps have been disabled: %s" : "次の互換性のないアプリは無効にされています: %s",
"Following apps have been disabled: %s" : "以下のアプリが無効にされています: %s",
"File is too big" : "ファイルが大きすぎます",
"Invalid file provided" : "無効なファイルが提供されました",
diff --git a/core/l10n/ko.js b/core/l10n/ko.js
index 4198d5ea74a..90cac2d0ded 100644
--- a/core/l10n/ko.js
+++ b/core/l10n/ko.js
@@ -15,7 +15,6 @@ OC.L10N.register(
"Repair error: " : "수리 오류:",
"Set log level to debug - current level: \"%s\"" : "로그 단계를 디버그로 설정함 - 현재 단계: \"%s\"",
"Reset log level to \"%s\"" : "로그 단계를 \"%s\"(으)로 초기화",
- "Following incompatible apps have been disabled: %s" : "다음 호환되지 않는 앱이 비활성화되었습니다: %s",
"Following apps have been disabled: %s" : "다음 앱이 비활성화되었습니다: %s",
"Already up to date" : "최신 상태임",
"File is too big" : "파일이 너무 큼",
diff --git a/core/l10n/ko.json b/core/l10n/ko.json
index 64341720004..c0623020662 100644
--- a/core/l10n/ko.json
+++ b/core/l10n/ko.json
@@ -13,7 +13,6 @@
"Repair error: " : "수리 오류:",
"Set log level to debug - current level: \"%s\"" : "로그 단계를 디버그로 설정함 - 현재 단계: \"%s\"",
"Reset log level to \"%s\"" : "로그 단계를 \"%s\"(으)로 초기화",
- "Following incompatible apps have been disabled: %s" : "다음 호환되지 않는 앱이 비활성화되었습니다: %s",
"Following apps have been disabled: %s" : "다음 앱이 비활성화되었습니다: %s",
"Already up to date" : "최신 상태임",
"File is too big" : "파일이 너무 큼",
diff --git a/core/l10n/lt_LT.js b/core/l10n/lt_LT.js
index 622dbb5ab3d..bead18595e6 100644
--- a/core/l10n/lt_LT.js
+++ b/core/l10n/lt_LT.js
@@ -14,7 +14,6 @@ OC.L10N.register(
"Repair error: " : "Taisymo klaida:",
"Set log level to debug - current level: \"%s\"" : "Nustatykite žurnalų lygį į derinimas - dabar \"%s\"",
"Reset log level to \"%s\"" : "Atkurkite žurnalų lygį į \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Nesudarinami įskiepiai buvo išjungti: %s",
"Following apps have been disabled: %s" : "Išjungti įskiepiai: %s",
"Already up to date" : "Jau naujausia",
"File is too big" : "Per didelis failas",
diff --git a/core/l10n/lt_LT.json b/core/l10n/lt_LT.json
index 998cd62a5b2..84f9e4a0f2d 100644
--- a/core/l10n/lt_LT.json
+++ b/core/l10n/lt_LT.json
@@ -12,7 +12,6 @@
"Repair error: " : "Taisymo klaida:",
"Set log level to debug - current level: \"%s\"" : "Nustatykite žurnalų lygį į derinimas - dabar \"%s\"",
"Reset log level to \"%s\"" : "Atkurkite žurnalų lygį į \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Nesudarinami įskiepiai buvo išjungti: %s",
"Following apps have been disabled: %s" : "Išjungti įskiepiai: %s",
"Already up to date" : "Jau naujausia",
"File is too big" : "Per didelis failas",
diff --git a/core/l10n/mk.js b/core/l10n/mk.js
index ef283e7d24f..bf4997c9069 100644
--- a/core/l10n/mk.js
+++ b/core/l10n/mk.js
@@ -10,7 +10,6 @@ OC.L10N.register(
"Updated \"%s\" to %s" : "Ажурирано е \"%s\" во %s",
"Repair warning: " : "Предупредувања при поправка:",
"Repair error: " : "Грешка при поправка:",
- "Following incompatible apps have been disabled: %s" : "Следниве некомпатибилни апликации се оневозможени: %s",
"Invalid file provided" : "Дадена е невалидна датотека",
"No image or file provided" : "Не е доставена фотографија или датотека",
"Unknown filetype" : "Непознат тип на датотека",
diff --git a/core/l10n/mk.json b/core/l10n/mk.json
index 258a912388d..39d238c8608 100644
--- a/core/l10n/mk.json
+++ b/core/l10n/mk.json
@@ -8,7 +8,6 @@
"Updated \"%s\" to %s" : "Ажурирано е \"%s\" во %s",
"Repair warning: " : "Предупредувања при поправка:",
"Repair error: " : "Грешка при поправка:",
- "Following incompatible apps have been disabled: %s" : "Следниве некомпатибилни апликации се оневозможени: %s",
"Invalid file provided" : "Дадена е невалидна датотека",
"No image or file provided" : "Не е доставена фотографија или датотека",
"Unknown filetype" : "Непознат тип на датотека",
diff --git a/core/l10n/nb_NO.js b/core/l10n/nb_NO.js
index 13cf58087a9..15d8a65b166 100644
--- a/core/l10n/nb_NO.js
+++ b/core/l10n/nb_NO.js
@@ -12,7 +12,6 @@ OC.L10N.register(
"Updated \"%s\" to %s" : "Oppdaterte \"%s\" til %s",
"Repair warning: " : "Advarsel fra reparering: ",
"Repair error: " : "Feil ved reparering: ",
- "Following incompatible apps have been disabled: %s" : "Følgende inkompatible apper har blitt deaktivert: %s",
"Following apps have been disabled: %s" : "Følgende apper har blitt deaktivert: %s",
"Already up to date" : "Allerede oppdatert",
"File is too big" : "Filen er for stor",
diff --git a/core/l10n/nb_NO.json b/core/l10n/nb_NO.json
index efdf8439833..1441a3a83d2 100644
--- a/core/l10n/nb_NO.json
+++ b/core/l10n/nb_NO.json
@@ -10,7 +10,6 @@
"Updated \"%s\" to %s" : "Oppdaterte \"%s\" til %s",
"Repair warning: " : "Advarsel fra reparering: ",
"Repair error: " : "Feil ved reparering: ",
- "Following incompatible apps have been disabled: %s" : "Følgende inkompatible apper har blitt deaktivert: %s",
"Following apps have been disabled: %s" : "Følgende apper har blitt deaktivert: %s",
"Already up to date" : "Allerede oppdatert",
"File is too big" : "Filen er for stor",
diff --git a/core/l10n/nds.js b/core/l10n/nds.js
index 9c81f34e70f..65aacb0a081 100644
--- a/core/l10n/nds.js
+++ b/core/l10n/nds.js
@@ -15,7 +15,6 @@ OC.L10N.register(
"Repair error: " : "Reparaturfehler",
"Set log level to debug - current level: \"%s\"" : "Protokollierungsstufe auf Debug gesetzt - Aktuelle Stufe: \"%s\"",
"Reset log level to \"%s\"" : "Protokollierungsstufe auf \"%s\" zurückgesetzt",
- "Following incompatible apps have been disabled: %s" : "Folgende inkompatible Apps wurden deaktiviert: %s",
"Following apps have been disabled: %s" : "Folgende Apps wurden deaktiviert: %s",
"Already up to date" : "Bereits aktuell",
"File is too big" : "Datei ist zu groß",
diff --git a/core/l10n/nds.json b/core/l10n/nds.json
index e62ab93e307..111325199df 100644
--- a/core/l10n/nds.json
+++ b/core/l10n/nds.json
@@ -13,7 +13,6 @@
"Repair error: " : "Reparaturfehler",
"Set log level to debug - current level: \"%s\"" : "Protokollierungsstufe auf Debug gesetzt - Aktuelle Stufe: \"%s\"",
"Reset log level to \"%s\"" : "Protokollierungsstufe auf \"%s\" zurückgesetzt",
- "Following incompatible apps have been disabled: %s" : "Folgende inkompatible Apps wurden deaktiviert: %s",
"Following apps have been disabled: %s" : "Folgende Apps wurden deaktiviert: %s",
"Already up to date" : "Bereits aktuell",
"File is too big" : "Datei ist zu groß",
diff --git a/core/l10n/nl.js b/core/l10n/nl.js
index 4828e3ba098..44ab2bd31f6 100644
--- a/core/l10n/nl.js
+++ b/core/l10n/nl.js
@@ -15,7 +15,6 @@ OC.L10N.register(
"Repair error: " : "Reparatiefout:",
"Set log level to debug - current level: \"%s\"" : "Instellen logniveau op debug - huidige niveau: \"%s\"",
"Reset log level to \"%s\"" : "Terugzetten logniveau op \"#%s\"",
- "Following incompatible apps have been disabled: %s" : "De volgende incompatibele apps zijn uitgeschakeld: %s",
"Following apps have been disabled: %s" : "De volgende apps zijn gedeactiveerd: %s",
"Already up to date" : "Al bijgewerkt",
"File is too big" : "Bestand te groot",
diff --git a/core/l10n/nl.json b/core/l10n/nl.json
index 900d89cdc50..6812d59aca6 100644
--- a/core/l10n/nl.json
+++ b/core/l10n/nl.json
@@ -13,7 +13,6 @@
"Repair error: " : "Reparatiefout:",
"Set log level to debug - current level: \"%s\"" : "Instellen logniveau op debug - huidige niveau: \"%s\"",
"Reset log level to \"%s\"" : "Terugzetten logniveau op \"#%s\"",
- "Following incompatible apps have been disabled: %s" : "De volgende incompatibele apps zijn uitgeschakeld: %s",
"Following apps have been disabled: %s" : "De volgende apps zijn gedeactiveerd: %s",
"Already up to date" : "Al bijgewerkt",
"File is too big" : "Bestand te groot",
diff --git a/core/l10n/oc.js b/core/l10n/oc.js
index a61d44857cb..b578bc1349f 100644
--- a/core/l10n/oc.js
+++ b/core/l10n/oc.js
@@ -10,7 +10,6 @@ OC.L10N.register(
"Updated \"%s\" to %s" : "Mesa a jorn de « %s » cap a %s",
"Repair warning: " : "Avertiment de reparacion :",
"Repair error: " : "Error de reparacion :",
- "Following incompatible apps have been disabled: %s" : "Las aplicacions incompatiblas seguentas son estadas desactivadas : %s",
"Invalid file provided" : "Fichièr invalid",
"No image or file provided" : "Cap de fichièr pas provesit",
"Unknown filetype" : "Tipe de fichièr desconegut",
diff --git a/core/l10n/oc.json b/core/l10n/oc.json
index 00927bdf52b..a0851af4b6c 100644
--- a/core/l10n/oc.json
+++ b/core/l10n/oc.json
@@ -8,7 +8,6 @@
"Updated \"%s\" to %s" : "Mesa a jorn de « %s » cap a %s",
"Repair warning: " : "Avertiment de reparacion :",
"Repair error: " : "Error de reparacion :",
- "Following incompatible apps have been disabled: %s" : "Las aplicacions incompatiblas seguentas son estadas desactivadas : %s",
"Invalid file provided" : "Fichièr invalid",
"No image or file provided" : "Cap de fichièr pas provesit",
"Unknown filetype" : "Tipe de fichièr desconegut",
diff --git a/core/l10n/pl.js b/core/l10n/pl.js
index 525c4aef880..017985efffd 100644
--- a/core/l10n/pl.js
+++ b/core/l10n/pl.js
@@ -10,7 +10,6 @@ OC.L10N.register(
"Updated \"%s\" to %s" : "Zaktualizowano \"%s\" do %s",
"Repair warning: " : "Ostrzeżenie naprawiania:",
"Repair error: " : "Błąd naprawiania:",
- "Following incompatible apps have been disabled: %s" : "Poniższe niezgodne aplikacje zostały wyłączone: %s",
"Invalid file provided" : "Podano błędny plik",
"No image or file provided" : "Brak obrazu lub pliku dostarczonego",
"Unknown filetype" : "Nieznany typ pliku",
diff --git a/core/l10n/pl.json b/core/l10n/pl.json
index d187cbcc626..4b554ae3742 100644
--- a/core/l10n/pl.json
+++ b/core/l10n/pl.json
@@ -8,7 +8,6 @@
"Updated \"%s\" to %s" : "Zaktualizowano \"%s\" do %s",
"Repair warning: " : "Ostrzeżenie naprawiania:",
"Repair error: " : "Błąd naprawiania:",
- "Following incompatible apps have been disabled: %s" : "Poniższe niezgodne aplikacje zostały wyłączone: %s",
"Invalid file provided" : "Podano błędny plik",
"No image or file provided" : "Brak obrazu lub pliku dostarczonego",
"Unknown filetype" : "Nieznany typ pliku",
diff --git a/core/l10n/pt_BR.js b/core/l10n/pt_BR.js
index a11d02acb78..bbe970f8cf9 100644
--- a/core/l10n/pt_BR.js
+++ b/core/l10n/pt_BR.js
@@ -15,7 +15,6 @@ OC.L10N.register(
"Repair error: " : "Reparação de erro:",
"Set log level to debug - current level: \"%s\"" : "Configure o nível de log para debug - nível corrente: \"%s\"",
"Reset log level to \"%s\"" : "Reconfigurar o nível de log para \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Seguir aplicativos incompatíveis foi desativado: %s",
"Following apps have been disabled: %s" : "Os seguintes aplicativos foram desabilitados: %s",
"Already up to date" : "Já está atualizado",
"File is too big" : "O arquivo é muito grande",
@@ -173,6 +172,7 @@ OC.L10N.register(
"Hello {name}" : "Olá {name}",
"_download %n file_::_download %n files_" : ["baixar %n arquivo","baixar %n arquivos"],
"{version} is available. Get more information on how to update." : "{version} está disponível. Obtenha mais informações sobre como atualizar.",
+ "The upgrade is in progress, leaving this page might interrupt the process in some environments." : "A atualização está em andamento, deixando esta página pode haver interrupção do processo em alguns ambientes.",
"Updating {productName} to version {version}, this may take a while." : "Atualizando {productName} para a versão {version}, isso pode demorar um pouco.",
"An error occurred." : "Ocorreu um erro.",
"Please reload the page." : "Por favor recarregue a página",
diff --git a/core/l10n/pt_BR.json b/core/l10n/pt_BR.json
index efced19042d..220c3998639 100644
--- a/core/l10n/pt_BR.json
+++ b/core/l10n/pt_BR.json
@@ -13,7 +13,6 @@
"Repair error: " : "Reparação de erro:",
"Set log level to debug - current level: \"%s\"" : "Configure o nível de log para debug - nível corrente: \"%s\"",
"Reset log level to \"%s\"" : "Reconfigurar o nível de log para \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Seguir aplicativos incompatíveis foi desativado: %s",
"Following apps have been disabled: %s" : "Os seguintes aplicativos foram desabilitados: %s",
"Already up to date" : "Já está atualizado",
"File is too big" : "O arquivo é muito grande",
@@ -171,6 +170,7 @@
"Hello {name}" : "Olá {name}",
"_download %n file_::_download %n files_" : ["baixar %n arquivo","baixar %n arquivos"],
"{version} is available. Get more information on how to update." : "{version} está disponível. Obtenha mais informações sobre como atualizar.",
+ "The upgrade is in progress, leaving this page might interrupt the process in some environments." : "A atualização está em andamento, deixando esta página pode haver interrupção do processo em alguns ambientes.",
"Updating {productName} to version {version}, this may take a while." : "Atualizando {productName} para a versão {version}, isso pode demorar um pouco.",
"An error occurred." : "Ocorreu um erro.",
"Please reload the page." : "Por favor recarregue a página",
diff --git a/core/l10n/pt_PT.js b/core/l10n/pt_PT.js
index 903124c6b63..2c96d2723fa 100644
--- a/core/l10n/pt_PT.js
+++ b/core/l10n/pt_PT.js
@@ -12,7 +12,6 @@ OC.L10N.register(
"Updated \"%s\" to %s" : "Atualizado \"%s\" para %s",
"Repair warning: " : "Aviso de reparação:",
"Repair error: " : "Corrija o erro:",
- "Following incompatible apps have been disabled: %s" : "As seguintes apps incompatíveis foram desativadas: %s",
"Following apps have been disabled: %s" : "As seguintes apps foram desativadas: %s",
"Already up to date" : "Já está atualizado",
"File is too big" : "O ficheiro é muito grande",
diff --git a/core/l10n/pt_PT.json b/core/l10n/pt_PT.json
index 733f7375feb..ee4061799a3 100644
--- a/core/l10n/pt_PT.json
+++ b/core/l10n/pt_PT.json
@@ -10,7 +10,6 @@
"Updated \"%s\" to %s" : "Atualizado \"%s\" para %s",
"Repair warning: " : "Aviso de reparação:",
"Repair error: " : "Corrija o erro:",
- "Following incompatible apps have been disabled: %s" : "As seguintes apps incompatíveis foram desativadas: %s",
"Following apps have been disabled: %s" : "As seguintes apps foram desativadas: %s",
"Already up to date" : "Já está atualizado",
"File is too big" : "O ficheiro é muito grande",
diff --git a/core/l10n/ro.js b/core/l10n/ro.js
index 45f5cdece60..2630fd3f2c0 100644
--- a/core/l10n/ro.js
+++ b/core/l10n/ro.js
@@ -8,7 +8,6 @@ OC.L10N.register(
"Updated \"%s\" to %s" : "\"%s\" a fost actualizat până la %s",
"Repair warning: " : "Alerte reparare:",
"Repair error: " : "Eroare de reparare:",
- "Following incompatible apps have been disabled: %s" : "Următoarele aplicații incompatibile au fost dezactivate: %s",
"No image or file provided" : "Nu a fost furnizat vreo imagine sau fișier",
"Unknown filetype" : "Tip fișier necunoscut",
"Invalid image" : "Imagine invalidă",
diff --git a/core/l10n/ro.json b/core/l10n/ro.json
index 1f85508c86e..e23282e054c 100644
--- a/core/l10n/ro.json
+++ b/core/l10n/ro.json
@@ -6,7 +6,6 @@
"Updated \"%s\" to %s" : "\"%s\" a fost actualizat până la %s",
"Repair warning: " : "Alerte reparare:",
"Repair error: " : "Eroare de reparare:",
- "Following incompatible apps have been disabled: %s" : "Următoarele aplicații incompatibile au fost dezactivate: %s",
"No image or file provided" : "Nu a fost furnizat vreo imagine sau fișier",
"Unknown filetype" : "Tip fișier necunoscut",
"Invalid image" : "Imagine invalidă",
diff --git a/core/l10n/ru.js b/core/l10n/ru.js
index ca13f012abc..0ed9bcc073e 100644
--- a/core/l10n/ru.js
+++ b/core/l10n/ru.js
@@ -15,7 +15,6 @@ OC.L10N.register(
"Repair error: " : "Ошибка восстановления:",
"Set log level to debug - current level: \"%s\"" : "Установить отладочное журналирование - текущий уровень: \"%s\"",
"Reset log level to \"%s\"" : "Сбросить уровень журналирования в \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Следующие несовместимые приложения были отключены: %s",
"Following apps have been disabled: %s" : "Были отключены следующие приложения: %s",
"Already up to date" : "Не нуждается в обновлении",
"File is too big" : "Файл слишком большой",
diff --git a/core/l10n/ru.json b/core/l10n/ru.json
index f00d40a16f9..19b44b89224 100644
--- a/core/l10n/ru.json
+++ b/core/l10n/ru.json
@@ -13,7 +13,6 @@
"Repair error: " : "Ошибка восстановления:",
"Set log level to debug - current level: \"%s\"" : "Установить отладочное журналирование - текущий уровень: \"%s\"",
"Reset log level to \"%s\"" : "Сбросить уровень журналирования в \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Следующие несовместимые приложения были отключены: %s",
"Following apps have been disabled: %s" : "Были отключены следующие приложения: %s",
"Already up to date" : "Не нуждается в обновлении",
"File is too big" : "Файл слишком большой",
diff --git a/core/l10n/sk_SK.js b/core/l10n/sk_SK.js
index 044f126f353..642b56f1839 100644
--- a/core/l10n/sk_SK.js
+++ b/core/l10n/sk_SK.js
@@ -11,7 +11,6 @@ OC.L10N.register(
"Updated \"%s\" to %s" : "Aktualizované \"%s\" na %s",
"Repair warning: " : "Oznámenie opravy:",
"Repair error: " : "Chyba opravy:",
- "Following incompatible apps have been disabled: %s" : "Nasledovné nekompatibilné aplikácie boli zakázané: %s",
"Invalid file provided" : "Zadaný neplatný súbor",
"No image or file provided" : "Obrázok alebo súbor nebol zadaný",
"Unknown filetype" : "Neznámy typ súboru",
diff --git a/core/l10n/sk_SK.json b/core/l10n/sk_SK.json
index 7938364de5f..61ca1276e5a 100644
--- a/core/l10n/sk_SK.json
+++ b/core/l10n/sk_SK.json
@@ -9,7 +9,6 @@
"Updated \"%s\" to %s" : "Aktualizované \"%s\" na %s",
"Repair warning: " : "Oznámenie opravy:",
"Repair error: " : "Chyba opravy:",
- "Following incompatible apps have been disabled: %s" : "Nasledovné nekompatibilné aplikácie boli zakázané: %s",
"Invalid file provided" : "Zadaný neplatný súbor",
"No image or file provided" : "Obrázok alebo súbor nebol zadaný",
"Unknown filetype" : "Neznámy typ súboru",
diff --git a/core/l10n/sl.js b/core/l10n/sl.js
index fd415376b14..fc03d628ae8 100644
--- a/core/l10n/sl.js
+++ b/core/l10n/sl.js
@@ -8,7 +8,6 @@ OC.L10N.register(
"Checked database schema update" : "Izbrana posodobitev sheme podatkovne zbirke",
"Checked database schema update for apps" : "Izbrana posodobitev sheme podatkovne zbirke za programe",
"Updated \"%s\" to %s" : "Datoteka \"%s\" je posodobljena na %s",
- "Following incompatible apps have been disabled: %s" : "Navedeni neskladni programi so onemogočeni: %s",
"No image or file provided" : "Ni podane datoteke ali slike",
"Unknown filetype" : "Neznana vrsta datoteke",
"Invalid image" : "Neveljavna slika",
diff --git a/core/l10n/sl.json b/core/l10n/sl.json
index df0ec47a292..357f21cd643 100644
--- a/core/l10n/sl.json
+++ b/core/l10n/sl.json
@@ -6,7 +6,6 @@
"Checked database schema update" : "Izbrana posodobitev sheme podatkovne zbirke",
"Checked database schema update for apps" : "Izbrana posodobitev sheme podatkovne zbirke za programe",
"Updated \"%s\" to %s" : "Datoteka \"%s\" je posodobljena na %s",
- "Following incompatible apps have been disabled: %s" : "Navedeni neskladni programi so onemogočeni: %s",
"No image or file provided" : "Ni podane datoteke ali slike",
"Unknown filetype" : "Neznana vrsta datoteke",
"Invalid image" : "Neveljavna slika",
diff --git a/core/l10n/sq.js b/core/l10n/sq.js
index 1df18f40ab5..971ea7f7d84 100644
--- a/core/l10n/sq.js
+++ b/core/l10n/sq.js
@@ -15,7 +15,6 @@ OC.L10N.register(
"Repair error: " : "Gabim ndreqjeje: ",
"Set log level to debug - current level: \"%s\"" : "Caktoni debug si nivel regjistri - niveli i tanishëm: \"%s\"",
"Reset log level to \"%s\"" : "Riktheni nivel regjistri në \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Janë çaktivizuar aplikacionet e papërputhshme vijuese: %s",
"Following apps have been disabled: %s" : "Janë çaktivizuar aplikacionet vijuese : %s",
"Already up to date" : "Tashmë e përditësuar",
"File is too big" : "Kartela është shumë e madhe",
@@ -25,6 +24,9 @@ OC.L10N.register(
"Invalid image" : "Figurë e pavlefshme",
"An error occurred. Please contact your admin." : "Ndodhi një gabim. Ju lutemi, lidhuni me përgjegjësin tuaj.",
"No temporary profile picture available, try again" : "S’ka gati foto të përkohshme profili, riprovoni",
+ "No crop data provided" : "S’u dhanë të dhëna qethjeje",
+ "No valid crop data provided" : "S’u dhanë të dhëna qethjeje të vlefshme",
+ "Crop is not square" : "Qethja s’është katrore",
"Sunday" : "E dielë",
"Monday" : "E hënë",
"Tuesday" : "E martë",
@@ -170,6 +172,7 @@ OC.L10N.register(
"Hello {name}" : "Tungjatjeta {name}",
"_download %n file_::_download %n files_" : ["shkarko %n kartelë","shkarko %n kartela"],
"{version} is available. Get more information on how to update." : "Është gati {version}. Merrni më tepër informacion se si ta përditësoni.",
+ "The upgrade is in progress, leaving this page might interrupt the process in some environments." : "Përmirësimi po kryhet, braktisja e kësaj faqeje mund ta ndërpresë procesin në disa mjedise.",
"Updating {productName} to version {version}, this may take a while." : "Po përditësohet {productName} me versionin {version}, kjo mund të zgjasë pak.",
"An error occurred." : "Ndodhi një gabim.",
"Please reload the page." : "Ju lutemi, ringarkoni faqen.",
diff --git a/core/l10n/sq.json b/core/l10n/sq.json
index 7b7c14010bb..23e9e4de7d9 100644
--- a/core/l10n/sq.json
+++ b/core/l10n/sq.json
@@ -13,7 +13,6 @@
"Repair error: " : "Gabim ndreqjeje: ",
"Set log level to debug - current level: \"%s\"" : "Caktoni debug si nivel regjistri - niveli i tanishëm: \"%s\"",
"Reset log level to \"%s\"" : "Riktheni nivel regjistri në \"%s\"",
- "Following incompatible apps have been disabled: %s" : "Janë çaktivizuar aplikacionet e papërputhshme vijuese: %s",
"Following apps have been disabled: %s" : "Janë çaktivizuar aplikacionet vijuese : %s",
"Already up to date" : "Tashmë e përditësuar",
"File is too big" : "Kartela është shumë e madhe",
@@ -23,6 +22,9 @@
"Invalid image" : "Figurë e pavlefshme",
"An error occurred. Please contact your admin." : "Ndodhi një gabim. Ju lutemi, lidhuni me përgjegjësin tuaj.",
"No temporary profile picture available, try again" : "S’ka gati foto të përkohshme profili, riprovoni",
+ "No crop data provided" : "S’u dhanë të dhëna qethjeje",
+ "No valid crop data provided" : "S’u dhanë të dhëna qethjeje të vlefshme",
+ "Crop is not square" : "Qethja s’është katrore",
"Sunday" : "E dielë",
"Monday" : "E hënë",
"Tuesday" : "E martë",
@@ -168,6 +170,7 @@
"Hello {name}" : "Tungjatjeta {name}",
"_download %n file_::_download %n files_" : ["shkarko %n kartelë","shkarko %n kartela"],
"{version} is available. Get more information on how to update." : "Është gati {version}. Merrni më tepër informacion se si ta përditësoni.",
+ "The upgrade is in progress, leaving this page might interrupt the process in some environments." : "Përmirësimi po kryhet, braktisja e kësaj faqeje mund ta ndërpresë procesin në disa mjedise.",
"Updating {productName} to version {version}, this may take a while." : "Po përditësohet {productName} me versionin {version}, kjo mund të zgjasë pak.",
"An error occurred." : "Ndodhi një gabim.",
"Please reload the page." : "Ju lutemi, ringarkoni faqen.",
diff --git a/core/l10n/sr.js b/core/l10n/sr.js
index f34b4213f0f..9b01b18fe07 100644
--- a/core/l10n/sr.js
+++ b/core/l10n/sr.js
@@ -12,7 +12,6 @@ OC.L10N.register(
"Updated \"%s\" to %s" : "„%s“ ажириран на %s",
"Repair warning: " : "Упозорење о поправци :",
"Repair error: " : "Грешка поправке:",
- "Following incompatible apps have been disabled: %s" : "Следеће неусаглашене апликације су искључене: %s",
"Following apps have been disabled: %s" : "Следеће апликације су искључене: %s",
"File is too big" : "Фајл је превелик",
"Invalid file provided" : "Понуђени фајл је неисправан",
diff --git a/core/l10n/sr.json b/core/l10n/sr.json
index 3825ab821cb..a50af15a742 100644
--- a/core/l10n/sr.json
+++ b/core/l10n/sr.json
@@ -10,7 +10,6 @@
"Updated \"%s\" to %s" : "„%s“ ажириран на %s",
"Repair warning: " : "Упозорење о поправци :",
"Repair error: " : "Грешка поправке:",
- "Following incompatible apps have been disabled: %s" : "Следеће неусаглашене апликације су искључене: %s",
"Following apps have been disabled: %s" : "Следеће апликације су искључене: %s",
"File is too big" : "Фајл је превелик",
"Invalid file provided" : "Понуђени фајл је неисправан",
diff --git a/core/l10n/th_TH.js b/core/l10n/th_TH.js
index 24f13a2c8fe..510f8f8b4ac 100644
--- a/core/l10n/th_TH.js
+++ b/core/l10n/th_TH.js
@@ -15,7 +15,6 @@ OC.L10N.register(
"Repair error: " : "เกิดข้อผิดพลาดในการซ่อมแซม:",
"Set log level to debug - current level: \"%s\"" : "การตั้งค่าระดับของการบันทึกเพื่อแก้ปัญหา - ระดับปัจจุบันคือ: \"%s\"",
"Reset log level to \"%s\"" : "รีเซ็ทระดับการบันทึกเป็น \"%s\"",
- "Following incompatible apps have been disabled: %s" : "แอพพลิเคชันต่อไปนี้เข้ากันไม่ได้มันจะถูกปิดการใช้งาน: %s",
"Following apps have been disabled: %s" : "แอพฯดังต่อไปนี้ถูกปิดการใช้งาน: %s",
"Already up to date" : "มีอยู่แล้วถึงวันที่",
"File is too big" : "ไฟล์มีขนาดใหญ่เกินไป",
diff --git a/core/l10n/th_TH.json b/core/l10n/th_TH.json
index 2742a569a6a..e8ccc1b2d54 100644
--- a/core/l10n/th_TH.json
+++ b/core/l10n/th_TH.json
@@ -13,7 +13,6 @@
"Repair error: " : "เกิดข้อผิดพลาดในการซ่อมแซม:",
"Set log level to debug - current level: \"%s\"" : "การตั้งค่าระดับของการบันทึกเพื่อแก้ปัญหา - ระดับปัจจุบันคือ: \"%s\"",
"Reset log level to \"%s\"" : "รีเซ็ทระดับการบันทึกเป็น \"%s\"",
- "Following incompatible apps have been disabled: %s" : "แอพพลิเคชันต่อไปนี้เข้ากันไม่ได้มันจะถูกปิดการใช้งาน: %s",
"Following apps have been disabled: %s" : "แอพฯดังต่อไปนี้ถูกปิดการใช้งาน: %s",
"Already up to date" : "มีอยู่แล้วถึงวันที่",
"File is too big" : "ไฟล์มีขนาดใหญ่เกินไป",
diff --git a/core/l10n/tr.js b/core/l10n/tr.js
index a040c37e73e..81603bc89ed 100644
--- a/core/l10n/tr.js
+++ b/core/l10n/tr.js
@@ -15,7 +15,6 @@ OC.L10N.register(
"Repair error: " : "Onarım hatası:",
"Set log level to debug - current level: \"%s\"" : "Günlük seviyesini hata ayıklamaya ayarla - geçerli seviye: \"%s\"",
"Reset log level to \"%s\"" : "Günlük seviyesini \"%s\" olarak sıfırla",
- "Following incompatible apps have been disabled: %s" : "Aşağıdaki uyumsuz uygulamalar devre dışı bırakıldı: %s",
"Following apps have been disabled: %s" : "Aşağıdaki uygulamalar devre dışı bırakıldı: %s",
"Already up to date" : "Zaten güncel",
"File is too big" : "Dosya çok büyük",
diff --git a/core/l10n/tr.json b/core/l10n/tr.json
index 2da5a2dec94..fc5f26a20ea 100644
--- a/core/l10n/tr.json
+++ b/core/l10n/tr.json
@@ -13,7 +13,6 @@
"Repair error: " : "Onarım hatası:",
"Set log level to debug - current level: \"%s\"" : "Günlük seviyesini hata ayıklamaya ayarla - geçerli seviye: \"%s\"",
"Reset log level to \"%s\"" : "Günlük seviyesini \"%s\" olarak sıfırla",
- "Following incompatible apps have been disabled: %s" : "Aşağıdaki uyumsuz uygulamalar devre dışı bırakıldı: %s",
"Following apps have been disabled: %s" : "Aşağıdaki uygulamalar devre dışı bırakıldı: %s",
"Already up to date" : "Zaten güncel",
"File is too big" : "Dosya çok büyük",
diff --git a/core/l10n/uk.js b/core/l10n/uk.js
index 1cd0de81ff5..f020b00c7d9 100644
--- a/core/l10n/uk.js
+++ b/core/l10n/uk.js
@@ -12,7 +12,6 @@ OC.L10N.register(
"Updated \"%s\" to %s" : "Оновлено \"%s\" до %s",
"Repair warning: " : "Попередження відновлення:",
"Repair error: " : "Помилка відновлення:",
- "Following incompatible apps have been disabled: %s" : "Наступні несумісні додатки були вимкнені: %s",
"Following apps have been disabled: %s" : "Наступні додатки були вимкнені: %s",
"Already up to date" : "Актуально",
"File is too big" : "Файл занадто великий",
diff --git a/core/l10n/uk.json b/core/l10n/uk.json
index 4e066cd6dd7..f3c74dbe667 100644
--- a/core/l10n/uk.json
+++ b/core/l10n/uk.json
@@ -10,7 +10,6 @@
"Updated \"%s\" to %s" : "Оновлено \"%s\" до %s",
"Repair warning: " : "Попередження відновлення:",
"Repair error: " : "Помилка відновлення:",
- "Following incompatible apps have been disabled: %s" : "Наступні несумісні додатки були вимкнені: %s",
"Following apps have been disabled: %s" : "Наступні додатки були вимкнені: %s",
"Already up to date" : "Актуально",
"File is too big" : "Файл занадто великий",
diff --git a/core/l10n/zh_CN.js b/core/l10n/zh_CN.js
index 305caeb0b80..86c05393953 100644
--- a/core/l10n/zh_CN.js
+++ b/core/l10n/zh_CN.js
@@ -14,7 +14,6 @@ OC.L10N.register(
"Repair error: " : "修复错误:",
"Set log level to debug - current level: \"%s\"" : "设置日志级别为 调试 - 目前级别:%s",
"Reset log level to \"%s\"" : "重设日志级别为 \"%s\"",
- "Following incompatible apps have been disabled: %s" : "下列不兼容应用已经被禁用:%s",
"Following apps have been disabled: %s" : "下列应用已经被禁用:%s",
"Already up to date" : "已经是最新",
"File is too big" : "文件太大",
diff --git a/core/l10n/zh_CN.json b/core/l10n/zh_CN.json
index 001338a4383..62145b4cc5e 100644
--- a/core/l10n/zh_CN.json
+++ b/core/l10n/zh_CN.json
@@ -12,7 +12,6 @@
"Repair error: " : "修复错误:",
"Set log level to debug - current level: \"%s\"" : "设置日志级别为 调试 - 目前级别:%s",
"Reset log level to \"%s\"" : "重设日志级别为 \"%s\"",
- "Following incompatible apps have been disabled: %s" : "下列不兼容应用已经被禁用:%s",
"Following apps have been disabled: %s" : "下列应用已经被禁用:%s",
"Already up to date" : "已经是最新",
"File is too big" : "文件太大",
diff --git a/core/l10n/zh_TW.js b/core/l10n/zh_TW.js
index c17dc5f09e2..c7dafb3dd45 100644
--- a/core/l10n/zh_TW.js
+++ b/core/l10n/zh_TW.js
@@ -12,7 +12,6 @@ OC.L10N.register(
"Updated \"%s\" to %s" : "已更新 %s 到 %s",
"Repair warning: " : "修復警告:",
"Repair error: " : "修復錯誤",
- "Following incompatible apps have been disabled: %s" : "以下不相容的應用程式已經被停用:%s",
"Following apps have been disabled: %s" : "以下應用程式已經被停用:%s",
"Already up to date" : "已經是最新版",
"File is too big" : "檔案太大",
diff --git a/core/l10n/zh_TW.json b/core/l10n/zh_TW.json
index e336e6f5e74..8ef3c8406f7 100644
--- a/core/l10n/zh_TW.json
+++ b/core/l10n/zh_TW.json
@@ -10,7 +10,6 @@
"Updated \"%s\" to %s" : "已更新 %s 到 %s",
"Repair warning: " : "修復警告:",
"Repair error: " : "修復錯誤",
- "Following incompatible apps have been disabled: %s" : "以下不相容的應用程式已經被停用:%s",
"Following apps have been disabled: %s" : "以下應用程式已經被停用:%s",
"Already up to date" : "已經是最新版",
"File is too big" : "檔案太大",
diff --git a/core/shipped.json b/core/shipped.json
index 184308d7a48..7d506c3401a 100644
--- a/core/shipped.json
+++ b/core/shipped.json
@@ -1,5 +1,4 @@
{
- "core-version": "8.1.0.0",
"shippedApps": [
"activity",
"admin_audit",
diff --git a/indie.json b/indie.json
deleted file mode 100644
index bb3fcb96691..00000000000
--- a/indie.json
+++ /dev/null
@@ -1,92 +0,0 @@
-{
- "name": "ownCloud",
- "icons": [
- {
- "src": "https://raw.githubusercontent.com/owncloud/www/master/assets/img/common/owncloud-square-logo.png",
- "sizes": "500x500",
- "type": "image/png",
- "density": "1"
- },
- {
- "src": "core/img/favicon-touch.png",
- "sizes": "128x128",
- "type": "image/png",
- "density": "1"
- },
- {
- "src": "core/img/favicon.png",
- "sizes": "32x32",
- "type": "image/png",
- "density": "1"
- }
- ],
- "start_url": "/",
- "display": "fullscreen",
- "orientation": "landscape",
- "short_description": "sync & share your stuff",
- "description": "ownCloud gives you web services under your control. It is a self-hosted open source platform with file sync & sharing at its core and available clients for desktop and mobile. The web frontend has apps for Pictures, Calendar, Contacts, News/RSS, Bookmarks, Notes, Music and much more via an open app platform.",
- "license": "AGPLv3",
- "license_url": "https://raw.githubusercontent.com/owncloud/core/master/COPYING-AGPL",
- "source_url": "https://github.com/owncloud/core",
- "version": "7.0.0",
- "developer": {
- "name": "ownCloud Inc.",
- "url": "https://owncloud.org"
- },
- "wikipedia_url": "https://wikipedia.org/wiki/ownCloud",
- "default_locale": "en",
- "protocols": [
- "SSL/TLS",
- "WebDAV",
- "CalDAV",
- "CardDAV",
- "Ampache",
- "RSS"
- ],
- "categories": [
- {
- "name": "BSD",
- "subcategories": [
- "Files",
- "Sync",
- "Calendar",
- "Contacts",
- "News",
- "Notes"
- ]
- },
- {
- "name": "GNU/Linux",
- "subcategories": [
- "Files",
- "Sync",
- "Calendar",
- "Contacts",
- "News",
- "Notes"
- ]
- },
- {
- "name": "OS X",
- "subcategories": [
- "Files",
- "Sync",
- "Calendar",
- "Contacts",
- "News",
- "Notes"
- ]
- },
- {
- "name": "Windows",
- "subcategories": [
- "Files",
- "Sync",
- "Calendar",
- "Contacts",
- "News",
- "Notes"
- ]
- }
- ]
-}
diff --git a/lib/base.php b/lib/base.php
index 09e1d0aea49..95a47dec1e2 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -133,7 +133,18 @@ class OC {
OC_Config::$object = new \OC\Config(self::$configDir);
OC::$SUBURI = str_replace("\\", "/", substr(realpath($_SERVER["SCRIPT_FILENAME"]), strlen(OC::$SERVERROOT)));
- $scriptName = $_SERVER['SCRIPT_NAME'];
+ /**
+ * FIXME: The following lines are required because we can't yet instantiiate
+ * \OC::$server->getRequest() since \OC::$server does not yet exist.
+ */
+ $params = [
+ 'server' => [
+ 'SCRIPT_NAME' => $_SERVER['SCRIPT_NAME'],
+ 'SCRIPT_FILENAME' => $_SERVER['SCRIPT_FILENAME'],
+ ],
+ ];
+ $fakeRequest = new \OC\AppFramework\Http\Request($params, null, new \OC\AllConfig(new \OC\SystemConfig()));
+ $scriptName = $fakeRequest->getScriptName();
if (substr($scriptName, -1) == '/') {
$scriptName .= 'index.php';
//make sure suburi follows the same rules as scriptName
@@ -145,6 +156,7 @@ class OC {
}
}
+
if (OC::$CLI) {
OC::$WEBROOT = OC_Config::getValue('overwritewebroot', '');
} else {
diff --git a/lib/private/api.php b/lib/private/api.php
index 10d58f2d9e6..6d7354c7193 100644
--- a/lib/private/api.php
+++ b/lib/private/api.php
@@ -231,7 +231,8 @@ class OC_API {
$picked = reset($shipped['failed']);
$code = $picked['response']->getStatusCode();
$meta = $picked['response']->getMeta();
- $response = new OC_OCS_Result($data, $code, $meta['message']);
+ $headers = $picked['response']->getHeaders();
+ $response = new OC_OCS_Result($data, $code, $meta['message'], $headers);
return $response;
} elseif(!empty($shipped['succeeded'])) {
$responses = array_merge($shipped['succeeded'], $thirdparty['succeeded']);
@@ -244,13 +245,16 @@ class OC_API {
$picked = reset($thirdparty['failed']);
$code = $picked['response']->getStatusCode();
$meta = $picked['response']->getMeta();
- $response = new OC_OCS_Result($data, $code, $meta['message']);
+ $headers = $picked['response']->getHeaders();
+ $response = new OC_OCS_Result($data, $code, $meta['message'], $headers);
return $response;
} else {
$responses = $thirdparty['succeeded'];
}
// Merge the successful responses
- $data = array();
+ $data = [];
+ $codes = [];
+ $header = [];
foreach($responses as $response) {
if($response['shipped']) {
@@ -258,8 +262,9 @@ class OC_API {
} else {
$data = array_merge_recursive($data, $response['response']->getData());
}
- $codes[] = array('code' => $response['response']->getStatusCode(),
- 'meta' => $response['response']->getMeta());
+ $header = array_merge_recursive($header, $response['response']->getHeaders());
+ $codes[] = ['code' => $response['response']->getStatusCode(),
+ 'meta' => $response['response']->getMeta()];
}
// Use any non 100 status codes
@@ -273,8 +278,7 @@ class OC_API {
}
}
- $result = new OC_OCS_Result($data, $statusCode, $statusMessage);
- return $result;
+ return new OC_OCS_Result($data, $statusCode, $statusMessage, $header);
}
/**
diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/appframework/dependencyinjection/dicontainer.php
index 651b268a35e..de8672bc4cd 100644
--- a/lib/private/appframework/dependencyinjection/dicontainer.php
+++ b/lib/private/appframework/dependencyinjection/dicontainer.php
@@ -226,6 +226,10 @@ class DIContainer extends SimpleContainer implements IAppContainer {
return $this->getServer();
});
+ $this->registerService('OCP\\AppFramework\\IAppContainer', function ($c) {
+ return $c;
+ });
+
// commonly used attributes
$this->registerService('UserId', function ($c) {
return $c->query('OCP\\IUserSession')->getSession()->get('user_id');
diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php
index 77785135162..96620838dfb 100644
--- a/lib/private/appframework/http/request.php
+++ b/lib/private/appframework/http/request.php
@@ -88,20 +88,17 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* - string 'method' the request method (GET, POST etc)
* - string|false 'requesttoken' the requesttoken or false when not available
* @param ISecureRandom $secureRandom
- * @param ICrypto $crypto
* @param IConfig $config
* @param string $stream
* @see http://www.php.net/manual/en/reserved.variables.php
*/
public function __construct(array $vars=array(),
ISecureRandom $secureRandom = null,
- ICrypto $crypto,
IConfig $config,
$stream='php://input') {
$this->inputStream = $stream;
$this->items['params'] = array();
$this->secureRandom = $secureRandom;
- $this->crypto = $crypto;
$this->config = $config;
if(!array_key_exists('method', $vars)) {
@@ -439,22 +436,18 @@ class Request implements \ArrayAccess, \Countable, IRequest {
return false;
}
- // Decrypt token to prevent BREACH like attacks
+ // Deobfuscate token to prevent BREACH like attacks
$token = explode(':', $token);
if (count($token) !== 2) {
return false;
}
- $encryptedToken = $token[0];
+ $obfuscatedToken = $token[0];
$secret = $token[1];
- try {
- $decryptedToken = $this->crypto->decrypt($encryptedToken, $secret);
- } catch (\Exception $e) {
- return false;
- }
+ $deobfuscatedToken = base64_decode($obfuscatedToken) ^ $secret;
// Check if the token is valid
- if(\OCP\Security\StringUtils::equals($decryptedToken, $this->items['requesttoken'])) {
+ if(\OCP\Security\StringUtils::equals($deobfuscatedToken, $this->items['requesttoken'])) {
return true;
} else {
return false;
diff --git a/lib/private/group/manager.php b/lib/private/group/manager.php
index 65ae49dfcd2..6905dd8f5f2 100644
--- a/lib/private/group/manager.php
+++ b/lib/private/group/manager.php
@@ -71,11 +71,13 @@ class Manager extends PublicEmitter implements IGroupManager {
*/
private $cachedUserGroups = array();
+ /** @var \OC\SubAdmin */
+ private $subAdmin = null;
/**
* @param \OC\User\Manager $userManager
*/
- public function __construct($userManager) {
+ public function __construct(\OC\User\Manager $userManager) {
$this->userManager = $userManager;
$cachedGroups = & $this->cachedGroups;
$cachedUserGroups = & $this->cachedUserGroups;
@@ -314,4 +316,19 @@ class Manager extends PublicEmitter implements IGroupManager {
}
return $matchingUsers;
}
+
+ /**
+ * @return \OC\SubAdmin
+ */
+ public function getSubAdmin() {
+ if (!$this->subAdmin) {
+ $this->subAdmin = new \OC\SubAdmin(
+ $this->userManager,
+ $this,
+ \OC::$server->getDatabaseConnection()
+ );
+ }
+
+ return $this->subAdmin;
+ }
}
diff --git a/lib/private/legacy/subadmin.php b/lib/private/legacy/subadmin.php
new file mode 100644
index 00000000000..d10b6e90bb5
--- /dev/null
+++ b/lib/private/legacy/subadmin.php
@@ -0,0 +1,172 @@
+<?php
+/**
+ * @author Bart Visscher <bartv@thisnet.nl>
+ * @author Georg Ehrke <georg@owncloud.com>
+ * @author Jörn Friedrich Dreyer <jfd@butonic.de>
+ * @author Lukas Reschke <lukas@owncloud.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Robin McCorkell <rmccorkell@karoshi.org.uk>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @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/>
+ *
+ */
+
+/**
+ * This class provides all methods needed for managing groups.
+ *
+ * Hooks provided:
+ * post_createSubAdmin($gid)
+ * post_deleteSubAdmin($gid)
+ */
+class OC_SubAdmin{
+
+ /**
+ * add a SubAdmin
+ * @param string $uid uid of the SubAdmin
+ * @param string $gid gid of the group
+ * @return boolean
+ */
+ public static function createSubAdmin($uid, $gid) {
+ $groupManager = \OC::$server->getGroupManager();
+ $userManager = \OC::$server->getUserManager();
+ $subAdmin = $groupManager->getSubAdmin();
+
+ return $subAdmin->createSubAdmin($userManager->get($uid), $groupManager->get($gid));
+ }
+
+ /**
+ * delete a SubAdmin
+ * @param string $uid uid of the SubAdmin
+ * @param string $gid gid of the group
+ * @return boolean
+ */
+ public static function deleteSubAdmin($uid, $gid) {
+ $groupManager = \OC::$server->getGroupManager();
+ $userManager = \OC::$server->getUserManager();
+ $subAdmin = $groupManager->getSubAdmin();
+
+ return $subAdmin->deleteSubAdmin($userManager->get($uid), $groupManager->get($gid));
+ }
+
+ /**
+ * get groups of a SubAdmin
+ * @param string $uid uid of the SubAdmin
+ * @return array
+ */
+ public static function getSubAdminsGroups($uid) {
+ $groupManager = \OC::$server->getGroupManager();
+ $userManager = \OC::$server->getUserManager();
+ $subAdmin = $groupManager->getSubAdmin();
+
+ $groups = $subAdmin->getSubAdminsGroups($userManager->get($uid));
+
+ // New class returns IGroup[] so convert back
+ $gids = [];
+ foreach ($groups as $group) {
+ $gids[] = $group->getGID();
+ }
+ return $gids;
+ }
+
+ /**
+ * get SubAdmins of a group
+ * @param string $gid gid of the group
+ * @return array
+ */
+ public static function getGroupsSubAdmins($gid) {
+ $groupManager = \OC::$server->getGroupManager();
+ $subAdmin = $groupManager->getSubAdmin();
+
+ $users = $subAdmin->getGroupsSubAdmins($groupManager->get($gid));
+
+ // New class returns IUser[] so convert back
+ $uids = [];
+ foreach ($users as $user) {
+ $uids[] = $user->getUID();
+ }
+ return $uids;
+ }
+
+ /**
+ * get all SubAdmins
+ * @return array
+ */
+ public static function getAllSubAdmins() {
+ $groupManager = \OC::$server->getGroupManager();
+ $subAdmin = $groupManager->getSubAdmin();
+
+ $subAdmins = $subAdmin->getAllSubAdmins();
+
+ // New class returns IUser[] so convert back
+ $result = [];
+ foreach ($subAdmins as $subAdmin) {
+ $result[] = [
+ 'gid' => $subAdmin['group']->getGID(),
+ 'uid' => $subAdmin['user']->getUID(),
+ ];
+ }
+ return $result;
+ }
+
+ /**
+ * checks if a user is a SubAdmin of a group
+ * @param string $uid uid of the subadmin
+ * @param string $gid gid of the group
+ * @return bool
+ */
+ public static function isSubAdminofGroup($uid, $gid) {
+ $groupManager = \OC::$server->getGroupManager();
+ $userManager = \OC::$server->getUserManager();
+ $subAdmin = $groupManager->getSubAdmin();
+
+ return $subAdmin->isSubAdminOfGroup($userManager->get($uid), $groupManager->get($gid));
+ }
+
+ /**
+ * checks if a user is a SubAdmin
+ * @param string $uid uid of the subadmin
+ * @return bool
+ */
+ public static function isSubAdmin($uid) {
+ $groupManager = \OC::$server->getGroupManager();
+ $userManager = \OC::$server->getUserManager();
+ $subAdmin = $groupManager->getSubAdmin();
+
+ return $subAdmin->isSubAdmin($userManager->get($uid));
+ }
+
+ /**
+ * checks if a user is a accessible by a subadmin
+ * @param string $subadmin uid of the subadmin
+ * @param string $user uid of the user
+ * @return bool
+ */
+ public static function isUserAccessible($subadmin, $user) {
+ $groupManager = \OC::$server->getGroupManager();
+ $userManager = \OC::$server->getUserManager();
+ $subAdmin = $groupManager->getSubAdmin();
+
+ return $subAdmin->isUserAccessible($userManager->get($subadmin), $userManager->get($user));
+ }
+
+ /*
+ * alias for self::isSubAdminofGroup()
+ */
+ public static function isGroupAccessible($subadmin, $group) {
+ return self::isSubAdminofGroup($subadmin, $group);
+ }
+}
diff --git a/lib/private/ocs/result.php b/lib/private/ocs/result.php
index 916e25e45ae..2c3f676510c 100644
--- a/lib/private/ocs/result.php
+++ b/lib/private/ocs/result.php
@@ -51,8 +51,9 @@ class OC_OCS_Result{
* @param mixed $data the data to return
* @param int $code
* @param null|string $message
+ * @param array $headers
*/
- public function __construct($data=null, $code=100, $message=null) {
+ public function __construct($data = null, $code = 100, $message = null, $headers = []) {
if ($data === null) {
$this->data = array();
} elseif (!is_array($data)) {
@@ -62,6 +63,7 @@ class OC_OCS_Result{
}
$this->statusCode = $code;
$this->message = $message;
+ $this->headers = $headers;
}
/**
diff --git a/lib/private/server.php b/lib/private/server.php
index 14fa323f74d..15ee3454d85 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -438,7 +438,6 @@ class Server extends SimpleContainer implements IServerContainer {
'requesttoken' => $requestToken,
],
$this->getSecureRandom(),
- $this->getCrypto(),
$this->getConfig(),
$stream
);
@@ -512,7 +511,6 @@ class Server extends SimpleContainer implements IServerContainer {
: null,
],
new SecureRandom(),
- $c->getCrypto(),
$c->getConfig()
);
diff --git a/lib/private/subadmin.php b/lib/private/subadmin.php
index ec4f9f3b899..0e130a7700a 100644
--- a/lib/private/subadmin.php
+++ b/lib/private/subadmin.php
@@ -2,10 +2,9 @@
/**
* @author Bart Visscher <bartv@thisnet.nl>
* @author Georg Ehrke <georg@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
* @author Lukas Reschke <lukas@owncloud.com>
* @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin McCorkell <rmccorkell@karoshi.org.uk>
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Thomas Müller <thomas.mueller@tmit.eu>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
@@ -24,171 +23,235 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
-OC_Hook::connect('OC_User', 'post_deleteUser', 'OC_SubAdmin', 'post_deleteUser');
-OC_Hook::connect('OC_User', 'post_deleteGroup', 'OC_SubAdmin', 'post_deleteGroup');
-/**
- * This class provides all methods needed for managing groups.
- *
- * Hooks provided:
- * post_createSubAdmin($gid)
- * post_deleteSubAdmin($gid)
- */
-class OC_SubAdmin{
+
+namespace OC;
+
+use OC\Hooks\PublicEmitter;
+use OCP\IUser;
+use OCP\IUserManager;
+use OCP\IGroup;
+use OCP\IGroupManager;
+use OCP\IDBConnection;
+
+class SubAdmin extends PublicEmitter {
+
+ /** @var IUserManager */
+ private $userManager;
+
+ /** @var IGroupManager */
+ private $groupManager;
+
+ /** @var IDBConnection */
+ private $dbConn;
+
+ public function __construct(IUserManager $userManager,
+ IGroupManager $groupManager,
+ IDBConnection $dbConn) {
+ $this->userManager = $userManager;
+ $this->groupManager = $groupManager;
+ $this->dbConn = $dbConn;
+
+ $this->userManager->listen('\OC\User', 'postDelete', function($user) {
+ $this->post_deleteUser($user);
+ });
+ $this->groupManager->listen('\OC\Group', 'postDelete', function($group) {
+ $this->post_deleteGroup($group);
+ });
+ }
/**
* add a SubAdmin
- * @param string $uid uid of the SubAdmin
- * @param string $gid gid of the group
- * @return boolean
+ * @param IUser $user user to be SubAdmin
+ * @param IGroup $group group $user becomes subadmin of
+ * @return bool
*/
- public static function createSubAdmin($uid, $gid) {
- $stmt = OC_DB::prepare('INSERT INTO `*PREFIX*group_admin` (`gid`,`uid`) VALUES(?,?)');
- $stmt->execute(array($gid, $uid));
- OC_Hook::emit( "OC_SubAdmin", "post_createSubAdmin", array( "gid" => $gid ));
+ public function createSubAdmin(IUser $user, IGroup $group) {
+ $qb = $this->dbConn->getQueryBuilder();
+
+ $result = $qb->insert('group_admin')
+ ->values([
+ 'gid' => $qb->createNamedParameter($group->getGID()),
+ 'uid' => $qb->createNamedParameter($user->getUID())
+ ])
+ ->execute();
+
+ $this->emit('\OC\SubAdmin', 'postCreateSubAdmin', [$user, $group]);
+ \OC_Hook::emit("OC_SubAdmin", "post_createSubAdmin", ["gid" => $group->getGID()]);
return true;
}
/**
* delete a SubAdmin
- * @param string $uid uid of the SubAdmin
- * @param string $gid gid of the group
- * @return boolean
+ * @param IUser $user the user that is the SubAdmin
+ * @param IGroup $group the group
+ * @return bool
*/
- public static function deleteSubAdmin($uid, $gid) {
- $stmt = OC_DB::prepare('DELETE FROM `*PREFIX*group_admin` WHERE `gid` = ? AND `uid` = ?');
- $stmt->execute(array($gid, $uid));
- OC_Hook::emit( "OC_SubAdmin", "post_deleteSubAdmin", array( "gid" => $gid ));
+ public function deleteSubAdmin(IUser $user, IGroup $group) {
+ $qb = $this->dbConn->getQueryBuilder();
+
+ $result = $qb->delete('group_admin')
+ ->where($qb->expr()->eq('gid', $qb->createNamedParameter($group->getGID())))
+ ->andWhere($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
+ ->execute();
+
+ $this->emit('\OC\SubAdmin', 'postDeleteSubAdmin', [$user, $group]);
+ \OC_Hook::emit("OC_SubAdmin", "post_deleteSubAdmin", ["gid" => $group->getGID()]);
return true;
}
/**
* get groups of a SubAdmin
- * @param string $uid uid of the SubAdmin
- * @return array
+ * @param IUser $user the SubAdmin
+ * @return IGroup[]
*/
- public static function getSubAdminsGroups($uid) {
- $stmt = OC_DB::prepare('SELECT `gid` FROM `*PREFIX*group_admin` WHERE `uid` = ?');
- $result = $stmt->execute(array($uid));
- $gids = array();
- while($row = $result->fetchRow()) {
- $gids[] = $row['gid'];
+ public function getSubAdminsGroups(IUser $user) {
+ $qb = $this->dbConn->getQueryBuilder();
+
+ $result = $qb->select('gid')
+ ->from('group_admin')
+ ->where($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
+ ->execute();
+
+ $groups = [];
+ while($row = $result->fetch()) {
+ $groups[] = $this->groupManager->get($row['gid']);
}
- return $gids;
+
+ return $groups;
}
/**
* get SubAdmins of a group
- * @param string $gid gid of the group
- * @return array
+ * @param IGroup $group the group
+ * @return IUser[]
*/
- public static function getGroupsSubAdmins($gid) {
- $stmt = OC_DB::prepare('SELECT `uid` FROM `*PREFIX*group_admin` WHERE `gid` = ?');
- $result = $stmt->execute(array($gid));
- $uids = array();
- while($row = $result->fetchRow()) {
- $uids[] = $row['uid'];
+ public function getGroupsSubAdmins(IGroup $group) {
+ $qb = $this->dbConn->getQueryBuilder();
+
+ $result = $qb->select('uid')
+ ->from('group_admin')
+ ->where($qb->expr()->eq('gid', $qb->createNamedParameter($group->getGID())))
+ ->execute();
+
+ $users = [];
+ while($row = $result->fetch()) {
+ $users[] = $this->userManager->get($row['uid']);
}
- return $uids;
+
+ return $users;
}
/**
* get all SubAdmins
* @return array
*/
- public static function getAllSubAdmins() {
- $stmt = OC_DB::prepare('SELECT * FROM `*PREFIX*group_admin`');
- $result = $stmt->execute();
- $subadmins = array();
- while($row = $result->fetchRow()) {
- $subadmins[] = $row;
+ public function getAllSubAdmins() {
+ $qb = $this->dbConn->getQueryBuilder();
+
+ $result = $qb->select('*')
+ ->from('group_admin')
+ ->execute();
+
+ $subadmins = [];
+ while($row = $result->fetch()) {
+ $subadmins[] = [
+ 'user' => $this->userManager->get($row['uid']),
+ 'group' => $this->groupManager->get($row['gid'])
+ ];
}
return $subadmins;
}
/**
* checks if a user is a SubAdmin of a group
- * @param string $uid uid of the subadmin
- * @param string $gid gid of the group
+ * @param IUser $user
+ * @param IGroup $group
* @return bool
*/
- public static function isSubAdminofGroup($uid, $gid) {
- $stmt = OC_DB::prepare('SELECT COUNT(*) AS `count` FROM `*PREFIX*group_admin` WHERE `uid` = ? AND `gid` = ?');
- $result = $stmt->execute(array($uid, $gid));
- $result = $result->fetchRow();
- if($result['count'] >= 1) {
- return true;
- }
- return false;
+ public function isSubAdminofGroup(IUser $user, IGroup $group) {
+ $qb = $this->dbConn->getQueryBuilder();
+
+ $result = $qb->select('*')
+ ->from('group_admin')
+ ->where($qb->expr()->eq('gid', $qb->createNamedParameter($group->getGID())))
+ ->andWhere($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
+ ->execute();
+
+ return !empty($result->fetch()) ? true : false;
}
/**
* checks if a user is a SubAdmin
- * @param string $uid uid of the subadmin
+ * @param IUser $user
* @return bool
*/
- public static function isSubAdmin($uid) {
+ public function isSubAdmin(IUser $user) {
// Check if the user is already an admin
- if(OC_Group::inGroup($uid, 'admin' )) {
+ if ($this->groupManager->isAdmin($user->getUID())) {
return true;
}
- $stmt = OC_DB::prepare('SELECT COUNT(*) AS `count` FROM `*PREFIX*group_admin` WHERE `uid` = ?');
- $result = $stmt->execute(array($uid));
- $result = $result->fetchRow();
- if($result['count'] > 0) {
- return true;
- }
- return false;
+ $qb = $this->dbConn->getQueryBuilder();
+
+ $result = $qb->select('gid')
+ ->from('group_admin')
+ ->andWhere($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
+ ->setMaxResults(1)
+ ->execute()
+ ->fetch();
+
+ return $result === false ? false : true;
}
/**
* checks if a user is a accessible by a subadmin
- * @param string $subadmin uid of the subadmin
- * @param string $user uid of the user
+ * @param IUser $subadmin
+ * @param IUser $user
* @return bool
*/
- public static function isUserAccessible($subadmin, $user) {
- if(!self::isSubAdmin($subadmin)) {
+ public function isUserAccessible($subadmin, $user) {
+ if(!$this->isSubAdmin($subadmin)) {
return false;
}
- if(OC_User::isAdminUser($user)) {
+ if($this->groupManager->isAdmin($user->getUID())) {
return false;
}
- $accessiblegroups = self::getSubAdminsGroups($subadmin);
+ $accessiblegroups = $this->getSubAdminsGroups($subadmin);
foreach($accessiblegroups as $accessiblegroup) {
- if(OC_Group::inGroup($user, $accessiblegroup)) {
+ if($accessiblegroup->inGroup($user)) {
return true;
}
}
return false;
}
- /*
- * alias for self::isSubAdminofGroup()
- */
- public static function isGroupAccessible($subadmin, $group) {
- return self::isSubAdminofGroup($subadmin, $group);
- }
-
/**
- * delete all SubAdmins by uid
- * @param array $parameters
+ * delete all SubAdmins by $user
+ * @param IUser $user
* @return boolean
*/
- public static function post_deleteUser($parameters) {
- $stmt = OC_DB::prepare('DELETE FROM `*PREFIX*group_admin` WHERE `uid` = ?');
- $stmt->execute(array($parameters['uid']));
+ private function post_deleteUser($user) {
+ $qb = $this->dbConn->getQueryBuilder();
+
+ $result = $qb->delete('group_admin')
+ ->where($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
+ ->execute();
+
return true;
}
/**
- * delete all SubAdmins by gid
- * @param array $parameters
+ * delete all SubAdmins by $group
+ * @param IGroup $group
* @return boolean
*/
- public static function post_deleteGroup($parameters) {
- $stmt = OC_DB::prepare('DELETE FROM `*PREFIX*group_admin` WHERE `gid` = ?');
- $stmt->execute(array($parameters['gid']));
+ private function post_deleteGroup($group) {
+ $qb = $this->dbConn->getQueryBuilder();
+
+ $result = $qb->delete('group_admin')
+ ->where($qb->expr()->eq('gid', $qb->createNamedParameter($group->getGID())))
+ ->execute();
+
return true;
}
}
diff --git a/lib/private/updater.php b/lib/private/updater.php
index 70d68863788..1e4421c39d7 100644
--- a/lib/private/updater.php
+++ b/lib/private/updater.php
@@ -315,6 +315,9 @@ class Updater extends BasicEmitter {
if ($this->updateStepEnabled) {
$this->doCoreUpgrade();
+ // install new shipped apps on upgrade
+ OC_Installer::installShippedApps();
+
// update all shipped apps
$disabledApps = $this->checkAppsRequirements();
$this->doAppUpgrade();
@@ -337,6 +340,8 @@ class Updater extends BasicEmitter {
}
protected function checkCoreUpgrade() {
+ $this->emit('\OC\Updater', 'dbSimulateUpgradeBefore');
+
// simulate core DB upgrade
\OC_DB::simulateUpdateDbFromStructure(\OC::$SERVERROOT . '/db_structure.xml');
@@ -344,6 +349,8 @@ class Updater extends BasicEmitter {
}
protected function doCoreUpgrade() {
+ $this->emit('\OC\Updater', 'dbUpgradeBefore');
+
// do the real upgrade
\OC_DB::updateDbFromStructure(\OC::$SERVERROOT . '/db_structure.xml');
@@ -355,6 +362,7 @@ class Updater extends BasicEmitter {
*/
protected function checkAppUpgrade($version) {
$apps = \OC_App::getEnabledApps();
+ $this->emit('\OC\Updater', 'appUpgradeCheckBefore');
foreach ($apps as $appId) {
$info = \OC_App::getAppInfo($appId);
@@ -372,6 +380,7 @@ class Updater extends BasicEmitter {
$this->includePreUpdate($appId);
}
if (file_exists(\OC_App::getAppPath($appId) . '/appinfo/database.xml')) {
+ $this->emit('\OC\Updater', 'appSimulateUpdate', array($appId));
\OC_DB::simulateUpdateDbFromStructure(\OC_App::getAppPath($appId) . '/appinfo/database.xml');
}
}
diff --git a/lib/private/util.php b/lib/private/util.php
index 05f10aef1e0..e51edaf0ee3 100644
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -1093,7 +1093,7 @@ class OC_Util {
return $id;
}
- protected static $encryptedToken;
+ protected static $obfuscatedToken;
/**
* Register an get/post call. Important to prevent CSRF attacks.
*
@@ -1107,24 +1107,27 @@ class OC_Util {
*/
public static function callRegister() {
// Use existing token if function has already been called
- if(isset(self::$encryptedToken)) {
- return self::$encryptedToken;
+ if(isset(self::$obfuscatedToken)) {
+ return self::$obfuscatedToken;
}
+ $tokenLength = 30;
+
// Check if a token exists
if (!\OC::$server->getSession()->exists('requesttoken')) {
// No valid token found, generate a new one.
- $requestToken = \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate(30);
+ $requestToken = \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate($tokenLength);
\OC::$server->getSession()->set('requesttoken', $requestToken);
} else {
// Valid token already exists, send it
$requestToken = \OC::$server->getSession()->get('requesttoken');
}
- // Encrypt the token to mitigate breach-like attacks
- $sharedSecret = \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate(10);
- self::$encryptedToken = \OC::$server->getCrypto()->encrypt($requestToken, $sharedSecret) . ':' . $sharedSecret;
- return self::$encryptedToken;
+ // XOR the token to mitigate breach-like attacks
+ $sharedSecret = \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate($tokenLength);
+ self::$obfuscatedToken = base64_encode($requestToken ^ $sharedSecret) .':'.$sharedSecret;
+
+ return self::$obfuscatedToken;
}
/**
diff --git a/settings/controller/checksetupcontroller.php b/settings/controller/checksetupcontroller.php
index 2ff55fc72c9..bd0737aacc4 100644
--- a/settings/controller/checksetupcontroller.php
+++ b/settings/controller/checksetupcontroller.php
@@ -195,7 +195,7 @@ 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
@@ -244,7 +244,7 @@ class CheckSetupController extends Controller {
// there are two different memcached modules for PHP
// we only support memcached and not memcache
// https://code.google.com/p/memcached/wiki/PHPClientComparison
- return !extension_loaded('memcached') && extension_loaded('memcache');
+ return !(!extension_loaded('memcached') && extension_loaded('memcache'));
}
/**
diff --git a/settings/controller/userscontroller.php b/settings/controller/userscontroller.php
index d9b6ba7f721..ddabd308a50 100644
--- a/settings/controller/userscontroller.php
+++ b/settings/controller/userscontroller.php
@@ -167,7 +167,7 @@ class UsersController extends Controller {
'name' => $user->getUID(),
'displayname' => $user->getDisplayName(),
'groups' => (empty($userGroups)) ? $this->groupManager->getUserGroupIds($user) : $userGroups,
- 'subadmin' => \OC_SubAdmin::getSubAdminsGroups($user->getUID()),
+ 'subadmin' => $this->subAdminFactory->getSubAdminsOfGroups($user->getUID()),
'quota' => $this->config->getUserValue($user->getUID(), 'files', 'quota', 'default'),
'storageLocation' => $user->getHome(),
'lastLogin' => $user->getLastLogin() * 1000,
diff --git a/settings/js/apps.js b/settings/js/apps.js
index d51c642c9c9..987153b778c 100644
--- a/settings/js/apps.js
+++ b/settings/js/apps.js
@@ -161,8 +161,8 @@ OC.Settings.Apps = OC.Settings.Apps || {
var page = $('#app-' + app.id);
- // image loading kung-fu
- if (app.preview) {
+ // image loading kung-fu (IE doesn't properly scale SVGs, so disable app icons)
+ if (app.preview && !OC.Util.isIE()) {
var currentImage = new Image();
currentImage.src = app.preview;
diff --git a/tests/lib/api.php b/tests/lib/api.php
index f8f03965711..1d1f97c4942 100644
--- a/tests/lib/api.php
+++ b/tests/lib/api.php
@@ -14,11 +14,13 @@ class Test_API extends \Test\TestCase {
* @param string $message
*/
function buildResponse($shipped, $data, $code, $message=null) {
- return array(
+ $resp = new OC_OCS_Result($data, $code, $message);
+ $resp->addHeader('KEY', 'VALUE');
+ return [
'shipped' => $shipped,
- 'response' => new OC_OCS_Result($data, $code, $message),
+ 'response' => $resp,
'app' => $this->getUniqueID('testapp_'),
- );
+ ];
}
// Validate details of the result
@@ -79,11 +81,11 @@ class Test_API extends \Test\TestCase {
}
function dataProviderTestOneResult() {
- return array(
- array(100, true),
- array(101, false),
- array(997, false),
- );
+ return [
+ [100, true],
+ [101, false],
+ [997, false],
+ ];
}
/**
@@ -94,47 +96,47 @@ class Test_API extends \Test\TestCase {
*/
public function testOneResult($statusCode, $succeeded) {
// Setup some data arrays
- $data1 = array(
- 'users' => array(
- 'tom' => array(
+ $data1 = [
+ 'users' => [
+ 'tom' => [
'key' => 'value',
- ),
- 'frank' => array(
+ ],
+ 'frank' => [
'key' => 'value',
- ),
- ));
+ ],
+ ]];
// Test merging one success result
$response = $this->buildResponse(true, $data1, $statusCode);
- $result = OC_API::mergeResponses(array($response));
+ $result = OC_API::mergeResponses([$response]);
$this->assertEquals($response['response'], $result);
$this->checkResult($result, $succeeded);
}
function dataProviderTestMergeResponses() {
- return array(
+ return [
// Two shipped success results
- array(true, 100, true, 100, true),
+ [true, 100, true, 100, true],
// Two shipped results, one success and one failure
- array(true, 100, true, 998, false),
+ [true, 100, true, 998, false],
// Two shipped results, both failure
- array(true, 997, true, 998, false),
+ [true, 997, true, 998, false],
// Two third party success results
- array(false, 100, false, 100, true),
+ [false, 100, false, 100, true],
// Two third party results, one success and one failure
- array(false, 100, false, 998, false),
+ [false, 100, false, 998, false],
// Two third party results, both failure
- array(false, 997, false, 998, false),
+ [false, 997, false, 998, false],
// One of each, both success
- array(false, 100, true, 100, true),
- array(true, 100, false, 100, true),
+ [false, 100, true, 100, true],
+ [true, 100, false, 100, true],
// One of each, both failure
- array(false, 997, true, 998, false),
+ [false, 997, true, 998, false],
// One of each, shipped success
- array(false, 997, true, 100, true),
+ [false, 997, true, 100, true],
// One of each, third party success
- array(false, 100, true, 998, false),
- );
+ [false, 100, true, 998, false],
+ ];
}
/**
* @dataProvider dataProviderTestMergeResponses
@@ -175,9 +177,11 @@ class Test_API extends \Test\TestCase {
$this->checkResult($result, $succeeded);
$resultData = $result->getData();
$resultMeta = $result->getMeta();
+ $resultHeaders = $result->getHeaders();
$resultStatusCode = $result->getStatusCode();
$this->assertArrayHasKey('jan', $resultData['users']);
+ $this->assertArrayHasKey('KEY', $resultHeaders);
// check if the returned status message matches the selected status code
if ($resultStatusCode === 997) {
diff --git a/tests/lib/appframework/controller/ApiControllerTest.php b/tests/lib/appframework/controller/ApiControllerTest.php
index 573fe7f3bad..137e5950f67 100644
--- a/tests/lib/appframework/controller/ApiControllerTest.php
+++ b/tests/lib/appframework/controller/ApiControllerTest.php
@@ -38,7 +38,6 @@ class ApiControllerTest extends \Test\TestCase {
$request = new Request(
['server' => ['HTTP_ORIGIN' => 'test']],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$this->controller = new ChildApiController('app', $request, 'verbs',
diff --git a/tests/lib/appframework/controller/ControllerTest.php b/tests/lib/appframework/controller/ControllerTest.php
index c847525c263..1493c0c3175 100644
--- a/tests/lib/appframework/controller/ControllerTest.php
+++ b/tests/lib/appframework/controller/ControllerTest.php
@@ -76,7 +76,6 @@ class ControllerTest extends \Test\TestCase {
'method' => 'hi',
],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
diff --git a/tests/lib/appframework/controller/OCSControllerTest.php b/tests/lib/appframework/controller/OCSControllerTest.php
index 292a56e3caa..92b092cf0e9 100644
--- a/tests/lib/appframework/controller/OCSControllerTest.php
+++ b/tests/lib/appframework/controller/OCSControllerTest.php
@@ -43,7 +43,6 @@ class OCSControllerTest extends \Test\TestCase {
],
],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$controller = new ChildOCSController('app', $request, 'verbs',
@@ -65,7 +64,6 @@ class OCSControllerTest extends \Test\TestCase {
$controller = new ChildOCSController('app', new Request(
[],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
));
$expected = "<?xml version=\"1.0\"?>\n" .
@@ -98,7 +96,6 @@ class OCSControllerTest extends \Test\TestCase {
$controller = new ChildOCSController('app', new Request(
[],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
));
$expected = "<?xml version=\"1.0\"?>\n" .
@@ -131,7 +128,6 @@ class OCSControllerTest extends \Test\TestCase {
$controller = new ChildOCSController('app', new Request(
[],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
));
$expected = '{"ocs":{"meta":{"status":"failure","statuscode":400,"message":"OK",' .
diff --git a/tests/lib/appframework/dependencyinjection/DIContainerTest.php b/tests/lib/appframework/dependencyinjection/DIContainerTest.php
index 598e70beffc..0cbdddbb205 100644
--- a/tests/lib/appframework/dependencyinjection/DIContainerTest.php
+++ b/tests/lib/appframework/dependencyinjection/DIContainerTest.php
@@ -74,7 +74,6 @@ class DIContainerTest extends \Test\TestCase {
$this->container['Request'] = new Request(
['method' => 'GET'],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$security = $this->container['SecurityMiddleware'];
diff --git a/tests/lib/appframework/http/DispatcherTest.php b/tests/lib/appframework/http/DispatcherTest.php
index c25fd7b6f85..02c86df8e72 100644
--- a/tests/lib/appframework/http/DispatcherTest.php
+++ b/tests/lib/appframework/http/DispatcherTest.php
@@ -295,7 +295,6 @@ class DispatcherTest extends \Test\TestCase {
'method' => 'POST'
],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$this->dispatcher = new Dispatcher(
@@ -323,7 +322,6 @@ class DispatcherTest extends \Test\TestCase {
'method' => 'POST',
],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$this->dispatcher = new Dispatcher(
@@ -354,7 +352,6 @@ class DispatcherTest extends \Test\TestCase {
'method' => 'GET'
],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$this->dispatcher = new Dispatcher(
@@ -384,7 +381,6 @@ class DispatcherTest extends \Test\TestCase {
'method' => 'GET'
],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$this->dispatcher = new Dispatcher(
@@ -415,7 +411,6 @@ class DispatcherTest extends \Test\TestCase {
'method' => 'PUT'
],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$this->dispatcher = new Dispatcher(
@@ -448,7 +443,6 @@ class DispatcherTest extends \Test\TestCase {
'method' => 'POST'
],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$this->dispatcher = new Dispatcher(
diff --git a/tests/lib/appframework/http/RequestTest.php b/tests/lib/appframework/http/RequestTest.php
index bb9910b6a46..f628a30f1da 100644
--- a/tests/lib/appframework/http/RequestTest.php
+++ b/tests/lib/appframework/http/RequestTest.php
@@ -54,7 +54,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
$vars,
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -87,7 +86,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
$vars,
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -110,7 +108,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
$vars,
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -130,7 +127,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
$vars,
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -150,7 +146,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
$vars,
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -167,7 +162,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
$vars,
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -189,7 +183,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
$vars,
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -213,7 +206,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
$vars,
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -235,7 +227,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
$vars,
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -260,7 +251,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
$vars,
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -281,7 +271,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
$vars,
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -306,7 +295,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
$vars,
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -336,7 +324,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
$vars,
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -358,7 +345,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
$vars,
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -382,7 +368,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
[],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -394,7 +379,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
[],
\OC::$server->getSecureRandom(),
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -419,7 +403,6 @@ class RequestTest extends \Test\TestCase {
],
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -448,7 +431,6 @@ class RequestTest extends \Test\TestCase {
],
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -477,7 +459,6 @@ class RequestTest extends \Test\TestCase {
],
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -510,7 +491,6 @@ class RequestTest extends \Test\TestCase {
],
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -561,7 +541,6 @@ class RequestTest extends \Test\TestCase {
],
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -589,7 +568,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
[],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -611,7 +589,6 @@ class RequestTest extends \Test\TestCase {
],
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -622,7 +599,6 @@ class RequestTest extends \Test\TestCase {
],
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -646,7 +622,6 @@ class RequestTest extends \Test\TestCase {
],
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -667,7 +642,6 @@ class RequestTest extends \Test\TestCase {
],
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -684,7 +658,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
[],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -705,7 +678,6 @@ class RequestTest extends \Test\TestCase {
],
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -727,7 +699,6 @@ class RequestTest extends \Test\TestCase {
]
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -816,7 +787,6 @@ class RequestTest extends \Test\TestCase {
]
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -833,7 +803,6 @@ class RequestTest extends \Test\TestCase {
]
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -851,7 +820,6 @@ class RequestTest extends \Test\TestCase {
]
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -869,7 +837,6 @@ class RequestTest extends \Test\TestCase {
]
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -897,7 +864,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
[],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -919,7 +885,6 @@ class RequestTest extends \Test\TestCase {
],
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -946,7 +911,6 @@ class RequestTest extends \Test\TestCase {
],
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -973,7 +937,6 @@ class RequestTest extends \Test\TestCase {
],
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -990,7 +953,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
[],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -1018,7 +980,6 @@ class RequestTest extends \Test\TestCase {
$request = new Request(
[],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -1034,7 +995,6 @@ class RequestTest extends \Test\TestCase {
]
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -1055,7 +1015,6 @@ class RequestTest extends \Test\TestCase {
]
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -1076,7 +1035,6 @@ class RequestTest extends \Test\TestCase {
]
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -1099,7 +1057,6 @@ class RequestTest extends \Test\TestCase {
]
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -1122,7 +1079,6 @@ class RequestTest extends \Test\TestCase {
]
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -1145,7 +1101,6 @@ class RequestTest extends \Test\TestCase {
]
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -1168,7 +1123,6 @@ class RequestTest extends \Test\TestCase {
]
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -1223,7 +1177,6 @@ class RequestTest extends \Test\TestCase {
]
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
);
@@ -1263,7 +1216,6 @@ class RequestTest extends \Test\TestCase {
]
],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
])
@@ -1277,25 +1229,17 @@ class RequestTest extends \Test\TestCase {
}
public function testPassesCSRFCheckWithGet() {
- $crypto = $this->getMock('\OCP\Security\ICrypto');
- $crypto
- ->expects($this->once())
- ->method('decrypt')
- ->with('1c637c4147e40a8a8f09428ec2059cebea3480c27b402b4e793c69710a731513|wlXxNUaFqHuQnZr5|e6ab49c9e0e20c8d3607e02f1d8e6ec17ad6020ae10b7d64ab4b0a6318c0875940943a6aa303dc090fea0b4cd5b9fb8bcbecac4308a2bd15d9f369cdc22121a4', 'secret')
- ->will($this->returnValue('MyStoredRequestToken'));
-
/** @var Request $request */
$request = $this->getMockBuilder('\OC\AppFramework\Http\Request')
->setMethods(['getScriptName'])
->setConstructorArgs([
[
'get' => [
- 'requesttoken' => '1c637c4147e40a8a8f09428ec2059cebea3480c27b402b4e793c69710a731513|wlXxNUaFqHuQnZr5|e6ab49c9e0e20c8d3607e02f1d8e6ec17ad6020ae10b7d64ab4b0a6318c0875940943a6aa303dc090fea0b4cd5b9fb8bcbecac4308a2bd15d9f369cdc22121a4:secret',
+ 'requesttoken' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
],
'requesttoken' => 'MyStoredRequestToken',
],
$this->secureRandom,
- $crypto,
$this->config,
$this->stream
])
@@ -1305,25 +1249,17 @@ class RequestTest extends \Test\TestCase {
}
public function testPassesCSRFCheckWithPost() {
- $crypto = $this->getMock('\OCP\Security\ICrypto');
- $crypto
- ->expects($this->once())
- ->method('decrypt')
- ->with('1c637c4147e40a8a8f09428ec2059cebea3480c27b402b4e793c69710a731513|wlXxNUaFqHuQnZr5|e6ab49c9e0e20c8d3607e02f1d8e6ec17ad6020ae10b7d64ab4b0a6318c0875940943a6aa303dc090fea0b4cd5b9fb8bcbecac4308a2bd15d9f369cdc22121a4', 'secret')
- ->will($this->returnValue('MyStoredRequestToken'));
-
/** @var Request $request */
$request = $this->getMockBuilder('\OC\AppFramework\Http\Request')
->setMethods(['getScriptName'])
->setConstructorArgs([
[
'post' => [
- 'requesttoken' => '1c637c4147e40a8a8f09428ec2059cebea3480c27b402b4e793c69710a731513|wlXxNUaFqHuQnZr5|e6ab49c9e0e20c8d3607e02f1d8e6ec17ad6020ae10b7d64ab4b0a6318c0875940943a6aa303dc090fea0b4cd5b9fb8bcbecac4308a2bd15d9f369cdc22121a4:secret',
+ 'requesttoken' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
],
'requesttoken' => 'MyStoredRequestToken',
],
$this->secureRandom,
- $crypto,
$this->config,
$this->stream
])
@@ -1333,24 +1269,17 @@ class RequestTest extends \Test\TestCase {
}
public function testPassesCSRFCheckWithHeader() {
- $crypto = $this->getMock('\OCP\Security\ICrypto');
- $crypto
- ->expects($this->once())
- ->method('decrypt')
- ->with('1c637c4147e40a8a8f09428ec2059cebea3480c27b402b4e793c69710a731513|wlXxNUaFqHuQnZr5|e6ab49c9e0e20c8d3607e02f1d8e6ec17ad6020ae10b7d64ab4b0a6318c0875940943a6aa303dc090fea0b4cd5b9fb8bcbecac4308a2bd15d9f369cdc22121a4', 'secret')
- ->will($this->returnValue('MyStoredRequestToken'));
/** @var Request $request */
$request = $this->getMockBuilder('\OC\AppFramework\Http\Request')
->setMethods(['getScriptName'])
->setConstructorArgs([
[
'server' => [
- 'HTTP_REQUESTTOKEN' => '1c637c4147e40a8a8f09428ec2059cebea3480c27b402b4e793c69710a731513|wlXxNUaFqHuQnZr5|e6ab49c9e0e20c8d3607e02f1d8e6ec17ad6020ae10b7d64ab4b0a6318c0875940943a6aa303dc090fea0b4cd5b9fb8bcbecac4308a2bd15d9f369cdc22121a4:secret',
+ 'HTTP_REQUESTTOKEN' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
],
'requesttoken' => 'MyStoredRequestToken',
],
$this->secureRandom,
- $crypto,
$this->config,
$this->stream
])
@@ -1359,6 +1288,9 @@ class RequestTest extends \Test\TestCase {
$this->assertTrue($request->passesCSRFCheck());
}
+ /**
+ * @return array
+ */
public function invalidTokenDataProvider() {
return [
['InvalidSentToken'],
@@ -1373,8 +1305,6 @@ class RequestTest extends \Test\TestCase {
* @param string $invalidToken
*/
public function testPassesCSRFCheckWithInvalidToken($invalidToken) {
- $crypto = new Crypto($this->config, $this->secureRandom);
-
/** @var Request $request */
$request = $this->getMockBuilder('\OC\AppFramework\Http\Request')
->setMethods(['getScriptName'])
@@ -1386,7 +1316,6 @@ class RequestTest extends \Test\TestCase {
'requesttoken' => 'MyStoredRequestToken',
],
$this->secureRandom,
- $crypto,
$this->config,
$this->stream
])
@@ -1402,7 +1331,6 @@ class RequestTest extends \Test\TestCase {
->setConstructorArgs([
[],
$this->secureRandom,
- $this->getMock('\OCP\Security\ICrypto'),
$this->config,
$this->stream
])
diff --git a/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php b/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php
index eab45b03c98..a8731525798 100644
--- a/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php
+++ b/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php
@@ -133,7 +133,6 @@ class MiddlewareDispatcherTest extends \Test\TestCase {
new Request(
['method' => 'GET'],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
)
]
diff --git a/tests/lib/appframework/middleware/MiddlewareTest.php b/tests/lib/appframework/middleware/MiddlewareTest.php
index 8e077b37e2f..33f04e1383d 100644
--- a/tests/lib/appframework/middleware/MiddlewareTest.php
+++ b/tests/lib/appframework/middleware/MiddlewareTest.php
@@ -61,7 +61,6 @@ class MiddlewareTest extends \Test\TestCase {
new Request(
[],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
)
]
diff --git a/tests/lib/appframework/middleware/security/CORSMiddlewareTest.php b/tests/lib/appframework/middleware/security/CORSMiddlewareTest.php
index f5e6106dc3a..ca526fb859c 100644
--- a/tests/lib/appframework/middleware/security/CORSMiddlewareTest.php
+++ b/tests/lib/appframework/middleware/security/CORSMiddlewareTest.php
@@ -42,7 +42,6 @@ class CORSMiddlewareTest extends \Test\TestCase {
]
],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$this->reflector->reflect($this, __FUNCTION__);
@@ -62,7 +61,6 @@ class CORSMiddlewareTest extends \Test\TestCase {
]
],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$middleware = new CORSMiddleware($request, $this->reflector, $this->session);
@@ -80,7 +78,6 @@ class CORSMiddlewareTest extends \Test\TestCase {
$request = new Request(
[],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$this->reflector->reflect($this, __FUNCTION__);
@@ -104,7 +101,6 @@ class CORSMiddlewareTest extends \Test\TestCase {
]
],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$this->reflector->reflect($this, __FUNCTION__);
@@ -123,7 +119,6 @@ class CORSMiddlewareTest extends \Test\TestCase {
$request = new Request(
[],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$this->reflector->reflect($this, __FUNCTION__);
@@ -149,7 +144,6 @@ class CORSMiddlewareTest extends \Test\TestCase {
'PHP_AUTH_PW' => 'pass'
]],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$this->session->expects($this->once())
@@ -175,7 +169,6 @@ class CORSMiddlewareTest extends \Test\TestCase {
'PHP_AUTH_PW' => 'pass'
]],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$this->session->expects($this->once())
@@ -197,7 +190,6 @@ class CORSMiddlewareTest extends \Test\TestCase {
'PHP_AUTH_PW' => 'pass'
]],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$middleware = new CORSMiddleware($request, $this->reflector, $this->session);
@@ -214,7 +206,6 @@ class CORSMiddlewareTest extends \Test\TestCase {
'PHP_AUTH_PW' => 'pass'
]],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$middleware = new CORSMiddleware($request, $this->reflector, $this->session);
@@ -235,7 +226,6 @@ class CORSMiddlewareTest extends \Test\TestCase {
'PHP_AUTH_PW' => 'pass'
]],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$middleware = new CORSMiddleware($request, $this->reflector, $this->session);
diff --git a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php
index 3b4d7987e94..347a0423ea6 100644
--- a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php
+++ b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php
@@ -322,7 +322,6 @@ class SecurityMiddlewareTest extends \Test\TestCase {
]
],
$this->getMock('\OCP\Security\ISecureRandom'),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$this->middleware = $this->getMiddleware(true, true);
diff --git a/tests/lib/appframework/middleware/sessionmiddlewaretest.php b/tests/lib/appframework/middleware/sessionmiddlewaretest.php
index 06390e96d4c..11c1600f515 100644
--- a/tests/lib/appframework/middleware/sessionmiddlewaretest.php
+++ b/tests/lib/appframework/middleware/sessionmiddlewaretest.php
@@ -36,7 +36,6 @@ class SessionMiddlewareTest extends \Test\TestCase {
$this->request = new Request(
[],
$this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock(),
- $this->getMock('\OCP\Security\ICrypto'),
$this->getMock('\OCP\IConfig')
);
$this->reflector = new ControllerMethodReflector();
diff --git a/tests/lib/subadmin.php b/tests/lib/subadmin.php
new file mode 100644
index 00000000000..0855e514c7e
--- /dev/null
+++ b/tests/lib/subadmin.php
@@ -0,0 +1,264 @@
+<?php
+/**
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @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 Test;
+
+class SubAdmin extends \Test\TestCase {
+
+ /** @var \OCP\IUserManager */
+ private $userManager;
+
+ /** @var \OCP\IGroupManager */
+ private $groupManager;
+
+ /** @var \OCP\IDBConnection */
+ private $dbConn;
+
+ /** @var \OCP\IUser[] */
+ private $users;
+
+ /** @var \OCP\IGroup[] */
+ private $groups;
+
+ public function setup() {
+ $this->users = [];
+ $this->groups = [];
+
+ $this->userManager = \OC::$server->getUserManager();
+ $this->groupManager = \OC::$server->getGroupManager();
+ $this->dbConn = \OC::$server->getDatabaseConnection();
+
+ // Create 3 users and 3 groups
+ for ($i = 0; $i < 3; $i++) {
+ $this->users[] = $this->userManager->createUser('user'.$i, 'user');
+ $this->groups[] = $this->groupManager->createGroup('group'.$i);
+ }
+
+ // Create admin group
+ if (!$this->groupManager->groupExists('admin')) {
+ $this->groupManager->createGroup('admin');
+ }
+ }
+
+ public function tearDown() {
+ foreach($this->users as $user) {
+ $user->delete();
+ }
+
+ foreach($this->groups as $group) {
+ $group->delete();
+ }
+ }
+
+ public function testCreateSubAdmin() {
+ $subAdmin = new \OC\SubAdmin($this->userManager, $this->groupManager, $this->dbConn);
+ $this->assertTrue($subAdmin->createSubAdmin($this->users[0], $this->groups[0]));
+
+ // Look for subadmin in the database
+ $qb = $this->dbConn->getQueryBuilder();
+ $result = $qb->select(['gid', 'uid'])
+ ->from('group_admin')
+ ->where($qb->expr()->eq('gid', $qb->createNamedParameter($this->groups[0]->getGID())))
+ ->andWHere($qb->expr()->eq('uid', $qb->createNamedParameter($this->users[0]->getUID())))
+ ->execute()
+ ->fetch();
+ $this->assertEquals(
+ [
+ 'gid' => $this->groups[0]->getGID(),
+ 'uid' => $this->users[0]->getUID()
+ ], $result);
+
+ // Delete subadmin
+ $result = $qb->delete('*PREFIX*group_admin')
+ ->where($qb->expr()->eq('gid', $qb->createNamedParameter($this->groups[0]->getGID())))
+ ->andWHere($qb->expr()->eq('uid', $qb->createNamedParameter($this->users[0]->getUID())))
+ ->execute();
+ }
+
+ public function testDeleteSubAdmin() {
+ $subAdmin = new \OC\SubAdmin($this->userManager, $this->groupManager, $this->dbConn);
+ $this->assertTrue($subAdmin->createSubAdmin($this->users[0], $this->groups[0]));
+ $this->assertTrue($subAdmin->deleteSubAdmin($this->users[0], $this->groups[0]));
+
+ // DB query should be empty
+ $qb = $this->dbConn->getQueryBuilder();
+ $result = $qb->select(['gid', 'uid'])
+ ->from('group_admin')
+ ->where($qb->expr()->eq('gid', $qb->createNamedParameter($this->groups[0]->getGID())))
+ ->andWHere($qb->expr()->eq('uid', $qb->createNamedParameter($this->users[0]->getUID())))
+ ->execute()
+ ->fetch();
+ $this->assertEmpty($result);
+ }
+
+ public function testGetSubAdminsGroups() {
+ $subAdmin = new \OC\SubAdmin($this->userManager, $this->groupManager, $this->dbConn);
+ $this->assertTrue($subAdmin->createSubAdmin($this->users[0], $this->groups[0]));
+ $this->assertTrue($subAdmin->createSubAdmin($this->users[0], $this->groups[1]));
+
+ $result = $subAdmin->getSubAdminsGroups($this->users[0]);
+
+ $this->assertContains($this->groups[0], $result);
+ $this->assertContains($this->groups[1], $result);
+ $this->assertNotContains($this->groups[2], $result);
+
+ $this->assertTrue($subAdmin->deleteSubAdmin($this->users[0], $this->groups[0]));
+ $this->assertTrue($subAdmin->deleteSubAdmin($this->users[0], $this->groups[1]));
+ }
+
+ public function testGetGroupsSubAdmins() {
+ $subAdmin = new \OC\SubAdmin($this->userManager, $this->groupManager, $this->dbConn);
+ $this->assertTrue($subAdmin->createSubAdmin($this->users[0], $this->groups[0]));
+ $this->assertTrue($subAdmin->createSubAdmin($this->users[1], $this->groups[0]));
+
+ $result = $subAdmin->getGroupsSubAdmins($this->groups[0]);
+
+ $this->assertContains($this->users[0], $result);
+ $this->assertContains($this->users[1], $result);
+ $this->assertNotContains($this->users[2], $result);
+
+ $this->assertTrue($subAdmin->deleteSubAdmin($this->users[0], $this->groups[0]));
+ $this->assertTrue($subAdmin->deleteSubAdmin($this->users[1], $this->groups[0]));
+ }
+
+ public function testGetAllSubAdmin() {
+ $subAdmin = new \OC\SubAdmin($this->userManager, $this->groupManager, $this->dbConn);
+
+ $this->assertTrue($subAdmin->createSubAdmin($this->users[0], $this->groups[0]));
+ $this->assertTrue($subAdmin->createSubAdmin($this->users[1], $this->groups[1]));
+ $this->assertTrue($subAdmin->createSubAdmin($this->users[2], $this->groups[1]));
+
+ $result = $subAdmin->getAllSubAdmins();
+
+ $this->assertContains(['user' => $this->users[0], 'group' => $this->groups[0]], $result);
+ $this->assertContains(['user' => $this->users[1], 'group' => $this->groups[1]], $result);
+ $this->assertContains(['user' => $this->users[2], 'group' => $this->groups[1]], $result);
+ }
+
+ public function testIsSubAdminofGroup() {
+ $subAdmin = new \OC\SubAdmin($this->userManager, $this->groupManager, $this->dbConn);
+ $this->assertTrue($subAdmin->createSubAdmin($this->users[0], $this->groups[0]));
+
+ $this->assertTrue($subAdmin->isSubAdminOfGroup($this->users[0], $this->groups[0]));
+ $this->assertFalse($subAdmin->isSubAdminOfGroup($this->users[0], $this->groups[1]));
+ $this->assertFalse($subAdmin->isSubAdminOfGroup($this->users[1], $this->groups[0]));
+
+ $this->assertTrue($subAdmin->deleteSubAdmin($this->users[0], $this->groups[0]));
+ }
+
+ public function testIsSubAdmin() {
+ $subAdmin = new \OC\SubAdmin($this->userManager, $this->groupManager, $this->dbConn);
+ $this->assertTrue($subAdmin->createSubAdmin($this->users[0], $this->groups[0]));
+
+ $this->assertTrue($subAdmin->isSubAdmin($this->users[0]));
+ $this->assertFalse($subAdmin->isSubAdmin($this->users[1]));
+
+ $this->assertTrue($subAdmin->deleteSubAdmin($this->users[0], $this->groups[0]));
+ }
+
+ public function testIsSubAdminAsAdmin() {
+ $subAdmin = new \OC\SubAdmin($this->userManager, $this->groupManager, $this->dbConn);
+ $this->groupManager->get('admin')->addUser($this->users[0]);
+
+ $this->assertTrue($subAdmin->isSubAdmin($this->users[0]));
+ }
+
+ public function testIsUserAccessible() {
+ $subAdmin = new \OC\SubAdmin($this->userManager, $this->groupManager, $this->dbConn);
+ $this->groups[0]->addUser($this->users[1]);
+ $this->groups[1]->addUser($this->users[1]);
+ $this->groups[1]->addUser($this->users[2]);
+ $this->assertTrue($subAdmin->createSubAdmin($this->users[0], $this->groups[0]));
+ $this->assertTrue($subAdmin->createSubAdmin($this->users[2], $this->groups[2]));
+
+ $this->assertTrue($subAdmin->isUserAccessible($this->users[0], $this->users[1]));
+ $this->assertFalse($subAdmin->isUserAccessible($this->users[0], $this->users[2]));
+ $this->assertFalse($subAdmin->isUserAccessible($this->users[2], $this->users[0]));
+
+ $this->assertTrue($subAdmin->deleteSubAdmin($this->users[0], $this->groups[0]));
+ $this->assertTrue($subAdmin->deleteSubAdmin($this->users[2], $this->groups[2]));
+ }
+
+ public function testIsUserAccessibleAsUser() {
+ $subAdmin = new \OC\SubAdmin($this->userManager, $this->groupManager, $this->dbConn);
+ $this->assertFalse($subAdmin->isUserAccessible($this->users[0], $this->users[1]));
+ }
+
+ public function testIsUserAccessibleAdmin() {
+ $subAdmin = new \OC\SubAdmin($this->userManager, $this->groupManager, $this->dbConn);
+ $this->assertTrue($subAdmin->createSubAdmin($this->users[0], $this->groups[0]));
+ $this->groupManager->get('admin')->addUser($this->users[1]);
+
+ $this->assertFalse($subAdmin->isUserAccessible($this->users[0], $this->users[1]));
+
+ }
+
+ public function testPostDeleteUser() {
+ $subAdmin = new \OC\SubAdmin($this->userManager, $this->groupManager, $this->dbConn);
+
+ $user = array_shift($this->users);
+ foreach($this->groups as $group) {
+ $this->assertTrue($subAdmin->createSubAdmin($user, $group));
+ }
+
+ $user->delete();
+ $this->assertEmpty($subAdmin->getAllSubAdmins());
+ }
+
+ public function testPostDeleteGroup() {
+ $subAdmin = new \OC\SubAdmin($this->userManager, $this->groupManager, $this->dbConn);
+
+ $group = array_shift($this->groups);
+ foreach($this->users as $user) {
+ $this->assertTrue($subAdmin->createSubAdmin($user, $group));
+ }
+
+ $group->delete();
+ $this->assertEmpty($subAdmin->getAllSubAdmins());
+ }
+
+ public function testHooks() {
+ $subAdmin = new \OC\SubAdmin($this->userManager, $this->groupManager, $this->dbConn);
+
+ $test = $this;
+ $u = $this->users[0];
+ $g = $this->groups[0];
+ $count = 0;
+
+ $subAdmin->listen('\OC\SubAdmin', 'postCreateSubAdmin', function ($user, $group) use ($test, $u, $g, &$count) {
+ $test->assertEquals($u->getUID(), $user->getUID());
+ $test->assertEquals($g->getGID(), $group->getGID());
+ $count++;
+ });
+
+ $subAdmin->listen('\OC\SubAdmin', 'postDeleteSubAdmin', function ($user, $group) use ($test, $u, $g, &$count) {
+ $test->assertEquals($u->getUID(), $user->getUID());
+ $test->assertEquals($g->getGID(), $group->getGID());
+ $count++;
+ });
+
+ $this->assertTrue($subAdmin->createSubAdmin($u, $g));
+ $this->assertEquals(1, $count);
+
+ $this->assertTrue($subAdmin->deleteSubAdmin($u, $g));
+ $this->assertEquals(2, $count);
+ }
+
+}
diff --git a/tests/lib/util.php b/tests/lib/util.php
index eaa3d0795e3..9974e799d08 100644
--- a/tests/lib/util.php
+++ b/tests/lib/util.php
@@ -91,7 +91,7 @@ class Test_Util extends \Test\TestCase {
function testCallRegister() {
$result = strlen(OC_Util::callRegister());
- $this->assertEquals(221, $result);
+ $this->assertEquals(71, $result);
}
function testSanitizeHTML() {
diff --git a/tests/settings/controller/userscontrollertest.php b/tests/settings/controller/userscontrollertest.php
index 6fab43d6a16..408ddc45589 100644
--- a/tests/settings/controller/userscontrollertest.php
+++ b/tests/settings/controller/userscontrollertest.php
@@ -153,6 +153,22 @@ class UsersControllerTest extends \Test\TestCase {
404, 'admin@bar.com',
2323, 'bar@dummy.com'));
+ $this->container['SubAdminFactory']
+ ->expects($this->at(0))
+ ->method('getSubAdminsOfGroups')
+ ->with('foo')
+ ->will($this->returnValue([]));
+ $this->container['SubAdminFactory']
+ ->expects($this->at(1))
+ ->method('getSubAdminsOfGroups')
+ ->with('admin')
+ ->will($this->returnValue([]));
+ $this->container['SubAdminFactory']
+ ->expects($this->at(2))
+ ->method('getSubAdminsOfGroups')
+ ->with('bar')
+ ->will($this->returnValue([]));
+
$expectedResponse = new DataResponse(
array(
0 => array(
@@ -199,11 +215,6 @@ class UsersControllerTest extends \Test\TestCase {
public function testIndexSubAdmin() {
$this->container['IsAdmin'] = false;
- $this->container['SubAdminFactory']
- ->expects($this->once())
- ->method('getSubAdminsOfGroups')
- ->with('username')
- ->will($this->returnValue(['SubGroup1', 'SubGroup2']));
$user = $this->getMockBuilder('\OC\User\User')
->disableOriginalConstructor()->getMock();
@@ -321,6 +332,15 @@ class UsersControllerTest extends \Test\TestCase {
2323, 'bar@dummy.com'
));
+ $this->container['SubAdminFactory']
+ ->method('getSubAdminsOfGroups')
+ ->will($this->returnValueMap([
+ ['username' , ['SubGroup1', 'SubGroup2']],
+ ['foo', []],
+ ['admin', []],
+ ['bar', []],
+ ]));
+
$expectedResponse = new DataResponse(
[
0 => [
@@ -452,6 +472,23 @@ class UsersControllerTest extends \Test\TestCase {
404, 'admin@bar.com',
2323, 'bar@dummy.com'));
+ $this->container['SubAdminFactory']
+ ->expects($this->at(0))
+ ->method('getSubAdminsOfGroups')
+ ->with('foo')
+ ->will($this->returnValue([]));
+ $this->container['SubAdminFactory']
+ ->expects($this->at(1))
+ ->method('getSubAdminsOfGroups')
+ ->with('admin')
+ ->will($this->returnValue([]));
+ $this->container['SubAdminFactory']
+ ->expects($this->at(2))
+ ->method('getSubAdminsOfGroups')
+ ->with('bar')
+ ->will($this->returnValue([]));
+
+
$expectedResponse = new DataResponse(
array(
0 => array(
@@ -532,6 +569,12 @@ class UsersControllerTest extends \Test\TestCase {
->with('')
->will($this->returnValue([$user]));
+ $this->container['SubAdminFactory']
+ ->expects($this->once())
+ ->method('getSubAdminsOfGroups')
+ ->with('foo')
+ ->will($this->returnValue([]));
+
$expectedResponse = new DataResponse(
array(
0 => array(
@@ -591,6 +634,11 @@ class UsersControllerTest extends \Test\TestCase {
->method('createUser')
->will($this->onConsecutiveCalls($user));
+ $this->container['SubAdminFactory']
+ ->expects($this->once())
+ ->method('getSubAdminsOfGroups')
+ ->with('foo')
+ ->will($this->returnValue([]));
$expectedResponse = new DataResponse(
array(
@@ -613,11 +661,6 @@ class UsersControllerTest extends \Test\TestCase {
public function testCreateSuccessfulWithoutGroupSubAdmin() {
$this->container['IsAdmin'] = false;
- $this->container['SubAdminFactory']
- ->expects($this->once())
- ->method('getSubAdminsOfGroups')
- ->with('username')
- ->will($this->returnValue(['SubGroup1', 'SubGroup2']));
$user = $this->getMockBuilder('\OC\User\User')
->disableOriginalConstructor()->getMock();
$user
@@ -671,6 +714,13 @@ class UsersControllerTest extends \Test\TestCase {
->with($user)
->will($this->onConsecutiveCalls(['SubGroup1', 'SubGroup2']));
+ $this->container['SubAdminFactory']
+ ->method('getSubAdminsOfGroups')
+ ->will($this->returnValueMap([
+ ['username', ['SubGroup1', 'SubGroup2']],
+ ['foo', []],
+ ]));
+
$expectedResponse = new DataResponse(
array(
'name' => 'foo',
@@ -740,6 +790,12 @@ class UsersControllerTest extends \Test\TestCase {
->with($user)
->will($this->onConsecutiveCalls(array('NewGroup', 'ExistingGroup')));
+ $this->container['SubAdminFactory']
+ ->expects($this->once())
+ ->method('getSubAdminsOfGroups')
+ ->with('foo')
+ ->will($this->returnValue([]));
+
$expectedResponse = new DataResponse(
array(
'name' => 'foo',
@@ -761,11 +817,6 @@ class UsersControllerTest extends \Test\TestCase {
public function testCreateSuccessfulWithGroupSubAdmin() {
$this->container['IsAdmin'] = false;
- $this->container['SubAdminFactory']
- ->expects($this->once())
- ->method('getSubAdminsOfGroups')
- ->with('username')
- ->will($this->returnValue(['SubGroup1', 'SubGroup2']));
$user = $this->getMockBuilder('\OC\User\User')
->disableOriginalConstructor()->getMock();
$user
@@ -819,6 +870,13 @@ class UsersControllerTest extends \Test\TestCase {
->with($user)
->will($this->onConsecutiveCalls(['SubGroup1']));
+ $this->container['SubAdminFactory']
+ ->method('getSubAdminsOfGroups')
+ ->will($this->returnValueMap([
+ ['username', ['SubGroup1', 'SubGroup2']],
+ ['foo', []],
+ ]));
+
$expectedResponse = new DataResponse(
array(
'name' => 'foo',
@@ -1286,6 +1344,11 @@ class UsersControllerTest extends \Test\TestCase {
list($user, $expectedResult) = $this->mockUser();
+ $this->container['SubAdminFactory']
+ ->method('getSubAdminsOfGroups')
+ ->with($user->getUID())
+ ->will($this->returnValue([]));
+
$result = self::invokePrivate($this->container['UsersController'], 'formatUserForIndex', [$user]);
$this->assertEquals($expectedResult, $result);
}
@@ -1323,6 +1386,11 @@ class UsersControllerTest extends \Test\TestCase {
)
->will($this->returnValue('1'));
+ $this->container['SubAdminFactory']
+ ->method('getSubAdminsOfGroups')
+ ->with($user->getUID())
+ ->will($this->returnValue([]));
+
$result = self::invokePrivate($this->container['UsersController'], 'formatUserForIndex', [$user]);
$this->assertEquals($expectedResult, $result);
}
@@ -1341,6 +1409,11 @@ class UsersControllerTest extends \Test\TestCase {
$expectedResult['isRestoreDisabled'] = true;
+ $this->container['SubAdminFactory']
+ ->method('getSubAdminsOfGroups')
+ ->with($user->getUID())
+ ->will($this->returnValue([]));
+
$result = self::invokePrivate($this->container['UsersController'], 'formatUserForIndex', [$user]);
$this->assertEquals($expectedResult, $result);
}
@@ -1380,6 +1453,11 @@ class UsersControllerTest extends \Test\TestCase {
$expectedResult['isRestoreDisabled'] = true;
+ $this->container['SubAdminFactory']
+ ->method('getSubAdminsOfGroups')
+ ->with($user->getUID())
+ ->will($this->returnValue([]));
+
$result = self::invokePrivate($this->container['UsersController'], 'formatUserForIndex', [$user]);
$this->assertEquals($expectedResult, $result);
}
diff --git a/version.php b/version.php
index cc5a18b1cb3..008bb7dafc6 100644
--- a/version.php
+++ b/version.php
@@ -25,7 +25,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(9, 0, 0, 0);
+$OC_Version = array(9, 0, 0, 1);
// The human readable string
$OC_VersionString = '9.0 pre alpha';