diff options
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'; |