diff options
324 files changed, 4043 insertions, 2664 deletions
diff --git a/.gitignore b/.gitignore index a36fd98b79f..c0d44301d57 100644 --- a/.gitignore +++ b/.gitignore @@ -89,6 +89,7 @@ nbproject # nodejs /build/lib/ +/build/jsdocs/ /npm-debug.log diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 2a555ad28f6..f66c1b86eac 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -2,6 +2,7 @@ filter: excluded_paths: - '3rdparty/*' - 'apps/*/3rdparty/*' + - 'apps/*/vendor/*' - 'l10n/*' - 'core/l10n/*' - 'apps/*/l10n/*' @@ -13,7 +14,6 @@ filter: - 'core/js/jquery-tipsy.js' - 'core/js/jquery-ui-1.10.0.custom.js' - 'core/js/placeholders.js' - - 'core/js/jquery.multiselect.js' imports: diff --git a/apps/files/js/app.js b/apps/files/js/app.js index 89098e3a8a3..ee5330485e7 100644 --- a/apps/files/js/app.js +++ b/apps/files/js/app.js @@ -15,12 +15,34 @@ (function() { if (!OCA.Files) { + /** + * Namespace for the files app + * @namespace OCA.Files + */ OCA.Files = {}; } - var App = { + /** + * @namespace OCA.Files.App + */ + OCA.Files.App = { + /** + * Navigation control + * + * @member {OCA.Files.Navigation} + */ navigation: null, + /** + * File list for the "All files" section. + * + * @member {OCA.Files.FileList} + */ + fileList: null, + + /** + * Initializes the files app + */ initialize: function() { this.navigation = new OCA.Files.Navigation($('#app-navigation')); @@ -191,7 +213,6 @@ OC.Util.History.pushState(params); } }; - OCA.Files.App = App; })(); $(document).ready(function() { diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js index 8df9b7ee6fe..af4e48c8f8c 100644 --- a/apps/files/js/breadcrumb.js +++ b/apps/files/js/breadcrumb.js @@ -19,10 +19,17 @@ * */ -/* global OC */ (function() { /** - * Creates an breadcrumb element in the given container + * @class BreadCrumb + * @memberof OCA.Files + * @classdesc Breadcrumbs that represent the current path. + * + * @param {Object} [options] options + * @param {Function} [options.onClick] click event handler + * @param {Function} [options.onDrop] drop event handler + * @param {Function} [options.getCrumbUrl] callback that returns + * the URL of a given breadcrumb */ var BreadCrumb = function(options){ this.$el = $('<div class="breadcrumb"></div>'); @@ -37,12 +44,17 @@ this.getCrumbUrl = options.getCrumbUrl; } }; + /** + * @memberof OCA.Files + */ BreadCrumb.prototype = { $el: null, dir: null, /** * Total width of all breadcrumbs + * @type int + * @private */ totalWidth: 0, breadcrumbs: [], @@ -64,8 +76,9 @@ /** * Returns the full URL to the given directory - * @param part crumb data as map - * @param index crumb index + * + * @param {Object.<String, String>} part crumb data as map + * @param {int} index crumb index * @return full URL */ getCrumbUrl: function(part, index) { @@ -121,8 +134,9 @@ /** * Makes a breadcrumb structure based on the given path - * @param dir path to split into a breadcrumb structure - * @return array of map {dir: path, name: displayName} + * + * @param {String} dir path to split into a breadcrumb structure + * @return {Object.<String, String>} map of {dir: path, name: displayName} */ _makeCrumbs: function(dir) { var crumbs = []; @@ -166,6 +180,8 @@ /** * Show/hide breadcrumbs to fit the given width + * + * @param {int} availableWidth available width */ setMaxWidth: function (availableWidth) { if (this.availableWidth !== availableWidth) { diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index 460c2435642..ab450dc5cac 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -49,7 +49,7 @@ function supportAjaxUploadWithProgress() { /** * keeps track of uploads in progress and implements callbacks for the conflicts dialog - * @type {OC.Upload} + * @namespace */ OC.Upload = { _uploads: [], diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js index 38ede46beb8..5bf1618b0b8 100644 --- a/apps/files/js/fileactions.js +++ b/apps/files/js/fileactions.js @@ -13,11 +13,14 @@ /** * Construct a new FileActions instance + * @constructs FileActions + * @memberof OCA.Files */ var FileActions = function() { this.initialize(); - } + }; FileActions.prototype = { + /** @lends FileActions.prototype */ actions: {}, defaults: {}, icons: {}, @@ -31,9 +34,14 @@ /** * List of handlers to be notified whenever a register() or * setDefault() was called. + * + * @member {Function[]} */ _updateListeners: {}, + /** + * @private + */ initialize: function() { this.clear(); // abusing jquery for events until we get a real event lib @@ -45,7 +53,7 @@ * Adds an event handler * * @param {String} eventName event name - * @param Function callback + * @param {Function} callback */ on: function(eventName, callback) { this.$el.on(eventName, callback); @@ -75,7 +83,7 @@ * Merges the actions from the given fileActions into * this instance. * - * @param fileActions instance of OCA.Files.FileActions + * @param {OCA.Files.FileActions} fileActions instance of OCA.Files.FileActions */ merge: function(fileActions) { var self = this; @@ -113,8 +121,9 @@ * to the name given in action.name * @param {String} action.mime mime type * @param {int} action.permissions permissions - * @param {(Function|String)} action.icon icon - * @param {Function} action.actionHandler function that performs the action + * @param {(Function|String)} action.icon icon path to the icon or function + * that returns it + * @param {OCA.Files.FileActions~actionHandler} action.actionHandler action handler function */ registerAction: function (action) { var mime = action.mime; @@ -130,6 +139,9 @@ this.icons[name] = action.icon; this._notifyUpdateListeners('registerAction', {action: action}); }, + /** + * Clears all registered file actions. + */ clear: function() { this.actions = {}; this.defaults = {}; @@ -137,6 +149,12 @@ this.currentFile = null; this._updateListeners = []; }, + /** + * Sets the default action for a given mime type. + * + * @param {String} mime mime type + * @param {String} name action name + */ setDefault: function (mime, name) { this.defaults[mime] = name; this._notifyUpdateListeners('setDefault', {defaultAction: {mime: mime, name: name}}); @@ -370,6 +388,18 @@ OCA.Files.FileActions = FileActions; + /** + * Action handler function for file actions + * + * @callback OCA.Files.FileActions~actionHandler + * @param {String} fileName name of the clicked file + * @param context context + * @param {String} context.dir directory of the file + * @param context.$file jQuery element of the file + * @param {OCA.Files.FileList} context.fileList the FileList instance on which the action occurred + * @param {OCA.Files.FileActions} context.fileActions the FileActions instance on which the action occurred + */ + // global file actions to be used by all lists OCA.Files.fileActions = new OCA.Files.FileActions(); OCA.Files.legacyFileActions = new OCA.Files.FileActions(); @@ -380,6 +410,7 @@ // their actions on. Since legacy apps are very likely to break with other // FileList views than the main one ("All files"), actions registered // through window.FileActions will be limited to the main file list. + // @deprecated use OCA.Files.FileActions instead window.FileActions = OCA.Files.legacyFileActions; window.FileActions.register = function (mime, name, permissions, icon, action, displayName) { console.warn('FileActions.register() is deprecated, please use OCA.Files.fileActions.register() instead', arguments); diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index cf1d9780d99..bec0155e90e 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -10,13 +10,26 @@ (function() { /** + * @class OCA.Files.FileList + * @classdesc + * * The FileList class manages a file list view. * A file list view consists of a controls bar and * a file list table. + * + * @param $el container element with existing markup for the #controls + * and a table + * @param [options] map of options, see other parameters + * @param [options.scrollContainer] scrollable container, defaults to $(window) + * @param [options.dragOptions] drag options, disabled by default + * @param [options.folderDropOptions] folder drop options, disabled by default */ var FileList = function($el, options) { this.initialize($el, options); }; + /** + * @memberof OCA.Files + */ FileList.prototype = { SORT_INDICATOR_ASC_CLASS: 'icon-triangle-n', SORT_INDICATOR_DESC_CLASS: 'icon-triangle-s', @@ -41,15 +54,27 @@ */ $fileList: null, + /** + * @type OCA.Files.BreadCrumb + */ breadcrumb: null, /** - * Instance of FileSummary + * @type OCA.Files.FileSummary */ fileSummary: null, + + /** + * Whether the file list was initialized already. + * @type boolean + */ initialized: false, - // number of files per page, calculated dynamically + /** + * Number of files per page + * + * @return {int} page size + */ pageSize: function() { return Math.ceil(this.$container.height() / 50); }, @@ -57,37 +82,44 @@ /** * Array of files in the current folder. * The entries are of file data. + * + * @type Array.<Object> */ files: [], /** * File actions handler, defaults to OCA.Files.FileActions + * @type OCA.Files.FileActions */ fileActions: null, /** * Map of file id to file data + * @type Object.<int, Object> */ _selectedFiles: {}, /** * Summary of selected files. - * Instance of FileSummary. + * @type OCA.Files.FileSummary */ _selectionSummary: null, /** * Sort attribute + * @type String */ _sort: 'name', /** * Sort direction: 'asc' or 'desc' + * @type String */ _sortDirection: 'asc', /** * Sort comparator function for the current sort + * @type Function */ _sortComparator: null, @@ -100,6 +132,7 @@ /** * Current directory + * @type String */ _currentDirectory: null, @@ -116,6 +149,7 @@ * @param options.dragOptions drag options, disabled by default * @param options.folderDropOptions folder drop options, disabled by default * @param options.scrollTo name of file to scroll to after the first load + * @private */ initialize: function($el, options) { var self = this; @@ -192,6 +226,11 @@ this.fileActions.off('setDefault', this._onFileActionsUpdated); }, + /** + * Initializes the file actions, set up listeners. + * + * @param {OCA.Files.FileActions} fileActions file actions + */ _initFileActions: function(fileActions) { this.fileActions = fileActions; if (!this.fileActions) { @@ -588,8 +627,8 @@ }, /** * Creates a new table row element using the given file data. - * @param fileData map of file attributes - * @param options map of attribute "loading" whether the entry is currently loading + * @param {OCA.Files.FileInfo} fileData file info attributes + * @param options map of attributes * @return new tr element (not appended to the table) */ _createRow: function(fileData, options) { @@ -728,12 +767,14 @@ * Adds an entry to the files array and also into the DOM * in a sorted manner. * - * @param fileData map of file attributes - * @param options map of attributes: - * @param options.updateSummary true to update the summary after adding (default), false otherwise - * @param options.silent true to prevent firing events like "fileActionsReady" - * @param options.animate true to animate preview loading (defaults to true here) - * @param options.scrollTo true to automatically scroll to the file's location + * @param {OCA.Files.FileInfo} fileData map of file attributes + * @param {Object} [options] map of attributes + * @param {boolean} [options.updateSummary] true to update the summary + * after adding (default), false otherwise. Defaults to true. + * @param {boolean} [options.silent] true to prevent firing events like "fileActionsReady", + * defaults to false. + * @param {boolean} [options.animate] true to animate the thumbnail image after load + * defaults to true. * @return new tr element (not appended to the table) */ add: function(fileData, options) { @@ -799,11 +840,13 @@ * Creates a new row element based on the given attributes * and returns it. * - * @param fileData map of file attributes - * @param options map of attributes: - * - "index" optional index at which to insert the element - * - "updateSummary" true to update the summary after adding (default), false otherwise - * - "animate" true to animate the preview rendering + * @param {OCA.Files.FileInfo} fileData map of file attributes + * @param {Object} [options] map of attributes + * @param {int} [options.index] index at which to insert the element + * @param {boolean} [options.updateSummary] true to update the summary + * after adding (default), false otherwise. Defaults to true. + * @param {boolean} [options.animate] true to animate the thumbnail image after load + * defaults to true. * @return new tr element (not appended to the table) */ _renderRow: function(fileData, options) { @@ -870,6 +913,7 @@ }, /** * Returns the current directory + * @method getCurrentDirectory * @return current directory */ getCurrentDirectory: function(){ @@ -1051,7 +1095,10 @@ /** * Generates a preview URL based on the URL space. - * @param urlSpec map with {x: width, y: height, file: file path} + * @param urlSpec attributes for the URL + * @param {int} urlSpec.x width + * @param {int} urlSpec.y height + * @param {String} urlSpec.file path to the file * @return preview URL */ generatePreviewUrl: function(urlSpec) { @@ -1158,8 +1205,9 @@ /** * Removes a file entry from the list * @param name name of the file to remove - * @param options optional options as map: - * "updateSummary": true to update the summary (default), false otherwise + * @param {Object} [options] map of attributes + * @param {boolean} [options.updateSummary] true to update the summary + * after removing, false otherwise. Defaults to true. * @return deleted element */ remove: function(name, options){ @@ -1201,6 +1249,8 @@ * Finds the index of the row before which the given * fileData should be inserted, considering the current * sorting + * + * @param {OCA.Files.FileInfo} fileData file info */ _findInsertionIndex: function(fileData) { var index = 0; @@ -1515,7 +1565,7 @@ /** * Shows the loading mask. * - * @see #hideMask + * @see OCA.Files.FileList#hideMask */ showMask: function() { // in case one was shown before @@ -1536,7 +1586,7 @@ }, /** * Hide the loading mask. - * @see #showMask + * @see OCA.Files.FileList#showMask */ hideMask: function() { this.$el.find('.mask').remove(); @@ -1961,15 +2011,17 @@ /** * Sort comparators. + * @namespace OCA.Files.FileList.Comparators + * @private */ FileList.Comparators = { /** * Compares two file infos by name, making directories appear * first. * - * @param fileInfo1 file info - * @param fileInfo2 file info - * @return -1 if the first file must appear before the second one, + * @param {OCA.Files.FileInfo} fileInfo1 file info + * @param {OCA.Files.FileInfo} fileInfo2 file info + * @return {int} -1 if the first file must appear before the second one, * 0 if they are identify, 1 otherwise. */ name: function(fileInfo1, fileInfo2) { @@ -1984,9 +2036,9 @@ /** * Compares two file infos by size. * - * @param fileInfo1 file info - * @param fileInfo2 file info - * @return -1 if the first file must appear before the second one, + * @param {OCA.Files.FileInfo} fileInfo1 file info + * @param {OCA.Files.FileInfo} fileInfo2 file info + * @return {int} -1 if the first file must appear before the second one, * 0 if they are identify, 1 otherwise. */ size: function(fileInfo1, fileInfo2) { @@ -1995,9 +2047,9 @@ /** * Compares two file infos by timestamp. * - * @param fileInfo1 file info - * @param fileInfo2 file info - * @return -1 if the first file must appear before the second one, + * @param {OCA.Files.FileInfo} fileInfo1 file info + * @param {OCA.Files.FileInfo} fileInfo2 file info + * @return {int} -1 if the first file must appear before the second one, * 0 if they are identify, 1 otherwise. */ mtime: function(fileInfo1, fileInfo2) { @@ -2005,6 +2057,27 @@ } }; + /** + * File info attributes. + * + * @todo make this a real class in the future + * @typedef {Object} OCA.Files.FileInfo + * + * @property {int} id file id + * @property {String} name file name + * @property {String} [path] file path, defaults to the list's current path + * @property {String} mimetype mime type + * @property {String} type "file" for files or "dir" for directories + * @property {int} permissions file permissions + * @property {int} mtime modification time in milliseconds + * @property {boolean} [isShareMountPoint] whether the file is a share mount + * point + * @property {boolean} [isPreviewAvailable] whether a preview is available + * for the given file type + * @property {String} [icon] path to the mime type icon + * @property {String} etag etag of the file + */ + OCA.Files.FileList = FileList; })(); diff --git a/apps/files/js/files.js b/apps/files/js/files.js index df268fea6de..b11ef03eab2 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -195,7 +195,10 @@ /** * Generates a preview URL based on the URL space. - * @param urlSpec map with {x: width, y: height, file: file path} + * @param urlSpec attributes for the URL + * @param {int} urlSpec.x width + * @param {int} urlSpec.y height + * @param {String} urlSpec.file path to the file * @return preview URL * @deprecated used OCA.Files.FileList.generatePreviewUrl instead */ diff --git a/apps/files/js/filesummary.js b/apps/files/js/filesummary.js index ca70259335c..f83eb54678b 100644 --- a/apps/files/js/filesummary.js +++ b/apps/files/js/filesummary.js @@ -19,14 +19,15 @@ * */ -/* global OC, n, t */ - (function() { /** * The FileSummary class encapsulates the file summary values and * the logic to render it in the given container + * + * @constructs FileSummary + * @memberof OCA.Files + * * @param $tr table row element - * $param summary optional initial summary value */ var FileSummary = function($tr) { this.$el = $tr; diff --git a/apps/files/js/navigation.js b/apps/files/js/navigation.js index b959e016e8c..be385f21f50 100644 --- a/apps/files/js/navigation.js +++ b/apps/files/js/navigation.js @@ -13,10 +13,19 @@ (function() { + /** + * @class OCA.Files.Navigation + * @classdesc Navigation control for the files app sidebar. + * + * @param $el element containing the navigation + */ var Navigation = function($el) { this.initialize($el); }; + /** + * @memberof OCA.Files + */ Navigation.prototype = { /** @@ -31,6 +40,8 @@ /** * Initializes the navigation from the given container + * + * @private * @param $el element containing the navigation */ initialize: function($el) { diff --git a/apps/files/js/upload.js b/apps/files/js/upload.js index 617cf4b1c1d..518608615e0 100644 --- a/apps/files/js/upload.js +++ b/apps/files/js/upload.js @@ -8,7 +8,6 @@ * */ -/* global OC */ function Upload(fileSelector) { if ($.support.xhrFileUpload) { return new XHRUpload(fileSelector.target.files); diff --git a/apps/files/l10n/it.js b/apps/files/l10n/it.js index 939f5e55dac..693888bb7c8 100644 --- a/apps/files/l10n/it.js +++ b/apps/files/l10n/it.js @@ -21,10 +21,10 @@ OC.L10N.register( "Error when creating the folder" : "Errore durante la creazione della cartella", "Unable to set upload directory." : "Impossibile impostare una cartella di caricamento.", "Invalid Token" : "Token non valido", - "No file was uploaded. Unknown error" : "Nessun file è stato inviato. Errore sconosciuto", + "No file was uploaded. Unknown error" : "Nessun file è stato caricato. Errore sconosciuto", "There is no error, the file uploaded with success" : "Non ci sono errori, il file è stato caricato correttamente", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " : "Il file caricato supera la direttiva upload_max_filesize in php.ini:", - "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Il file inviato supera la direttiva MAX_FILE_SIZE specificata nel modulo HTML", + "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Il file caricato supera la direttiva MAX_FILE_SIZE specificata nel modulo HTML", "The uploaded file was only partially uploaded" : "Il file è stato caricato solo parzialmente", "No file was uploaded" : "Nessun file è stato caricato", "Missing a temporary folder" : "Manca una cartella temporanea", @@ -38,7 +38,7 @@ OC.L10N.register( "Unable to upload {filename} as it is a directory or has 0 bytes" : "Impossibile caricare {filename} poiché è una cartella oppure ha una dimensione di 0 byte.", "Total file size {size1} exceeds upload limit {size2}" : "La dimensione totale del file {size1} supera il limite di caricamento {size2}", "Not enough free space, you are uploading {size1} but only {size2} is left" : "Spazio insufficiente, stai caricando {size1}, ma è rimasto solo {size2}", - "Upload cancelled." : "Invio annullato", + "Upload cancelled." : "Caricamento annullato.", "Could not get result from server." : "Impossibile ottenere il risultato dal server.", "File upload is in progress. Leaving the page now will cancel the upload." : "Caricamento del file in corso. La chiusura della pagina annullerà il caricamento.", "URL cannot be empty" : "L'URL non può essere vuoto.", @@ -76,7 +76,7 @@ OC.L10N.register( "%s could not be renamed" : "%s non può essere rinominato", "Upload (max. %s)" : "Carica (massimo %s)", "File handling" : "Gestione file", - "Maximum upload size" : "Dimensione massima upload", + "Maximum upload size" : "Dimensione massima caricamento", "max. possible: " : "numero mass.: ", "Save" : "Salva", "WebDAV" : "WebDAV", diff --git a/apps/files/l10n/it.json b/apps/files/l10n/it.json index 8686051f461..4efbf6f64b4 100644 --- a/apps/files/l10n/it.json +++ b/apps/files/l10n/it.json @@ -19,10 +19,10 @@ "Error when creating the folder" : "Errore durante la creazione della cartella", "Unable to set upload directory." : "Impossibile impostare una cartella di caricamento.", "Invalid Token" : "Token non valido", - "No file was uploaded. Unknown error" : "Nessun file è stato inviato. Errore sconosciuto", + "No file was uploaded. Unknown error" : "Nessun file è stato caricato. Errore sconosciuto", "There is no error, the file uploaded with success" : "Non ci sono errori, il file è stato caricato correttamente", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " : "Il file caricato supera la direttiva upload_max_filesize in php.ini:", - "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Il file inviato supera la direttiva MAX_FILE_SIZE specificata nel modulo HTML", + "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Il file caricato supera la direttiva MAX_FILE_SIZE specificata nel modulo HTML", "The uploaded file was only partially uploaded" : "Il file è stato caricato solo parzialmente", "No file was uploaded" : "Nessun file è stato caricato", "Missing a temporary folder" : "Manca una cartella temporanea", @@ -36,7 +36,7 @@ "Unable to upload {filename} as it is a directory or has 0 bytes" : "Impossibile caricare {filename} poiché è una cartella oppure ha una dimensione di 0 byte.", "Total file size {size1} exceeds upload limit {size2}" : "La dimensione totale del file {size1} supera il limite di caricamento {size2}", "Not enough free space, you are uploading {size1} but only {size2} is left" : "Spazio insufficiente, stai caricando {size1}, ma è rimasto solo {size2}", - "Upload cancelled." : "Invio annullato", + "Upload cancelled." : "Caricamento annullato.", "Could not get result from server." : "Impossibile ottenere il risultato dal server.", "File upload is in progress. Leaving the page now will cancel the upload." : "Caricamento del file in corso. La chiusura della pagina annullerà il caricamento.", "URL cannot be empty" : "L'URL non può essere vuoto.", @@ -74,7 +74,7 @@ "%s could not be renamed" : "%s non può essere rinominato", "Upload (max. %s)" : "Carica (massimo %s)", "File handling" : "Gestione file", - "Maximum upload size" : "Dimensione massima upload", + "Maximum upload size" : "Dimensione massima caricamento", "max. possible: " : "numero mass.: ", "Save" : "Salva", "WebDAV" : "WebDAV", diff --git a/apps/files/lib/capabilities.php b/apps/files/lib/capabilities.php index d4820e931ba..690cc314ccd 100644 --- a/apps/files/lib/capabilities.php +++ b/apps/files/lib/capabilities.php @@ -15,7 +15,6 @@ class Capabilities { 'capabilities' => array( 'files' => array( 'bigfilechunking' => true, - 'undelete' => true, ), ), )); diff --git a/apps/files/tests/ajax_rename.php b/apps/files/tests/ajax_rename.php index 5ed8b1931f4..3bccaca1231 100644 --- a/apps/files/tests/ajax_rename.php +++ b/apps/files/tests/ajax_rename.php @@ -34,7 +34,14 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { */ private $files; - function setUp() { + /** @var \OC\Files\Storage\Storage */ + private $originalStorage; + + protected function setUp() { + parent::setUp(); + + $this->originalStorage = \OC\Files\Filesystem::getStorage('/'); + // mock OC_L10n if (!self::$user) { self::$user = uniqid(); @@ -59,10 +66,13 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { $this->files = new \OCA\Files\App($viewMock, $l10nMock); } - function tearDown() { + protected function tearDown() { $result = \OC_User::deleteUser(self::$user); $this->assertTrue($result); \OC\Files\Filesystem::tearDown(); + \OC\Files\Filesystem::mount($this->originalStorage, array(), '/'); + + parent::tearDown(); } /** diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 3a0a37c0a59..eadd2b64b80 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -263,6 +263,19 @@ class Hooks { }
}
+ /**
+ * after password reset we create a new key pair for the user
+ *
+ * @param array $params
+ */
+ public static function postPasswordReset($params) {
+ $uid = $params['uid'];
+ $password = $params['password'];
+
+ $util = new Util(new \OC\Files\View(), $uid);
+ $util->replaceUserKeys($password);
+ }
+
/*
* check if files can be encrypted to every user.
*/
diff --git a/apps/files_encryption/js/encryption.js b/apps/files_encryption/js/encryption.js index 65ffabe55e6..d2d1c3a1fc5 100644 --- a/apps/files_encryption/js/encryption.js +++ b/apps/files_encryption/js/encryption.js @@ -5,6 +5,10 @@ * See the COPYING-README file. */ +/** + * @namespace + * @memberOf OC + */ OC.Encryption={ MIGRATION_OPEN:0, MIGRATION_COMPLETED:1, diff --git a/apps/files_encryption/l10n/en_GB.js b/apps/files_encryption/l10n/en_GB.js index daf72aae608..cae7d2c9679 100644 --- a/apps/files_encryption/l10n/en_GB.js +++ b/apps/files_encryption/l10n/en_GB.js @@ -13,6 +13,9 @@ OC.L10N.register( "Please repeat the new recovery password" : "Please repeat the new recovery password", "Password successfully changed." : "Password changed successfully.", "Could not change the password. Maybe the old password was not correct." : "Could not change the password. Maybe the old password was incorrect.", + "Could not update the private key password." : "Could not update the private key password.", + "The old password was not correct, please try again." : "The old password was not correct, please try again.", + "The current log-in password was not correct, please try again." : "The current log-in password was not correct, please try again.", "Private key password successfully updated." : "Private key password updated successfully.", "File recovery settings updated" : "File recovery settings updated", "Could not update file recovery" : "Could not update file recovery", diff --git a/apps/files_encryption/l10n/en_GB.json b/apps/files_encryption/l10n/en_GB.json index e6a4ca0eef3..d0b9ece1781 100644 --- a/apps/files_encryption/l10n/en_GB.json +++ b/apps/files_encryption/l10n/en_GB.json @@ -11,6 +11,9 @@ "Please repeat the new recovery password" : "Please repeat the new recovery password", "Password successfully changed." : "Password changed successfully.", "Could not change the password. Maybe the old password was not correct." : "Could not change the password. Maybe the old password was incorrect.", + "Could not update the private key password." : "Could not update the private key password.", + "The old password was not correct, please try again." : "The old password was not correct, please try again.", + "The current log-in password was not correct, please try again." : "The current log-in password was not correct, please try again.", "Private key password successfully updated." : "Private key password updated successfully.", "File recovery settings updated" : "File recovery settings updated", "Could not update file recovery" : "Could not update file recovery", diff --git a/apps/files_encryption/l10n/et_EE.js b/apps/files_encryption/l10n/et_EE.js index f525eedc1ae..93fa8084ff9 100644 --- a/apps/files_encryption/l10n/et_EE.js +++ b/apps/files_encryption/l10n/et_EE.js @@ -13,6 +13,9 @@ OC.L10N.register( "Please repeat the new recovery password" : "Palun korda uut taastevõtme parooli", "Password successfully changed." : "Parool edukalt vahetatud.", "Could not change the password. Maybe the old password was not correct." : "Ei suutnud vahetada parooli. Võib-olla on vana parool valesti sisestatud.", + "Could not update the private key password." : "Ei suutnud uuendada privaatse võtme parooli.", + "The old password was not correct, please try again." : "Vana parool polnud õige, palun proovi uuesti.", + "The current log-in password was not correct, please try again." : "Praeguse sisselogimise parool polnud õige, palun proovi uuesti.", "Private key password successfully updated." : "Privaatse võtme parool edukalt uuendatud.", "File recovery settings updated" : "Faili taaste seaded uuendatud", "Could not update file recovery" : "Ei suuda uuendada taastefaili", diff --git a/apps/files_encryption/l10n/et_EE.json b/apps/files_encryption/l10n/et_EE.json index ef47ab1212d..873bc8945d7 100644 --- a/apps/files_encryption/l10n/et_EE.json +++ b/apps/files_encryption/l10n/et_EE.json @@ -11,6 +11,9 @@ "Please repeat the new recovery password" : "Palun korda uut taastevõtme parooli", "Password successfully changed." : "Parool edukalt vahetatud.", "Could not change the password. Maybe the old password was not correct." : "Ei suutnud vahetada parooli. Võib-olla on vana parool valesti sisestatud.", + "Could not update the private key password." : "Ei suutnud uuendada privaatse võtme parooli.", + "The old password was not correct, please try again." : "Vana parool polnud õige, palun proovi uuesti.", + "The current log-in password was not correct, please try again." : "Praeguse sisselogimise parool polnud õige, palun proovi uuesti.", "Private key password successfully updated." : "Privaatse võtme parool edukalt uuendatud.", "File recovery settings updated" : "Faili taaste seaded uuendatud", "Could not update file recovery" : "Ei suuda uuendada taastefaili", diff --git a/apps/files_encryption/l10n/fr.js b/apps/files_encryption/l10n/fr.js index 96aaba8bcb0..b5bcaff19c2 100644 --- a/apps/files_encryption/l10n/fr.js +++ b/apps/files_encryption/l10n/fr.js @@ -11,8 +11,8 @@ OC.L10N.register( "Please provide the old recovery password" : "Veuillez entrer l'ancien mot de passe de récupération", "Please provide a new recovery password" : "Veuillez entrer un nouveau mot de passe de récupération", "Please repeat the new recovery password" : "Veuillez répéter le nouveau mot de passe de récupération", - "Password successfully changed." : "Mot de passe changé avec succès ", - "Could not change the password. Maybe the old password was not correct." : "Ne peut pas changer le mot de passe. L'ancien mot de passe est peut-être incorrect.", + "Password successfully changed." : "Mot de passe changé avec succès.", + "Could not change the password. Maybe the old password was not correct." : "Erreur lors du changement de mot de passe. L'ancien mot de passe est peut-être incorrect.", "Could not update the private key password." : "Impossible de mettre à jour le mot de passe de la clé privée.", "The old password was not correct, please try again." : "L'ancien mot de passe est incorrect. Veuillez réessayer.", "The current log-in password was not correct, please try again." : "Le mot de passe actuel n'est pas correct, veuillez réessayer.", @@ -34,8 +34,8 @@ OC.L10N.register( "Enable recovery key (allow to recover users files in case of password loss):" : "Activer la clef de récupération (permet de récupérer les fichiers des utilisateurs en cas de perte de mot de passe).", "Recovery key password" : "Mot de passe de la clef de récupération", "Repeat Recovery key password" : "Répétez le mot de passe de la clé de récupération", - "Enabled" : "Activer", - "Disabled" : "Désactiver", + "Enabled" : "Activé", + "Disabled" : "Désactivé", "Change recovery key password:" : "Modifier le mot de passe de la clef de récupération :", "Old Recovery key password" : "Ancien mot de passe de la clef de récupération", "New Recovery key password" : "Nouveau mot de passe de la clef de récupération", diff --git a/apps/files_encryption/l10n/fr.json b/apps/files_encryption/l10n/fr.json index 5cd3d8dde54..24de660bb3c 100644 --- a/apps/files_encryption/l10n/fr.json +++ b/apps/files_encryption/l10n/fr.json @@ -9,8 +9,8 @@ "Please provide the old recovery password" : "Veuillez entrer l'ancien mot de passe de récupération", "Please provide a new recovery password" : "Veuillez entrer un nouveau mot de passe de récupération", "Please repeat the new recovery password" : "Veuillez répéter le nouveau mot de passe de récupération", - "Password successfully changed." : "Mot de passe changé avec succès ", - "Could not change the password. Maybe the old password was not correct." : "Ne peut pas changer le mot de passe. L'ancien mot de passe est peut-être incorrect.", + "Password successfully changed." : "Mot de passe changé avec succès.", + "Could not change the password. Maybe the old password was not correct." : "Erreur lors du changement de mot de passe. L'ancien mot de passe est peut-être incorrect.", "Could not update the private key password." : "Impossible de mettre à jour le mot de passe de la clé privée.", "The old password was not correct, please try again." : "L'ancien mot de passe est incorrect. Veuillez réessayer.", "The current log-in password was not correct, please try again." : "Le mot de passe actuel n'est pas correct, veuillez réessayer.", @@ -32,8 +32,8 @@ "Enable recovery key (allow to recover users files in case of password loss):" : "Activer la clef de récupération (permet de récupérer les fichiers des utilisateurs en cas de perte de mot de passe).", "Recovery key password" : "Mot de passe de la clef de récupération", "Repeat Recovery key password" : "Répétez le mot de passe de la clé de récupération", - "Enabled" : "Activer", - "Disabled" : "Désactiver", + "Enabled" : "Activé", + "Disabled" : "Désactivé", "Change recovery key password:" : "Modifier le mot de passe de la clef de récupération :", "Old Recovery key password" : "Ancien mot de passe de la clef de récupération", "New Recovery key password" : "Nouveau mot de passe de la clef de récupération", diff --git a/apps/files_encryption/l10n/pl.js b/apps/files_encryption/l10n/pl.js index e4532cb0604..29b67619139 100644 --- a/apps/files_encryption/l10n/pl.js +++ b/apps/files_encryption/l10n/pl.js @@ -2,12 +2,20 @@ OC.L10N.register( "files_encryption", { "Unknown error" : "Nieznany błąd", + "Missing recovery key password" : "Brakujące hasło klucza odzyskiwania", "Please repeat the recovery key password" : "Proszę powtórz nowe hasło klucza odzyskiwania", + "Repeated recovery key password does not match the provided recovery key password" : "Hasła klucza odzyskiwania nie zgadzają się", "Recovery key successfully enabled" : "Klucz odzyskiwania włączony", "Could not disable recovery key. Please check your recovery key password!" : "Nie można wyłączyć klucza odzyskiwania. Proszę sprawdzić swoje hasło odzyskiwania!", "Recovery key successfully disabled" : "Klucz odzyskiwania wyłączony", + "Please provide the old recovery password" : "Podaj stare hasło odzyskiwania", + "Please provide a new recovery password" : "Podaj nowe hasło odzyskiwania", + "Please repeat the new recovery password" : "Proszę powtórz nowe hasło odzyskiwania", "Password successfully changed." : "Zmiana hasła udana.", "Could not change the password. Maybe the old password was not correct." : "Nie można zmienić hasła. Może stare hasło nie było poprawne.", + "Could not update the private key password." : "Nie można zmienić hasła klucza prywatnego.", + "The old password was not correct, please try again." : "Stare hasło nie było poprawne. Spróbuj jeszcze raz.", + "The current log-in password was not correct, please try again." : "Obecne hasło logowania nie było poprawne. Spróbuj ponownie.", "Private key password successfully updated." : "Pomyślnie zaktualizowano hasło klucza prywatnego.", "File recovery settings updated" : "Ustawienia odzyskiwania plików zmienione", "Could not update file recovery" : "Nie można zmienić pliku odzyskiwania", diff --git a/apps/files_encryption/l10n/pl.json b/apps/files_encryption/l10n/pl.json index 8ef5297d191..8d70e50340e 100644 --- a/apps/files_encryption/l10n/pl.json +++ b/apps/files_encryption/l10n/pl.json @@ -1,11 +1,19 @@ { "translations": { "Unknown error" : "Nieznany błąd", + "Missing recovery key password" : "Brakujące hasło klucza odzyskiwania", "Please repeat the recovery key password" : "Proszę powtórz nowe hasło klucza odzyskiwania", + "Repeated recovery key password does not match the provided recovery key password" : "Hasła klucza odzyskiwania nie zgadzają się", "Recovery key successfully enabled" : "Klucz odzyskiwania włączony", "Could not disable recovery key. Please check your recovery key password!" : "Nie można wyłączyć klucza odzyskiwania. Proszę sprawdzić swoje hasło odzyskiwania!", "Recovery key successfully disabled" : "Klucz odzyskiwania wyłączony", + "Please provide the old recovery password" : "Podaj stare hasło odzyskiwania", + "Please provide a new recovery password" : "Podaj nowe hasło odzyskiwania", + "Please repeat the new recovery password" : "Proszę powtórz nowe hasło odzyskiwania", "Password successfully changed." : "Zmiana hasła udana.", "Could not change the password. Maybe the old password was not correct." : "Nie można zmienić hasła. Może stare hasło nie było poprawne.", + "Could not update the private key password." : "Nie można zmienić hasła klucza prywatnego.", + "The old password was not correct, please try again." : "Stare hasło nie było poprawne. Spróbuj jeszcze raz.", + "The current log-in password was not correct, please try again." : "Obecne hasło logowania nie było poprawne. Spróbuj ponownie.", "Private key password successfully updated." : "Pomyślnie zaktualizowano hasło klucza prywatnego.", "File recovery settings updated" : "Ustawienia odzyskiwania plików zmienione", "Could not update file recovery" : "Nie można zmienić pliku odzyskiwania", diff --git a/apps/files_encryption/l10n/ru.js b/apps/files_encryption/l10n/ru.js index 6d4cfe371e3..965f383691f 100644 --- a/apps/files_encryption/l10n/ru.js +++ b/apps/files_encryption/l10n/ru.js @@ -13,11 +13,14 @@ OC.L10N.register( "Please repeat the new recovery password" : "Пожалуйста, повторите новый пароль для восстановления", "Password successfully changed." : "Пароль изменен удачно.", "Could not change the password. Maybe the old password was not correct." : "Невозможно изменить пароль. Возможно старый пароль не был верен.", - "Private key password successfully updated." : "Пароль секретного ключа успешно обновлён.", + "Could not update the private key password." : "Невозможно обновить пароль для закрытого ключа.", + "The old password was not correct, please try again." : "Старый пароль введён неверно. Пожалуйста повторите попытку.", + "The current log-in password was not correct, please try again." : "Текущий пароль для учётной записи введён неверно, пожалуйста повторите попытку.", + "Private key password successfully updated." : "Пароль закрытого ключа успешно обновлён.", "File recovery settings updated" : "Настройки файла восстановления обновлены", "Could not update file recovery" : "Невозможно обновить файл восстановления", "Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." : "Приложение шифрации не инициализированно! Возможно приложение шифрации было реактивировано во время вашей сессии. Пожалуйста, попробуйте выйти и войти снова чтобы проинициализировать приложение шифрации.", - "Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." : "Ваш секретный ключ не действителен! Вероятно, ваш пароль был изменен вне %s (например, корпоративный каталог). Вы можете обновить секретный ключ в личных настройках на странице восстановления доступа к зашифрованным файлам. ", + "Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." : "Ваш закрытый ключ недействителен! Вероятно, ваш пароль был изменен вне %s (например, корпоративный каталог). Вы можете обновить закрытый ключ в личных настройках на странице восстановления доступа к зашифрованным файлам. ", "Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Не могу расшифровать файл, возможно это опубликованный файл. Пожалуйста, попросите владельца файла поделиться им с вами еще раз.", "Unknown error. Please check your system settings or contact your administrator" : "Неизвестная ошибка. Пожалуйста, проверьте системные настройки или свяжитесь с администратором", "Missing requirements." : "Требования отсутствуют.", @@ -38,12 +41,12 @@ OC.L10N.register( "New Recovery key password" : "Новый пароль для ключа восстановления", "Repeat New Recovery key password" : "Повторите новый пароль восстановления ключа", "Change Password" : "Изменить пароль", - "Your private key password no longer matches your log-in password." : "Пароль от Вашего закрытого ключа больше не соответствует паролю от вашей учетной записи.", - "Set your old private key password to your current log-in password:" : "Замените старый пароль от закрытого ключа на новый пароль входа.", + "Your private key password no longer matches your log-in password." : "Пароль для Вашего закрытого ключа больше не соответствует паролю вашей учетной записи.", + "Set your old private key password to your current log-in password:" : "Замените старый пароль для закрытого ключа на текущий пароль учётной записи.", " If you don't remember your old password you can ask your administrator to recover your files." : "Если вы не помните свой старый пароль, вы можете попросить своего администратора восстановить ваши файлы", - "Old log-in password" : "Старый пароль для входа", - "Current log-in password" : "Текущйи пароль для входа", - "Update Private Key Password" : "Обновить пароль от секретного ключа", + "Old log-in password" : "Старый пароль для учётной записи", + "Current log-in password" : "Текущий пароль для учётной записи", + "Update Private Key Password" : "Обновить пароль для закрытого ключа", "Enable password recovery:" : "Включить восстановление пароля:", "Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" : "Включение этой опции позволит вам получить доступ к своим зашифрованным файлам в случае утери пароля" }, diff --git a/apps/files_encryption/l10n/ru.json b/apps/files_encryption/l10n/ru.json index 8de97d847cd..7548e510c43 100644 --- a/apps/files_encryption/l10n/ru.json +++ b/apps/files_encryption/l10n/ru.json @@ -11,11 +11,14 @@ "Please repeat the new recovery password" : "Пожалуйста, повторите новый пароль для восстановления", "Password successfully changed." : "Пароль изменен удачно.", "Could not change the password. Maybe the old password was not correct." : "Невозможно изменить пароль. Возможно старый пароль не был верен.", - "Private key password successfully updated." : "Пароль секретного ключа успешно обновлён.", + "Could not update the private key password." : "Невозможно обновить пароль для закрытого ключа.", + "The old password was not correct, please try again." : "Старый пароль введён неверно. Пожалуйста повторите попытку.", + "The current log-in password was not correct, please try again." : "Текущий пароль для учётной записи введён неверно, пожалуйста повторите попытку.", + "Private key password successfully updated." : "Пароль закрытого ключа успешно обновлён.", "File recovery settings updated" : "Настройки файла восстановления обновлены", "Could not update file recovery" : "Невозможно обновить файл восстановления", "Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." : "Приложение шифрации не инициализированно! Возможно приложение шифрации было реактивировано во время вашей сессии. Пожалуйста, попробуйте выйти и войти снова чтобы проинициализировать приложение шифрации.", - "Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." : "Ваш секретный ключ не действителен! Вероятно, ваш пароль был изменен вне %s (например, корпоративный каталог). Вы можете обновить секретный ключ в личных настройках на странице восстановления доступа к зашифрованным файлам. ", + "Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." : "Ваш закрытый ключ недействителен! Вероятно, ваш пароль был изменен вне %s (например, корпоративный каталог). Вы можете обновить закрытый ключ в личных настройках на странице восстановления доступа к зашифрованным файлам. ", "Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Не могу расшифровать файл, возможно это опубликованный файл. Пожалуйста, попросите владельца файла поделиться им с вами еще раз.", "Unknown error. Please check your system settings or contact your administrator" : "Неизвестная ошибка. Пожалуйста, проверьте системные настройки или свяжитесь с администратором", "Missing requirements." : "Требования отсутствуют.", @@ -36,12 +39,12 @@ "New Recovery key password" : "Новый пароль для ключа восстановления", "Repeat New Recovery key password" : "Повторите новый пароль восстановления ключа", "Change Password" : "Изменить пароль", - "Your private key password no longer matches your log-in password." : "Пароль от Вашего закрытого ключа больше не соответствует паролю от вашей учетной записи.", - "Set your old private key password to your current log-in password:" : "Замените старый пароль от закрытого ключа на новый пароль входа.", + "Your private key password no longer matches your log-in password." : "Пароль для Вашего закрытого ключа больше не соответствует паролю вашей учетной записи.", + "Set your old private key password to your current log-in password:" : "Замените старый пароль для закрытого ключа на текущий пароль учётной записи.", " If you don't remember your old password you can ask your administrator to recover your files." : "Если вы не помните свой старый пароль, вы можете попросить своего администратора восстановить ваши файлы", - "Old log-in password" : "Старый пароль для входа", - "Current log-in password" : "Текущйи пароль для входа", - "Update Private Key Password" : "Обновить пароль от секретного ключа", + "Old log-in password" : "Старый пароль для учётной записи", + "Current log-in password" : "Текущий пароль для учётной записи", + "Update Private Key Password" : "Обновить пароль для закрытого ключа", "Enable password recovery:" : "Включить восстановление пароля:", "Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" : "Включение этой опции позволит вам получить доступ к своим зашифрованным файлам в случае утери пароля" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" diff --git a/apps/files_encryption/l10n/uk.js b/apps/files_encryption/l10n/uk.js index 87433d99fbc..db740bc45e6 100644 --- a/apps/files_encryption/l10n/uk.js +++ b/apps/files_encryption/l10n/uk.js @@ -13,6 +13,9 @@ OC.L10N.register( "Please repeat the new recovery password" : "Будь ласка, введіть новий пароль відновлення ще раз", "Password successfully changed." : "Пароль змінено.", "Could not change the password. Maybe the old password was not correct." : "Не вдалося змінити пароль. Можливо ви неправильно ввели старий пароль.", + "Could not update the private key password." : "Не вдалося оновити пароль секретного ключа.", + "The old password was not correct, please try again." : "Старий пароль введено не вірно, спробуйте ще раз.", + "The current log-in password was not correct, please try again." : "Невірний пароль входу, будь ласка, спробуйте ще раз.", "Private key password successfully updated." : "Пароль секретного ключа оновлено.", "File recovery settings updated" : "Налаштування файла відновлення оновлено", "Could not update file recovery" : "Не вдалося оновити файл відновлення ", diff --git a/apps/files_encryption/l10n/uk.json b/apps/files_encryption/l10n/uk.json index a981ff225d0..b2953e5e53c 100644 --- a/apps/files_encryption/l10n/uk.json +++ b/apps/files_encryption/l10n/uk.json @@ -11,6 +11,9 @@ "Please repeat the new recovery password" : "Будь ласка, введіть новий пароль відновлення ще раз", "Password successfully changed." : "Пароль змінено.", "Could not change the password. Maybe the old password was not correct." : "Не вдалося змінити пароль. Можливо ви неправильно ввели старий пароль.", + "Could not update the private key password." : "Не вдалося оновити пароль секретного ключа.", + "The old password was not correct, please try again." : "Старий пароль введено не вірно, спробуйте ще раз.", + "The current log-in password was not correct, please try again." : "Невірний пароль входу, будь ласка, спробуйте ще раз.", "Private key password successfully updated." : "Пароль секретного ключа оновлено.", "File recovery settings updated" : "Налаштування файла відновлення оновлено", "Could not update file recovery" : "Не вдалося оновити файл відновлення ", diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php index 53c380ab2b3..7a50ade82f3 100644 --- a/apps/files_encryption/lib/helper.php +++ b/apps/files_encryption/lib/helper.php @@ -70,6 +70,7 @@ class Helper { \OCP\Util::connectHook('OC_Filesystem', 'delete', 'OCA\Encryption\Hooks', 'preDelete'); \OCP\Util::connectHook('OC_Filesystem', 'post_umount', 'OCA\Encryption\Hooks', 'postUmount'); \OCP\Util::connectHook('OC_Filesystem', 'umount', 'OCA\Encryption\Hooks', 'preUmount'); + \OCP\Util::connectHook('\OC\Core\LostPassword\Controller\LostController', 'post_passwordReset', 'OCA\Encryption\Hooks', 'postPasswordReset'); } /** diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index 672a5878a24..4038e641343 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -580,6 +580,7 @@ class Stream { \OC_FileProxy::$enabled = false; if ($this->rootView->file_exists($this->rawPath) && $this->size === 0) { + fclose($this->handle); $this->rootView->unlink($this->rawPath); } diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index c8697ae7c80..d12b003b227 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -125,6 +125,18 @@ class Util { } /** + * create a new public/private key pair for the user + * + * @param string $password password for the private key + */ + public function replaceUserKeys($password) { + $this->backupAllKeys('password_reset'); + $this->view->unlink($this->publicKeyPath); + $this->view->unlink($this->privateKeyPath); + $this->setupServerSide($password); + } + + /** * Sets up user folders and keys for serverside encryption * * @param string $passphrase to encrypt server-stored private key with diff --git a/apps/files_encryption/tests/crypt.php b/apps/files_encryption/tests/crypt.php index 1b8291fea28..7369be8ff05 100755 --- a/apps/files_encryption/tests/crypt.php +++ b/apps/files_encryption/tests/crypt.php @@ -12,7 +12,7 @@ use OCA\Encryption; /** * Class Test_Encryption_Crypt */ -class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { +class Test_Encryption_Crypt extends \OCA\Files_Encryption\Tests\TestCase { const TEST_ENCRYPTION_CRYPT_USER1 = "test-crypt-user1"; @@ -31,6 +31,8 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { public $genPublicKey; public static function setUpBeforeClass() { + parent::setUpBeforeClass(); + // reset backend \OC_User::clearBackends(); \OC_User::useBackend('database'); @@ -46,12 +48,14 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { \OC_FileProxy::register(new OCA\Encryption\Proxy()); // create test user - \Test_Encryption_Util::loginHelper(\Test_Encryption_Crypt::TEST_ENCRYPTION_CRYPT_USER1, true); + self::loginHelper(\Test_Encryption_Crypt::TEST_ENCRYPTION_CRYPT_USER1, true); } - function setUp() { + protected function setUp() { + parent::setUp(); + // set user id - \Test_Encryption_Util::loginHelper(\Test_Encryption_Crypt::TEST_ENCRYPTION_CRYPT_USER1); + self::loginHelper(\Test_Encryption_Crypt::TEST_ENCRYPTION_CRYPT_USER1); $this->userId = \Test_Encryption_Crypt::TEST_ENCRYPTION_CRYPT_USER1; $this->pass = \Test_Encryption_Crypt::TEST_ENCRYPTION_CRYPT_USER1; @@ -77,7 +81,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { \OC_App::disable('files_trashbin'); } - function tearDown() { + protected function tearDown() { // reset app files_trashbin if ($this->stateFilesTrashbin) { OC_App::enable('files_trashbin'); @@ -87,6 +91,8 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { $this->assertTrue(\OC_FileProxy::$enabled); \OCP\Config::deleteSystemValue('cipher'); + + parent::tearDown(); } public static function tearDownAfterClass() { @@ -100,12 +106,14 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { $view = new \OC\Files\View('/'); $view->rmdir('public-keys'); $view->rmdir('owncloud_private_key'); + + parent::tearDownAfterClass(); } /** * @medium */ - function testGenerateKey() { + public function testGenerateKey() { # TODO: use more accurate (larger) string length for test confirmation @@ -115,7 +123,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { } - function testDecryptPrivateKey() { + public function testDecryptPrivateKey() { // test successful decrypt $crypted = Encryption\Crypt::symmetricEncryptFileContent($this->genPrivateKey, 'hat'); @@ -137,7 +145,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** * @medium */ - function testSymmetricEncryptFileContent() { + public function testSymmetricEncryptFileContent() { # TODO: search in keyfile for actual content as IV will ensure this test always passes @@ -155,7 +163,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** * @medium */ - function testSymmetricEncryptFileContentAes128() { + public function testSymmetricEncryptFileContentAes128() { # TODO: search in keyfile for actual content as IV will ensure this test always passes @@ -173,9 +181,9 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** * @medium */ - function testSymmetricStreamEncryptShortFileContent() { + public function testSymmetricStreamEncryptShortFileContent() { - $filename = 'tmp-' . uniqid() . '.test'; + $filename = 'tmp-' . $this->getUniqueID() . '.test'; $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/'. $filename, $this->dataShort); @@ -210,9 +218,9 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** * @medium */ - function testSymmetricStreamEncryptShortFileContentAes128() { + public function testSymmetricStreamEncryptShortFileContentAes128() { - $filename = 'tmp-' . uniqid() . '.test'; + $filename = 'tmp-' . $this->getUniqueID() . '.test'; \OCP\Config::setSystemValue('cipher', 'AES-128-CFB'); @@ -255,10 +263,10 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { * @note If this test fails with truncate content, check that enough array slices are being rejoined to form $e, as the crypt.php file may have gotten longer and broken the manual * reassembly of its data */ - function testSymmetricStreamEncryptLongFileContent() { + public function testSymmetricStreamEncryptLongFileContent() { // Generate a a random filename - $filename = 'tmp-' . uniqid() . '.test'; + $filename = 'tmp-' . $this->getUniqueID() . '.test'; // Save long data as encrypted file using stream wrapper $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong . $this->dataLong); @@ -299,10 +307,10 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { * @note If this test fails with truncate content, check that enough array slices are being rejoined to form $e, as the crypt.php file may have gotten longer and broken the manual * reassembly of its data */ - function testSymmetricStreamEncryptLongFileContentAes128() { + public function testSymmetricStreamEncryptLongFileContentAes128() { // Generate a a random filename - $filename = 'tmp-' . uniqid() . '.test'; + $filename = 'tmp-' . $this->getUniqueID() . '.test'; \OCP\Config::setSystemValue('cipher', 'AES-128-CFB'); @@ -347,10 +355,10 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { * @note If this test fails with truncate content, check that enough array slices are being rejoined to form $e, as the crypt.php file may have gotten longer and broken the manual * reassembly of its data */ - function testStreamDecryptLongFileContentWithoutHeader() { + public function testStreamDecryptLongFileContentWithoutHeader() { // Generate a a random filename - $filename = 'tmp-' . uniqid() . '.test'; + $filename = 'tmp-' . $this->getUniqueID() . '.test'; \OCP\Config::setSystemValue('cipher', 'AES-128-CFB'); @@ -395,7 +403,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** * @medium */ - function testIsEncryptedContent() { + public function testIsEncryptedContent() { $this->assertFalse(Encryption\Crypt::isCatfileContent($this->dataUrl)); @@ -410,7 +418,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** * @large */ - function testMultiKeyEncrypt() { + public function testMultiKeyEncrypt() { # TODO: search in keyfile for actual content as IV will ensure this test always passes @@ -437,9 +445,9 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** * @medium */ - function testRenameFile() { + public function testRenameFile() { - $filename = 'tmp-' . uniqid(); + $filename = 'tmp-' . $this->getUniqueID(); // Save long data as encrypted file using stream wrapper $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong); @@ -452,7 +460,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { $this->assertEquals($this->dataLong, $decrypt); - $newFilename = 'tmp-new-' . uniqid(); + $newFilename = 'tmp-new-' . $this->getUniqueID(); $view = new \OC\Files\View('/' . $this->userId . '/files'); $view->rename($filename, $newFilename); @@ -468,9 +476,9 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** * @medium */ - function testMoveFileIntoFolder() { + public function testMoveFileIntoFolder() { - $filename = 'tmp-' . uniqid(); + $filename = 'tmp-' . $this->getUniqueID(); // Save long data as encrypted file using stream wrapper $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong); @@ -483,8 +491,8 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { $this->assertEquals($this->dataLong, $decrypt); - $newFolder = '/newfolder' . uniqid(); - $newFilename = 'tmp-new-' . uniqid(); + $newFolder = '/newfolder' . $this->getUniqueID(); + $newFilename = 'tmp-new-' . $this->getUniqueID(); $view = new \OC\Files\View('/' . $this->userId . '/files'); $view->mkdir($newFolder); $view->rename($filename, $newFolder . '/' . $newFilename); @@ -501,12 +509,12 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** * @medium */ - function testMoveFolder() { + public function testMoveFolder() { $view = new \OC\Files\View('/' . $this->userId . '/files'); - $filename = '/tmp-' . uniqid(); - $folder = '/folder' . uniqid(); + $filename = '/tmp-' . $this->getUniqueID(); + $folder = '/folder' . $this->getUniqueID(); $view->mkdir($folder); @@ -521,7 +529,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { $this->assertEquals($this->dataLong, $decrypt); - $newFolder = '/newfolder/subfolder' . uniqid(); + $newFolder = '/newfolder/subfolder' . $this->getUniqueID(); $view->mkdir('/newfolder'); $view->rename($folder, $newFolder); @@ -539,8 +547,8 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** * @medium */ - function testChangePassphrase() { - $filename = 'tmp-' . uniqid(); + public function testChangePassphrase() { + $filename = 'tmp-' . $this->getUniqueID(); // Save long data as encrypted file using stream wrapper $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong); @@ -576,9 +584,9 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** * @medium */ - function testViewFilePutAndGetContents() { + public function testViewFilePutAndGetContents() { - $filename = '/tmp-' . uniqid(); + $filename = '/tmp-' . $this->getUniqueID(); $view = new \OC\Files\View('/' . $this->userId . '/files'); // Save short data as encrypted file using stream wrapper @@ -610,8 +618,8 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** * @large */ - function testTouchExistingFile() { - $filename = '/tmp-' . uniqid(); + public function testTouchExistingFile() { + $filename = '/tmp-' . $this->getUniqueID(); $view = new \OC\Files\View('/' . $this->userId . '/files'); // Save short data as encrypted file using stream wrapper @@ -634,8 +642,8 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** * @medium */ - function testTouchFile() { - $filename = '/tmp-' . uniqid(); + public function testTouchFile() { + $filename = '/tmp-' . $this->getUniqueID(); $view = new \OC\Files\View('/' . $this->userId . '/files'); $view->touch($filename); @@ -658,8 +666,8 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { /** * @medium */ - function testFopenFile() { - $filename = '/tmp-' . uniqid(); + public function testFopenFile() { + $filename = '/tmp-' . $this->getUniqueID(); $view = new \OC\Files\View('/' . $this->userId . '/files'); // Save short data as encrypted file using stream wrapper @@ -676,6 +684,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { $this->assertEquals($this->dataShort, $decrypt); // tear down + fclose($handle); $view->unlink($filename); } diff --git a/apps/files_encryption/tests/helper.php b/apps/files_encryption/tests/helper.php index ed543bf89f6..fcde7dc5df3 100644 --- a/apps/files_encryption/tests/helper.php +++ b/apps/files_encryption/tests/helper.php @@ -6,32 +6,38 @@ * See the COPYING-README file. */ -require_once __DIR__ . '/util.php'; - use OCA\Encryption; /** * Class Test_Encryption_Helper */ -class Test_Encryption_Helper extends \PHPUnit_Framework_TestCase { +class Test_Encryption_Helper extends \OCA\Files_Encryption\Tests\TestCase { const TEST_ENCRYPTION_HELPER_USER1 = "test-helper-user1"; const TEST_ENCRYPTION_HELPER_USER2 = "test-helper-user2"; - public function setUp() { + protected function setUpUsers() { // create test user - \Test_Encryption_Util::loginHelper(\Test_Encryption_Helper::TEST_ENCRYPTION_HELPER_USER2, true); - \Test_Encryption_Util::loginHelper(\Test_Encryption_Helper::TEST_ENCRYPTION_HELPER_USER1, true); + self::loginHelper(\Test_Encryption_Helper::TEST_ENCRYPTION_HELPER_USER2, true); + self::loginHelper(\Test_Encryption_Helper::TEST_ENCRYPTION_HELPER_USER1, true); } - public function tearDown() { + protected function cleanUpUsers() { // cleanup test user \OC_User::deleteUser(\Test_Encryption_Helper::TEST_ENCRYPTION_HELPER_USER1); \OC_User::deleteUser(\Test_Encryption_Helper::TEST_ENCRYPTION_HELPER_USER2); } - public static function tearDownAfterClass() { + public static function setupHooks() { + // Filesystem related hooks + \OCA\Encryption\Helper::registerFilesystemHooks(); + + // clear and register hooks + \OC_FileProxy::clearProxies(); + \OC_FileProxy::register(new OCA\Encryption\Proxy()); + } + public static function tearDownAfterClass() { \OC_Hook::clear(); \OC_FileProxy::clearProxies(); @@ -39,6 +45,8 @@ class Test_Encryption_Helper extends \PHPUnit_Framework_TestCase { $view = new \OC\Files\View('/'); $view->rmdir('public-keys'); $view->rmdir('owncloud_private_key'); + + parent::tearDownAfterClass(); } /** @@ -90,19 +98,20 @@ class Test_Encryption_Helper extends \PHPUnit_Framework_TestCase { } function testGetUser() { + self::setUpUsers(); $path1 = "/" . self::TEST_ENCRYPTION_HELPER_USER1 . "/files/foo/bar.txt"; $path2 = "/" . self::TEST_ENCRYPTION_HELPER_USER1 . "/cache/foo/bar.txt"; $path3 = "/" . self::TEST_ENCRYPTION_HELPER_USER2 . "/thumbnails/foo"; $path4 ="/" . "/" . self::TEST_ENCRYPTION_HELPER_USER1; - \Test_Encryption_Util::loginHelper(self::TEST_ENCRYPTION_HELPER_USER1); + self::loginHelper(self::TEST_ENCRYPTION_HELPER_USER1); // if we are logged-in every path should return the currently logged-in user $this->assertEquals(self::TEST_ENCRYPTION_HELPER_USER1, Encryption\Helper::getUser($path3)); // now log out - \Test_Encryption_Util::logoutHelper(); + self::logoutHelper(); // now we should only get the user from /user/files and user/cache paths $this->assertEquals(self::TEST_ENCRYPTION_HELPER_USER1, Encryption\Helper::getUser($path1)); @@ -112,12 +121,13 @@ class Test_Encryption_Helper extends \PHPUnit_Framework_TestCase { $this->assertFalse(Encryption\Helper::getUser($path4)); // Log-in again - \Test_Encryption_Util::loginHelper(\Test_Encryption_Helper::TEST_ENCRYPTION_HELPER_USER1); + self::loginHelper(\Test_Encryption_Helper::TEST_ENCRYPTION_HELPER_USER1); + self::cleanUpUsers(); } function userNamesProvider() { return array( - array('testuser' . uniqid()), + array('testuser' . $this->getUniqueID()), array('user.name.with.dots'), ); } @@ -128,12 +138,13 @@ class Test_Encryption_Helper extends \PHPUnit_Framework_TestCase { * @dataProvider userNamesProvider */ function testFindShareKeys($userName) { + self::setUpUsers(); // note: not using dataProvider as we want to make // sure that the correct keys are match and not any // other ones that might happen to have similar names - \Test_Encryption_Util::setupHooks(); - \Test_Encryption_Util::loginHelper($userName, true); - $testDir = 'testFindShareKeys' . uniqid() . '/'; + self::setupHooks(); + self::loginHelper($userName, true); + $testDir = 'testFindShareKeys' . $this->getUniqueID() . '/'; $baseDir = $userName . '/files/' . $testDir; $fileList = array( 't est.txt', @@ -164,6 +175,6 @@ class Test_Encryption_Helper extends \PHPUnit_Framework_TestCase { $result ); } + self::cleanUpUsers(); } - } diff --git a/apps/files_encryption/tests/hooks.php b/apps/files_encryption/tests/hooks.php index c2434c0f5f6..9ea84cc94c2 100644 --- a/apps/files_encryption/tests/hooks.php +++ b/apps/files_encryption/tests/hooks.php @@ -20,24 +20,22 @@ * */ -require_once __DIR__ . '/util.php'; - use OCA\Encryption; /** * Class Test_Encryption_Hooks * this class provide basic hook app tests */ -class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { +class Test_Encryption_Hooks extends \OCA\Files_Encryption\Tests\TestCase { const TEST_ENCRYPTION_HOOKS_USER1 = "test-encryption-hooks-user1.dot"; const TEST_ENCRYPTION_HOOKS_USER2 = "test-encryption-hooks-user2.dot"; - /** - * @var \OC\Files\View - */ + /** @var \OC\Files\View */ public $user1View; // view on /data/user1/files + /** @var \OC\Files\View */ public $user2View; // view on /data/user2/files + /** @var \OC\Files\View */ public $rootView; // view on /data/user public $data; public $filename; @@ -46,6 +44,8 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { private static $testFiles; public static function setUpBeforeClass() { + parent::setUpBeforeClass(); + // note: not using a data provider because these // files all need to coexist to make sure the // share keys are found properly (pattern matching) @@ -86,13 +86,15 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { \OC_FileProxy::register(new OCA\Encryption\Proxy()); // create test user - \Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1, true); - \Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2, true); + self::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1, true); + self::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2, true); } - function setUp() { + protected function setUp() { + parent::setUp(); + // set user id - \Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1); + self::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1); \OC_User::setUserId(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1); // init filesystem view @@ -102,8 +104,8 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { // init short data $this->data = 'hats'; - $this->filename = 'enc_hooks_tests-' . uniqid() . '.txt'; - $this->folder = 'enc_hooks_tests_folder-' . uniqid(); + $this->filename = 'enc_hooks_tests-' . $this->getUniqueID() . '.txt'; + $this->folder = 'enc_hooks_tests_folder-' . $this->getUniqueID(); } @@ -119,6 +121,8 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { $view = new \OC\Files\View('/'); $view->rmdir('public-keys'); $view->rmdir('owncloud_private_key'); + + parent::tearDownAfterClass(); } function testDisableHook() { @@ -140,7 +144,7 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { // relogin user to initialize the encryption again $user = \OCP\User::getUser(); - \Test_Encryption_Util::loginHelper($user); + self::loginHelper($user); } @@ -165,8 +169,8 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/' . $this->filename . '.key')); - \Test_Encryption_Util::logoutHelper(); - \Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2); + self::logoutHelper(); + self::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2); \OC_User::setUserId(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2); @@ -223,8 +227,8 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { function testDeleteHooksForSharedFiles() { - \Test_Encryption_Util::logoutHelper(); - \Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1); + self::logoutHelper(); + self::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1); \OC_User::setUserId(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1); // remember files_trashbin state @@ -259,8 +263,8 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/' . $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey')); - \Test_Encryption_Util::logoutHelper(); - \Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2); + self::logoutHelper(); + self::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2); \OC_User::setUserId(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2); // user2 update the shared file @@ -290,8 +294,8 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { // cleanup - \Test_Encryption_Util::logoutHelper(); - \Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1); + self::logoutHelper(); + self::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1); \OC_User::setUserId(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1); if ($stateFilesTrashbin) { diff --git a/apps/files_encryption/tests/keymanager.php b/apps/files_encryption/tests/keymanager.php index e2486ee93eb..b4dc6ddeb56 100644 --- a/apps/files_encryption/tests/keymanager.php +++ b/apps/files_encryption/tests/keymanager.php @@ -6,14 +6,12 @@ * See the COPYING-README file. */ -require_once __DIR__ . '/util.php'; - use OCA\Encryption; /** * Class Test_Encryption_Keymanager */ -class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase { +class Test_Encryption_Keymanager extends \OCA\Files_Encryption\Tests\TestCase { const TEST_USER = "test-keymanager-user.dot"; @@ -28,6 +26,8 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase { public $dataShort; public static function setUpBeforeClass() { + parent::setUpBeforeClass(); + // reset backend \OC_User::clearBackends(); \OC_User::useBackend('database'); @@ -50,10 +50,11 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase { // create test user \OC_User::deleteUser(\Test_Encryption_Keymanager::TEST_USER); - \Test_Encryption_Util::loginHelper(\Test_Encryption_Keymanager::TEST_USER, true); + parent::loginHelper(\Test_Encryption_Keymanager::TEST_USER, true); } - function setUp() { + protected function setUp() { + parent::setUp(); // set content for encrypting / decrypting in tests $this->dataLong = file_get_contents(__DIR__ . '/../lib/crypt.php'); $this->dataShort = 'hats'; @@ -68,7 +69,7 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase { $this->view = new \OC\Files\View('/'); - \Test_Encryption_Util::loginHelper(Test_Encryption_Keymanager::TEST_USER); + self::loginHelper(Test_Encryption_Keymanager::TEST_USER); $this->userId = \Test_Encryption_Keymanager::TEST_USER; $this->pass = \Test_Encryption_Keymanager::TEST_USER; @@ -79,6 +80,8 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase { function tearDown() { $this->view->deleteAll('/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/share-keys'); $this->view->deleteAll('/'.Test_Encryption_Keymanager::TEST_USER.'/files_encryption/keyfiles'); + + parent::tearDown(); } public static function tearDownAfterClass() { @@ -98,6 +101,8 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase { $view = new \OC\Files\View('/'); $view->rmdir('public-keys'); $view->rmdir('owncloud_private_key'); + + parent::tearDownAfterClass(); } /** @@ -163,7 +168,7 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase { $key = $this->randomKey; - $file = 'unittest-' . uniqid() . '.txt'; + $file = 'unittest-' . $this->getUniqueID() . '.txt'; $util = new Encryption\Util($this->view, $this->userId); diff --git a/apps/files_encryption/tests/proxy.php b/apps/files_encryption/tests/proxy.php index d3e568f8914..a91222327f1 100644 --- a/apps/files_encryption/tests/proxy.php +++ b/apps/files_encryption/tests/proxy.php @@ -20,15 +20,13 @@ * */ -require_once __DIR__ . '/util.php'; - use OCA\Encryption; /** * Class Test_Encryption_Proxy * this class provide basic proxy app tests */ -class Test_Encryption_Proxy extends \PHPUnit_Framework_TestCase { +class Test_Encryption_Proxy extends \OCA\Files_Encryption\Tests\TestCase { const TEST_ENCRYPTION_PROXY_USER1 = "test-proxy-user1"; @@ -44,6 +42,8 @@ class Test_Encryption_Proxy extends \PHPUnit_Framework_TestCase { public $filename; public static function setUpBeforeClass() { + parent::setUpBeforeClass(); + // reset backend \OC_User::clearBackends(); \OC_User::useBackend('database'); @@ -59,10 +59,12 @@ class Test_Encryption_Proxy extends \PHPUnit_Framework_TestCase { \OC_FileProxy::register(new OCA\Encryption\Proxy()); // create test user - \Test_Encryption_Util::loginHelper(\Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1, true); + self::loginHelper(\Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1, true); } - function setUp() { + protected function setUp() { + parent::setUp(); + // set user id \OC_User::setUserId(\Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1); $this->userId = \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1; @@ -75,7 +77,7 @@ class Test_Encryption_Proxy extends \PHPUnit_Framework_TestCase { // init short data $this->data = 'hats'; $this->dataLong = file_get_contents(__DIR__ . '/../lib/crypt.php'); - $this->filename = 'enc_proxy_tests-' . uniqid() . '.txt'; + $this->filename = 'enc_proxy_tests-' . $this->getUniqueID() . '.txt'; } @@ -90,6 +92,8 @@ class Test_Encryption_Proxy extends \PHPUnit_Framework_TestCase { $view = new \OC\Files\View('/'); $view->rmdir('public-keys'); $view->rmdir('owncloud_private_key'); + + parent::tearDownAfterClass(); } /** diff --git a/apps/files_encryption/tests/share.php b/apps/files_encryption/tests/share.php index d7efe21a8fd..20ee2cc7064 100755 --- a/apps/files_encryption/tests/share.php +++ b/apps/files_encryption/tests/share.php @@ -20,14 +20,12 @@ * */ -require_once __DIR__ . '/util.php'; - use OCA\Encryption; /** * Class Test_Encryption_Share */ -class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { +class Test_Encryption_Share extends \OCA\Files_Encryption\Tests\TestCase { const TEST_ENCRYPTION_SHARE_USER1 = "test-share-user1"; const TEST_ENCRYPTION_SHARE_USER2 = "test-share-user2"; @@ -47,6 +45,8 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { public $subsubfolder; public static function setUpBeforeClass() { + parent::setUpBeforeClass(); + // reset backend \OC_User::clearBackends(); \OC_User::useBackend('database'); @@ -73,10 +73,10 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { \OC_FileProxy::register(new OCA\Encryption\Proxy()); // create users - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1, true); - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, true); - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3, true); - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4, true); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1, true); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, true); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3, true); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4, true); // create group and assign users \OC_Group::createGroup(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_GROUP1); @@ -84,7 +84,9 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { \OC_Group::addToGroup(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_GROUP1); } - function setUp() { + protected function setUp() { + parent::setUp(); + $this->dataShort = 'hats'; $this->view = new \OC\Files\View('/'); @@ -101,16 +103,18 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { \OC_App::disable('files_trashbin'); // login as first user - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); } - function tearDown() { + protected function tearDown() { // reset app files_trashbin if ($this->stateFilesTrashbin) { OC_App::enable('files_trashbin'); } else { OC_App::disable('files_trashbin'); } + + parent::tearDown(); } public static function tearDownAfterClass() { @@ -130,6 +134,8 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { $view = new \OC\Files\View('/'); $view->rmdir('public-keys'); $view->rmdir('owncloud_private_key'); + + parent::tearDownAfterClass(); } @@ -139,7 +145,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { */ function testShareFile($withTeardown = true) { // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // save file with content $cryptedFile = file_put_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename, $this->dataShort); @@ -168,7 +174,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, OCP\PERMISSION_ALL); // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // check if share key for user1 exists $this->assertTrue($this->view->file_exists( @@ -176,7 +182,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); // login as user1 - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); // get file contents $retrievedCryptedFile = $this->view->file_get_contents( @@ -189,7 +195,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { if ($withTeardown) { // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // unshare the file \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); @@ -219,7 +225,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { $this->testShareFile(false); // login as user2 - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); // get the file info $fileInfo = $this->view->getFileInfo( @@ -229,7 +235,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3, OCP\PERMISSION_ALL); // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // check if share key for user2 exists $this->assertTrue($this->view->file_exists( @@ -237,7 +243,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.shareKey')); // login as user2 - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3); // get file contents $retrievedCryptedFile = $this->view->file_get_contents( @@ -250,13 +256,13 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { if ($withTeardown) { // login as user1 - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); // unshare the file with user2 \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3); // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // check if share key not exists $this->assertFalse($this->view->file_exists( @@ -290,7 +296,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { */ function testShareFolder($withTeardown = true) { // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // create folder structure $this->view->mkdir('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files' . $this->folder1); @@ -325,7 +331,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { \OCP\Share::shareItem('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, OCP\PERMISSION_ALL); // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // check if share key for user1 exists $this->assertTrue($this->view->file_exists( @@ -334,7 +340,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); // login as user1 - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); // get file contents $retrievedCryptedFile = $this->view->file_get_contents( @@ -348,7 +354,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { if ($withTeardown) { // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // unshare the folder with user1 \OCP\Share::unshare('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); @@ -382,7 +388,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { $fileInfoFolder1 = $this->testShareFolder(false); // login as user2 - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); // disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; @@ -403,7 +409,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { \OCP\Share::shareItem('folder', $fileInfoSubFolder['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3, OCP\PERMISSION_ALL); // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // check if share key for user3 exists $this->assertTrue($this->view->file_exists( @@ -412,7 +418,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.shareKey')); // login as user3 - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3); // get file contents $retrievedCryptedFile = $this->view->file_get_contents( @@ -434,7 +440,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4, OCP\PERMISSION_ALL); // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // check if share key for user3 exists $this->assertTrue($this->view->file_exists( @@ -443,7 +449,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4 . '.shareKey')); // login as user3 - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4); // get file contents $retrievedCryptedFile = $this->view->file_get_contents( @@ -456,7 +462,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { if ($withTeardown) { // login as user2 - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3); // unshare the file with user3 \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4); @@ -468,7 +474,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4 . '.shareKey')); // login as user1 - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); // unshare the folder with user2 \OCP\Share::unshare('folder', $fileInfoSubFolder['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3); @@ -480,7 +486,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.shareKey')); // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // unshare the folder1 with user1 \OCP\Share::unshare('folder', $fileInfoFolder1['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); @@ -507,7 +513,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { function testPublicShareFile() { // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // save file with content $cryptedFile = file_put_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename, $this->dataShort); @@ -536,7 +542,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, false, OCP\PERMISSION_ALL); // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); $publicShareKeyId = \OC::$server->getAppConfig()->getValue('files_encryption', 'publicShareKeyId'); @@ -548,7 +554,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { // some hacking to simulate public link //$GLOBALS['app'] = 'files_sharing'; //$GLOBALS['fileOwner'] = \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1; - \Test_Encryption_Util::logoutHelper(); + self::logoutHelper(); // get file contents $retrievedCryptedFile = file_get_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename); @@ -559,7 +565,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { // tear down // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // unshare the file \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null); @@ -585,7 +591,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { */ function testShareFileWithGroup() { // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // save file with content $cryptedFile = file_put_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename, $this->dataShort); @@ -614,7 +620,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_GROUP1, OCP\PERMISSION_ALL); // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // check if share key for user2 and user3 exists $this->assertTrue($this->view->file_exists( @@ -625,7 +631,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4 . '.shareKey')); // login as user1 - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3); // get file contents $retrievedCryptedFile = $this->view->file_get_contents( @@ -635,7 +641,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { $this->assertEquals($this->dataShort, $retrievedCryptedFile); // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // unshare the file \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_GROUP1); @@ -666,13 +672,13 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { function testRecoveryFile() { // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); \OCA\Encryption\Helper::adminEnableRecovery(null, 'test123'); $recoveryKeyId = \OC::$server->getAppConfig()->getValue('files_encryption', 'recoveryKeyId'); // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); $util = new \OCA\Encryption\Util(new \OC\Files\View('/'), \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); @@ -772,7 +778,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { function testRecoveryForUser() { // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); $result = \OCA\Encryption\Helper::adminEnableRecovery(null, 'test123'); $this->assertTrue($result); @@ -780,7 +786,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { $recoveryKeyId = \OC::$server->getAppConfig()->getValue('files_encryption', 'recoveryKeyId'); // login as user2 - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); $util = new \OCA\Encryption\Util(new \OC\Files\View('/'), \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); @@ -824,7 +830,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { . $this->filename . '.' . $recoveryKeyId . '.shareKey')); // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // change password \OC_User::setPassword(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, 'test', 'test123'); @@ -834,7 +840,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { \OCA\Encryption\Hooks::setPassphrase($params); // login as user2 - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, false, 'test'); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, false, 'test'); // get file contents $retrievedCryptedFile1 = file_get_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename); @@ -886,7 +892,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { */ function testFailShareFile() { // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // save file with content $cryptedFile = file_put_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename, $this->dataShort); @@ -924,7 +930,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // check if share key for user1 not exists $this->assertFalse($this->view->file_exists( @@ -969,7 +975,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { function testRename() { // login as admin - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // save file with content $cryptedFile = file_put_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename, $this->dataShort); @@ -994,7 +1000,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { // login as user2 - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename)); @@ -1017,7 +1023,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { $this->assertEquals($this->dataShort, $retrievedRenamedFile); // cleanup - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename); } @@ -1029,8 +1035,8 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { $view = new \OC\Files\View('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); - $filename = '/tmp-' . uniqid(); - $folder = '/folder' . uniqid(); + $filename = '/tmp-' . $this->getUniqueID(); + $folder = '/folder' . $this->getUniqueID(); \OC\Files\Filesystem::mkdir($folder); @@ -1045,7 +1051,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { $this->assertEquals($this->dataShort, $decrypt); - $newFolder = '/newfolder/subfolder' . uniqid(); + $newFolder = '/newfolder/subfolder' . $this->getUniqueID(); \OC\Files\Filesystem::mkdir('/newfolder'); // get the file info from previous created file @@ -1087,8 +1093,8 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { function testMoveFileToFolder($userId) { $view = new \OC\Files\View('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); - $filename = '/tmp-' . uniqid(); - $folder = '/folder' . uniqid(); + $filename = '/tmp-' . $this->getUniqueID(); + $folder = '/folder' . $this->getUniqueID(); \OC\Files\Filesystem::mkdir($folder); @@ -1103,7 +1109,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { $this->assertEquals($this->dataShort, $decrypt); - $subFolder = $folder . '/subfolder' . uniqid(); + $subFolder = $folder . '/subfolder' . $this->getUniqueID(); \OC\Files\Filesystem::mkdir($subFolder); // get the file info from previous created file @@ -1118,9 +1124,9 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { $this->assertTrue($view->file_exists('files_encryption/share-keys' . $folder . '/' . $filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); // move the file into the subfolder as the test user - \Test_Encryption_Util::loginHelper($userId); + self::loginHelper($userId); \OC\Files\Filesystem::rename($folder . $filename, $subFolder . $filename); - \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); + self::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // Get file decrypted contents $newDecrypt = \OC\Files\Filesystem::file_get_contents($subFolder . $filename); diff --git a/apps/files_encryption/tests/stream.php b/apps/files_encryption/tests/stream.php index 2b57f11c680..b1404ca282a 100644 --- a/apps/files_encryption/tests/stream.php +++ b/apps/files_encryption/tests/stream.php @@ -20,15 +20,13 @@ * */ -require_once __DIR__ . '/util.php'; - use OCA\Encryption; /** * Class Test_Encryption_Stream * this class provide basic stream tests */ -class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase { +class Test_Encryption_Stream extends \OCA\Files_Encryption\Tests\TestCase { const TEST_ENCRYPTION_STREAM_USER1 = "test-stream-user1"; @@ -42,6 +40,8 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase { public $stateFilesTrashbin; public static function setUpBeforeClass() { + parent::setUpBeforeClass(); + // reset backend \OC_User::clearBackends(); \OC_User::useBackend('database'); @@ -54,10 +54,12 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase { \OC_FileProxy::register(new OCA\Encryption\Proxy()); // create test user - \Test_Encryption_Util::loginHelper(\Test_Encryption_Stream::TEST_ENCRYPTION_STREAM_USER1, true); + self::loginHelper(\Test_Encryption_Stream::TEST_ENCRYPTION_STREAM_USER1, true); } - function setUp() { + protected function setUp() { + parent::setUp(); + // set user id \OC_User::setUserId(\Test_Encryption_Stream::TEST_ENCRYPTION_STREAM_USER1); $this->userId = \Test_Encryption_Stream::TEST_ENCRYPTION_STREAM_USER1; @@ -76,7 +78,7 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase { \OC_App::disable('files_trashbin'); } - function tearDown() { + protected function tearDown() { // reset app files_trashbin if ($this->stateFilesTrashbin) { OC_App::enable('files_trashbin'); @@ -84,6 +86,8 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase { else { OC_App::disable('files_trashbin'); } + + parent::tearDown(); } public static function tearDownAfterClass() { @@ -97,10 +101,12 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase { $view = new \OC\Files\View('/'); $view->rmdir('public-keys'); $view->rmdir('owncloud_private_key'); + + parent::tearDownAfterClass(); } function testStreamOptions() { - $filename = '/tmp-' . uniqid(); + $filename = '/tmp-' . $this->getUniqueID(); $view = new \OC\Files\View('/' . $this->userId . '/files'); // Save short data as encrypted file using stream wrapper @@ -118,12 +124,14 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase { $this->assertTrue(flock($handle, LOCK_SH)); $this->assertTrue(flock($handle, LOCK_UN)); + fclose($handle); + // tear down $view->unlink($filename); } function testStreamSetBlocking() { - $filename = '/tmp-' . uniqid(); + $filename = '/tmp-' . $this->getUniqueID(); $view = new \OC\Files\View('/' . $this->userId . '/files'); // Save short data as encrypted file using stream wrapper @@ -134,6 +142,13 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase { $handle = $view->fopen($filename, 'r'); + + if (\OC_Util::runningOnWindows()) { + fclose($handle); + $view->unlink($filename); + $this->markTestSkipped('[Windows] stream_set_blocking() does not work as expected on Windows.'); + } + // set stream options $this->assertTrue(stream_set_blocking($handle, 1)); @@ -147,7 +162,7 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase { * @medium */ function testStreamSetTimeout() { - $filename = '/tmp-' . uniqid(); + $filename = '/tmp-' . $this->getUniqueID(); $view = new \OC\Files\View('/' . $this->userId . '/files'); // Save short data as encrypted file using stream wrapper @@ -168,7 +183,7 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase { } function testStreamSetWriteBuffer() { - $filename = '/tmp-' . uniqid(); + $filename = '/tmp-' . $this->getUniqueID(); $view = new \OC\Files\View('/' . $this->userId . '/files'); // Save short data as encrypted file using stream wrapper @@ -194,9 +209,9 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase { */ function testStreamFromLocalFile() { - $filename = '/' . $this->userId . '/files/' . 'tmp-' . uniqid().'.txt'; + $filename = '/' . $this->userId . '/files/' . 'tmp-' . $this->getUniqueID().'.txt'; - $tmpFilename = "/tmp/" . uniqid() . ".txt"; + $tmpFilename = "/tmp/" . $this->getUniqueID() . ".txt"; // write an encrypted file $cryptedFile = $this->view->file_put_contents($filename, $this->dataShort); @@ -221,6 +236,8 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase { // check if it was successful $this->assertEquals($this->dataShort, $contentFromTmpFile); + fclose($handle); + // clean up unlink($tmpFilename); $this->view->unlink($filename); diff --git a/apps/files_encryption/tests/testcase.php b/apps/files_encryption/tests/testcase.php new file mode 100644 index 00000000000..3106aeda8ea --- /dev/null +++ b/apps/files_encryption/tests/testcase.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright (c) 2012 Sam Tuke <samtuke@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCA\Files_Encryption\Tests; + +use OCA\Encryption; + +/** + * Class Test_Encryption_TestCase + */ +abstract class TestCase extends \Test\TestCase { + /** + * @param string $user + * @param bool $create + * @param bool $password + */ + public static function loginHelper($user, $create = false, $password = false, $loadEncryption = true) { + if ($create) { + try { + \OC_User::createUser($user, $user); + } catch (\Exception $e) { + // catch username is already being used from previous aborted runs + } + } + + if ($password === false) { + $password = $user; + } + + \OC_Util::tearDownFS(); + \OC_User::setUserId(''); + \OC\Files\Filesystem::tearDown(); + \OC_User::setUserId($user); + \OC_Util::setupFS($user); + + if ($loadEncryption) { + $params['uid'] = $user; + $params['password'] = $password; + \OCA\Encryption\Hooks::login($params); + } + } + + public static function logoutHelper() { + \OC_Util::tearDownFS(); + \OC_User::setUserId(false); + \OC\Files\Filesystem::tearDown(); + } +} diff --git a/apps/files_encryption/tests/trashbin.php b/apps/files_encryption/tests/trashbin.php index d795240399c..a43e8f964a2 100755 --- a/apps/files_encryption/tests/trashbin.php +++ b/apps/files_encryption/tests/trashbin.php @@ -20,15 +20,13 @@ * */ -require_once __DIR__ . '/util.php'; - use OCA\Encryption; /** * Class Test_Encryption_Trashbin * this class provide basic trashbin app tests */ -class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { +class Test_Encryption_Trashbin extends \OCA\Files_Encryption\Tests\TestCase { const TEST_ENCRYPTION_TRASHBIN_USER1 = "test-trashbin-user1"; @@ -45,6 +43,8 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { public $subsubfolder; public static function setUpBeforeClass() { + parent::setUpBeforeClass(); + // reset backend \OC_User::clearBackends(); \OC_User::useBackend('database'); @@ -63,14 +63,16 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { \OC_FileProxy::register(new OCA\Encryption\Proxy()); // create test user - \Test_Encryption_Util::loginHelper(\Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1, true); + self::loginHelper(self::TEST_ENCRYPTION_TRASHBIN_USER1, true); } - function setUp() { + protected function setUp() { + parent::setUp(); + // set user id - \OC_User::setUserId(\Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1); - $this->userId = \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1; - $this->pass = \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1; + \OC_User::setUserId(self::TEST_ENCRYPTION_TRASHBIN_USER1); + $this->userId = self::TEST_ENCRYPTION_TRASHBIN_USER1; + $this->pass = self::TEST_ENCRYPTION_TRASHBIN_USER1; // init filesystem view $this->view = new \OC\Files\View('/'); @@ -89,7 +91,7 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { \OC_App::enable('files_trashbin'); } - function tearDown() { + protected function tearDown() { // reset app files_trashbin if ($this->stateFilesTrashbin) { OC_App::enable('files_trashbin'); @@ -97,11 +99,13 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { else { OC_App::disable('files_trashbin'); } + + parent::tearDown(); } public static function tearDownAfterClass() { // cleanup test user - \OC_User::deleteUser(\Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1); + \OC_User::deleteUser(self::TEST_ENCRYPTION_TRASHBIN_USER1); \OC_Hook::clear(); \OC_FileProxy::clearProxies(); @@ -110,6 +114,8 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { $view = new \OC\Files\View('/'); $view->rmdir('public-keys'); $view->rmdir('owncloud_private_key'); + + parent::tearDownAfterClass(); } /** @@ -119,12 +125,12 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { function testDeleteFile() { // generate filename - $filename = 'tmp-' . uniqid() . '.txt'; + $filename = 'tmp-' . $this->getUniqueID() . '.txt'; $filename2 = $filename . '.backup'; // a second file with similar name // save file with content - $cryptedFile = file_put_contents('crypt:///' .\Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1. '/files/'. $filename, $this->dataShort); - $cryptedFile2 = file_put_contents('crypt:///' .\Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1. '/files/'. $filename2, $this->dataShort); + $cryptedFile = file_put_contents('crypt:///' .self::TEST_ENCRYPTION_TRASHBIN_USER1. '/files/'. $filename, $this->dataShort); + $cryptedFile2 = file_put_contents('crypt:///' .self::TEST_ENCRYPTION_TRASHBIN_USER1. '/files/'. $filename2, $this->dataShort); // test that data was successfully written $this->assertTrue(is_int($cryptedFile)); @@ -132,59 +138,59 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { // check if key for admin exists $this->assertTrue($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename . '.key')); $this->assertTrue($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename2 + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename2 . '.key')); // check if share key for admin exists $this->assertTrue($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/' - . $filename . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/' + . $filename . '.' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); $this->assertTrue($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/' - . $filename2 . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/' + . $filename2 . '.' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); // delete first file \OC\FIles\Filesystem::unlink($filename); // check if file not exists $this->assertFalse($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename)); + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename)); // check if key for admin not exists $this->assertFalse($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename . '.key')); // check if share key for admin not exists $this->assertFalse($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/' - . $filename . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/' + . $filename . '.' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); // check that second file still exists $this->assertTrue($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename2)); + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename2)); // check that key for second file still exists $this->assertTrue($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename2 + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename2 . '.key')); // check that share key for second file still exists $this->assertTrue($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/' - . $filename2 . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/' + . $filename2 . '.' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); // get files $trashFiles = $this->view->getDirectoryContent( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/files/'); + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/files/'); $trashFileSuffix = null; // find created file with timestamp foreach ($trashFiles as $file) { - if (strncmp($file['path'], $filename, strlen($filename))) { + if (strpos($file['path'], $filename . '.d') !== false) { $path_parts = pathinfo($file['name']); $trashFileSuffix = $path_parts['extension']; } @@ -195,13 +201,13 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { // check if key for admin not exists $this->assertTrue($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keyfiles/' . $filename + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keyfiles/' . $filename . '.key.' . $trashFileSuffix)); // check if share key for admin not exists $this->assertTrue($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/share-keys/' . $filename - . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey.' . $trashFileSuffix)); + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/share-keys/' . $filename + . '.' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey.' . $trashFileSuffix)); } /** @@ -210,32 +216,27 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { */ function testRestoreFile() { // generate filename - $filename = 'tmp-' . uniqid() . '.txt'; + $filename = 'tmp-' . $this->getUniqueID() . '.txt'; $filename2 = $filename . '.backup'; // a second file with similar name // save file with content - $cryptedFile = file_put_contents('crypt:///' .\Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1. '/files/'. $filename, $this->dataShort); - $cryptedFile2 = file_put_contents('crypt:///' .\Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1. '/files/'. $filename2, $this->dataShort); + $cryptedFile = file_put_contents('crypt:///' . self::TEST_ENCRYPTION_TRASHBIN_USER1. '/files/'. $filename, $this->dataShort); + $cryptedFile2 = file_put_contents('crypt:///' . self::TEST_ENCRYPTION_TRASHBIN_USER1. '/files/'. $filename2, $this->dataShort); // delete both files \OC\Files\Filesystem::unlink($filename); \OC\Files\Filesystem::unlink($filename2); - $trashFiles = $this->view->getDirectoryContent( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/files/'); + $trashFiles = $this->view->getDirectoryContent('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/files/'); $trashFileSuffix = null; $trashFileSuffix2 = null; // find created file with timestamp foreach ($trashFiles as $file) { - if (strncmp($file['path'], $filename, strlen($filename))) { + if (strpos($file['path'], $filename . '.d') !== false) { $path_parts = pathinfo($file['name']); $trashFileSuffix = $path_parts['extension']; } - if (strncmp($file['path'], $filename2, strlen($filename2))) { - $path_parts = pathinfo($file['name']); - $trashFileSuffix2 = $path_parts['extension']; - } } // prepare file information @@ -246,31 +247,31 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { // check if file exists $this->assertTrue($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename)); + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename)); // check if key for admin exists $this->assertTrue($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename . '.key')); // check if share key for admin exists $this->assertTrue($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/' - . $filename . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/' + . $filename . '.' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); // check that second file was NOT restored $this->assertFalse($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename2)); + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename2)); // check if key for admin exists $this->assertFalse($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename2 . '.key')); // check if share key for admin exists $this->assertFalse($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/' - . $filename2 . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/' + . $filename2 . '.' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); } /** @@ -280,7 +281,7 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { function testPermanentDeleteFile() { // generate filename - $filename = 'tmp-' . uniqid() . '.txt'; + $filename = 'tmp-' . $this->getUniqueID() . '.txt'; // save file with content $cryptedFile = file_put_contents('crypt:///' .$this->userId. '/files/' . $filename, $this->dataShort); @@ -290,30 +291,30 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { // check if key for admin exists $this->assertTrue($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename . '.key')); // check if share key for admin exists $this->assertTrue($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/' - . $filename . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/' + . $filename . '.' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); // delete file \OC\Files\Filesystem::unlink($filename); // check if file not exists $this->assertFalse($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename)); + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename)); // check if key for admin not exists $this->assertFalse($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keyfiles/' . $filename . '.key')); // check if share key for admin not exists $this->assertFalse($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/' - . $filename . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/share-keys/' + . $filename . '.' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); // find created file with timestamp $query = \OC_DB::prepare('SELECT `timestamp`,`type` FROM `*PREFIX*files_trash`' @@ -327,13 +328,13 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { // check if key for admin exists $this->assertTrue($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keyfiles/' . $filename + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keyfiles/' . $filename . '.key.' . $trashFileSuffix)); // check if share key for admin exists $this->assertTrue($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/share-keys/' . $filename - . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey.' . $trashFileSuffix)); + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/share-keys/' . $filename + . '.' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey.' . $trashFileSuffix)); // get timestamp from file $timestamp = str_replace('d', '', $trashFileSuffix); @@ -343,18 +344,18 @@ class Test_Encryption_Trashbin extends \PHPUnit_Framework_TestCase { // check if key for admin not exists $this->assertFalse($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/files/' . $filename . '.' + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/files/' . $filename . '.' . $trashFileSuffix)); // check if key for admin not exists $this->assertFalse($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keyfiles/' . $filename + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keyfiles/' . $filename . '.key.' . $trashFileSuffix)); // check if share key for admin not exists $this->assertFalse($this->view->file_exists( - '/' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/share-keys/' . $filename - . '.' . \Test_Encryption_Trashbin::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey.' . $trashFileSuffix)); + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/share-keys/' . $filename + . '.' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey.' . $trashFileSuffix)); } } diff --git a/apps/files_encryption/tests/util.php b/apps/files_encryption/tests/util.php index 210ffcc5410..bbf6efae5b9 100755 --- a/apps/files_encryption/tests/util.php +++ b/apps/files_encryption/tests/util.php @@ -11,7 +11,7 @@ use OCA\Encryption; /** * Class Test_Encryption_Util */ -class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { +class Test_Encryption_Util extends \OCA\Files_Encryption\Tests\TestCase { const TEST_ENCRYPTION_UTIL_USER1 = "test-util-user1"; const TEST_ENCRYPTION_UTIL_USER2 = "test-util-user2"; @@ -41,6 +41,8 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { public $stateFilesTrashbin; public static function setUpBeforeClass() { + parent::setUpBeforeClass(); + // reset backend \OC_User::clearBackends(); \OC_User::useBackend('database'); @@ -48,9 +50,9 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { self::setupHooks(); // create test user - \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1, true); - \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER2, true); - \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER, true); + self::loginHelper(self::TEST_ENCRYPTION_UTIL_USER1, true); + self::loginHelper(self::TEST_ENCRYPTION_UTIL_USER2, true); + self::loginHelper(self::TEST_ENCRYPTION_UTIL_LEGACY_USER, true); // create groups \OC_Group::createGroup(self::TEST_ENCRYPTION_UTIL_GROUP1); @@ -60,13 +62,14 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { \OC_Group::addToGroup(self::TEST_ENCRYPTION_UTIL_USER1, self::TEST_ENCRYPTION_UTIL_GROUP1); } + protected function setUp() { + parent::setUp(); - function setUp() { // login user - \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1); - \OC_User::setUserId(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1); - $this->userId = \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1; - $this->pass = \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1; + self::loginHelper(self::TEST_ENCRYPTION_UTIL_USER1); + \OC_User::setUserId(self::TEST_ENCRYPTION_UTIL_USER1); + $this->userId = self::TEST_ENCRYPTION_UTIL_USER1; + $this->pass = self::TEST_ENCRYPTION_UTIL_USER1; // set content for encrypting / decrypting in tests $this->dataUrl = __DIR__ . '/../lib/crypt.php'; @@ -101,7 +104,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { \OC_App::disable('files_trashbin'); } - function tearDown() { + protected function tearDown() { // reset app files_trashbin if ($this->stateFilesTrashbin) { OC_App::enable('files_trashbin'); @@ -109,13 +112,15 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { else { OC_App::disable('files_trashbin'); } + + parent::tearDown(); } public static function tearDownAfterClass() { // cleanup test user - \OC_User::deleteUser(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1); - \OC_User::deleteUser(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER2); - \OC_User::deleteUser(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER); + \OC_User::deleteUser(self::TEST_ENCRYPTION_UTIL_USER1); + \OC_User::deleteUser(self::TEST_ENCRYPTION_UTIL_USER2); + \OC_User::deleteUser(self::TEST_ENCRYPTION_UTIL_LEGACY_USER); //cleanup groups \OC_Group::deleteGroup(self::TEST_ENCRYPTION_UTIL_GROUP1); @@ -128,6 +133,8 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { $view = new \OC\Files\View('/'); $view->rmdir('public-keys'); $view->rmdir('owncloud_private_key'); + + parent::tearDownAfterClass(); } public static function setupHooks() { @@ -164,8 +171,8 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { self::loginHelper($this->userId); - $unencryptedFile = '/tmpUnencrypted-' . uniqid() . '.txt'; - $encryptedFile = '/tmpEncrypted-' . uniqid() . '.txt'; + $unencryptedFile = '/tmpUnencrypted-' . $this->getUniqueID() . '.txt'; + $encryptedFile = '/tmpEncrypted-' . $this->getUniqueID() . '.txt'; // Disable encryption proxy to write a unencrypted file $proxyStatus = \OC_FileProxy::$enabled; @@ -244,9 +251,9 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { */ function testGetUidAndFilename() { - \OC_User::setUserId(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1); + \OC_User::setUserId(self::TEST_ENCRYPTION_UTIL_USER1); - $filename = '/tmp-' . uniqid() . '.test'; + $filename = '/tmp-' . $this->getUniqueID() . '.test'; // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; @@ -261,7 +268,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { list($fileOwnerUid, $file) = $util->getUidAndFilename($filename); - $this->assertEquals(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1, $fileOwnerUid); + $this->assertEquals(self::TEST_ENCRYPTION_UTIL_USER1, $fileOwnerUid); $this->assertEquals($file, $filename); @@ -272,9 +279,9 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { * Test that data that is read by the crypto stream wrapper */ function testGetFileSize() { - \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1); + self::loginHelper(self::TEST_ENCRYPTION_UTIL_USER1); - $filename = 'tmp-' . uniqid(); + $filename = 'tmp-' . $this->getUniqueID(); $externalFilename = '/' . $this->userId . '/files/' . $filename; // Test for 0 byte files @@ -298,7 +305,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { function testEncryptAll() { - $filename = "/encryptAll" . uniqid() . ".txt"; + $filename = "/encryptAll" . $this->getUniqueID() . ".txt"; $util = new Encryption\Util($this->view, $this->userId); // disable encryption to upload a unencrypted file @@ -329,7 +336,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { function testDecryptAll() { - $filename = "/decryptAll" . uniqid() . ".txt"; + $filename = "/decryptAll" . $this->getUniqueID() . ".txt"; $datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT . '/data/'); $userdir = $datadir . '/' . $this->userId . '/files/'; @@ -448,8 +455,8 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { function testDescryptAllWithBrokenFiles() { - $file1 = "/decryptAll1" . uniqid() . ".txt"; - $file2 = "/decryptAll2" . uniqid() . ".txt"; + $file1 = "/decryptAll1" . $this->getUniqueID() . ".txt"; + $file2 = "/decryptAll2" . $this->getUniqueID() . ".txt"; $util = new Encryption\Util($this->view, $this->userId); diff --git a/apps/files_encryption/tests/webdav.php b/apps/files_encryption/tests/webdav.php index c838ddd29d1..7cadeaf0ba9 100755 --- a/apps/files_encryption/tests/webdav.php +++ b/apps/files_encryption/tests/webdav.php @@ -20,8 +20,6 @@ * */ -require_once __DIR__ . '/util.php'; - use OCA\Encryption; /** @@ -29,7 +27,7 @@ use OCA\Encryption; * * this class provide basic webdav tests for PUT,GET and DELETE */ -class Test_Encryption_Webdav extends \PHPUnit_Framework_TestCase { +class Test_Encryption_Webdav extends \OCA\Files_Encryption\Tests\TestCase { const TEST_ENCRYPTION_WEBDAV_USER1 = "test-webdav-user1"; @@ -45,6 +43,8 @@ class Test_Encryption_Webdav extends \PHPUnit_Framework_TestCase { private $storage; public static function setUpBeforeClass() { + parent::setUpBeforeClass(); + // reset backend \OC_User::clearBackends(); \OC_User::useBackend('database'); @@ -60,11 +60,13 @@ class Test_Encryption_Webdav extends \PHPUnit_Framework_TestCase { \OC_FileProxy::register(new OCA\Encryption\Proxy()); // create test user - \Test_Encryption_Util::loginHelper(\Test_Encryption_Webdav::TEST_ENCRYPTION_WEBDAV_USER1, true); + self::loginHelper(\Test_Encryption_Webdav::TEST_ENCRYPTION_WEBDAV_USER1, true); } - function setUp() { + protected function setUp() { + parent::setUp(); + // reset backend \OC_User::useBackend('database'); @@ -86,16 +88,18 @@ class Test_Encryption_Webdav extends \PHPUnit_Framework_TestCase { \OC_App::disable('files_trashbin'); // create test user - \Test_Encryption_Util::loginHelper(\Test_Encryption_Webdav::TEST_ENCRYPTION_WEBDAV_USER1); + self::loginHelper(\Test_Encryption_Webdav::TEST_ENCRYPTION_WEBDAV_USER1); } - function tearDown() { + protected function tearDown() { // reset app files_trashbin if ($this->stateFilesTrashbin) { OC_App::enable('files_trashbin'); } else { OC_App::disable('files_trashbin'); } + + parent::tearDown(); } public static function tearDownAfterClass() { @@ -109,6 +113,8 @@ class Test_Encryption_Webdav extends \PHPUnit_Framework_TestCase { $view = new \OC\Files\View('/'); $view->rmdir('public-keys'); $view->rmdir('owncloud_private_key'); + + parent::tearDownAfterClass(); } /** @@ -117,7 +123,7 @@ class Test_Encryption_Webdav extends \PHPUnit_Framework_TestCase { function testWebdavPUT() { // generate filename - $filename = '/tmp-' . uniqid() . '.txt'; + $filename = '/tmp-' . $this->getUniqueID() . '.txt'; // set server vars $_SERVER['REQUEST_METHOD'] = 'OPTIONS'; diff --git a/apps/files_external/js/app.js b/apps/files_external/js/app.js index 58ad1a0f6ef..bf853f926dc 100644 --- a/apps/files_external/js/app.js +++ b/apps/files_external/js/app.js @@ -9,8 +9,14 @@ */ if (!OCA.External) { + /** + * @namespace + */ OCA.External = {}; } +/** + * @namespace + */ OCA.External.App = { fileList: null, diff --git a/apps/files_external/js/mountsfilelist.js b/apps/files_external/js/mountsfilelist.js index 20bf0f785db..c45faafd9bf 100644 --- a/apps/files_external/js/mountsfilelist.js +++ b/apps/files_external/js/mountsfilelist.js @@ -10,15 +10,29 @@ (function() { /** - * External storage file list - */ + * @class OCA.External.FileList + * @augments OCA.Files.FileList + * + * @classdesc External storage file list. + * + * Displays a list of mount points visible + * for the current user. + * + * @param $el container element with existing markup for the #controls + * and a table + * @param [options] map of options, see other parameters + **/ var FileList = function($el, options) { this.initialize($el, options); }; - FileList.prototype = _.extend({}, OCA.Files.FileList.prototype, { + FileList.prototype = _.extend({}, OCA.Files.FileList.prototype, + /** @lends OCA.External.FileList.prototype */ { appName: 'External storage', + /** + * @private + */ initialize: function($el, options) { OCA.Files.FileList.prototype.initialize.apply(this, arguments); if (this.initialized) { @@ -26,6 +40,9 @@ } }, + /** + * @param {OCA.External.MountPointInfo} fileData + */ _createRow: function(fileData) { // TODO: hook earlier and render the whole row here var $tr = OCA.Files.FileList.prototype._createRow.apply(this, arguments); @@ -114,5 +131,15 @@ } }); + /** + * Mount point info attributes. + * + * @typedef {Object} OCA.External.MountPointInfo + * + * @property {String} name mount point name + * @property {String} scope mount point scope "personal" or "system" + * @property {String} backend external storage backend name + */ + OCA.External.FileList = FileList; })(); diff --git a/apps/files_external/l10n/fr.js b/apps/files_external/l10n/fr.js index a5efda84f81..7f827ec6fd4 100644 --- a/apps/files_external/l10n/fr.js +++ b/apps/files_external/l10n/fr.js @@ -55,8 +55,8 @@ OC.L10N.register( "Saved" : "Sauvegarder", "<b>Note:</b> " : "<b>Attention :</b>", " and " : "et", - "<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>Attention :</b> Le support de cURL de PHP n'est pas activé ou installé. Le montage de %s n'est pas possible. Contactez votre administrateur système pour l'installer.", - "<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>Attention : </b> Le support FTP de PHP n'est pas activé ou installé. Le montage de %s n'est pas possible. Contactez votre administrateur système pour l'installer.", + "<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>Attention :</b> La prise en charge de cURL par PHP n'est pas activée ou installée. Le montage de %s n'est pas possible. Contactez votre administrateur système pour l'installer.", + "<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>Attention : </b> La prise en charge du FTP par PHP n'est pas activée ou installée. Le montage de %s n'est pas possible. Contactez votre administrateur système pour l'installer.", "<b>Note:</b> \"%s\" is not installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Attention : </b> \"%s\" n'est pas installé. Le montage de %s n'est pas possible. Contactez votre administrateur système pour l'installer.", "You don't have any external storages" : "Vous n'avez pas de support de stockage externe", "Name" : "Nom", diff --git a/apps/files_external/l10n/fr.json b/apps/files_external/l10n/fr.json index fc59b74d3c5..e8a9e299c24 100644 --- a/apps/files_external/l10n/fr.json +++ b/apps/files_external/l10n/fr.json @@ -53,8 +53,8 @@ "Saved" : "Sauvegarder", "<b>Note:</b> " : "<b>Attention :</b>", " and " : "et", - "<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>Attention :</b> Le support de cURL de PHP n'est pas activé ou installé. Le montage de %s n'est pas possible. Contactez votre administrateur système pour l'installer.", - "<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>Attention : </b> Le support FTP de PHP n'est pas activé ou installé. Le montage de %s n'est pas possible. Contactez votre administrateur système pour l'installer.", + "<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>Attention :</b> La prise en charge de cURL par PHP n'est pas activée ou installée. Le montage de %s n'est pas possible. Contactez votre administrateur système pour l'installer.", + "<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>Attention : </b> La prise en charge du FTP par PHP n'est pas activée ou installée. Le montage de %s n'est pas possible. Contactez votre administrateur système pour l'installer.", "<b>Note:</b> \"%s\" is not installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Attention : </b> \"%s\" n'est pas installé. Le montage de %s n'est pas possible. Contactez votre administrateur système pour l'installer.", "You don't have any external storages" : "Vous n'avez pas de support de stockage externe", "Name" : "Nom", diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index 53adb929e29..4d94e3561f8 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -267,10 +267,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { $file = basename( isset($object['Key']) ? $object['Key'] : $object['Prefix'] ); - - if ($file != basename($path)) { - $files[] = $file; - } + $files[] = $file; } \OC\Files\Stream\Dir::register('amazons3' . $path, $files); diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 62b0f182e98..a4337bc937b 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -496,7 +496,10 @@ class Google extends \OC\Files\Storage\Common { $result = false; if ($file) { if (isset($mtime)) { - $file->setModifiedDate($mtime); + // This is just RFC3339, but frustratingly, GDrive's API *requires* + // the fractions portion be present, while no handy PHP constant + // for RFC3339 or ISO8601 includes it. So we do it ourselves. + $file->setModifiedDate(date('Y-m-d\TH:i:s.uP', $mtime)); $result = $this->service->files->patch($file->getId(), $file, array( 'setModifiedDate' => true, )); diff --git a/apps/files_sharing/appinfo/routes.php b/apps/files_sharing/appinfo/routes.php index d58a97e2956..68f33d94995 100644 --- a/apps/files_sharing/appinfo/routes.php +++ b/apps/files_sharing/appinfo/routes.php @@ -1,4 +1,5 @@ <?php + /** @var $this \OCP\Route\IRouter */ $this->create('core_ajax_public_preview', '/publicpreview')->action( function() { diff --git a/apps/files_sharing/appinfo/update.php b/apps/files_sharing/appinfo/update.php deleted file mode 100644 index e393b1575af..00000000000 --- a/apps/files_sharing/appinfo/update.php +++ /dev/null @@ -1,120 +0,0 @@ -<?php - -$installedVersion = OCP\Config::getAppValue('files_sharing', 'installed_version'); - -if (version_compare($installedVersion, '0.5', '<')) { - updateFilePermissions(); -} - -if (version_compare($installedVersion, '0.4', '<')) { - removeSharedFolder(); -} - -// clean up oc_share table from files which are no longer exists -if (version_compare($installedVersion, '0.3.5.6', '<')) { - \OC\Files\Cache\Shared_Updater::fixBrokenSharesOnAppUpdate(); -} - - -/** - * it is no longer possible to share single files with delete permissions. User - * should only be able to unshare single files but never to delete them. - */ -function updateFilePermissions($chunkSize = 99) { - $query = OCP\DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `item_type` = ?'); - $result = $query->execute(array('file')); - - $updatedRows = array(); - - while ($row = $result->fetchRow()) { - if ($row['permissions'] & \OCP\PERMISSION_DELETE) { - $updatedRows[$row['id']] = (int)$row['permissions'] & ~\OCP\PERMISSION_DELETE; - } - } - - $connection = \OC_DB::getConnection(); - $chunkedPermissionList = array_chunk($updatedRows, $chunkSize, true); - - foreach ($chunkedPermissionList as $subList) { - $statement = "UPDATE `*PREFIX*share` SET `permissions` = CASE `id` "; - //update share table - $ids = implode(',', array_keys($subList)); - foreach ($subList as $id => $permission) { - $statement .= "WHEN " . $connection->quote($id, \PDO::PARAM_INT) . " THEN " . $permission . " "; - } - $statement .= ' END WHERE `id` IN (' . $ids . ')'; - - $query = OCP\DB::prepare($statement); - $query->execute(); - } - -} - -/** - * update script for the removal of the logical "Shared" folder, we create physical "Shared" folder and - * update the users file_target so that it doesn't make any difference for the user - * @note parameters are just for testing, please ignore them - */ -function removeSharedFolder($mkdirs = true, $chunkSize = 99) { - $query = OCP\DB::prepare('SELECT * FROM `*PREFIX*share`'); - $result = $query->execute(); - $view = new \OC\Files\View('/'); - $users = array(); - $shares = array(); - //we need to set up user backends - OC_User::useBackend(new OC_User_Database()); - OC_Group::useBackend(new OC_Group_Database()); - OC_App::loadApps(array('authentication')); - //we need to set up user backends, otherwise creating the shares will fail with "because user does not exist" - while ($row = $result->fetchRow()) { - //collect all user shares - if ((int)$row['share_type'] === 0 && ($row['item_type'] === 'file' || $row['item_type'] === 'folder')) { - $users[] = $row['share_with']; - $shares[$row['id']] = $row['file_target']; - } else if ((int)$row['share_type'] === 1 && ($row['item_type'] === 'file' || $row['item_type'] === 'folder')) { - //collect all group shares - $users = array_merge($users, \OC_group::usersInGroup($row['share_with'])); - $shares[$row['id']] = $row['file_target']; - } else if ((int)$row['share_type'] === 2) { - $shares[$row['id']] = $row['file_target']; - } - } - - $unique_users = array_unique($users); - - if (!empty($unique_users) && !empty($shares)) { - - // create folder Shared for each user - - if ($mkdirs) { - foreach ($unique_users as $user) { - \OC\Files\Filesystem::initMountPoints($user); - if (!$view->file_exists('/' . $user . '/files/Shared')) { - $view->mkdir('/' . $user . '/files/Shared'); - } - } - } - - $chunkedShareList = array_chunk($shares, $chunkSize, true); - $connection = \OC_DB::getConnection(); - - foreach ($chunkedShareList as $subList) { - - $statement = "UPDATE `*PREFIX*share` SET `file_target` = CASE `id` "; - //update share table - $ids = implode(',', array_keys($subList)); - foreach ($subList as $id => $target) { - $statement .= "WHEN " . $connection->quote($id, \PDO::PARAM_INT) . " THEN " . $connection->quote('/Shared' . $target, \PDO::PARAM_STR); - } - $statement .= ' END WHERE `id` IN (' . $ids . ')'; - - $query = OCP\DB::prepare($statement); - - $query->execute(array()); - } - - // set config to keep the Shared folder as the default location for new shares - \OCA\Files_Sharing\Helper::setShareFolder('/Shared'); - - } -} diff --git a/apps/files_sharing/application.php b/apps/files_sharing/application.php new file mode 100644 index 00000000000..089ed6afbda --- /dev/null +++ b/apps/files_sharing/application.php @@ -0,0 +1,73 @@ +<?php +/** + * @author Lukas Reschke + * @copyright 2014 Lukas Reschke lukas@owncloud.com + * + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCA\Files_Sharing; + +use OC\AppFramework\Utility\SimpleContainer; +use OCA\Files_Sharing\Controllers\ShareController; +use OCA\Files_Sharing\Middleware\SharingCheckMiddleware; +use \OCP\AppFramework\App; + +/** + * @package OCA\Files_Sharing + */ +class Application extends App { + + + /** + * @param array $urlParams + */ + public function __construct(array $urlParams=array()){ + parent::__construct('files_sharing', $urlParams); + + $container = $this->getContainer(); + + /** + * Controllers + */ + $container->registerService('ShareController', function(SimpleContainer $c) { + return new ShareController( + $c->query('AppName'), + $c->query('Request'), + $c->query('UserSession'), + $c->query('ServerContainer')->getAppConfig(), + $c->query('ServerContainer')->getConfig(), + $c->query('URLGenerator'), + $c->query('ServerContainer')->getUserManager(), + $c->query('ServerContainer')->getLogger() + ); + }); + + /** + * Core class wrappers + */ + $container->registerService('UserSession', function(SimpleContainer $c) { + return $c->query('ServerContainer')->getUserSession(); + }); + $container->registerService('URLGenerator', function(SimpleContainer $c) { + return $c->query('ServerContainer')->getUrlGenerator(); + }); + + /** + * Middleware + */ + $container->registerService('SharingCheckMiddleware', function(SimpleContainer $c){ + return new SharingCheckMiddleware( + $c->query('AppName'), + $c->query('ServerContainer')->getAppConfig(), + $c->getCoreApi() + ); + }); + + // Execute middlewares + $container->registerMiddleware('SharingCheckMiddleware'); + } + +} diff --git a/apps/files_sharing/js/app.js b/apps/files_sharing/js/app.js index 1a3bfac5b97..1314304c567 100644 --- a/apps/files_sharing/js/app.js +++ b/apps/files_sharing/js/app.js @@ -9,8 +9,14 @@ */ if (!OCA.Sharing) { + /** + * @namespace OCA.Sharing + */ OCA.Sharing = {}; } +/** + * @namespace + */ OCA.Sharing.App = { _inFileList: null, diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js index c4b5508692e..0627ed6ab54 100644 --- a/apps/files_sharing/js/public.js +++ b/apps/files_sharing/js/public.js @@ -16,9 +16,17 @@ if (!OCA.Sharing) { if (!OCA.Files) { OCA.Files = {}; } +/** + * @namespace + */ OCA.Sharing.PublicApp = { _initialized: false, + /** + * Initializes the public share app. + * + * @param $el container + */ initialize: function ($el) { var self = this; var fileActions; @@ -101,14 +109,12 @@ OCA.Sharing.PublicApp = { filename = JSON.stringify(filename); } var path = dir || FileList.getCurrentDirectory(); + var token = $('#sharingToken').val(); var params = { - service: 'files', - t: $('#sharingToken').val(), path: path, - files: filename, - download: null + files: filename }; - return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params); + return OC.generateUrl('/s/'+token+'/download') + '?' + OC.buildQueryString(params); }; this.fileList.getAjaxUrl = function (action, params) { @@ -118,12 +124,11 @@ OCA.Sharing.PublicApp = { }; this.fileList.linkTo = function (dir) { + var token = $('#sharingToken').val(); var params = { - service: 'files', - t: $('#sharingToken').val(), dir: dir }; - return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params); + return OC.generateUrl('/s/'+token+'') + '?' + OC.buildQueryString(params); }; this.fileList.generatePreviewUrl = function (urlSpec) { @@ -185,8 +190,6 @@ OCA.Sharing.PublicApp = { _onDirectoryChanged: function (e) { OC.Util.History.pushState({ - service: 'files', - t: $('#sharingToken').val(), // arghhhh, why is this not called "dir" !? path: e.dir }); diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js index 853e9f689f6..8474c66d4b8 100644 --- a/apps/files_sharing/js/share.js +++ b/apps/files_sharing/js/share.js @@ -12,7 +12,19 @@ if (!OCA.Sharing) { OCA.Sharing = {}; } + /** + * @namespace + */ OCA.Sharing.Util = { + /** + * Initialize the sharing app overrides of the default + * file list. + * + * Registers the "Share" file action and adds additional + * DOM attributes for the sharing file info. + * + * @param {OCA.Files.FileActions} fileActions file actions to extend + */ initialize: function(fileActions) { if (OCA.Files.FileList) { var oldCreateRow = OCA.Files.FileList.prototype._createRow; @@ -165,9 +177,9 @@ * other ones will be shown as "+x" where "x" is the number of * remaining recipients. * - * @param recipients recipients array - * @param count optional total recipients count (in case the array was shortened) - * @return formatted recipients display text + * @param {Array.<String>} recipients recipients array + * @param {int} count optional total recipients count (in case the array was shortened) + * @return {String} formatted recipients display text */ formatRecipients: function(recipients, count) { var maxRecipients = 4; diff --git a/apps/files_sharing/js/sharedfilelist.js b/apps/files_sharing/js/sharedfilelist.js index b99611f9bf0..5869d7f77f7 100644 --- a/apps/files_sharing/js/sharedfilelist.js +++ b/apps/files_sharing/js/sharedfilelist.js @@ -10,15 +10,25 @@ (function() { /** - * Sharing file list + * @class OCA.Sharing.FileList + * @augments OCA.Files.FileList * + * @classdesc Sharing file list. * Contains both "shared with others" and "shared with you" modes. + * + * @param $el container element with existing markup for the #controls + * and a table + * @param [options] map of options, see other parameters + * @param {boolean} [options.sharedWithUser] true to return files shared with + * the current user, false to return files that the user shared with others. + * Defaults to false. + * @param {boolean} [options.linksOnly] true to return only link shares */ var FileList = function($el, options) { this.initialize($el, options); }; - - FileList.prototype = _.extend({}, OCA.Files.FileList.prototype, { + FileList.prototype = _.extend({}, OCA.Files.FileList.prototype, + /** @lends OCA.Sharing.FileList.prototype */ { appName: 'Shares', /** @@ -27,9 +37,11 @@ */ _sharedWithUser: false, _linksOnly: false, - _clientSideSort: true, + /** + * @private + */ initialize: function($el, options) { OCA.Files.FileList.prototype.initialize.apply(this, arguments); if (this.initialized) { @@ -138,8 +150,8 @@ /** * Converts the OCS API share response data to a file info * list - * @param OCS API share array - * @return array of file info maps + * @param {Array} data OCS API share array + * @return {Array.<OCA.Sharing.SharedFileInfo>} array of shared file info */ _makeFilesFromShares: function(data) { /* jshint camelcase: false */ @@ -259,5 +271,33 @@ } }); + /** + * Share info attributes. + * + * @typedef {Object} OCA.Sharing.ShareInfo + * + * @property {int} id share ID + * @property {int} type share type + * @property {String} target share target, either user name or group name + * @property {int} stime share timestamp in milliseconds + * @property {String} [targetDisplayName] display name of the recipient + * (only when shared with others) + * + */ + + /** + * Shared file info attributes. + * + * @typedef {OCA.Files.FileInfo} OCA.Sharing.SharedFileInfo + * + * @property {Array.<OCA.Sharing.ShareInfo>} shares array of shares for + * this file + * @property {int} mtime most recent share time (if multiple shares) + * @property {String} shareOwner name of the share owner + * @property {Array.<String>} recipients name of the first 4 recipients + * (this is mostly for display purposes) + * @property {String} recipientsDisplayName display name + */ + OCA.Sharing.FileList = FileList; })(); diff --git a/apps/files_sharing/l10n/et_EE.js b/apps/files_sharing/l10n/et_EE.js index 93ac6d01000..e8158129527 100644 --- a/apps/files_sharing/l10n/et_EE.js +++ b/apps/files_sharing/l10n/et_EE.js @@ -33,6 +33,9 @@ OC.L10N.register( "Add to your ownCloud" : "Lisa oma ownCloudi", "Download" : "Lae alla", "Download %s" : "Laadi alla %s", - "Direct link" : "Otsene link" + "Direct link" : "Otsene link", + "Server-to-Server Sharing" : "Serverist-serverisse jagamine", + "Allow users on this server to send shares to other servers" : "Luba selle serveri kasutajatel saata faile teistesse serveritesse", + "Allow users on this server to receive shares from other servers" : "Luba selle serveri kasutajatel võtta vastu jagamisi teistest serveritest" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/et_EE.json b/apps/files_sharing/l10n/et_EE.json index d5bf52aa59d..bb17d22b99f 100644 --- a/apps/files_sharing/l10n/et_EE.json +++ b/apps/files_sharing/l10n/et_EE.json @@ -31,6 +31,9 @@ "Add to your ownCloud" : "Lisa oma ownCloudi", "Download" : "Lae alla", "Download %s" : "Laadi alla %s", - "Direct link" : "Otsene link" + "Direct link" : "Otsene link", + "Server-to-Server Sharing" : "Serverist-serverisse jagamine", + "Allow users on this server to send shares to other servers" : "Luba selle serveri kasutajatel saata faile teistesse serveritesse", + "Allow users on this server to receive shares from other servers" : "Luba selle serveri kasutajatel võtta vastu jagamisi teistest serveritest" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/files_sharing/l10n/pt_PT.js b/apps/files_sharing/l10n/pt_PT.js index 5f287489876..9df977ef41d 100644 --- a/apps/files_sharing/l10n/pt_PT.js +++ b/apps/files_sharing/l10n/pt_PT.js @@ -8,9 +8,9 @@ OC.L10N.register( "Shared with you" : "Partilhado consigo ", "Shared with others" : "Partilhado com outros", "Shared by link" : "Partilhado pela hiperligação", - "No files have been shared with you yet." : "Ainda não partilhados quaisquer ficheuiros consigo.", + "No files have been shared with you yet." : "Ainda não foram partilhados quaisquer ficheiros consigo.", "You haven't shared any files yet." : "Ainda não partilhou quaisquer ficheiros.", - "You haven't shared any files by link yet." : "Ainda não partilhou quaisquer ficheiros por hiperligação.", + "You haven't shared any files by link yet." : "Ainda não partilhou quaisquer ficheiros através de hiperligação.", "Do you want to add the remote share {name} from {owner}@{remote}?" : "Deseja adicionar a partilha remota {nome} de {proprietário}@{remoto}?", "Remote share" : "Partilha remota", "Remote share password" : "Senha da partilha remota", diff --git a/apps/files_sharing/l10n/pt_PT.json b/apps/files_sharing/l10n/pt_PT.json index 5a14b7a3a1b..a1500f4d827 100644 --- a/apps/files_sharing/l10n/pt_PT.json +++ b/apps/files_sharing/l10n/pt_PT.json @@ -6,9 +6,9 @@ "Shared with you" : "Partilhado consigo ", "Shared with others" : "Partilhado com outros", "Shared by link" : "Partilhado pela hiperligação", - "No files have been shared with you yet." : "Ainda não partilhados quaisquer ficheuiros consigo.", + "No files have been shared with you yet." : "Ainda não foram partilhados quaisquer ficheiros consigo.", "You haven't shared any files yet." : "Ainda não partilhou quaisquer ficheiros.", - "You haven't shared any files by link yet." : "Ainda não partilhou quaisquer ficheiros por hiperligação.", + "You haven't shared any files by link yet." : "Ainda não partilhou quaisquer ficheiros através de hiperligação.", "Do you want to add the remote share {name} from {owner}@{remote}?" : "Deseja adicionar a partilha remota {nome} de {proprietário}@{remoto}?", "Remote share" : "Partilha remota", "Remote share password" : "Senha da partilha remota", diff --git a/apps/files_sharing/l10n/uk.js b/apps/files_sharing/l10n/uk.js index a41afdceb71..e4506d34c62 100644 --- a/apps/files_sharing/l10n/uk.js +++ b/apps/files_sharing/l10n/uk.js @@ -33,6 +33,9 @@ OC.L10N.register( "Add to your ownCloud" : "Додати до вашого ownCloud", "Download" : "Завантажити", "Download %s" : "Завантажити %s", - "Direct link" : "Пряме посилання" + "Direct link" : "Пряме посилання", + "Server-to-Server Sharing" : "Публікація між серверами", + "Allow users on this server to send shares to other servers" : "Дозволити користувачам цього сервера публікувати на інших серверах", + "Allow users on this server to receive shares from other servers" : "Дозволити користувачам на цьому сервері отримувати публікації з інших серверів" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/files_sharing/l10n/uk.json b/apps/files_sharing/l10n/uk.json index a8d66aae2e9..4e85a0a459c 100644 --- a/apps/files_sharing/l10n/uk.json +++ b/apps/files_sharing/l10n/uk.json @@ -31,6 +31,9 @@ "Add to your ownCloud" : "Додати до вашого ownCloud", "Download" : "Завантажити", "Download %s" : "Завантажити %s", - "Direct link" : "Пряме посилання" + "Direct link" : "Пряме посилання", + "Server-to-Server Sharing" : "Публікація між серверами", + "Allow users on this server to send shares to other servers" : "Дозволити користувачам цього сервера публікувати на інших серверах", + "Allow users on this server to receive shares from other servers" : "Дозволити користувачам на цьому сервері отримувати публікації з інших серверів" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" }
\ No newline at end of file diff --git a/apps/files_sharing/lib/controllers/sharecontroller.php b/apps/files_sharing/lib/controllers/sharecontroller.php new file mode 100644 index 00000000000..e5fd0f401c2 --- /dev/null +++ b/apps/files_sharing/lib/controllers/sharecontroller.php @@ -0,0 +1,272 @@ +<?php +/** + * @author Clark Tomlinson <clark@owncloud.com> + * @author Lukas Reschke <lukas@owncloud.com> + * @copyright 2014 Clark Tomlinson & Lukas Reschke + * + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCA\Files_Sharing\Controllers; + +use OC; +use OC\Files\Filesystem; +use OC_Files; +use OC_Util; +use OCP; +use OCP\Template; +use OCP\JSON; +use OCP\Share; +use OCP\AppFramework\Controller; +use OCP\IRequest; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Http\RedirectResponse; +use OCP\AppFramework\IApi; +use OC\URLGenerator; +use OC\AppConfig; +use OCP\ILogger; +use OCA\Files_Sharing\Helper; +use OCP\User; +use OCP\Util; + +/** + * Class ShareController + * + * @package OCA\Files_Sharing\Controllers + */ +class ShareController extends Controller { + + /** @var \OC\User\Session */ + protected $userSession; + /** @var \OC\AppConfig */ + protected $appConfig; + /** @var \OCP\IConfig */ + protected $config; + /** @var \OC\URLGenerator */ + protected $urlGenerator; + /** @var \OC\User\Manager */ + protected $userManager; + /** @var \OCP\ILogger */ + protected $logger; + + /** + * @param string $appName + * @param IRequest $request + * @param OC\User\Session $userSession + * @param AppConfig $appConfig + * @param OCP\IConfig $config + * @param URLGenerator $urlGenerator + * @param OC\User\Manager $userManager + * @param ILogger $logger + */ + public function __construct($appName, + IRequest $request, + OC\User\Session $userSession, + AppConfig $appConfig, + OCP\IConfig $config, + URLGenerator $urlGenerator, + OC\User\Manager $userManager, + ILogger $logger) { + parent::__construct($appName, $request); + + $this->userSession = $userSession; + $this->appConfig = $appConfig; + $this->config = $config; + $this->urlGenerator = $urlGenerator; + $this->userManager = $userManager; + $this->logger = $logger; + } + + /** + * @PublicPage + * @NoCSRFRequired + * + * @param string $token + * + * @return TemplateResponse|RedirectResponse + */ + public function showAuthenticate($token) { + $linkItem = Share::getShareByToken($token, false); + + if(Helper::authenticate($linkItem)) { + return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $token))); + } + + return new TemplateResponse($this->appName, 'authenticate', array(), 'guest'); + } + + /** + * @PublicPage + * + * Authenticates against password-protected shares + * @param $token + * @param string $password + * @return RedirectResponse|TemplateResponse + */ + public function authenticate($token, $password = '') { + $linkItem = Share::getShareByToken($token, false); + if($linkItem === false) { + return new TemplateResponse('core', '404', array(), 'guest'); + } + + $authenticate = Helper::authenticate($linkItem, $password); + + if($authenticate === true) { + return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $token))); + } + + return new TemplateResponse($this->appName, 'authenticate', array('wrongpw' => true), 'guest'); + } + + /** + * @PublicPage + * @NoCSRFRequired + * + * @param string $token + * @param string $path + * + * @return TemplateResponse + */ + public function showShare($token, $path = '') { + \OC_User::setIncognitoMode(true); + + // Check whether share exists + $linkItem = Share::getShareByToken($token, false); + if($linkItem === false) { + return new TemplateResponse('core', '404', array(), 'guest'); + } + + $linkItem = OCP\Share::getShareByToken($token, false); + $shareOwner = $linkItem['uid_owner']; + $originalSharePath = null; + $rootLinkItem = OCP\Share::resolveReShare($linkItem); + if (isset($rootLinkItem['uid_owner'])) { + OCP\JSON::checkUserExists($rootLinkItem['uid_owner']); + OC_Util::tearDownFS(); + OC_Util::setupFS($rootLinkItem['uid_owner']); + $originalSharePath = Filesystem::getPath($linkItem['file_source']); + } + + // Share is password protected - check whether the user is permitted to access the share + if (isset($linkItem['share_with']) && !Helper::authenticate($linkItem)) { + return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate', + array('token' => $token))); + } + + if (Filesystem::isReadable($originalSharePath . $path)) { + $getPath = Filesystem::normalizePath($path); + $originalSharePath .= $path; + } + + $dir = dirname($originalSharePath); + $file = basename($originalSharePath); + + $shareTmpl = array(); + $shareTmpl['displayName'] = User::getDisplayName($shareOwner); + $shareTmpl['filename'] = $file; + $shareTmpl['directory_path'] = $linkItem['file_target']; + $shareTmpl['mimetype'] = Filesystem::getMimeType($originalSharePath); + $shareTmpl['dirToken'] = $linkItem['token']; + $shareTmpl['sharingToken'] = $token; + $shareTmpl['server2serversharing'] = Helper::isOutgoingServer2serverShareEnabled(); + $shareTmpl['protected'] = isset($linkItem['share_with']) ? 'true' : 'false'; + $shareTmpl['dir'] = $dir; + $shareTmpl['fileSize'] = \OCP\Util::humanFileSize(\OC\Files\Filesystem::filesize($originalSharePath)); + + // Show file list + if (Filesystem::is_dir($originalSharePath)) { + $shareTmpl['dir'] = $getPath; + $files = array(); + $maxUploadFilesize = Util::maxUploadFilesize($originalSharePath); + $freeSpace = Util::freeSpace($originalSharePath); + $uploadLimit = Util::uploadLimit(); + $folder = new Template('files', 'list', ''); + $folder->assign('dir', $getPath); + $folder->assign('dirToken', $linkItem['token']); + $folder->assign('permissions', OCP\PERMISSION_READ); + $folder->assign('isPublic', true); + $folder->assign('publicUploadEnabled', 'no'); + $folder->assign('files', $files); + $folder->assign('uploadMaxFilesize', $maxUploadFilesize); + $folder->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); + $folder->assign('freeSpace', $freeSpace); + $folder->assign('uploadLimit', $uploadLimit); // PHP upload limit + $folder->assign('usedSpacePercent', 0); + $folder->assign('trash', false); + $shareTmpl['folder'] = $folder->fetchPage(); + } + + $shareTmpl['downloadURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.downloadShare', array('token' => $token)); + + return new TemplateResponse($this->appName, 'public', $shareTmpl, 'base'); + } + + /** + * @PublicPage + * @NoCSRFRequired + * @param string $token + * @param string $files + * @param string $path + * @return void|RedirectResponse + */ + public function downloadShare($token, $files = null, $path = '') { + \OC_User::setIncognitoMode(true); + + $linkItem = OCP\Share::getShareByToken($token, false); + + // Share is password protected - check whether the user is permitted to access the share + if (isset($linkItem['share_with'])) { + if(!Helper::authenticate($linkItem)) { + return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate', + array('token' => $token))); + } + } + + $originalSharePath = self::getPath($token); + + if (isset($originalSharePath) && Filesystem::isReadable($originalSharePath . $path)) { + $getPath = Filesystem::normalizePath($path); + $originalSharePath .= $getPath; + } + + if (!is_null($files)) { // download selected files + $files_list = json_decode($files); + // in case we get only a single file + if ($files_list === NULL ) { + $files_list = array($files); + } + + // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well + // after dispatching the request which results in a "Cannot modify header information" notice. + OC_Files::get($originalSharePath, $files_list, $_SERVER['REQUEST_METHOD'] == 'HEAD'); + exit(); + } else { + // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well + // after dispatching the request which results in a "Cannot modify header information" notice. + OC_Files::get(dirname($originalSharePath), basename($originalSharePath), $_SERVER['REQUEST_METHOD'] == 'HEAD'); + exit(); + } + } + + /** + * @param $token + * @return null|string + */ + private function getPath($token) { + $linkItem = Share::getShareByToken($token, false); + $path = null; + if (is_array($linkItem) && isset($linkItem['uid_owner'])) { + // seems to be a valid share + $rootLinkItem = Share::resolveReShare($linkItem); + if (isset($rootLinkItem['uid_owner'])) { + JSON::checkUserExists($rootLinkItem['uid_owner']); + OC_Util::tearDownFS(); + OC_Util::setupFS($rootLinkItem['uid_owner']); + $path = Filesystem::getPath($linkItem['file_source']); + } + } + return $path; + } +} diff --git a/apps/files_sharing/lib/helper.php b/apps/files_sharing/lib/helper.php index e7ca4fcccd4..3a2d51cddb7 100644 --- a/apps/files_sharing/lib/helper.php +++ b/apps/files_sharing/lib/helper.php @@ -95,7 +95,7 @@ class Helper { * * @return boolean true if authorized, false otherwise */ - public static function authenticate($linkItem, $password) { + public static function authenticate($linkItem, $password = null) { if ($password !== null) { if ($linkItem['share_type'] == \OCP\Share::SHARE_TYPE_LINK) { // Check Password diff --git a/apps/files_sharing/lib/middleware/sharingcheckmiddleware.php b/apps/files_sharing/lib/middleware/sharingcheckmiddleware.php new file mode 100644 index 00000000000..af79cd9e94a --- /dev/null +++ b/apps/files_sharing/lib/middleware/sharingcheckmiddleware.php @@ -0,0 +1,84 @@ +<?php +/** + * @author Lukas Reschke + * @copyright 2014 Lukas Reschke lukas@owncloud.com + * + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCA\Files_Sharing\Middleware; + +use OCP\AppFramework\IApi; +use \OCP\AppFramework\Middleware; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IAppConfig; + +/** + * Checks whether the "sharing check" is enabled + * + * @package OCA\Files_Sharing\Middleware + */ +class SharingCheckMiddleware extends Middleware { + + /** @var string */ + protected $appName; + /** @var IAppConfig */ + protected $appConfig; + /** @var IApi */ + protected $api; + + /*** + * @param string $appName + * @param IAppConfig $appConfig + * @param IApi $api + */ + public function __construct($appName, + IAppConfig $appConfig, + IApi $api) { + $this->appName = $appName; + $this->appConfig = $appConfig; + $this->api = $api; + } + + /** + * Check if sharing is enabled before the controllers is executed + */ + public function beforeController($controller, $methodName) { + if(!$this->isSharingEnabled()) { + throw new \Exception('Sharing is disabled.'); + } + } + + /** + * Return 404 page in case of an exception + * @param \OCP\AppFramework\Controller $controller + * @param string $methodName + * @param \Exception $exception + * @return TemplateResponse + */ + public function afterException($controller, $methodName, \Exception $exception){ + return new TemplateResponse('core', '404', array(), 'guest'); + } + + /** + * Check whether sharing is enabled + * @return bool + */ + private function isSharingEnabled() { + // FIXME: This check is done here since the route is globally defined and not inside the files_sharing app + // Check whether the sharing application is enabled + if(!$this->api->isAppEnabled($this->appName)) { + return false; + } + + // Check whether public sharing is enabled + if($this->appConfig->getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') { + return false; + } + + return true; + } + +} diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index 4320c105103..d9b8f0f4f30 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -1,205 +1,17 @@ <?php -// Load other apps for file previews -use OCA\Files_Sharing\Helper; - -OC_App::loadApps(); - -$appConfig = \OC::$server->getAppConfig(); - -if ($appConfig->getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') { - header('HTTP/1.0 404 Not Found'); - $tmpl = new OCP\Template('', '404', 'guest'); - $tmpl->printPage(); - exit(); -} - -// Legacy sharing links via public.php have the token in $GET['t'] -if (isset($_GET['t'])) { - $token = $_GET['t']; -} - -if (isset($token)) { - $linkItem = OCP\Share::getShareByToken($token, false); - if (is_array($linkItem) && isset($linkItem['uid_owner'])) { - // seems to be a valid share - $type = $linkItem['item_type']; - $fileSource = $linkItem['file_source']; - $shareOwner = $linkItem['uid_owner']; - $path = null; - $rootLinkItem = OCP\Share::resolveReShare($linkItem); - if (isset($rootLinkItem['uid_owner'])) { - OCP\JSON::checkUserExists($rootLinkItem['uid_owner']); - OC_Util::tearDownFS(); - OC_Util::setupFS($rootLinkItem['uid_owner']); - $path = \OC\Files\Filesystem::getPath($linkItem['file_source']); - } - } -} -if (isset($path)) { - if (!isset($linkItem['item_type'])) { - OCP\Util::writeLog('share', 'No item type set for share id: ' . $linkItem['id'], \OCP\Util::ERROR); - header('HTTP/1.0 404 Not Found'); - $tmpl = new OCP\Template('', '404', 'guest'); - $tmpl->printPage(); - exit(); - } - if (isset($linkItem['share_with'])) { - // Authenticate share_with - $url = OCP\Util::linkToPublic('files') . '&t=' . $token; - if (isset($_GET['file'])) { - $url .= '&file=' . urlencode($_GET['file']); - } else { - if (isset($_GET['dir'])) { - $url .= '&dir=' . urlencode($_GET['dir']); - } - } - if (isset($_POST['password'])) { - $password = $_POST['password']; - if ($linkItem['share_type'] == OCP\Share::SHARE_TYPE_LINK) { - // Check Password - $forcePortable = (CRYPT_BLOWFISH != 1); - $hasher = new PasswordHash(8, $forcePortable); - if (!($hasher->CheckPassword($password.OC_Config::getValue('passwordsalt', ''), - $linkItem['share_with']))) { - OCP\Util::addStyle('files_sharing', 'authenticate'); - $tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest'); - $tmpl->assign('URL', $url); - $tmpl->assign('wrongpw', true); - $tmpl->printPage(); - exit(); - } else { - // Save item id in session for future requests - \OC::$server->getSession()->set('public_link_authenticated', $linkItem['id']); - } - } else { - OCP\Util::writeLog('share', 'Unknown share type '.$linkItem['share_type'] - .' for share id '.$linkItem['id'], \OCP\Util::ERROR); - header('HTTP/1.0 404 Not Found'); - $tmpl = new OCP\Template('', '404', 'guest'); - $tmpl->printPage(); - exit(); - } - - } else { - // Check if item id is set in session - if ( ! \OC::$server->getSession()->exists('public_link_authenticated') - || \OC::$server->getSession()->get('public_link_authenticated') !== $linkItem['id'] - ) { - // Prompt for password - OCP\Util::addStyle('files_sharing', 'authenticate'); - $tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest'); - $tmpl->assign('URL', $url); - $tmpl->printPage(); - exit(); - } - } - } - $basePath = $path; - $rootName = \OC_Util::basename($path); - if (isset($_GET['path']) && \OC\Files\Filesystem::isReadable($basePath . $_GET['path'])) { - $getPath = \OC\Files\Filesystem::normalizePath($_GET['path']); - $path .= $getPath; - } else { - $getPath = ''; - } - $dir = dirname($path); - $file = basename($path); - // Download the file - if (isset($_GET['download'])) { - if (!\OCP\App::isEnabled('files_encryption')) { - // encryption app requires the session to store the keys in - \OC::$server->getSession()->close(); - } - if (isset($_GET['files'])) { // download selected files - $files = $_GET['files']; - $files_list = json_decode($files); - // in case we get only a single file - if (!is_array($files_list)) { - $files_list = array($files); - } - OC_Files::get($path, $files_list, $_SERVER['REQUEST_METHOD'] == 'HEAD'); - } else { - OC_Files::get($dir, $file, $_SERVER['REQUEST_METHOD'] == 'HEAD'); - } - exit(); - } else { - OCP\Util::addScript('files', 'file-upload'); - OCP\Util::addStyle('files_sharing', 'public'); - OCP\Util::addStyle('files_sharing', 'mobile'); - OCP\Util::addScript('files_sharing', 'public'); - OCP\Util::addScript('files', 'fileactions'); - OCP\Util::addScript('files', 'jquery.iframe-transport'); - OCP\Util::addScript('files', 'jquery.fileupload'); - $maxUploadFilesize=OCP\Util::maxUploadFilesize($path); - $tmpl = new OCP\Template('files_sharing', 'public', 'base'); - $tmpl->assign('displayName', \OCP\User::getDisplayName($shareOwner)); - $tmpl->assign('filename', $file); - $tmpl->assign('directory_path', $linkItem['file_target']); - $tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path)); - $tmpl->assign('dirToken', $linkItem['token']); - $tmpl->assign('sharingToken', $token); - $tmpl->assign('server2serversharing', Helper::isOutgoingServer2serverShareEnabled()); - $tmpl->assign('protected', isset($linkItem['share_with']) ? 'true' : 'false'); - - $urlLinkIdentifiers= (isset($token)?'&t='.$token:'') - .(isset($_GET['dir'])?'&dir='.$_GET['dir']:'') - .(isset($_GET['file'])?'&file='.$_GET['file']:''); - // Show file list - if (\OC\Files\Filesystem::is_dir($path)) { - $tmpl->assign('dir', $getPath); - - OCP\Util::addStyle('files', 'files'); - OCP\Util::addStyle('files', 'upload'); - OCP\Util::addScript('files', 'filesummary'); - OCP\Util::addScript('files', 'breadcrumb'); - OCP\Util::addScript('files', 'files'); - OCP\Util::addScript('files', 'filelist'); - OCP\Util::addscript('files', 'keyboardshortcuts'); - $files = array(); - $rootLength = strlen($basePath) + 1; - $maxUploadFilesize=OCP\Util::maxUploadFilesize($path); - - $freeSpace=OCP\Util::freeSpace($path); - $uploadLimit=OCP\Util::uploadLimit(); - $folder = new OCP\Template('files', 'list', ''); - $folder->assign('dir', $getPath); - $folder->assign('dirToken', $linkItem['token']); - $folder->assign('permissions', OCP\PERMISSION_READ); - $folder->assign('isPublic', true); - $folder->assign('publicUploadEnabled', 'no'); - $folder->assign('files', $files); - $folder->assign('uploadMaxFilesize', $maxUploadFilesize); - $folder->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); - $folder->assign('freeSpace', $freeSpace); - $folder->assign('uploadLimit', $uploadLimit); // PHP upload limit - $folder->assign('usedSpacePercent', 0); - $folder->assign('trash', false); - $tmpl->assign('folder', $folder->fetchPage()); - $tmpl->assign('downloadURL', - OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&download&path=' . urlencode($getPath)); - } else { - $tmpl->assign('dir', $dir); - - // Show file preview if viewer is available - if ($type == 'file') { - $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&download'); - } else { - $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files') - .$urlLinkIdentifiers.'&download&path='.urlencode($getPath)); - } - } - $tmpl->printPage(); - } - exit(); -} else { - OCP\Util::writeLog('share', 'could not resolve linkItem', \OCP\Util::DEBUG); -} - -$errorTemplate = new OCP\Template('files_sharing', 'part.404', ''); -$errorContent = $errorTemplate->fetchPage(); - -header('HTTP/1.0 404 Not Found'); -OCP\Util::addStyle('files_sharing', '404'); -$tmpl = new OCP\Template('', '404', 'guest'); -$tmpl->assign('content', $errorContent); -$tmpl->printPage(); +/** + * @author Lukas Reschke + * @copyright 2014 Lukas Reschke lukas@owncloud.com + * + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +// This file is just used to redirect the legacy sharing URLs (< ownCloud 8) to the new ones + +$urlGenerator = new \OC\URLGenerator(\OC::$server->getConfig()); +$token = isset($_GET['t']) ? $_GET['t'] : ''; +$route = isset($_GET['download']) ? 'files_sharing.sharecontroller.downloadshare' : 'files_sharing.sharecontroller.showshare'; + +OC_Response::redirect($urlGenerator->linkToRoute($route, array('token' => $token))); diff --git a/apps/files_sharing/templates/authenticate.php b/apps/files_sharing/templates/authenticate.php index 0c4ac6ca445..e3aa62b9ece 100644 --- a/apps/files_sharing/templates/authenticate.php +++ b/apps/files_sharing/templates/authenticate.php @@ -1,4 +1,9 @@ -<form action="<?php p($_['URL']); ?>" method="post"> +<?php + /** @var $_ array */ + /** @var $l OC_L10N */ + style('files_sharing', 'authenticate'); +?> +<form method="post"> <fieldset> <?php if (!isset($_['wrongpw'])): ?> <div class="warning-info"><?php p($l->t('This share is password-protected')); ?></div> @@ -8,6 +13,7 @@ <?php endif; ?> <p> <label for="password" class="infield"><?php p($l->t('Password')); ?></label> + <input type="hidden" name="requesttoken" value="<?php p($_['requesttoken']) ?>" /> <input type="password" name="password" id="password" placeholder="<?php p($l->t('Password')); ?>" value="" autocomplete="off" autocapitalize="off" autocorrect="off" diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php index 46bf90b1b41..57c8707e962 100644 --- a/apps/files_sharing/templates/public.php +++ b/apps/files_sharing/templates/public.php @@ -1,8 +1,28 @@ -<?php /** @var $l OC_L10N */ ?> <?php +/** @var $l OC_L10N */ +/** @var $_ array */ + +OCP\Util::addScript('files', 'file-upload'); +OCP\Util::addStyle('files_sharing', 'public'); +OCP\Util::addStyle('files_sharing', 'mobile'); +OCP\Util::addScript('files_sharing', 'public'); +OCP\Util::addScript('files', 'fileactions'); +OCP\Util::addScript('files', 'jquery.iframe-transport'); +OCP\Util::addScript('files', 'jquery.fileupload'); + +// JS required for folders +OCP\Util::addStyle('files', 'files'); +OCP\Util::addStyle('files', 'upload'); +OCP\Util::addScript('files', 'filesummary'); +OCP\Util::addScript('files', 'breadcrumb'); +OCP\Util::addScript('files', 'files'); +OCP\Util::addScript('files', 'filelist'); +OCP\Util::addscript('files', 'keyboardshortcuts'); + $thumbSize=1024; $previewSupported = OC\Preview::isMimeSupported($_['mimetype']) ? 'true' : 'false'; ?> + <?php if ( \OC\Preview::isMimeSupported($_['mimetype'])): /* This enables preview images for links (e.g. on Facebook, Google+, ...)*/?> <link rel="image_src" href="<?php p(OCP\Util::linkToRoute( 'core_ajax_public_preview', array('x' => $thumbSize, 'y' => $thumbSize, 'file' => $_['directory_path'], 't' => $_['dirToken']))); ?>" /> <?php endif; ?> @@ -24,7 +44,7 @@ $previewSupported = OC\Preview::isMimeSupported($_['mimetype']) ? 'true' : 'fals <header><div id="header" class="<?php p((isset($_['folder']) ? 'share-folder' : 'share-file')) ?>"> <a href="<?php print_unescaped(link_to('', 'index.php')); ?>" - title="" id="owncloud"> + title="" id="owncloud"> <div class="logo-wide svg"></div> </a> <div id="logo-claim" style="display:none;"><?php p($theme->getLogoClaim()); ?></div> @@ -48,7 +68,7 @@ $previewSupported = OC\Preview::isMimeSupported($_['mimetype']) ? 'true' : 'fals </a> </span> </div> -</div></header> + </div></header> <div id="content"> <div id="preview"> <?php if (isset($_['folder'])): ?> @@ -67,7 +87,7 @@ $previewSupported = OC\Preview::isMimeSupported($_['mimetype']) ? 'true' : 'fals <div class="directDownload"> <a href="<?php p($_['downloadURL']); ?>" id="download" class="button"> <img class="svg" alt="" src="<?php print_unescaped(OCP\image_path("core", "actions/download.svg")); ?>"/> - <?php p($l->t('Download %s', array($_['filename'])))?> + <?php p($l->t('Download %s', array($_['filename'])))?> (<?php p($_['fileSize']) ?>) </a> </div> <div class="directLink"> diff --git a/apps/files_sharing/tests/cache.php b/apps/files_sharing/tests/cache.php index 2c9790ce66d..0e96f5a4e09 100644 --- a/apps/files_sharing/tests/cache.php +++ b/apps/files_sharing/tests/cache.php @@ -30,6 +30,18 @@ class Test_Files_Sharing_Cache extends TestCase { */ public $user2View; + /** @var \OC\Files\Cache\Cache */ + protected $ownerCache; + + /** @var \OC\Files\Cache\Cache */ + protected $sharedCache; + + /** @var \OC\Files\Storage\Storage */ + protected $ownerStorage; + + /** @var \OC\Files\Storage\Storage */ + protected $sharedStorage; + function setUp() { parent::setUp(); @@ -54,7 +66,7 @@ class Test_Files_Sharing_Cache extends TestCase { $this->view->file_put_contents('container/shareddir/subdir/another too.txt', $textData); $this->view->file_put_contents('container/shareddir/subdir/not a text file.xml', '<xml></xml>'); - list($this->ownerStorage, $internalPath) = $this->view->resolvePath(''); + list($this->ownerStorage,) = $this->view->resolvePath(''); $this->ownerCache = $this->ownerStorage->getCache(); $this->ownerStorage->getScanner()->scan(''); @@ -72,7 +84,7 @@ class Test_Files_Sharing_Cache extends TestCase { // retrieve the shared storage $secondView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2); - list($this->sharedStorage, $internalPath) = $secondView->resolvePath('files/shareddir'); + list($this->sharedStorage,) = $secondView->resolvePath('files/shareddir'); $this->sharedCache = $this->sharedStorage->getCache(); } @@ -354,7 +366,7 @@ class Test_Files_Sharing_Cache extends TestCase { self::loginHelper(self::TEST_FILES_SHARING_API_USER1); \OC\Files\Filesystem::mkdir('foo'); \OC\Files\Filesystem::mkdir('foo/bar'); - \OC\Files\Filesystem::touch('foo/bar/test.txt', 'bar'); + \OC\Files\Filesystem::touch('foo/bar/test.txt'); $folderInfo = \OC\Files\Filesystem::getFileInfo('foo'); $fileInfo = \OC\Files\Filesystem::getFileInfo('foo/bar/test.txt'); \OCP\Share::shareItem('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, \OCP\PERMISSION_ALL); diff --git a/apps/files_sharing/tests/controller/sharecontroller.php b/apps/files_sharing/tests/controller/sharecontroller.php new file mode 100644 index 00000000000..8dcb2475564 --- /dev/null +++ b/apps/files_sharing/tests/controller/sharecontroller.php @@ -0,0 +1,171 @@ +<?php +/** + * @author Lukas Reschke <lukas@owncloud.com> + * @copyright 2014 Lukas Reschke + * + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCA\Files_Sharing\Controllers; + +use OC\Files\Filesystem; +use OCA\Files_Sharing\Application; +use OCP\AppFramework\IAppContainer; +use OCP\Files; +use OCP\AppFramework\Http\RedirectResponse; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\Security\ISecureRandom; +use OC\Files\View; +use OCP\Share; +use OC\URLGenerator; + +/** + * @package OCA\Files_Sharing\Controllers + */ +class ShareControllerTest extends \PHPUnit_Framework_TestCase { + + /** @var IAppContainer */ + private $container; + /** @var string */ + private $user; + /** @var string */ + private $token; + /** @var string */ + private $oldUser; + /** @var ShareController */ + private $shareController; + /** @var URLGenerator */ + private $urlGenerator; + + protected function setUp() { + $app = new Application(); + $this->container = $app->getContainer(); + $this->container['Config'] = $this->getMockBuilder('\OCP\IConfig') + ->disableOriginalConstructor()->getMock(); + $this->container['AppName'] = 'files_sharing'; + $this->container['UserSession'] = $this->getMockBuilder('\OC\User\Session') + ->disableOriginalConstructor()->getMock(); + $this->container['URLGenerator'] = $this->getMockBuilder('\OC\URLGenerator') + ->disableOriginalConstructor()->getMock(); + $this->urlGenerator = $this->container['URLGenerator']; + $this->shareController = $this->container['ShareController']; + + // Store current user + $this->oldUser = \OC_User::getUser(); + + // Create a dummy user + $this->user = \OC::$server->getSecureRandom()->getLowStrengthGenerator()->generate(12, ISecureRandom::CHAR_LOWER); + + \OC_User::createUser($this->user, $this->user); + \OC_Util::tearDownFS(); + \OC_User::setUserId(''); + Filesystem::tearDown(); + \OC_User::setUserId($this->user); + \OC_Util::setupFS($this->user); + + // Create a dummy shared file + $view = new View('/'. $this->user . '/files'); + $view->file_put_contents('file1.txt', 'I am such an awesome shared file!'); + $this->token = \OCP\Share::shareItem( + Filesystem::getFileInfo('file1.txt')->getType(), + Filesystem::getFileInfo('file1.txt')->getId(), + \OCP\Share::SHARE_TYPE_LINK, + 'IAmPasswordProtected!', + 1 + ); + } + + protected function tearDown() { + \OC_Util::tearDownFS(); + \OC_User::setUserId(''); + Filesystem::tearDown(); + \OC_User::deleteUser($this->user); + \OC_User::setIncognitoMode(false); + + \OC::$server->getSession()->set('public_link_authenticated', ''); + + // Set old user + \OC_User::setUserId($this->oldUser); + \OC_Util::setupFS($this->oldUser); + } + + public function testShowAuthenticate() { + $linkItem = \OCP\Share::getShareByToken($this->token, false); + + // Test without being authenticated + $response = $this->shareController->showAuthenticate($this->token); + $expectedResponse = new TemplateResponse($this->container['AppName'], 'authenticate', array(), 'guest'); + $this->assertEquals($expectedResponse, $response); + + // Test with being authenticated for another file + \OC::$server->getSession()->set('public_link_authenticated', $linkItem['id']-1); + $response = $this->shareController->showAuthenticate($this->token); + $expectedResponse = new TemplateResponse($this->container['AppName'], 'authenticate', array(), 'guest'); + $this->assertEquals($expectedResponse, $response); + + // Test with being authenticated for the correct file + \OC::$server->getSession()->set('public_link_authenticated', $linkItem['id']); + $response = $this->shareController->showAuthenticate($this->token); + $expectedResponse = new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $this->token))); + $this->assertEquals($expectedResponse, $response); + } + + public function testAuthenticate() { + // Test without a not existing token + $response = $this->shareController->authenticate('ThisTokenShouldHopefullyNeverExistSoThatTheUnitTestWillAlwaysPass :)'); + $expectedResponse = new TemplateResponse('core', '404', array(), 'guest'); + $this->assertEquals($expectedResponse, $response); + + // Test with a valid password + $response = $this->shareController->authenticate($this->token, 'IAmPasswordProtected!'); + $expectedResponse = new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $this->token))); + $this->assertEquals($expectedResponse, $response); + + // Test with a invalid password + $response = $this->shareController->authenticate($this->token, 'WrongPw!'); + $expectedResponse = new TemplateResponse($this->container['AppName'], 'authenticate', array('wrongpw' => true), 'guest'); + $this->assertEquals($expectedResponse, $response); + } + + public function testShowShare() { + // Test without a not existing token + $response = $this->shareController->showShare('ThisTokenShouldHopefullyNeverExistSoThatTheUnitTestWillAlwaysPass :)'); + $expectedResponse = new TemplateResponse('core', '404', array(), 'guest'); + $this->assertEquals($expectedResponse, $response); + + // Test with a password protected share and no authentication + $response = $this->shareController->showShare($this->token); + $expectedResponse = new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate', array('token' => $this->token))); + $this->assertEquals($expectedResponse, $response); + + // Test with password protected share and authentication + $linkItem = Share::getShareByToken($this->token, false); + \OC::$server->getSession()->set('public_link_authenticated', $linkItem['id']); + $response = $this->shareController->showShare($this->token); + $sharedTmplParams = array( + 'displayName' => $this->user, + 'filename' => 'file1.txt', + 'directory_path' => '/file1.txt', + 'mimetype' => 'text/plain', + 'dirToken' => $this->token, + 'sharingToken' => $this->token, + 'server2serversharing' => true, + 'protected' => 'true', + 'dir' => '/', + 'downloadURL' => null, + 'fileSize' => '33 B' + ); + $expectedResponse = new TemplateResponse($this->container['AppName'], 'public', $sharedTmplParams, 'base'); + $this->assertEquals($expectedResponse, $response); + } + + public function testDownloadShare() { + // Test with a password protected share and no authentication + $response = $this->shareController->downloadShare($this->token); + $expectedResponse = new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate', + array('token' => $this->token))); + $this->assertEquals($expectedResponse, $response); + } +} diff --git a/apps/files_sharing/tests/middleware/sharingcheckmiddleware.php b/apps/files_sharing/tests/middleware/sharingcheckmiddleware.php new file mode 100644 index 00000000000..90c9a7bba10 --- /dev/null +++ b/apps/files_sharing/tests/middleware/sharingcheckmiddleware.php @@ -0,0 +1,76 @@ +<?php +/** + * @author Lukas Reschke <lukas@owncloud.com> + * @copyright 2014 Lukas Reschke + * + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCA\Files_Sharing\Middleware; + + +/** + * @package OCA\Files_Sharing\Middleware\SharingCheckMiddleware + */ +class SharingCheckMiddlewareTest extends \PHPUnit_Framework_TestCase { + + /** @var \OCP\IAppConfig */ + private $appConfig; + /** @var \OCP\AppFramework\IApi */ + private $api; + /** @var SharingCheckMiddleware */ + private $sharingCheckMiddleware; + + protected function setUp() { + $this->appConfig = $this->getMockBuilder('\OCP\IAppConfig') + ->disableOriginalConstructor()->getMock(); + $this->api = $this->getMockBuilder('\OCP\AppFramework\IApi') + ->disableOriginalConstructor()->getMock(); + + $this->sharingCheckMiddleware = new SharingCheckMiddleware('files_sharing', $this->appConfig, $this->api); + } + + public function testIsSharingEnabledWithEverythingEnabled() { + $this->api + ->expects($this->once()) + ->method('isAppEnabled') + ->with('files_sharing') + ->will($this->returnValue(true)); + + $this->appConfig + ->expects($this->once()) + ->method('getValue') + ->with('core', 'shareapi_allow_links', 'yes') + ->will($this->returnValue('yes')); + + $this->assertTrue(\Test_Helper::invokePrivate($this->sharingCheckMiddleware, 'isSharingEnabled')); + } + + public function testIsSharingEnabledWithAppDisabled() { + $this->api + ->expects($this->once()) + ->method('isAppEnabled') + ->with('files_sharing') + ->will($this->returnValue(false)); + + $this->assertFalse(\Test_Helper::invokePrivate($this->sharingCheckMiddleware, 'isSharingEnabled')); + } + + public function testIsSharingEnabledWithSharingDisabled() { + $this->api + ->expects($this->once()) + ->method('isAppEnabled') + ->with('files_sharing') + ->will($this->returnValue(true)); + + $this->appConfig + ->expects($this->once()) + ->method('getValue') + ->with('core', 'shareapi_allow_links', 'yes') + ->will($this->returnValue('no')); + + $this->assertFalse(\Test_Helper::invokePrivate($this->sharingCheckMiddleware, 'isSharingEnabled')); + } +} diff --git a/apps/files_sharing/tests/testcase.php b/apps/files_sharing/tests/testcase.php index 78277dc907f..034baa785da 100644 --- a/apps/files_sharing/tests/testcase.php +++ b/apps/files_sharing/tests/testcase.php @@ -22,6 +22,7 @@ namespace OCA\Files_Sharing\Tests; +use OC\Files\Filesystem; use OCA\Files\Share; /** @@ -115,6 +116,10 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase { } else { \OC_App::disable('files_encryption'); } + + \OC_Util::tearDownFS(); + \OC_User::setUserId(''); + Filesystem::tearDown(); } /** diff --git a/apps/files_sharing/tests/update.php b/apps/files_sharing/tests/update.php deleted file mode 100644 index 583f607d9cb..00000000000 --- a/apps/files_sharing/tests/update.php +++ /dev/null @@ -1,252 +0,0 @@ -<?php -/** - * ownCloud - * - * @author Morris Jobke, Bjoern Schiessle - * @copyright 2014 Morris Jobke <morris.jobke@gmail.com> - * 2014 Bjoern Schiessle <schiessle@ownlcoud.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - * - */ - -require_once __DIR__ . '/../appinfo/update.php'; - -/** - * Class Test_Files_Sharing_Update - */ -class Test_Files_Sharing_Update_Routine extends OCA\Files_Sharing\Tests\TestCase { - - const TEST_FOLDER_NAME = '/folder_share_api_test'; - - function setUp() { - parent::setUp(); - - $this->folder = self::TEST_FOLDER_NAME; - - $this->filename = '/share-api-test.txt'; - - // save file with content - $this->view->file_put_contents($this->filename, $this->data); - $this->view->mkdir($this->folder); - $this->view->file_put_contents($this->folder . '/' . $this->filename, $this->data); - } - - function tearDown() { - $this->view->unlink($this->filename); - $this->view->deleteAll($this->folder); - - $removeShares = \OC_DB::prepare('DELETE FROM `*PREFIX*share`'); - $removeShares->execute(); - $removeItems = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache`'); - $removeItems->execute(); - - parent::tearDown(); - } - - /** - * test update of file permission. The update should remove from all shared - * files the delete permission - */ - function testUpdateFilePermissions() { - - self::prepareDBUpdateFilePermissions(); - // run the update routine to update the share permission - updateFilePermissions(2); - - // verify results - $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share`'); - $result = $query->execute(array()); - - while ($row = $result->fetchRow()) { - if ($row['item_type'] === 'file') { - // for all files the delete permission should be removed - $this->assertSame(0, (int)$row['permissions'] & \OCP\PERMISSION_DELETE); - } else { - // for all other the permission shouldn't change - $this->assertSame(31, (int)$row['permissions'] & \OCP\PERMISSION_ALL); - } - } - - // cleanup - $this->cleanupSharedTable(); - } - - /** - * @medium - */ - function testRemoveBrokenFileShares() { - - $this->prepareFileCache(); - - // check if there are just 4 shares (see setUp - precondition: empty table) - $countAllShares = \OC_DB::prepare('SELECT COUNT(`id`) FROM `*PREFIX*share`'); - $result = $countAllShares->execute()->fetchOne(); - $this->assertEquals(4, $result); - - // check if there are just 3 file shares (see setUp - precondition: empty table) - $countFileShares = \OC_DB::prepare('SELECT COUNT(`id`) FROM `*PREFIX*share` WHERE `item_type` IN (\'file\', \'folder\')'); - $result = $countFileShares->execute()->fetchOne(); - $this->assertEquals(3, $result); - - // check if there are just 2 items (see setUp - precondition: empty table) - $countItems = \OC_DB::prepare('SELECT COUNT(`fileid`) FROM `*PREFIX*filecache`'); - $result = $countItems->execute()->fetchOne(); - $this->assertEquals(2, $result); - - // execute actual code which should be tested - \OC\Files\Cache\Shared_Updater::fixBrokenSharesOnAppUpdate(); - - // check if there are just 2 shares (one gets killed by the code as there is no filecache entry for this) - $result = $countFileShares->execute()->fetchOne(); - $this->assertEquals(2, $result); - - // check if the share of file '200' is removed as there is no entry for this in filecache table - $countFileShares = \OC_DB::prepare('SELECT COUNT(`id`) FROM `*PREFIX*share` WHERE `file_source` = 200'); - $result = $countFileShares->execute()->fetchOne(); - $this->assertEquals(0, $result); - - // check if there are just 2 items - $countItems = \OC_DB::prepare('SELECT COUNT(`fileid`) FROM `*PREFIX*filecache`'); - $result = $countItems->execute()->fetchOne(); - $this->assertEquals(2, $result); - - // the calendar share survived - $countOtherShares = \OC_DB::prepare('SELECT COUNT(`id`) FROM `*PREFIX*share` WHERE `item_source` = \'999\''); - $result = $countOtherShares->execute()->fetchOne(); - $this->assertEquals(1, $result); - } - - /** - * test update for the removal of the logical "Shared" folder. It should update - * the file_target for every share and create a physical "Shared" folder for each user - */ - function testRemoveSharedFolder() { - self::prepareDB(); - // run the update routine to remove the shared folder and replace it with a real folder - removeSharedFolder(false, 2); - - // verify results - $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share`'); - $result = $query->execute(array()); - - $newDBContent = $result->fetchAll(); - - foreach ($newDBContent as $row) { - if ((int)$row['share_type'] === \OCP\Share::SHARE_TYPE_USER) { - $this->assertSame('/Shared', substr($row['file_target'], 0, strlen('/Shared'))); - } else { - $this->assertSame('/ShouldNotChange', $row['file_target']); - } - } - - $shareFolder = \OCP\Config::getSystemValue('share_folder', '/'); - - $this->assertSame('/Shared', $shareFolder); - - // cleanup - $this->cleanupSharedTable(); - \OCP\Config::deleteSystemValue('share_folder'); - - } - - private function cleanupSharedTable() { - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*share`'); - $query->execute(); - } - - /** - * prepare sharing table for testRemoveSharedFolder() - */ - private function prepareDB() { - $this->cleanupSharedTable(); - // add items except one - because this is the test case for the broken share table - $addItems = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`share_type`, `item_type`, ' . - '`share_with`, `uid_owner` , `file_target`) ' . - 'VALUES (?, ?, ?, ?, ?)'); - $items = array( - array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user1', 'admin' , '/foo'), - array(\OCP\Share::SHARE_TYPE_USER, 'folder', 'user2', 'admin', '/foo2'), - array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user3', 'admin', '/foo3'), - array(\OCP\Share::SHARE_TYPE_USER, 'folder', 'user4', 'admin', '/foo4'), - array(\OCP\Share::SHARE_TYPE_USER, 'folder', 'user4', 'admin', "/foo'4"), - array(\OCP\Share::SHARE_TYPE_LINK, 'file', 'user1', 'admin', '/ShouldNotChange'), - array(\OCP\Share::SHARE_TYPE_CONTACT, 'contact', 'admin', 'user1', '/ShouldNotChange'), - - ); - foreach($items as $item) { - // the number is used as path_hash - $addItems->execute($item); - } - } - - /** - * prepare sharing table for testUpdateFilePermissions() - */ - private function prepareDBUpdateFilePermissions() { - $this->cleanupSharedTable(); - // add items except one - because this is the test case for the broken share table - $addItems = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`share_type`, `item_type`, ' . - '`share_with`, `uid_owner` , `file_target`, `permissions`) ' . - 'VALUES (?, ?, ?, ?, ?, ?)'); - $items = array( - array(\OCP\Share::SHARE_TYPE_LINK, 'file', 'user1', 'admin', '/foo', \OCP\PERMISSION_ALL), - array(\OCP\Share::SHARE_TYPE_CONTACT, 'contact', 'admin', 'user1', '/foo', \OCP\PERMISSION_ALL), - array(\OCP\Share::SHARE_TYPE_USER, 'folder', 'user4', 'admin', '/foo', \OCP\PERMISSION_ALL), - array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user3', 'admin', '/foo3', \OCP\PERMISSION_ALL), - array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user1', 'admin' , '/foo', \OCP\PERMISSION_DELETE), - array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user1', 'admin' , '/foo', \OCP\PERMISSION_READ & \OCP\PERMISSION_DELETE), - array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user1', 'admin' , '/foo', \OCP\PERMISSION_SHARE & \OCP\PERMISSION_UPDATE), - array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user1', 'admin' , '/foo', \OCP\PERMISSION_ALL), - array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user1', 'admin' , '/foo', \OCP\PERMISSION_SHARE & \OCP\PERMISSION_READ & \OCP\PERMISSION_DELETE), - ); - foreach($items as $item) { - // the number is used as path_hash - $addItems->execute($item); - } - } - - /** - * prepare file cache for testRemoveBrokenShares() - */ - private function prepareFileCache() { - // some previous tests didn't clean up and therefore this has to be done here - // FIXME: DIRTY HACK - TODO: find tests, that don't clean up and fix it there - $this->tearDown(); - - // add items except one - because this is the test case for the broken share table - $addItems = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache` (`storage`, `path_hash`, ' . - '`parent`, `mimetype`, `mimepart`, `size`, `mtime`, `storage_mtime`) ' . - 'VALUES (1, ?, 1, 1, 1, 1, 1, 1)'); - $items = array(1, 3); - $fileIds = array(); - foreach($items as $item) { - // the number is used as path_hash - $addItems->execute(array($item)); - $fileIds[] = \OC_DB::insertId('*PREFIX*filecache'); - } - - $addShares = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`file_source`, `item_type`, `uid_owner`) VALUES (?, \'file\', 1)'); - // the number is used as item_source - $addShares->execute(array($fileIds[0])); - $addShares->execute(array(200)); // id of "deleted" file - $addShares->execute(array($fileIds[1])); - - // add a few unrelated shares, calendar share that must be left untouched - $addShares = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_source`, `item_type`, `uid_owner`) VALUES (?, \'calendar\', 1)'); - // the number is used as item_source - $addShares->execute(array(999)); - } - -} diff --git a/apps/files_sharing/tests/updater.php b/apps/files_sharing/tests/updater.php index 07349c1334d..861516dff7f 100644 --- a/apps/files_sharing/tests/updater.php +++ b/apps/files_sharing/tests/updater.php @@ -20,7 +20,6 @@ * */ -require_once __DIR__ . '/../appinfo/update.php'; /** * Class Test_Files_Sharing_Updater diff --git a/apps/files_trashbin/appinfo/routes.php b/apps/files_trashbin/appinfo/routes.php index da268f4fdfd..56dbf382735 100644 --- a/apps/files_trashbin/appinfo/routes.php +++ b/apps/files_trashbin/appinfo/routes.php @@ -13,3 +13,7 @@ $this->create('files_trashbin_ajax_list', 'ajax/list.php') ->actionInclude('files_trashbin/ajax/list.php'); $this->create('files_trashbin_ajax_undelete', 'ajax/undelete.php') ->actionInclude('files_trashbin/ajax/undelete.php'); + + +// Register with the capabilities API +\OC_API::register('get', '/cloud/capabilities', array('OCA\Files_Trashbin\Capabilities', 'getCapabilities'), 'files_trashbin', \OC_API::USER_AUTH); diff --git a/apps/files_trashbin/js/app.js b/apps/files_trashbin/js/app.js index 376ee7b01ca..a9727542bad 100644 --- a/apps/files_trashbin/js/app.js +++ b/apps/files_trashbin/js/app.js @@ -8,7 +8,13 @@ * */ +/** + * @namespace OCA.Trashbin + */ OCA.Trashbin = {}; +/** + * @namespace OCA.Trashbin.App + */ OCA.Trashbin.App = { _initialized: false, diff --git a/apps/files_trashbin/js/filelist.js b/apps/files_trashbin/js/filelist.js index b8688d89765..a3631a2d0fe 100644 --- a/apps/files_trashbin/js/filelist.js +++ b/apps/files_trashbin/js/filelist.js @@ -14,8 +14,8 @@ * Convert a file name in the format filename.d12345 to the real file name. * This will use basename. * The name will not be changed if it has no ".d12345" suffix. - * @param name file name - * @return converted file name + * @param {String} name file name + * @return {String} converted file name */ function getDeletedFileName(name) { name = OC.basename(name); @@ -26,13 +26,26 @@ return name; } + /** + * @class OCA.Trashbin.FileList + * @augments OCA.Files.FileList + * @classdesc List of deleted files + * + * @param $el container element with existing markup for the #controls + * and a table + * @param [options] map of options + */ var FileList = function($el, options) { this.initialize($el, options); }; - FileList.prototype = _.extend({}, OCA.Files.FileList.prototype, { + FileList.prototype = _.extend({}, OCA.Files.FileList.prototype, + /** @lends OCA.Trashbin.FileList.prototype */ { id: 'trashbin', appName: t('files_trashbin', 'Deleted files'), + /** + * @private + */ initialize: function() { var result = OCA.Files.FileList.prototype.initialize.apply(this, arguments); this.$el.find('.undelete').click('click', _.bind(this._onClickRestoreSelected, this)); diff --git a/apps/files_trashbin/l10n/pt_PT.js b/apps/files_trashbin/l10n/pt_PT.js index 5d22e3bca21..303c8ad8c37 100644 --- a/apps/files_trashbin/l10n/pt_PT.js +++ b/apps/files_trashbin/l10n/pt_PT.js @@ -7,9 +7,9 @@ OC.L10N.register( "Restore" : "Restaurar", "Error" : "Erro", "restored" : "Restaurado", - "Nothing in here. Your trash bin is empty!" : "Não hà ficheiros. O lixo está vazio!", + "Nothing in here. Your trash bin is empty!" : "Não existe nada aqui. O seu caixote de lixo está vazio!", "Name" : "Nome", - "Deleted" : "Apagado", + "Deleted" : "Eliminado", "Delete" : "Eliminar" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_trashbin/l10n/pt_PT.json b/apps/files_trashbin/l10n/pt_PT.json index 4feb75abd9a..431c381074a 100644 --- a/apps/files_trashbin/l10n/pt_PT.json +++ b/apps/files_trashbin/l10n/pt_PT.json @@ -5,9 +5,9 @@ "Restore" : "Restaurar", "Error" : "Erro", "restored" : "Restaurado", - "Nothing in here. Your trash bin is empty!" : "Não hà ficheiros. O lixo está vazio!", + "Nothing in here. Your trash bin is empty!" : "Não existe nada aqui. O seu caixote de lixo está vazio!", "Name" : "Nome", - "Deleted" : "Apagado", + "Deleted" : "Eliminado", "Delete" : "Eliminar" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/files_trashbin/lib/capabilities.php b/apps/files_trashbin/lib/capabilities.php new file mode 100644 index 00000000000..3f137d22b6f --- /dev/null +++ b/apps/files_trashbin/lib/capabilities.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright (c) Lukas Reschke <lukas@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCA\Files_Trashbin; + + +/** + * Class Capabilities + * + * @package OCA\Files_Trashbin + */ +class Capabilities { + + /** + * @return \OC_OCS_Result + */ + public static function getCapabilities() { + return new \OC_OCS_Result(array( + 'capabilities' => array( + 'files' => array( + 'undelete' => true, + ), + ), + )); + } + +} diff --git a/apps/files_versions/js/versions.js b/apps/files_versions/js/versions.js index 64e0df76490..1a47c1749f9 100644 --- a/apps/files_versions/js/versions.js +++ b/apps/files_versions/js/versions.js @@ -11,6 +11,8 @@ /* global scanFiles, escapeHTML, formatDate */ $(document).ready(function(){ + // TODO: namespace all this as OCA.FileVersions + if ($('#isPublic').val()){ // no versions actions in public mode // beware of https://github.com/owncloud/core/issues/4545 diff --git a/apps/user_ldap/l10n/cs_CZ.js b/apps/user_ldap/l10n/cs_CZ.js index 017b4f37e39..2b8142bced6 100644 --- a/apps/user_ldap/l10n/cs_CZ.js +++ b/apps/user_ldap/l10n/cs_CZ.js @@ -79,7 +79,7 @@ OC.L10N.register( "LDAP" : "LDAP", "Expert" : "Expertní", "Advanced" : "Pokročilé", - "<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." : "<b>Varování:</b> Aplikace user_ldap a user_webdavauth jsou vzájemně nekompatibilní. Můžete zaznamenat neočekávané chování. Požádejte prosím vašeho systémového administrátora o zakázání jednoho z nich.", + "<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." : "<b>Varování:</b> Aplikace user_ldap a user_webdavauth jsou vzájemně nekompatibilní. Můžete zaznamenat neočekávané chování. Požádejte prosím svého správce systému o zakázání jedné z nich.", "<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." : "<b>Varování:</b> není nainstalován LDAP modul pro PHP, podpůrná vrstva nebude fungovat. Požádejte, prosím, správce systému, aby jej nainstaloval.", "Connection Settings" : "Nastavení spojení", "Configuration Active" : "Nastavení aktivní", diff --git a/apps/user_ldap/l10n/cs_CZ.json b/apps/user_ldap/l10n/cs_CZ.json index b63a3fb11ff..819f4e6d534 100644 --- a/apps/user_ldap/l10n/cs_CZ.json +++ b/apps/user_ldap/l10n/cs_CZ.json @@ -77,7 +77,7 @@ "LDAP" : "LDAP", "Expert" : "Expertní", "Advanced" : "Pokročilé", - "<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." : "<b>Varování:</b> Aplikace user_ldap a user_webdavauth jsou vzájemně nekompatibilní. Můžete zaznamenat neočekávané chování. Požádejte prosím vašeho systémového administrátora o zakázání jednoho z nich.", + "<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." : "<b>Varování:</b> Aplikace user_ldap a user_webdavauth jsou vzájemně nekompatibilní. Můžete zaznamenat neočekávané chování. Požádejte prosím svého správce systému o zakázání jedné z nich.", "<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." : "<b>Varování:</b> není nainstalován LDAP modul pro PHP, podpůrná vrstva nebude fungovat. Požádejte, prosím, správce systému, aby jej nainstaloval.", "Connection Settings" : "Nastavení spojení", "Configuration Active" : "Nastavení aktivní", diff --git a/apps/user_ldap/l10n/fr.js b/apps/user_ldap/l10n/fr.js index f1e8abe46d4..3736ade73ce 100644 --- a/apps/user_ldap/l10n/fr.js +++ b/apps/user_ldap/l10n/fr.js @@ -108,7 +108,7 @@ OC.L10N.register( "Group Search Attributes" : "Recherche des attributs du groupe", "Group-Member association" : "Association groupe-membre", "Nested Groups" : "Groupes imbriqués", - "When switched on, groups that contain groups are supported. (Only works if the group member attribute contains DNs.)" : "Si activé, les groupes contenant d'autres groupes sont supportés (fonctionne uniquement si l'attribut membre du groupe contient des DNs).", + "When switched on, groups that contain groups are supported. (Only works if the group member attribute contains DNs.)" : "Si activé, les groupes contenant d'autres groupes sont pris en charge (fonctionne uniquement si l'attribut membre du groupe contient des DNs).", "Paging chunksize" : "Dimensionnement des paginations", "Chunksize used for paged LDAP searches that may return bulky results like user or group enumeration. (Setting it 0 disables paged LDAP searches in those situations.)" : "La taille d'une part (chunksize) est utilisée pour les recherches paginées de LDAP qui peuvent retourner des résultats par lots comme une énumération d'utilisateurs ou groupes. (Configurer à 0 pour désactiver les recherches paginées de LDAP.)", "Special Attributes" : "Attributs spéciaux", diff --git a/apps/user_ldap/l10n/fr.json b/apps/user_ldap/l10n/fr.json index d8ab51ba632..58ac6f3d248 100644 --- a/apps/user_ldap/l10n/fr.json +++ b/apps/user_ldap/l10n/fr.json @@ -106,7 +106,7 @@ "Group Search Attributes" : "Recherche des attributs du groupe", "Group-Member association" : "Association groupe-membre", "Nested Groups" : "Groupes imbriqués", - "When switched on, groups that contain groups are supported. (Only works if the group member attribute contains DNs.)" : "Si activé, les groupes contenant d'autres groupes sont supportés (fonctionne uniquement si l'attribut membre du groupe contient des DNs).", + "When switched on, groups that contain groups are supported. (Only works if the group member attribute contains DNs.)" : "Si activé, les groupes contenant d'autres groupes sont pris en charge (fonctionne uniquement si l'attribut membre du groupe contient des DNs).", "Paging chunksize" : "Dimensionnement des paginations", "Chunksize used for paged LDAP searches that may return bulky results like user or group enumeration. (Setting it 0 disables paged LDAP searches in those situations.)" : "La taille d'une part (chunksize) est utilisée pour les recherches paginées de LDAP qui peuvent retourner des résultats par lots comme une énumération d'utilisateurs ou groupes. (Configurer à 0 pour désactiver les recherches paginées de LDAP.)", "Special Attributes" : "Attributs spéciaux", diff --git a/apps/user_ldap/l10n/it.js b/apps/user_ldap/l10n/it.js index 92bab544984..d7a4e192ec6 100644 --- a/apps/user_ldap/l10n/it.js +++ b/apps/user_ldap/l10n/it.js @@ -63,7 +63,7 @@ OC.L10N.register( "You can omit the protocol, except you require SSL. Then start with ldaps://" : "È possibile omettere il protocollo, ad eccezione se è necessario SSL. Quindi inizia con ldaps://", "Port" : "Porta", "User DN" : "DN utente", - "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Il DN per il client dell'utente con cui deve essere associato, ad esempio uid=agent,dc=example,dc=com. Per l'accesso anonimo, lasciare vuoti i campi DN e Password", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Il DN per il client dell'utente con cui deve essere associato, ad esempio uid=agente,dc=esempio,dc=com. Per l'accesso anonimo, lasciare vuoti i campi DN e Password", "Password" : "Password", "For anonymous access, leave DN and Password empty." : "Per l'accesso anonimo, lasciare vuoti i campi DN e Password", "One Base DN per line" : "Un DN base per riga", diff --git a/apps/user_ldap/l10n/it.json b/apps/user_ldap/l10n/it.json index 31a694a4b1c..44a529bc0c5 100644 --- a/apps/user_ldap/l10n/it.json +++ b/apps/user_ldap/l10n/it.json @@ -61,7 +61,7 @@ "You can omit the protocol, except you require SSL. Then start with ldaps://" : "È possibile omettere il protocollo, ad eccezione se è necessario SSL. Quindi inizia con ldaps://", "Port" : "Porta", "User DN" : "DN utente", - "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Il DN per il client dell'utente con cui deve essere associato, ad esempio uid=agent,dc=example,dc=com. Per l'accesso anonimo, lasciare vuoti i campi DN e Password", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Il DN per il client dell'utente con cui deve essere associato, ad esempio uid=agente,dc=esempio,dc=com. Per l'accesso anonimo, lasciare vuoti i campi DN e Password", "Password" : "Password", "For anonymous access, leave DN and Password empty." : "Per l'accesso anonimo, lasciare vuoti i campi DN e Password", "One Base DN per line" : "Un DN base per riga", diff --git a/apps/user_ldap/l10n/uk.js b/apps/user_ldap/l10n/uk.js index 538061db520..0b8e8946e0f 100644 --- a/apps/user_ldap/l10n/uk.js +++ b/apps/user_ldap/l10n/uk.js @@ -76,6 +76,7 @@ OC.L10N.register( "Saving" : "Збереження", "Back" : "Назад", "Continue" : "Продовжити", + "LDAP" : "LDAP", "Expert" : "Експерт", "Advanced" : "Додатково", "<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." : "<b>Попередження:</b> Застосунки user_ldap та user_webdavauth не сумісні. Ви можете зіткнутися з несподіваною поведінкою. Будь ласка, зверніться до системного адміністратора, щоб відключити одну з них.", diff --git a/apps/user_ldap/l10n/uk.json b/apps/user_ldap/l10n/uk.json index f0b439ac979..9fb1ce119fb 100644 --- a/apps/user_ldap/l10n/uk.json +++ b/apps/user_ldap/l10n/uk.json @@ -74,6 +74,7 @@ "Saving" : "Збереження", "Back" : "Назад", "Continue" : "Продовжити", + "LDAP" : "LDAP", "Expert" : "Експерт", "Advanced" : "Додатково", "<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." : "<b>Попередження:</b> Застосунки user_ldap та user_webdavauth не сумісні. Ви можете зіткнутися з несподіваною поведінкою. Будь ласка, зверніться до системного адміністратора, щоб відключити одну з них.", diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php index 12c6f8118d3..d89029abf17 100644 --- a/apps/user_ldap/lib/access.php +++ b/apps/user_ldap/lib/access.php @@ -928,7 +928,7 @@ class Access extends LDAPUtility implements user\IUserTools { foreach($searchResults as $res) { $count = intval($this->ldap->countEntries($cr, $res)); $counter += $count; - if($count === $limit) { + if($count > 0 && $count === $limit) { $hasHitLimit = true; } } diff --git a/apps/user_ldap/settings.php b/apps/user_ldap/settings.php index ca61a53b196..3b448aec757 100644 --- a/apps/user_ldap/settings.php +++ b/apps/user_ldap/settings.php @@ -28,9 +28,9 @@ OC_Util::checkAdminUser(); OCP\Util::addScript('user_ldap', 'ldapFilter'); OCP\Util::addScript('user_ldap', 'experiencedAdmin'); OCP\Util::addScript('user_ldap', 'settings'); -OCP\Util::addScript('core', 'jquery.multiselect'); +\OC_Util::addVendorScript('user_ldap', 'ui-multiselect/src/jquery.multiselect'); OCP\Util::addStyle('user_ldap', 'settings'); -OCP\Util::addStyle('core', 'jquery.multiselect'); +\OC_Util::addVendorStyle('user_ldap', 'ui-multiselect/jquery.multiselect'); OCP\Util::addStyle('core', 'jquery-ui-1.10.0.custom'); // fill template diff --git a/apps/user_ldap/vendor/ui-multiselect/MIT-LICENSE b/apps/user_ldap/vendor/ui-multiselect/MIT-LICENSE new file mode 100644 index 00000000000..2dc8e79e3ad --- /dev/null +++ b/apps/user_ldap/vendor/ui-multiselect/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2011 Eric Hynds + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/core/css/jquery.multiselect.css b/apps/user_ldap/vendor/ui-multiselect/jquery.multiselect.css index 9b81c3bdcfb..9b81c3bdcfb 100644 --- a/core/css/jquery.multiselect.css +++ b/apps/user_ldap/vendor/ui-multiselect/jquery.multiselect.css diff --git a/core/js/jquery.multiselect.js b/apps/user_ldap/vendor/ui-multiselect/src/jquery.multiselect.js index 16ae4264177..16ae4264177 100644 --- a/core/js/jquery.multiselect.js +++ b/apps/user_ldap/vendor/ui-multiselect/src/jquery.multiselect.js diff --git a/autotest.sh b/autotest.sh index 8edb5f3915a..83a20699d01 100755 --- a/autotest.sh +++ b/autotest.sh @@ -40,7 +40,7 @@ if ! [ $PHPUNIT_MAJOR_VERSION -gt 3 -o \( $PHPUNIT_MAJOR_VERSION -eq 3 -a $PHPUN exit 4 fi -if ! [ -w config -a -w config/config.php ]; then +if ! [ \( -w config -a ! -f config/config.php \) -o \( -f config/config.php -a -w config/config.php \) ]; then echo "Please enable write permissions on config and config/config.php" >&2 exit 1 fi diff --git a/buildjsdocs.sh b/buildjsdocs.sh new file mode 100755 index 00000000000..ef18dc8c9a9 --- /dev/null +++ b/buildjsdocs.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# +# ownCloud +# +# Run JS tests +# +# @author Vincent Petry +# @copyright 2014 Vincent Petry <pvince81@owncloud.com> +# +NPM="$(which npm 2>/dev/null)" +PREFIX="build" +OUTPUT_DIR="build/jsdocs" + +JS_FILES="core/js/*.js apps/*/js/*.js" + +if test -z "$NPM" +then + echo 'Node JS >= 0.8 is required to build the documentation' >&2 + exit 1 +fi + +# update/install test packages +mkdir -p "$PREFIX" && $NPM install --link --prefix "$PREFIX" jsdoc || exit 3 + +JSDOC_BIN="$(which jsdoc 2>/dev/null)" + +# If not installed globally, try local version +if test -z "$JSDOC_BIN" +then + JSDOC_BIN="$PREFIX/node_modules/jsdoc/jsdoc.js" +fi + +if test -z "$JSDOC_BIN" +then + echo 'jsdoc executable not found' >&2 + exit 2 +fi + +mkdir -p "$OUTPUT_DIR" + +NODE_PATH="$PREFIX/node_modules" $JSDOC_BIN -d "$OUTPUT_DIR" $JS_FILES + diff --git a/config/config.sample.php b/config/config.sample.php index 59f892d133b..daca5aed362 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -672,6 +672,12 @@ $CONFIG = array( 'forcessl' => false, /** + * Change this to ``true`` to require HTTPS connections also for all subdomains. + * Works only together when `forcessl` is set to true. + */ +'forceSSLforSubdomains' => false, + +/** * Extra SSL options to be used for configuration. */ 'openssl' => array( diff --git a/core/application.php b/core/application.php index 33801847758..c36ab559c27 100644 --- a/core/application.php +++ b/core/application.php @@ -10,13 +10,22 @@ namespace OC\Core; +use OC\AppFramework\Utility\SimpleContainer; use \OCP\AppFramework\App; use OC\Core\LostPassword\Controller\LostController; use OC\Core\User\UserController; +use \OCP\Util; +/** + * Class Application + * + * @package OC\Core + */ class Application extends App { - + /** + * @param array $urlParams + */ public function __construct(array $urlParams=array()){ parent::__construct('core', $urlParams); @@ -25,29 +34,56 @@ class Application extends App { /** * Controllers */ - $container->registerService('LostController', function($c) { + $container->registerService('LostController', function(SimpleContainer $c) { return new LostController( $c->query('AppName'), $c->query('Request'), - $c->query('ServerContainer')->getURLGenerator(), - $c->query('ServerContainer')->getUserManager(), - new \OC_Defaults(), - $c->query('ServerContainer')->getL10N('core'), - $c->query('ServerContainer')->getConfig(), - $c->query('ServerContainer')->getUserSession(), - \OCP\Util::getDefaultEmailAddress('lostpassword-noreply'), - \OC_App::isEnabled('files_encryption') + $c->query('URLGenerator'), + $c->query('UserManager'), + $c->query('Defaults'), + $c->query('L10N'), + $c->query('Config'), + $c->query('SecureRandom'), + $c->query('DefaultEmailAddress'), + $c->query('IsEncryptionEnabled') ); }); - $container->registerService('UserController', function($c) { + $container->registerService('UserController', function(SimpleContainer $c) { return new UserController( $c->query('AppName'), $c->query('Request'), - $c->query('ServerContainer')->getUserManager(), - new \OC_Defaults() + $c->query('UserManager'), + $c->query('Defaults') ); }); - } + /** + * Core class wrappers + */ + $container->registerService('IsEncryptionEnabled', function() { + return \OC_App::isEnabled('files_encryption'); + }); + $container->registerService('URLGenerator', function(SimpleContainer $c) { + return $c->query('ServerContainer')->getURLGenerator(); + }); + $container->registerService('UserManager', function(SimpleContainer $c) { + return $c->query('ServerContainer')->getUserManager(); + }); + $container->registerService('Config', function(SimpleContainer $c) { + return $c->query('ServerContainer')->getConfig(); + }); + $container->registerService('L10N', function(SimpleContainer $c) { + return $c->query('ServerContainer')->getL10N('core'); + }); + $container->registerService('SecureRandom', function(SimpleContainer $c) { + return $c->query('ServerContainer')->getSecureRandom(); + }); + $container->registerService('Defaults', function() { + return new \OC_Defaults; + }); + $container->registerService('DefaultEmailAddress', function() { + return Util::getDefaultEmailAddress('lostpassword-noreply'); + }); + } } diff --git a/core/css/styles.css b/core/css/styles.css index c45588cece6..2859399b59e 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -353,6 +353,12 @@ input[type="submit"].enabled { filter: alpha(opacity=60); opacity: .6; } +/* overrides another !important statement that sets this to unreadable black */ +#body-login form .warning input[type="checkbox"]:hover+label, +#body-login form .warning input[type="checkbox"]:focus+label, +#body-login form .warning input[type="checkbox"]+label { + color: #fff !important; +} #body-login .update h2 { font-size: 20px; diff --git a/core/js/config.js b/core/js/config.js index 52d1c3aee25..b034b7e8cd3 100644 --- a/core/js/config.js +++ b/core/js/config.js @@ -4,6 +4,9 @@ * See the COPYING-README file. */ +/** + * @namespace + */ OC.AppConfig={ url:OC.filePath('core','ajax','appconfig.php'), getCall:function(action,data,callback){ diff --git a/core/js/eventsource.js b/core/js/eventsource.js index 46bd9f60bb5..6f23cebb685 100644 --- a/core/js/eventsource.js +++ b/core/js/eventsource.js @@ -34,6 +34,8 @@ * Create a new event source * @param {string} src * @param {object} [data] to be send as GET + * + * @constructs OC.EventSource */ OC.EventSource=function(src,data){ var dataStr=''; @@ -92,6 +94,16 @@ OC.EventSource.prototype={ iframe:null, listeners:{},//only for fallback useFallBack:false, + /** + * Fallback callback for browsers that don't have the + * native EventSource object. + * + * Calls the registered listeners. + * + * @private + * @param {String} type event type + * @param {Object} data received data + */ fallBackCallBack:function(type,data){ var i; // ignore messages that might appear after closing @@ -111,6 +123,12 @@ OC.EventSource.prototype={ } }, lastLength:0,//for fallback + /** + * Listen to a given type of events. + * + * @param {String} type event type + * @param {Function} callback event callback + */ listen:function(type,callback){ if(callback && callback.call){ @@ -134,6 +152,9 @@ OC.EventSource.prototype={ } } }, + /** + * Closes this event source. + */ close:function(){ this.closed = true; if (typeof this.source !== 'undefined') { diff --git a/core/js/js.js b/core/js/js.js index b1a61ddf502..39e382b544b 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -5,6 +5,7 @@ * To the end of config/config.php to enable debug mode. * The undefined checks fix the broken ie8 console */ + var oc_debug; var oc_webroot; @@ -57,6 +58,7 @@ function fileDownloadPath(dir, file) { return OC.filePath('files', 'ajax', 'download.php')+'?files='+encodeURIComponent(file)+'&dir='+encodeURIComponent(dir); } +/** @namespace */ var OC={ PERMISSION_CREATE:4, PERMISSION_READ:1, @@ -251,14 +253,22 @@ var OC={ }, /** - * @todo Write the documentation + * Returns the base name of the given path. + * For example for "/abc/somefile.txt" it will return "somefile.txt" + * + * @param {String} path + * @return {String} base name */ basename: function(path) { return path.replace(/\\/g,'/').replace( /.*\//, '' ); }, /** - * @todo Write the documentation + * Returns the dir name of the given path. + * For example for "/abc/somefile.txt" it will return "/abc" + * + * @param {String} path + * @return {String} dir name */ dirname: function(path) { return path.replace(/\\/g,'/').replace(/\/[^\/]*$/, ''); @@ -277,12 +287,16 @@ var OC={ }); } }, 500), + /** + * Dialog helper for jquery dialogs. + * + * @namespace OC.dialogs + */ dialogs:OCdialogs, - /** * Parses a URL query string into a JS map * @param {string} queryString query string in the format param1=1234¶m2=abcde¶m3=xyz - * @return map containing key/values matching the URL parameters + * @return {Object.<string, string>} map containing key/values matching the URL parameters */ parseQueryString:function(queryString){ var parts, @@ -334,7 +348,7 @@ var OC={ /** * Builds a URL query from a JS map. - * @param params parameter map + * @param {Object.<string, string>} params map containing key/values matching the URL parameters * @return {string} String containing a URL query (without question) mark */ buildQueryString: function(params) { @@ -454,7 +468,7 @@ var OC={ * * This is makes it possible for unit tests to * stub matchMedia (which doesn't work in PhantomJS) - * @todo Write documentation + * @private */ _matchMedia: function(media) { if (window.matchMedia) { @@ -464,6 +478,9 @@ var OC={ } }; +/** + * @namespace OC.search + */ OC.search.customResults={}; OC.search.currentResult=-1; OC.search.lastQuery=''; @@ -531,6 +548,7 @@ OC.msg={ /** * @todo Write documentation + * @namespace */ OC.Notification={ queuedNotifications: [], @@ -607,7 +625,12 @@ OC.Notification={ }; /** - * @todo Write documentation + * Breadcrumb class + * + * @namespace + * + * @deprecated will be replaced by the breadcrumb implementation + * of the files app in the future */ OC.Breadcrumb={ container:null, @@ -721,6 +744,7 @@ OC.Breadcrumb={ if(typeof localStorage !=='undefined' && localStorage !== null){ /** * User and instance aware localstorage + * @namespace */ OC.localStorage={ namespace:'oc_'+OC.currentUser+'_'+OC.webroot+'_', @@ -1164,6 +1188,7 @@ function relative_modified_date(timestamp) { /** * Utility functions + * @namespace */ OC.Util = { // TODO: remove original functions from global namespace @@ -1314,6 +1339,8 @@ OC.Util = { * Utility class for the history API, * includes fallback to using the URL hash when * the browser doesn't support the history API. + * + * @namespace */ OC.Util.History = { _handlers: [], @@ -1473,6 +1500,7 @@ OC.set=function(name, value) { /** * Namespace for apps + * @namespace OCA */ window.OCA = {}; diff --git a/core/js/lostpassword.js b/core/js/lostpassword.js index ad221cb30fc..35173fd3d33 100644 --- a/core/js/lostpassword.js +++ b/core/js/lostpassword.js @@ -8,19 +8,12 @@ OC.Lostpassword = { + ('<br /><input type="checkbox" id="encrypted-continue" value="Yes" />') + '<label for="encrypted-continue">' + t('core', 'I know what I\'m doing') - + '</label><br />' - + '<a id="lost-password-encryption" href>' - + t('core', 'Reset password') - + '</a>', + + '</label><br />', resetErrorMsg : t('core', 'Password can not be changed. Please contact your administrator.'), init : function() { - if ($('#lost-password-encryption').length){ - $('#lost-password-encryption').click(OC.Lostpassword.sendLink); - } else { - $('#lost-password').click(OC.Lostpassword.sendLink); - } + $('#lost-password').click(OC.Lostpassword.sendLink); $('#reset-password #submit').click(OC.Lostpassword.resetPassword); }, @@ -32,8 +25,7 @@ OC.Lostpassword = { $.post( OC.generateUrl('/lostpassword/email'), { - user : $('#user').val(), - proceed: $('#encrypted-continue').attr('checked') ? 'Yes' : 'No' + user : $('#user').val() }, OC.Lostpassword.sendLinkDone ); @@ -84,11 +76,16 @@ OC.Lostpassword = { $.post( $('#password').parents('form').attr('action'), { - password : $('#password').val() + password : $('#password').val(), + proceed: $('#encrypted-continue').attr('checked') ? 'true' : 'false' }, OC.Lostpassword.resetDone ); } + if($('#encrypted-continue').attr('checked')) { + $('#reset-password #submit').hide(); + $('#reset-password #float-spinner').removeClass('hidden'); + } }, resetDone : function(result){ @@ -126,7 +123,7 @@ OC.Lostpassword = { getResetStatusNode : function (){ if (!$('#lost-password').length){ - $('<p id="lost-password"></p>').insertAfter($('#submit')); + $('<p id="lost-password"></p>').insertBefore($('#reset-password fieldset')); } else { $('#lost-password').replaceWith($('<p id="lost-password"></p>')); } diff --git a/core/js/oc-dialogs.js b/core/js/oc-dialogs.js index bd6fd2e5007..9e5afea1a6f 100644 --- a/core/js/oc-dialogs.js +++ b/core/js/oc-dialogs.js @@ -23,6 +23,7 @@ /** * this class to ease the usage of jquery dialogs + * @lends OC.dialogs */ var OCdialogs = { // dialog button types diff --git a/core/js/setup.js b/core/js/setup.js index 1eceb8ced70..e65b795646e 100644 --- a/core/js/setup.js +++ b/core/js/setup.js @@ -103,4 +103,18 @@ $(document).ready(function() { t('core', 'Strong password') ] }); + + // centers the database chooser if it is too wide + if($('#databaseBackend').width() > 300) { + // this somehow needs to wait 250 milliseconds + // otherwise it gets overwritten + setTimeout(function(){ + // calculate negative left margin + // half of the difference of width and default bix width of 300 + // add 10 to clear left side padding of button group + var leftMargin = (($('#databaseBackend').width() - 300) / 2 + 10 ) * -1; + + $('#databaseBackend').css('margin-left', Math.floor(leftMargin) + 'px'); + }, 250); + } }); diff --git a/core/js/snap.js b/core/js/snap.js deleted file mode 100644 index 19942e866a9..00000000000 --- a/core/js/snap.js +++ /dev/null @@ -1,785 +0,0 @@ -/*! Snap.js v2.0.0-rc1 */ -(function(win, doc) { - - 'use strict'; - - // Our export - var Namespace = 'Snap'; - - // Our main toolbelt - var utils = { - - /** - * Deeply extends two objects - * @param {Object} destination The destination object - * @param {Object} source The custom options to extend destination by - * @return {Object} The desination object - */ - extend: function(destination, source) { - var property; - for (property in source) { - if (source[property] && source[property].constructor && source[property].constructor === Object) { - destination[property] = destination[property] || {}; - utils.extend(destination[property], source[property]); - } else { - destination[property] = source[property]; - } - } - return destination; - } - }; - - /** - * Our Snap global that initializes our instance - * @param {Object} opts The custom Snap.js options - */ - var Core = function( opts ) { - - var self = this; - - /** - * Our default settings for a Snap instance - * @type {Object} - */ - var settings = self.settings = { - element: null, - dragger: null, - disable: 'none', - addBodyClasses: true, - hyperextensible: true, - resistance: 0.5, - flickThreshold: 50, - transitionSpeed: 0.3, - easing: 'ease', - maxPosition: 266, - minPosition: -266, - tapToClose: true, - touchToDrag: true, - clickToDrag: true, - slideIntent: 40, // degrees - minDragDistance: 5 - }; - - /** - * Stores internally global data - * @type {Object} - */ - var cache = self.cache = { - isDragging: false, - simpleStates: { - opening: null, - towards: null, - hyperExtending: null, - halfway: null, - flick: null, - translation: { - absolute: 0, - relative: 0, - sinceDirectionChange: 0, - percentage: 0 - } - } - }; - - var eventList = self.eventList = {}; - - utils.extend(utils, { - - /** - * Determines if we are interacting with a touch device - * @type {Boolean} - */ - hasTouch: ('ontouchstart' in doc.documentElement || win.navigator.msPointerEnabled), - - /** - * Returns the appropriate event type based on whether we are a touch device or not - * @param {String} action The "action" event you're looking for: up, down, move, out - * @return {String} The browsers supported event name - */ - eventType: function(action) { - var eventTypes = { - down: (utils.hasTouch ? 'touchstart' : settings.clickToDrag ? 'mousedown' : ''), - move: (utils.hasTouch ? 'touchmove' : settings.clickToDrag ? 'mousemove' : ''), - up: (utils.hasTouch ? 'touchend' : settings.clickToDrag ? 'mouseup': ''), - out: (utils.hasTouch ? 'touchcancel' : settings.clickToDrag ? 'mouseout' : '') - }; - return eventTypes[action]; - }, - - /** - * Returns the correct "cursor" position on both browser and mobile - * @param {String} t The coordinate to retrieve, either "X" or "Y" - * @param {Object} e The event object being triggered - * @return {Number} The desired coordiante for the events interaction - */ - page: function(t, e){ - return (utils.hasTouch && e.touches.length && e.touches[0]) ? e.touches[0]['page'+t] : e['page'+t]; - }, - - - klass: { - - /** - * Checks if an element has a class name - * @param {Object} el The element to check - * @param {String} name The class name to search for - * @return {Boolean} Returns true if the class exists - */ - has: function(el, name){ - return (el.className).indexOf(name) !== -1; - }, - - /** - * Adds a class name to an element - * @param {Object} el The element to add to - * @param {String} name The class name to add - */ - add: function(el, name){ - if(!utils.klass.has(el, name) && settings.addBodyClasses){ - el.className += " "+name; - } - }, - - /** - * Removes a class name - * @param {Object} el The element to remove from - * @param {String} name The class name to remove - */ - remove: function(el, name){ - if(utils.klass.has(el, name) && settings.addBodyClasses){ - el.className = (el.className).replace(name, "").replace(/^\s+|\s+$/g, ''); - } - } - }, - - /** - * Dispatch a custom Snap.js event - * @param {String} type The event name - */ - dispatchEvent: function(type) { - if( typeof eventList[type] === 'function') { - return eventList[type].apply(); - } - }, - - /** - * Determines the browsers vendor prefix for CSS3 - * @return {String} The browsers vendor prefix - */ - vendor: function(){ - var tmp = doc.createElement("div"), - prefixes = 'webkit Moz O ms'.split(' '), - i; - for (i in prefixes) { - if (typeof tmp.style[prefixes[i] + 'Transition'] !== 'undefined') { - return prefixes[i]; - } - } - }, - - /** - * Determines the browsers vendor prefix for transition callback events - * @return {String} The event name - */ - transitionCallback: function(){ - return (cache.vendor==='Moz' || cache.vendor==='ms') ? 'transitionend' : cache.vendor+'TransitionEnd'; - }, - - /** - * Determines if the users browser supports CSS3 transformations - * @return {[type]} [description] - */ - canTransform: function(){ - return typeof settings.element.style[cache.vendor+'Transform'] !== 'undefined'; - }, - - /** - * Determines an angle between two points - * @param {Number} x The X coordinate - * @param {Number} y The Y coordinate - * @return {Number} The number of degrees between the two points - */ - angleOfDrag: function(x, y) { - var degrees, theta; - // Calc Theta - theta = Math.atan2(-(cache.startDragY - y), (cache.startDragX - x)); - if (theta < 0) { - theta += 2 * Math.PI; - } - // Calc Degrees - degrees = Math.floor(theta * (180 / Math.PI) - 180); - if (degrees < 0 && degrees > -180) { - degrees = 360 - Math.abs(degrees); - } - return Math.abs(degrees); - }, - - - events: { - - /** - * Adds an event to an element - * @param {Object} element Element to add event to - * @param {String} eventName The event name - * @param {Function} func Callback function - */ - addEvent: function addEvent(element, eventName, func) { - if (element.addEventListener) { - return element.addEventListener(eventName, func, false); - } else if (element.attachEvent) { - return element.attachEvent("on" + eventName, func); - } - }, - - /** - * Removes an event to an element - * @param {Object} element Element to remove event from - * @param {String} eventName The event name - * @param {Function} func Callback function - */ - removeEvent: function addEvent(element, eventName, func) { - if (element.addEventListener) { - return element.removeEventListener(eventName, func, false); - } else if (element.attachEvent) { - return element.detachEvent("on" + eventName, func); - } - }, - - /** - * Prevents the default event - * @param {Object} e The event object - */ - prevent: function(e) { - if (e.preventDefault) { - e.preventDefault(); - } else { - e.returnValue = false; - } - } - }, - - /** - * Searches the parent element until a specified attribute has been matched - * @param {Object} el The element to search from - * @param {String} attr The attribute to search for - * @return {Object|null} Returns a matched element if it exists, else, null - */ - parentUntil: function(el, attr) { - var isStr = typeof attr === 'string'; - while (el.parentNode) { - if (isStr && el.getAttribute && el.getAttribute(attr)){ - return el; - } else if(!isStr && el === attr){ - return el; - } - el = el.parentNode; - } - return null; - } - }); - - - var action = self.action = { - - /** - * Handles translating the elements position - * @type {Object} - */ - translate: { - get: { - - /** - * Returns the amount an element is translated - * @param {Number} index The index desired from the CSS3 values of translate3d - * @return {Number} The amount of pixels an element is translated - */ - matrix: function(index) { - - if( !cache.canTransform ){ - return parseInt(settings.element.style.left, 10); - } else { - var matrix = win.getComputedStyle(settings.element)[cache.vendor+'Transform'].match(/\((.*)\)/), - ieOffset = 8; - if (matrix) { - matrix = matrix[1].split(','); - - // Internet Explorer likes to give us 16 fucking values - if(matrix.length===16){ - index+=ieOffset; - } - return parseInt(matrix[index], 10); - } - return 0; - } - } - }, - - /** - * Called when the element has finished transitioning - */ - easeCallback: function(fn){ - settings.element.style[cache.vendor+'Transition'] = ''; - cache.translation = action.translate.get.matrix(4); - cache.easing = false; - - if(cache.easingTo===0){ - utils.klass.remove(doc.body, 'snapjs-right'); - utils.klass.remove(doc.body, 'snapjs-left'); - } - - if( cache.once ){ - cache.once.call(self, self.state()); - delete cache.once; - } - - utils.dispatchEvent('animated'); - utils.events.removeEvent(settings.element, utils.transitionCallback(), action.translate.easeCallback); - - }, - - /** - * Animates the pane by the specified amount of pixels - * @param {Number} n The amount of pixels to move the pane - */ - easeTo: function(n, cb) { - - if( !cache.canTransform ){ - cache.translation = n; - action.translate.x(n); - } else { - cache.easing = true; - cache.easingTo = n; - - settings.element.style[cache.vendor+'Transition'] = 'all ' + settings.transitionSpeed + 's ' + settings.easing; - - cache.once = cb; - - utils.events.addEvent(settings.element, utils.transitionCallback(), action.translate.easeCallback); - action.translate.x(n); - } - if(n===0){ - settings.element.style[cache.vendor+'Transform'] = ''; - } - }, - - /** - * Immediately translates the element on its X axis - * @param {Number} n Amount of pixels to translate - */ - x: function(n) { - if( (settings.disable==='left' && n>0) || - (settings.disable==='right' && n<0) - ){ return; } - - if( !settings.hyperextensible ){ - if( n===settings.maxPosition || n>settings.maxPosition ){ - n=settings.maxPosition; - } else if( n===settings.minPosition || n<settings.minPosition ){ - n=settings.minPosition; - } - } - - n = parseInt(n, 10); - if(isNaN(n)){ - n = 0; - } - - if( cache.canTransform ){ - var theTranslate = 'translate3d(' + n + 'px, 0,0)'; - settings.element.style[cache.vendor+'Transform'] = theTranslate; - } else { - settings.element.style.width = (win.innerWidth || doc.documentElement.clientWidth)+'px'; - - settings.element.style.left = n+'px'; - settings.element.style.right = ''; - } - } - }, - - /** - * Handles all the events that interface with dragging - * @type {Object} - */ - drag: { - - /** - * Begins listening for drag events on our element - */ - listen: function() { - cache.translation = 0; - cache.easing = false; - utils.events.addEvent(self.settings.element, utils.eventType('down'), action.drag.startDrag); - utils.events.addEvent(self.settings.element, utils.eventType('move'), action.drag.dragging); - utils.events.addEvent(self.settings.element, utils.eventType('up'), action.drag.endDrag); - }, - - /** - * Stops listening for drag events on our element - */ - stopListening: function() { - utils.events.removeEvent(settings.element, utils.eventType('down'), action.drag.startDrag); - utils.events.removeEvent(settings.element, utils.eventType('move'), action.drag.dragging); - utils.events.removeEvent(settings.element, utils.eventType('up'), action.drag.endDrag); - }, - - /** - * Fired immediately when the user begins to drag the content pane - * @param {Object} e Event object - */ - startDrag: function(e) { - // No drag on ignored elements - var target = e.target ? e.target : e.srcElement, - ignoreParent = utils.parentUntil(target, 'data-snap-ignore'); - - if (ignoreParent) { - utils.dispatchEvent('ignore'); - return; - } - - - if(settings.dragger){ - var dragParent = utils.parentUntil(target, settings.dragger); - - // Only use dragger if we're in a closed state - if( !dragParent && - (cache.translation !== settings.minPosition && - cache.translation !== settings.maxPosition - )){ - return; - } - } - - utils.dispatchEvent('start'); - settings.element.style[cache.vendor+'Transition'] = ''; - cache.isDragging = true; - - cache.intentChecked = false; - cache.startDragX = utils.page('X', e); - cache.startDragY = utils.page('Y', e); - cache.dragWatchers = { - current: 0, - last: 0, - hold: 0, - state: '' - }; - cache.simpleStates = { - opening: null, - towards: null, - hyperExtending: null, - halfway: null, - flick: null, - translation: { - absolute: 0, - relative: 0, - sinceDirectionChange: 0, - percentage: 0 - } - }; - }, - - /** - * Fired while the user is moving the content pane - * @param {Object} e Event object - */ - dragging: function(e) { - - if (cache.isDragging && settings.touchToDrag) { - - var thePageX = utils.page('X', e), - thePageY = utils.page('Y', e), - translated = cache.translation, - absoluteTranslation = action.translate.get.matrix(4), - whileDragX = thePageX - cache.startDragX, - openingLeft = absoluteTranslation > 0, - translateTo = whileDragX, - diff; - - // Shown no intent already - if((cache.intentChecked && !cache.hasIntent)){ - return; - } - - if(settings.addBodyClasses){ - if((absoluteTranslation)>0){ - utils.klass.add(doc.body, 'snapjs-left'); - utils.klass.remove(doc.body, 'snapjs-right'); - } else if((absoluteTranslation)<0){ - utils.klass.add(doc.body, 'snapjs-right'); - utils.klass.remove(doc.body, 'snapjs-left'); - } - } - - if (cache.hasIntent === false || cache.hasIntent === null) { - - var deg = utils.angleOfDrag(thePageX, thePageY), - inRightRange = (deg >= 0 && deg <= settings.slideIntent) || (deg <= 360 && deg > (360 - settings.slideIntent)), - inLeftRange = (deg >= 180 && deg <= (180 + settings.slideIntent)) || (deg <= 180 && deg >= (180 - settings.slideIntent)); - if (!inLeftRange && !inRightRange) { - cache.hasIntent = false; - } else { - cache.hasIntent = true; - } - cache.intentChecked = true; - } - - if ( - (settings.minDragDistance>=Math.abs(thePageX-cache.startDragX)) || // Has user met minimum drag distance? - (cache.hasIntent === false) - ) { - return; - } - - utils.events.prevent(e); - utils.dispatchEvent('drag'); - - cache.dragWatchers.current = thePageX; - - // Determine which direction we are going - if (cache.dragWatchers.last > thePageX) { - if (cache.dragWatchers.state !== 'left') { - cache.dragWatchers.state = 'left'; - cache.dragWatchers.hold = thePageX; - } - cache.dragWatchers.last = thePageX; - } else if (cache.dragWatchers.last < thePageX) { - if (cache.dragWatchers.state !== 'right') { - cache.dragWatchers.state = 'right'; - cache.dragWatchers.hold = thePageX; - } - cache.dragWatchers.last = thePageX; - } - if (openingLeft) { - // Pulling too far to the right - if (settings.maxPosition < absoluteTranslation) { - diff = (absoluteTranslation - settings.maxPosition) * settings.resistance; - translateTo = whileDragX - diff; - } - cache.simpleStates = { - opening: 'left', - towards: cache.dragWatchers.state, - hyperExtending: settings.maxPosition < absoluteTranslation, - halfway: absoluteTranslation > (settings.maxPosition / 2), - flick: Math.abs(cache.dragWatchers.current - cache.dragWatchers.hold) > settings.flickThreshold, - translation: { - absolute: absoluteTranslation, - relative: whileDragX, - sinceDirectionChange: (cache.dragWatchers.current - cache.dragWatchers.hold), - percentage: (absoluteTranslation/settings.maxPosition)*100 - } - }; - } else { - // Pulling too far to the left - if (settings.minPosition > absoluteTranslation) { - diff = (absoluteTranslation - settings.minPosition) * settings.resistance; - translateTo = whileDragX - diff; - } - cache.simpleStates = { - opening: 'right', - towards: cache.dragWatchers.state, - hyperExtending: settings.minPosition > absoluteTranslation, - halfway: absoluteTranslation < (settings.minPosition / 2), - flick: Math.abs(cache.dragWatchers.current - cache.dragWatchers.hold) > settings.flickThreshold, - translation: { - absolute: absoluteTranslation, - relative: whileDragX, - sinceDirectionChange: (cache.dragWatchers.current - cache.dragWatchers.hold), - percentage: (absoluteTranslation/settings.minPosition)*100 - } - }; - } - action.translate.x(translateTo + translated); - } - }, - - /** - * Fired when the user releases the content pane - * @param {Object} e Event object - */ - endDrag: function(e) { - if (cache.isDragging) { - utils.dispatchEvent('end'); - var translated = action.translate.get.matrix(4); - - // Tap Close - if (cache.dragWatchers.current === 0 && translated !== 0 && settings.tapToClose) { - utils.dispatchEvent('close'); - utils.events.prevent(e); - action.translate.easeTo(0); - cache.isDragging = false; - cache.startDragX = 0; - return; - } - - // Revealing Left - if (cache.simpleStates.opening === 'left') { - // Halfway, Flicking, or Too Far Out - if ((cache.simpleStates.halfway || cache.simpleStates.hyperExtending || cache.simpleStates.flick)) { - if (cache.simpleStates.flick && cache.simpleStates.towards === 'left') { // Flicking Closed - action.translate.easeTo(0); - } else if ( - (cache.simpleStates.flick && cache.simpleStates.towards === 'right') || // Flicking Open OR - (cache.simpleStates.halfway || cache.simpleStates.hyperExtending) // At least halfway open OR hyperextending - ) { - action.translate.easeTo(settings.maxPosition); // Open Left - } - } else { - action.translate.easeTo(0); // Close Left - } - // Revealing Right - } else if (cache.simpleStates.opening === 'right') { - // Halfway, Flicking, or Too Far Out - if ((cache.simpleStates.halfway || cache.simpleStates.hyperExtending || cache.simpleStates.flick)) { - if (cache.simpleStates.flick && cache.simpleStates.towards === 'right') { // Flicking Closed - action.translate.easeTo(0); - } else if ( - (cache.simpleStates.flick && cache.simpleStates.towards === 'left') || // Flicking Open OR - (cache.simpleStates.halfway || cache.simpleStates.hyperExtending) // At least halfway open OR hyperextending - ) { - action.translate.easeTo(settings.minPosition); // Open Right - } - } else { - action.translate.easeTo(0); // Close Right - } - } - cache.isDragging = false; - cache.startDragX = utils.page('X', e); - } - } - } - }; - - - // Initialize - if (opts.element) { - utils.extend(settings, opts); - cache.vendor = utils.vendor(); - cache.canTransform = utils.canTransform(); - action.drag.listen(); - } - }; - - - utils.extend(Core.prototype, { - - /** - * Opens the specified side menu - * @param {String} side Must be "left" or "right" - */ - open: function(side, cb) { - utils.dispatchEvent('open'); - utils.klass.remove(doc.body, 'snapjs-expand-left'); - utils.klass.remove(doc.body, 'snapjs-expand-right'); - - if (side === 'left') { - this.cache.simpleStates.opening = 'left'; - this.cache.simpleStates.towards = 'right'; - utils.klass.add(doc.body, 'snapjs-left'); - utils.klass.remove(doc.body, 'snapjs-right'); - this.action.translate.easeTo(this.settings.maxPosition, cb); - } else if (side === 'right') { - this.cache.simpleStates.opening = 'right'; - this.cache.simpleStates.towards = 'left'; - utils.klass.remove(doc.body, 'snapjs-left'); - utils.klass.add(doc.body, 'snapjs-right'); - this.action.translate.easeTo(this.settings.minPosition, cb); - } - }, - - /** - * Closes the pane - */ - close: function(cb) { - utils.dispatchEvent('close'); - this.action.translate.easeTo(0, cb); - }, - - /** - * Hides the content pane completely allowing for full menu visibility - * @param {String} side Must be "left" or "right" - */ - expand: function(side){ - var to = win.innerWidth || doc.documentElement.clientWidth; - - if(side==='left'){ - utils.dispatchEvent('expandLeft'); - utils.klass.add(doc.body, 'snapjs-expand-left'); - utils.klass.remove(doc.body, 'snapjs-expand-right'); - } else { - utils.dispatchEvent('expandRight'); - utils.klass.add(doc.body, 'snapjs-expand-right'); - utils.klass.remove(doc.body, 'snapjs-expand-left'); - to *= -1; - } - this.action.translate.easeTo(to); - }, - - /** - * Listen in to custom Snap events - * @param {String} evt The snap event name - * @param {Function} fn Callback function - * @return {Object} Snap instance - */ - on: function(evt, fn) { - this.eventList[evt] = fn; - return this; - }, - - /** - * Stops listening to custom Snap events - * @param {String} evt The snap event name - */ - off: function(evt) { - if (this.eventList[evt]) { - this.eventList[evt] = false; - } - }, - - /** - * Enables Snap.js events - */ - enable: function() { - utils.dispatchEvent('enable'); - this.action.drag.listen(); - }, - - /** - * Disables Snap.js events - */ - disable: function() { - utils.dispatchEvent('disable'); - this.action.drag.stopListening(); - }, - - /** - * Updates the instances settings - * @param {Object} opts The Snap options to set - */ - settings: function(opts){ - utils.extend(this.settings, opts); - }, - - /** - * Returns information about the state of the content pane - * @return {Object} Information regarding the state of the pane - */ - state: function() { - var state, - fromLeft = this.action.translate.get.matrix(4); - if (fromLeft === this.settings.maxPosition) { - state = 'left'; - } else if (fromLeft === this.settings.minPosition) { - state = 'right'; - } else { - state = 'closed'; - } - return { - state: state, - info: this.cache.simpleStates - }; - } - }); - - // Assign to the global namespace - this[Namespace] = Core; - -}).call(this, window, document); diff --git a/core/l10n/cs_CZ.js b/core/l10n/cs_CZ.js index c9aed4a7c45..e858dede737 100644 --- a/core/l10n/cs_CZ.js +++ b/core/l10n/cs_CZ.js @@ -35,12 +35,12 @@ OC.L10N.register( "December" : "Prosinec", "Settings" : "Nastavení", "Saving..." : "Ukládám...", - "Couldn't send reset email. Please contact your administrator." : "Nepodařilo se odeslat email pro změnu hesla. Kontaktujte vašeho administrátora.", - "The link to reset your password has been sent to your email. If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator." : "Odkaz na obnovení hesla byl odeslán na vaši e-mailovou adresu. Pokud jej v krátké době neobdržíte, zkontrolujte složku nevyžádané pošty a koš.<br>Pokud jej nenaleznete, kontaktujte svého administrátora.", - "Your files are encrypted. If you haven't enabled the recovery key, there will be no way to get your data back after your password is reset.<br />If you are not sure what to do, please contact your administrator before you continue. <br />Do you really want to continue?" : "Vaše soubory jsou šifrovány. Pokud jste nepovolili klíč pro obnovení, neexistuje způsob jak získat po změně hesla vaše data.<br />Pokud si nejste jisti co dělat, kontaktujte nejprve svého administrátora než budete pokračovat. <br />Opravdu si přejete pokračovat?", + "Couldn't send reset email. Please contact your administrator." : "Nepodařilo se odeslat email pro změnu hesla. Kontaktujte svého správce systému.", + "The link to reset your password has been sent to your email. If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator." : "Odkaz na obnovení hesla byl odeslán na vaši e-mailovou adresu. Pokud jej v krátké době neobdržíte, zkontrolujte složku nevyžádané pošty a koš.<br>Pokud jej nenaleznete, kontaktujte svého správce systému.", + "Your files are encrypted. If you haven't enabled the recovery key, there will be no way to get your data back after your password is reset.<br />If you are not sure what to do, please contact your administrator before you continue. <br />Do you really want to continue?" : "Vaše soubory jsou šifrovány. Pokud jste nepovolili klíč pro obnovení, neexistuje způsob jak získat po změně hesla vaše data zpět.<br />Pokud si nejste jisti co dělat, kontaktujte nejprve svého správce systému, než budete pokračovat. <br />Opravdu si přejete pokračovat?", "I know what I'm doing" : "Vím co dělám", "Reset password" : "Obnovit heslo", - "Password can not be changed. Please contact your administrator." : "Heslo nelze změnit. Kontaktujte prosím svého administrátora.", + "Password can not be changed. Please contact your administrator." : "Heslo nelze změnit. Kontaktujte prosím svého správce systému.", "No" : "Ne", "Yes" : "Ano", "Choose" : "Vybrat", @@ -121,7 +121,7 @@ OC.L10N.register( "The update was successful. Redirecting you to ownCloud now." : "Aktualizace byla úspěšná. Přesměrovávám na ownCloud.", "Couldn't reset password because the token is invalid" : "Heslo nebylo změněno kvůli neplatnému tokenu", "Couldn't send reset email. Please make sure your username is correct." : "Nelze odeslat email pro změnu hesla. Ujistěte se prosím, že zadáváte správné uživatelské jméno.", - "Couldn't send reset email because there is no email address for this username. Please contact your administrator." : "Nelze odeslat email pro změnu hesla, protože u tohoto uživatelského jména není uvedena e-mailová adresa. Kontaktujte prosím svého administrátora.", + "Couldn't send reset email because there is no email address for this username. Please contact your administrator." : "Nelze odeslat email pro změnu hesla, protože u tohoto uživatelského jména není uvedena e-mailová adresa. Kontaktujte prosím svého správce systému.", "%s password reset" : "reset hesla %s", "Use the following link to reset your password: {link}" : "Heslo obnovíte použitím následujícího odkazu: {link}", "You will receive a link to reset your password via Email." : "E-mailem Vám bude zaslán odkaz pro obnovu hesla.", @@ -154,7 +154,7 @@ OC.L10N.register( "Cheers!" : "Ať slouží!", "Internal Server Error" : "Vnitřní chyba serveru", "The server encountered an internal error and was unable to complete your request." : "Server zaznamenal interní chybu a nebyl schopen dokončit váš požadavek.", - "Please contact the server administrator if this error reappears multiple times, please include the technical details below in your report." : "Kontaktujte prosím administrátora serveru, pokud se bude tato chyba opakovat. Připojte do svého hlášení níže zobrazené technické detaily.", + "Please contact the server administrator if this error reappears multiple times, please include the technical details below in your report." : "Kontaktujte prosím správce serveru, pokud se bude tato chyba opakovat. Připojte do svého hlášení níže zobrazené technické detaily.", "More details can be found in the server log." : "Více podrobností k nalezení v serverovém logu.", "Technical details" : "Technické detaily", "Remote Address: %s" : "Vzdálená adresa: %s", @@ -195,11 +195,11 @@ OC.L10N.register( "Hey there,<br><br>just letting you know that %s shared <strong>%s</strong> with you.<br><a href=\"%s\">View it!</a><br><br>" : "Hej ty,<br><br>jen ti dávám vědět, že %s sdílí <strong>%s</strong> s tebou.<br><a href=\"%s\">Zobrazit!</a><br><br>", "This ownCloud instance is currently in single user mode." : "Tato instalace ownCloudu je momentálně v jednouživatelském módu.", "This means only administrators can use the instance." : "To znamená, že pouze správci systému mohou aplikaci používat.", - "Contact your system administrator if this message persists or appeared unexpectedly." : "Kontaktujte, prosím, správce systému, pokud se tato zpráva objevuje opakovaně nebo nečekaně.", - "Thank you for your patience." : "Děkuji za trpělivost.", + "Contact your system administrator if this message persists or appeared unexpectedly." : "Kontaktujte prosím správce systému, pokud se tato zpráva objevuje opakovaně nebo nečekaně.", + "Thank you for your patience." : "Děkujeme za vaši trpělivost.", "You are accessing the server from an untrusted domain." : "Přistupujete na server z nedůvěryhodné domény.", "Please contact your administrator. If you are an administrator of this instance, configure the \"trusted_domain\" setting in config/config.php. An example configuration is provided in config/config.sample.php." : "Kontaktujte prosím správce. Pokud jste správce této instalace, nastavte \"trusted_domain\" v souboru config/config.php. Příklad konfigurace najdete v souboru config/config.sample.php.", - "Depending on your configuration, as an administrator you might also be able to use the button below to trust this domain." : "V závislosti na vaší konfiguraci vám může být, jako administrátorovi, umožněno použití tlačítka níže k označení této domény jako důvěryhodné.", + "Depending on your configuration, as an administrator you might also be able to use the button below to trust this domain." : "V závislosti na vaší konfiguraci vám může být, jako správci, umožněno použití tlačítka níže k označení této domény jako důvěryhodné.", "Add \"%s\" as trusted domain" : "Přidat \"%s\" jako důvěryhodnou doménu", "%s will be updated to version %s." : "%s bude aktualizován na verzi %s.", "The following apps will be disabled:" : "Následující aplikace budou zakázány:", @@ -207,7 +207,7 @@ OC.L10N.register( "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Před provedením dalšího kroku se prosím ujistěte, že databáze a konfigurační a datový adresář byly zazálohovány. ", "Start update" : "Spustit aktualizaci", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Abyste zabránili vypršení časového limitu u větších instalací, můžete namísto toho spustit následující příkaz v hlavním adresáři:", - "This %s instance is currently being updated, which may take a while." : "Tato instalace %s je právě aktualizována a to může chvíli trvat.", + "This %s instance is currently being updated, which may take a while." : "Tato instalace %s je právě aktualizována. Mějte chvíli strpení.", "This page will refresh itself when the %s instance is available again." : "Tato stránka se automaticky načte poté, co bude opět dostupná instance %s." }, "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"); diff --git a/core/l10n/cs_CZ.json b/core/l10n/cs_CZ.json index 67250ae52e7..7d0b3ada708 100644 --- a/core/l10n/cs_CZ.json +++ b/core/l10n/cs_CZ.json @@ -33,12 +33,12 @@ "December" : "Prosinec", "Settings" : "Nastavení", "Saving..." : "Ukládám...", - "Couldn't send reset email. Please contact your administrator." : "Nepodařilo se odeslat email pro změnu hesla. Kontaktujte vašeho administrátora.", - "The link to reset your password has been sent to your email. If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator." : "Odkaz na obnovení hesla byl odeslán na vaši e-mailovou adresu. Pokud jej v krátké době neobdržíte, zkontrolujte složku nevyžádané pošty a koš.<br>Pokud jej nenaleznete, kontaktujte svého administrátora.", - "Your files are encrypted. If you haven't enabled the recovery key, there will be no way to get your data back after your password is reset.<br />If you are not sure what to do, please contact your administrator before you continue. <br />Do you really want to continue?" : "Vaše soubory jsou šifrovány. Pokud jste nepovolili klíč pro obnovení, neexistuje způsob jak získat po změně hesla vaše data.<br />Pokud si nejste jisti co dělat, kontaktujte nejprve svého administrátora než budete pokračovat. <br />Opravdu si přejete pokračovat?", + "Couldn't send reset email. Please contact your administrator." : "Nepodařilo se odeslat email pro změnu hesla. Kontaktujte svého správce systému.", + "The link to reset your password has been sent to your email. If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator." : "Odkaz na obnovení hesla byl odeslán na vaši e-mailovou adresu. Pokud jej v krátké době neobdržíte, zkontrolujte složku nevyžádané pošty a koš.<br>Pokud jej nenaleznete, kontaktujte svého správce systému.", + "Your files are encrypted. If you haven't enabled the recovery key, there will be no way to get your data back after your password is reset.<br />If you are not sure what to do, please contact your administrator before you continue. <br />Do you really want to continue?" : "Vaše soubory jsou šifrovány. Pokud jste nepovolili klíč pro obnovení, neexistuje způsob jak získat po změně hesla vaše data zpět.<br />Pokud si nejste jisti co dělat, kontaktujte nejprve svého správce systému, než budete pokračovat. <br />Opravdu si přejete pokračovat?", "I know what I'm doing" : "Vím co dělám", "Reset password" : "Obnovit heslo", - "Password can not be changed. Please contact your administrator." : "Heslo nelze změnit. Kontaktujte prosím svého administrátora.", + "Password can not be changed. Please contact your administrator." : "Heslo nelze změnit. Kontaktujte prosím svého správce systému.", "No" : "Ne", "Yes" : "Ano", "Choose" : "Vybrat", @@ -119,7 +119,7 @@ "The update was successful. Redirecting you to ownCloud now." : "Aktualizace byla úspěšná. Přesměrovávám na ownCloud.", "Couldn't reset password because the token is invalid" : "Heslo nebylo změněno kvůli neplatnému tokenu", "Couldn't send reset email. Please make sure your username is correct." : "Nelze odeslat email pro změnu hesla. Ujistěte se prosím, že zadáváte správné uživatelské jméno.", - "Couldn't send reset email because there is no email address for this username. Please contact your administrator." : "Nelze odeslat email pro změnu hesla, protože u tohoto uživatelského jména není uvedena e-mailová adresa. Kontaktujte prosím svého administrátora.", + "Couldn't send reset email because there is no email address for this username. Please contact your administrator." : "Nelze odeslat email pro změnu hesla, protože u tohoto uživatelského jména není uvedena e-mailová adresa. Kontaktujte prosím svého správce systému.", "%s password reset" : "reset hesla %s", "Use the following link to reset your password: {link}" : "Heslo obnovíte použitím následujícího odkazu: {link}", "You will receive a link to reset your password via Email." : "E-mailem Vám bude zaslán odkaz pro obnovu hesla.", @@ -152,7 +152,7 @@ "Cheers!" : "Ať slouží!", "Internal Server Error" : "Vnitřní chyba serveru", "The server encountered an internal error and was unable to complete your request." : "Server zaznamenal interní chybu a nebyl schopen dokončit váš požadavek.", - "Please contact the server administrator if this error reappears multiple times, please include the technical details below in your report." : "Kontaktujte prosím administrátora serveru, pokud se bude tato chyba opakovat. Připojte do svého hlášení níže zobrazené technické detaily.", + "Please contact the server administrator if this error reappears multiple times, please include the technical details below in your report." : "Kontaktujte prosím správce serveru, pokud se bude tato chyba opakovat. Připojte do svého hlášení níže zobrazené technické detaily.", "More details can be found in the server log." : "Více podrobností k nalezení v serverovém logu.", "Technical details" : "Technické detaily", "Remote Address: %s" : "Vzdálená adresa: %s", @@ -193,11 +193,11 @@ "Hey there,<br><br>just letting you know that %s shared <strong>%s</strong> with you.<br><a href=\"%s\">View it!</a><br><br>" : "Hej ty,<br><br>jen ti dávám vědět, že %s sdílí <strong>%s</strong> s tebou.<br><a href=\"%s\">Zobrazit!</a><br><br>", "This ownCloud instance is currently in single user mode." : "Tato instalace ownCloudu je momentálně v jednouživatelském módu.", "This means only administrators can use the instance." : "To znamená, že pouze správci systému mohou aplikaci používat.", - "Contact your system administrator if this message persists or appeared unexpectedly." : "Kontaktujte, prosím, správce systému, pokud se tato zpráva objevuje opakovaně nebo nečekaně.", - "Thank you for your patience." : "Děkuji za trpělivost.", + "Contact your system administrator if this message persists or appeared unexpectedly." : "Kontaktujte prosím správce systému, pokud se tato zpráva objevuje opakovaně nebo nečekaně.", + "Thank you for your patience." : "Děkujeme za vaši trpělivost.", "You are accessing the server from an untrusted domain." : "Přistupujete na server z nedůvěryhodné domény.", "Please contact your administrator. If you are an administrator of this instance, configure the \"trusted_domain\" setting in config/config.php. An example configuration is provided in config/config.sample.php." : "Kontaktujte prosím správce. Pokud jste správce této instalace, nastavte \"trusted_domain\" v souboru config/config.php. Příklad konfigurace najdete v souboru config/config.sample.php.", - "Depending on your configuration, as an administrator you might also be able to use the button below to trust this domain." : "V závislosti na vaší konfiguraci vám může být, jako administrátorovi, umožněno použití tlačítka níže k označení této domény jako důvěryhodné.", + "Depending on your configuration, as an administrator you might also be able to use the button below to trust this domain." : "V závislosti na vaší konfiguraci vám může být, jako správci, umožněno použití tlačítka níže k označení této domény jako důvěryhodné.", "Add \"%s\" as trusted domain" : "Přidat \"%s\" jako důvěryhodnou doménu", "%s will be updated to version %s." : "%s bude aktualizován na verzi %s.", "The following apps will be disabled:" : "Následující aplikace budou zakázány:", @@ -205,7 +205,7 @@ "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Před provedením dalšího kroku se prosím ujistěte, že databáze a konfigurační a datový adresář byly zazálohovány. ", "Start update" : "Spustit aktualizaci", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Abyste zabránili vypršení časového limitu u větších instalací, můžete namísto toho spustit následující příkaz v hlavním adresáři:", - "This %s instance is currently being updated, which may take a while." : "Tato instalace %s je právě aktualizována a to může chvíli trvat.", + "This %s instance is currently being updated, which may take a while." : "Tato instalace %s je právě aktualizována. Mějte chvíli strpení.", "This page will refresh itself when the %s instance is available again." : "Tato stránka se automaticky načte poté, co bude opět dostupná instance %s." },"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;" }
\ No newline at end of file diff --git a/core/l10n/en_GB.js b/core/l10n/en_GB.js index dd27b6c114d..0c80072e67d 100644 --- a/core/l10n/en_GB.js +++ b/core/l10n/en_GB.js @@ -64,7 +64,7 @@ OC.L10N.register( "Good password" : "Good password", "Strong password" : "Strong password", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." : "Your web server is not yet properly setup to allow files synchronisation because the WebDAV interface seems to be broken.", - "This server has no working internet connection. This means that some of the features like mounting of external storage, notifications about updates or installation of 3rd party apps don´t work. Accessing files from remote and sending of notification emails might also not work. We suggest to enable internet connection for this server if you want to have all features." : "This server has no working internet connection. This means that some of the features like mounting of external storage, notifications about updates or installation of 3rd party apps don't work. Accessing files from remote and sending of notification emails might also not work. We suggest to enable internet connection for this server if you want to have all features.", + "This server has no working internet connection. This means that some of the features like mounting of external storage, notifications about updates or installation of 3rd party apps don´t work. Accessing files from remote and sending of notification emails might also not work. We suggest to enable internet connection for this server if you want to have all features." : "This server has no working internet connection. This means that some of the features such as mounting external storage, notifications about updates, or installation of 3rd party apps won't work. Accessing files remotely and sending notification emails might also not work. We suggest enabling an internet connection for this server if you want to have all the features.", "Error occurred while checking server setup" : "Error occurred whilst checking server setup", "Shared" : "Shared", "Shared with {recipients}" : "Shared with {recipients}", diff --git a/core/l10n/en_GB.json b/core/l10n/en_GB.json index b1f6556f900..4a20f00dd6a 100644 --- a/core/l10n/en_GB.json +++ b/core/l10n/en_GB.json @@ -62,7 +62,7 @@ "Good password" : "Good password", "Strong password" : "Strong password", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." : "Your web server is not yet properly setup to allow files synchronisation because the WebDAV interface seems to be broken.", - "This server has no working internet connection. This means that some of the features like mounting of external storage, notifications about updates or installation of 3rd party apps don´t work. Accessing files from remote and sending of notification emails might also not work. We suggest to enable internet connection for this server if you want to have all features." : "This server has no working internet connection. This means that some of the features like mounting of external storage, notifications about updates or installation of 3rd party apps don't work. Accessing files from remote and sending of notification emails might also not work. We suggest to enable internet connection for this server if you want to have all features.", + "This server has no working internet connection. This means that some of the features like mounting of external storage, notifications about updates or installation of 3rd party apps don´t work. Accessing files from remote and sending of notification emails might also not work. We suggest to enable internet connection for this server if you want to have all features." : "This server has no working internet connection. This means that some of the features such as mounting external storage, notifications about updates, or installation of 3rd party apps won't work. Accessing files remotely and sending notification emails might also not work. We suggest enabling an internet connection for this server if you want to have all the features.", "Error occurred while checking server setup" : "Error occurred whilst checking server setup", "Shared" : "Shared", "Shared with {recipients}" : "Shared with {recipients}", diff --git a/core/l10n/fr.js b/core/l10n/fr.js index 7be2663e412..0ff630f70ba 100644 --- a/core/l10n/fr.js +++ b/core/l10n/fr.js @@ -6,7 +6,7 @@ OC.L10N.register( "Turned off maintenance mode" : "Mode de maintenance désactivé", "Updated database" : "Base de données mise à jour", "Checked database schema update" : "Mise à jour du schéma de la base de données vérifiée", - "Checked database schema update for apps" : "La mise à jour du schéma de la base de données pour les applications a été vérifiée", + "Checked database schema update for apps" : "Mise à jour du schéma de la base de données pour les applications vérifiée", "Updated \"%s\" to %s" : "Mise à jour de « %s » vers %s", "Disabled incompatible apps: %s" : "Applications incompatibles désactivées : %s", "No image or file provided" : "Aucun fichier fourni", diff --git a/core/l10n/fr.json b/core/l10n/fr.json index 591eabdcecb..0fed5b79ab7 100644 --- a/core/l10n/fr.json +++ b/core/l10n/fr.json @@ -4,7 +4,7 @@ "Turned off maintenance mode" : "Mode de maintenance désactivé", "Updated database" : "Base de données mise à jour", "Checked database schema update" : "Mise à jour du schéma de la base de données vérifiée", - "Checked database schema update for apps" : "La mise à jour du schéma de la base de données pour les applications a été vérifiée", + "Checked database schema update for apps" : "Mise à jour du schéma de la base de données pour les applications vérifiée", "Updated \"%s\" to %s" : "Mise à jour de « %s » vers %s", "Disabled incompatible apps: %s" : "Applications incompatibles désactivées : %s", "No image or file provided" : "Aucun fichier fourni", diff --git a/core/l10n/pt_PT.js b/core/l10n/pt_PT.js index bc84fc7bbd9..f304226c321 100644 --- a/core/l10n/pt_PT.js +++ b/core/l10n/pt_PT.js @@ -1,19 +1,19 @@ OC.L10N.register( "core", { - "Couldn't send mail to following users: %s " : "Não conseguiu enviar correio aos seguintes utilizadores: %s", - "Turned on maintenance mode" : "Activado o modo de manutenção", - "Turned off maintenance mode" : "Desactivado o modo de manutenção", - "Updated database" : "Base de dados actualizada", + "Couldn't send mail to following users: %s " : "Não foi possível enviar o correio para os seguintes utilizadores: %s", + "Turned on maintenance mode" : "Ativado o modo de manutenção", + "Turned off maintenance mode" : "Desativado o modo de manutenção", + "Updated database" : "Base de dados atualizada", "Checked database schema update" : "Atualização do esquema da base de dados verificada.", "Checked database schema update for apps" : "Atualização do esquema da base de dados verificada.", - "Updated \"%s\" to %s" : "Actualizado \"%s\" para %s", + "Updated \"%s\" to %s" : "Atualizado \"%s\" para %s", "Disabled incompatible apps: %s" : "Apps incompatíveis desativadas: %s", - "No image or file provided" : "Não foi selecionado nenhum ficheiro para importar", - "Unknown filetype" : "Ficheiro desconhecido", + "No image or file provided" : "Não foi fornecido nenhum ficheiro ou imagem", + "Unknown filetype" : "Tipo de ficheiro desconhecido", "Invalid image" : "Imagem inválida", - "No temporary profile picture available, try again" : "Foto temporária de perfil indisponível, tente novamente", - "No crop data provided" : "Sem dados de corte fornecidos", + "No temporary profile picture available, try again" : "Fotografia temporária do perfil indisponível, tente novamente", + "No crop data provided" : "Não foram fornecidos dados de recorte", "Sunday" : "Domingo", "Monday" : "Segunda", "Tuesday" : "Terça", @@ -34,13 +34,13 @@ OC.L10N.register( "November" : "Novembro", "December" : "Dezembro", "Settings" : "Configurações", - "Saving..." : "A guardar...", - "Couldn't send reset email. Please contact your administrator." : "Ocorreu um problema com o envio do e-mail, por favor contactar o administrador.", + "Saving..." : "A guardar ...", + "Couldn't send reset email. Please contact your administrator." : "Não foi possível enviar o e-mail de reposição. Por favor, contacte o administrador.", "The link to reset your password has been sent to your email. If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator." : "O link para fazer reset à sua password foi enviado para o seu e-mail. <br> Se não o recebeu dentro um espaço de tempo aceitável, por favor verifique a sua pasta de SPAM.<br> Se não o encontrar, por favor contacte o seu administrador.", "Your files are encrypted. If you haven't enabled the recovery key, there will be no way to get your data back after your password is reset.<br />If you are not sure what to do, please contact your administrator before you continue. <br />Do you really want to continue?" : "Os seus ficheiros estão encriptados. Se não activou a chave de recuperação, não vai ser possível recuperar os seus dados no caso da sua password ser reinicializada. Se não tem a certeza do que precisa de fazer, por favor contacte o seu administrador antes de continuar. Tem a certeza que quer continuar?", - "I know what I'm doing" : "Tenho a certeza", - "Reset password" : "Repor password", - "Password can not be changed. Please contact your administrator." : "A password não pode ser alterada. Contacte o seu administrador.", + "I know what I'm doing" : "Eu sei o que Eu estou a fazer", + "Reset password" : "Repor palavra-passe", + "Password can not be changed. Please contact your administrator." : "A palavra-passe não pode ser alterada. Por favor, contacte o seu administrador.", "No" : "Não", "Yes" : "Sim", "Choose" : "Escolha", @@ -58,11 +58,11 @@ OC.L10N.register( "(all selected)" : "(todos seleccionados)", "({count} selected)" : "({count} seleccionados)", "Error loading file exists template" : "Erro ao carregar o modelo de existências do ficheiro", - "Very weak password" : "Password muito fraca", - "Weak password" : "Password fraca", - "So-so password" : "Password aceitável", - "Good password" : "Password Forte", - "Strong password" : "Password muito forte", + "Very weak password" : "Palavra-passe muito fraca", + "Weak password" : "Palavra-passe fraca", + "So-so password" : "Palavra-passe aceitável", + "Good password" : "Palavra-passe boa", + "Strong password" : "Palavra-passe forte", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." : "O seu servidor web não está configurado correctamente para autorizar sincronização de ficheiros, pois o interface WebDAV parece estar com problemas.", "This server has no working internet connection. This means that some of the features like mounting of external storage, notifications about updates or installation of 3rd party apps don´t work. Accessing files from remote and sending of notification emails might also not work. We suggest to enable internet connection for this server if you want to have all features." : "Este servidor ownCloud não tem uma ligação de internet a funcionar. Isto significa que algumas funcionalidades como o acesso a locais externos (dropbox, gdrive, etc), notificações sobre actualizções, ou a instalação de aplicações não irá funcionar. Sugerimos que active uma ligação à internet se pretender obter todas as funcionalidades do ownCloud.", "Error occurred while checking server setup" : "Ocorreu um erro durante a verificação da configuração do servidor", @@ -78,8 +78,8 @@ OC.L10N.register( "Share with user or group …" : "Partilhar com utilizador ou grupo...", "Share link" : "Partilhar o link", "The public link will expire no later than {days} days after it is created" : "O link público expira, o mais tardar {days} dias após sua criação", - "Password protect" : "Proteger com palavra-passe", - "Choose a password for the public link" : "Defina a palavra-passe para o link público", + "Password protect" : "Proteger com Palavra-passe", + "Choose a password for the public link" : "Defina a palavra-passe para a hiperligação pública", "Allow Public Upload" : "Permitir Envios Públicos", "Email link to person" : "Enviar o link por e-mail", "Send" : "Enviar", @@ -97,7 +97,7 @@ OC.L10N.register( "create" : "criar", "update" : "actualizar", "delete" : "apagar", - "Password protected" : "Protegido com palavra-passe", + "Password protected" : "Protegido com Palavra-passe", "Error unsetting expiration date" : "Erro ao retirar a data de expiração", "Error setting expiration date" : "Erro ao aplicar a data de expiração", "Sending ..." : "A Enviar...", @@ -119,18 +119,18 @@ OC.L10N.register( "Please reload the page." : "Por favor recarregue a página.", "The update was unsuccessful." : "Não foi possível atualizar.", "The update was successful. Redirecting you to ownCloud now." : "A actualização foi concluída com sucesso. Vai ser redireccionado para o ownCloud agora.", - "Couldn't reset password because the token is invalid" : "É impossível efetuar reset à password. ", + "Couldn't reset password because the token is invalid" : "Não foi possível repor a palavra-passe porque a senha é inválida", "Couldn't send reset email. Please make sure your username is correct." : "Ocorreu um problema com o envio do e-mail, por favor confirme o seu utilizador.", "Couldn't send reset email because there is no email address for this username. Please contact your administrator." : "Ocorreu um problema com o envio do e-mail, por favor contacte o administrador.", - "%s password reset" : "%s reposição da password", - "Use the following link to reset your password: {link}" : "Use o seguinte endereço para repor a sua password: {link}", - "You will receive a link to reset your password via Email." : "Vai receber um endereço para repor a sua password", + "%s password reset" : "%s reposição da palavra-passe", + "Use the following link to reset your password: {link}" : "Utilize a seguinte hiperligação para repor a sua palavra-passe: {link}", + "You will receive a link to reset your password via Email." : "Vai receber uma hiperligação via e-mail para repor a sua palavra-passe", "Username" : "Nome de utilizador", "Your files are encrypted. If you haven't enabled the recovery key, there will be no way to get your data back after your password is reset. If you are not sure what to do, please contact your administrator before you continue. Do you really want to continue?" : "Os seus ficheiros estão encriptados. Se não activou a chave de recuperação, não vai ser possível recuperar os seus dados no caso da sua password ser reinicializada. Se não tem a certeza do que precisa de fazer, por favor contacte o seu administrador antes de continuar. Tem a certeza que quer continuar?", - "Yes, I really want to reset my password now" : "Sim, tenho a certeza que pretendo redefinir a minha palavra-passe agora.", + "Yes, I really want to reset my password now" : "Sim, eu tenho a certeza que pretendo redefinir agora a minha palavra-passe.", "Reset" : "Repor", "New password" : "Nova palavra-chave", - "New Password" : "Nova password", + "New Password" : "Nova palavra-passe", "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " : "Esta plataforma não suporta o sistema operativo Mac OS X e o %s poderá não funcionar correctamente. Utilize por sua conta e risco.", "For the best results, please consider using a GNU/Linux server instead." : "Para um melhor resultado, utilize antes o servidor GNU/Linux.", "Personal" : "Pessoal", @@ -170,13 +170,13 @@ OC.L10N.register( "Your data directory and files are probably accessible from the internet because the .htaccess file does not work." : "A pasta de dados do ownCloud e os respectivos ficheiros, estarão provavelmente acessíveis a partir da internet, pois o ficheiros .htaccess não funciona.", "For information how to properly configure your server, please see the <a href=\"%s\" target=\"_blank\">documentation</a>." : "Para obter informações de como configurar correctamente o servidor, veja em: <a href=\"%s\" target=\"_blank\">documentação</a>.", "Create an <strong>admin account</strong>" : "Criar uma <strong>conta administrativa</strong>", - "Password" : "Password", + "Password" : "Palavra-passe", "Storage & database" : "Armazenamento e base de dados", "Data folder" : "Pasta de dados", "Configure the database" : "Configure a base de dados", "Only %s is available." : "Apenas %s está disponível.", "Database user" : "Utilizador da base de dados", - "Database password" : "Password da base de dados", + "Database password" : "Palavra-passe da base de dados", "Database name" : "Nome da base de dados", "Database tablespace" : "Tablespace da base de dados", "Database host" : "Anfitrião da base de dados", @@ -188,7 +188,7 @@ OC.L10N.register( "Log out" : "Sair", "Server side authentication failed!" : "Autenticação do lado do servidor falhou!", "Please contact your administrator." : "Por favor contacte o administrador.", - "Forgot your password? Reset it!" : "Esqueceu-se da password? Recupere-a!", + "Forgot your password? Reset it!" : "Esqueceu-se da sua palavra-passe? Recupere-a!", "remember" : "lembrar", "Log in" : "Entrar", "Alternative Logins" : "Contas de acesso alternativas", diff --git a/core/l10n/pt_PT.json b/core/l10n/pt_PT.json index f61e3c076d0..70586658f8a 100644 --- a/core/l10n/pt_PT.json +++ b/core/l10n/pt_PT.json @@ -1,17 +1,17 @@ { "translations": { - "Couldn't send mail to following users: %s " : "Não conseguiu enviar correio aos seguintes utilizadores: %s", - "Turned on maintenance mode" : "Activado o modo de manutenção", - "Turned off maintenance mode" : "Desactivado o modo de manutenção", - "Updated database" : "Base de dados actualizada", + "Couldn't send mail to following users: %s " : "Não foi possível enviar o correio para os seguintes utilizadores: %s", + "Turned on maintenance mode" : "Ativado o modo de manutenção", + "Turned off maintenance mode" : "Desativado o modo de manutenção", + "Updated database" : "Base de dados atualizada", "Checked database schema update" : "Atualização do esquema da base de dados verificada.", "Checked database schema update for apps" : "Atualização do esquema da base de dados verificada.", - "Updated \"%s\" to %s" : "Actualizado \"%s\" para %s", + "Updated \"%s\" to %s" : "Atualizado \"%s\" para %s", "Disabled incompatible apps: %s" : "Apps incompatíveis desativadas: %s", - "No image or file provided" : "Não foi selecionado nenhum ficheiro para importar", - "Unknown filetype" : "Ficheiro desconhecido", + "No image or file provided" : "Não foi fornecido nenhum ficheiro ou imagem", + "Unknown filetype" : "Tipo de ficheiro desconhecido", "Invalid image" : "Imagem inválida", - "No temporary profile picture available, try again" : "Foto temporária de perfil indisponível, tente novamente", - "No crop data provided" : "Sem dados de corte fornecidos", + "No temporary profile picture available, try again" : "Fotografia temporária do perfil indisponível, tente novamente", + "No crop data provided" : "Não foram fornecidos dados de recorte", "Sunday" : "Domingo", "Monday" : "Segunda", "Tuesday" : "Terça", @@ -32,13 +32,13 @@ "November" : "Novembro", "December" : "Dezembro", "Settings" : "Configurações", - "Saving..." : "A guardar...", - "Couldn't send reset email. Please contact your administrator." : "Ocorreu um problema com o envio do e-mail, por favor contactar o administrador.", + "Saving..." : "A guardar ...", + "Couldn't send reset email. Please contact your administrator." : "Não foi possível enviar o e-mail de reposição. Por favor, contacte o administrador.", "The link to reset your password has been sent to your email. If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator." : "O link para fazer reset à sua password foi enviado para o seu e-mail. <br> Se não o recebeu dentro um espaço de tempo aceitável, por favor verifique a sua pasta de SPAM.<br> Se não o encontrar, por favor contacte o seu administrador.", "Your files are encrypted. If you haven't enabled the recovery key, there will be no way to get your data back after your password is reset.<br />If you are not sure what to do, please contact your administrator before you continue. <br />Do you really want to continue?" : "Os seus ficheiros estão encriptados. Se não activou a chave de recuperação, não vai ser possível recuperar os seus dados no caso da sua password ser reinicializada. Se não tem a certeza do que precisa de fazer, por favor contacte o seu administrador antes de continuar. Tem a certeza que quer continuar?", - "I know what I'm doing" : "Tenho a certeza", - "Reset password" : "Repor password", - "Password can not be changed. Please contact your administrator." : "A password não pode ser alterada. Contacte o seu administrador.", + "I know what I'm doing" : "Eu sei o que Eu estou a fazer", + "Reset password" : "Repor palavra-passe", + "Password can not be changed. Please contact your administrator." : "A palavra-passe não pode ser alterada. Por favor, contacte o seu administrador.", "No" : "Não", "Yes" : "Sim", "Choose" : "Escolha", @@ -56,11 +56,11 @@ "(all selected)" : "(todos seleccionados)", "({count} selected)" : "({count} seleccionados)", "Error loading file exists template" : "Erro ao carregar o modelo de existências do ficheiro", - "Very weak password" : "Password muito fraca", - "Weak password" : "Password fraca", - "So-so password" : "Password aceitável", - "Good password" : "Password Forte", - "Strong password" : "Password muito forte", + "Very weak password" : "Palavra-passe muito fraca", + "Weak password" : "Palavra-passe fraca", + "So-so password" : "Palavra-passe aceitável", + "Good password" : "Palavra-passe boa", + "Strong password" : "Palavra-passe forte", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." : "O seu servidor web não está configurado correctamente para autorizar sincronização de ficheiros, pois o interface WebDAV parece estar com problemas.", "This server has no working internet connection. This means that some of the features like mounting of external storage, notifications about updates or installation of 3rd party apps don´t work. Accessing files from remote and sending of notification emails might also not work. We suggest to enable internet connection for this server if you want to have all features." : "Este servidor ownCloud não tem uma ligação de internet a funcionar. Isto significa que algumas funcionalidades como o acesso a locais externos (dropbox, gdrive, etc), notificações sobre actualizções, ou a instalação de aplicações não irá funcionar. Sugerimos que active uma ligação à internet se pretender obter todas as funcionalidades do ownCloud.", "Error occurred while checking server setup" : "Ocorreu um erro durante a verificação da configuração do servidor", @@ -76,8 +76,8 @@ "Share with user or group …" : "Partilhar com utilizador ou grupo...", "Share link" : "Partilhar o link", "The public link will expire no later than {days} days after it is created" : "O link público expira, o mais tardar {days} dias após sua criação", - "Password protect" : "Proteger com palavra-passe", - "Choose a password for the public link" : "Defina a palavra-passe para o link público", + "Password protect" : "Proteger com Palavra-passe", + "Choose a password for the public link" : "Defina a palavra-passe para a hiperligação pública", "Allow Public Upload" : "Permitir Envios Públicos", "Email link to person" : "Enviar o link por e-mail", "Send" : "Enviar", @@ -95,7 +95,7 @@ "create" : "criar", "update" : "actualizar", "delete" : "apagar", - "Password protected" : "Protegido com palavra-passe", + "Password protected" : "Protegido com Palavra-passe", "Error unsetting expiration date" : "Erro ao retirar a data de expiração", "Error setting expiration date" : "Erro ao aplicar a data de expiração", "Sending ..." : "A Enviar...", @@ -117,18 +117,18 @@ "Please reload the page." : "Por favor recarregue a página.", "The update was unsuccessful." : "Não foi possível atualizar.", "The update was successful. Redirecting you to ownCloud now." : "A actualização foi concluída com sucesso. Vai ser redireccionado para o ownCloud agora.", - "Couldn't reset password because the token is invalid" : "É impossível efetuar reset à password. ", + "Couldn't reset password because the token is invalid" : "Não foi possível repor a palavra-passe porque a senha é inválida", "Couldn't send reset email. Please make sure your username is correct." : "Ocorreu um problema com o envio do e-mail, por favor confirme o seu utilizador.", "Couldn't send reset email because there is no email address for this username. Please contact your administrator." : "Ocorreu um problema com o envio do e-mail, por favor contacte o administrador.", - "%s password reset" : "%s reposição da password", - "Use the following link to reset your password: {link}" : "Use o seguinte endereço para repor a sua password: {link}", - "You will receive a link to reset your password via Email." : "Vai receber um endereço para repor a sua password", + "%s password reset" : "%s reposição da palavra-passe", + "Use the following link to reset your password: {link}" : "Utilize a seguinte hiperligação para repor a sua palavra-passe: {link}", + "You will receive a link to reset your password via Email." : "Vai receber uma hiperligação via e-mail para repor a sua palavra-passe", "Username" : "Nome de utilizador", "Your files are encrypted. If you haven't enabled the recovery key, there will be no way to get your data back after your password is reset. If you are not sure what to do, please contact your administrator before you continue. Do you really want to continue?" : "Os seus ficheiros estão encriptados. Se não activou a chave de recuperação, não vai ser possível recuperar os seus dados no caso da sua password ser reinicializada. Se não tem a certeza do que precisa de fazer, por favor contacte o seu administrador antes de continuar. Tem a certeza que quer continuar?", - "Yes, I really want to reset my password now" : "Sim, tenho a certeza que pretendo redefinir a minha palavra-passe agora.", + "Yes, I really want to reset my password now" : "Sim, eu tenho a certeza que pretendo redefinir agora a minha palavra-passe.", "Reset" : "Repor", "New password" : "Nova palavra-chave", - "New Password" : "Nova password", + "New Password" : "Nova palavra-passe", "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " : "Esta plataforma não suporta o sistema operativo Mac OS X e o %s poderá não funcionar correctamente. Utilize por sua conta e risco.", "For the best results, please consider using a GNU/Linux server instead." : "Para um melhor resultado, utilize antes o servidor GNU/Linux.", "Personal" : "Pessoal", @@ -168,13 +168,13 @@ "Your data directory and files are probably accessible from the internet because the .htaccess file does not work." : "A pasta de dados do ownCloud e os respectivos ficheiros, estarão provavelmente acessíveis a partir da internet, pois o ficheiros .htaccess não funciona.", "For information how to properly configure your server, please see the <a href=\"%s\" target=\"_blank\">documentation</a>." : "Para obter informações de como configurar correctamente o servidor, veja em: <a href=\"%s\" target=\"_blank\">documentação</a>.", "Create an <strong>admin account</strong>" : "Criar uma <strong>conta administrativa</strong>", - "Password" : "Password", + "Password" : "Palavra-passe", "Storage & database" : "Armazenamento e base de dados", "Data folder" : "Pasta de dados", "Configure the database" : "Configure a base de dados", "Only %s is available." : "Apenas %s está disponível.", "Database user" : "Utilizador da base de dados", - "Database password" : "Password da base de dados", + "Database password" : "Palavra-passe da base de dados", "Database name" : "Nome da base de dados", "Database tablespace" : "Tablespace da base de dados", "Database host" : "Anfitrião da base de dados", @@ -186,7 +186,7 @@ "Log out" : "Sair", "Server side authentication failed!" : "Autenticação do lado do servidor falhou!", "Please contact your administrator." : "Por favor contacte o administrador.", - "Forgot your password? Reset it!" : "Esqueceu-se da password? Recupere-a!", + "Forgot your password? Reset it!" : "Esqueceu-se da sua palavra-passe? Recupere-a!", "remember" : "lembrar", "Log in" : "Entrar", "Alternative Logins" : "Contas de acesso alternativas", diff --git a/core/l10n/uk.js b/core/l10n/uk.js index a4ce73653df..38f9d17e692 100644 --- a/core/l10n/uk.js +++ b/core/l10n/uk.js @@ -110,7 +110,11 @@ OC.L10N.register( "Edit tags" : "Редагувати теги", "Error loading dialog template: {error}" : "Помилка при завантаженні шаблону діалогу: {error}", "No tags selected for deletion." : "Жодних тегів не обрано для видалення.", - "_download %n file_::_download %n files_" : ["","",""], + "unknown text" : "невідомий текст", + "Hello world!" : "Привіт світ!", + "sunny" : "сонячно", + "Hello {name}, the weather is {weather}" : "Привіт {name}, {weather} погода", + "_download %n file_::_download %n files_" : ["завантяження %n файлу","завантаження %n файлів","завантаження %n файлів"], "Updating {productName} to version {version}, this may take a while." : "Оновлення {productName} до версії {version}, це може займати деякий час.", "Please reload the page." : "Будь ласка, перезавантажте сторінку.", "The update was unsuccessful." : "Оновлення завершилось невдачею.", diff --git a/core/l10n/uk.json b/core/l10n/uk.json index 885a797ee36..8ec13dedae7 100644 --- a/core/l10n/uk.json +++ b/core/l10n/uk.json @@ -108,7 +108,11 @@ "Edit tags" : "Редагувати теги", "Error loading dialog template: {error}" : "Помилка при завантаженні шаблону діалогу: {error}", "No tags selected for deletion." : "Жодних тегів не обрано для видалення.", - "_download %n file_::_download %n files_" : ["","",""], + "unknown text" : "невідомий текст", + "Hello world!" : "Привіт світ!", + "sunny" : "сонячно", + "Hello {name}, the weather is {weather}" : "Привіт {name}, {weather} погода", + "_download %n file_::_download %n files_" : ["завантяження %n файлу","завантаження %n файлів","завантаження %n файлів"], "Updating {productName} to version {version}, this may take a while." : "Оновлення {productName} до версії {version}, це може займати деякий час.", "Please reload the page." : "Будь ласка, перезавантажте сторінку.", "The update was unsuccessful." : "Оновлення завершилось невдачею.", diff --git a/core/lostpassword/controller/lostcontroller.php b/core/lostpassword/controller/lostcontroller.php index e4d51fde077..aee4001ed37 100644 --- a/core/lostpassword/controller/lostcontroller.php +++ b/core/lostpassword/controller/lostcontroller.php @@ -9,68 +9,73 @@ namespace OC\Core\LostPassword\Controller; use \OCP\AppFramework\Controller; -use \OCP\AppFramework\Http\JSONResponse; use \OCP\AppFramework\Http\TemplateResponse; use \OCP\IURLGenerator; use \OCP\IRequest; use \OCP\IL10N; use \OCP\IConfig; -use \OCP\IUserSession; -use \OC\Core\LostPassword\EncryptedDataException; +use OCP\IUserManager; +use OCP\Security\ISecureRandom; +use \OC_Defaults; +use OCP\Security\StringUtils; +/** + * Class LostController + * + * Successfully changing a password will emit the post_passwordReset hook. + * + * @package OC\Core\LostPassword\Controller + */ class LostController extends Controller { - /** - * @var \OCP\IURLGenerator - */ + /** @var IURLGenerator */ protected $urlGenerator; - - /** - * @var \OCP\IUserManager - */ + /** @var IUserManager */ protected $userManager; - - /** - * @var \OC_Defaults - */ + /** @var OC_Defaults */ protected $defaults; - - /** - * @var IL10N - */ + /** @var IL10N */ protected $l10n; + /** @var string */ protected $from; + /** @var bool */ protected $isDataEncrypted; - - /** - * @var IConfig - */ + /** @var IConfig */ protected $config; + /** @var ISecureRandom */ + protected $secureRandom; /** - * @var IUserSession + * @param string $appName + * @param IRequest $request + * @param IURLGenerator $urlGenerator + * @param IUserManager $userManager + * @param OC_Defaults $defaults + * @param IL10N $l10n + * @param IConfig $config + * @param ISecureRandom $secureRandom + * @param string $from + * @param string $isDataEncrypted */ - protected $userSession; - public function __construct($appName, - IRequest $request, - IURLGenerator $urlGenerator, - $userManager, - $defaults, - IL10N $l10n, - IConfig $config, - IUserSession $userSession, - $from, - $isDataEncrypted) { + IRequest $request, + IURLGenerator $urlGenerator, + IUserManager $userManager, + OC_Defaults $defaults, + IL10N $l10n, + IConfig $config, + ISecureRandom $secureRandom, + $from, + $isDataEncrypted) { parent::__construct($appName, $request); $this->urlGenerator = $urlGenerator; $this->userManager = $userManager; $this->defaults = $defaults; $this->l10n = $l10n; + $this->secureRandom = $secureRandom; $this->from = $from; $this->isDataEncrypted = $isDataEncrypted; $this->config = $config; - $this->userSession = $userSession; } /** @@ -81,23 +86,31 @@ class LostController extends Controller { * * @param string $token * @param string $userId + * @return TemplateResponse */ public function resetform($token, $userId) { return new TemplateResponse( 'core/lostpassword', 'resetpassword', array( - 'isEncrypted' => $this->isDataEncrypted, - 'link' => $this->getLink('core.lost.setPassword', $userId, $token), + 'link' => $this->urlGenerator->linkToRouteAbsolute('core.lost.setPassword', array('userId' => $userId, 'token' => $token)), ), 'guest' ); } + /** + * @param $message + * @param array $additional + * @return array + */ private function error($message, array $additional=array()) { return array_merge(array('status' => 'error', 'msg' => $message), $additional); } + /** + * @return array + */ private function success() { return array('status'=>'success'); } @@ -106,14 +119,12 @@ class LostController extends Controller { * @PublicPage * * @param string $user - * @param bool $proceed + * @return array */ - public function email($user, $proceed){ + public function email($user){ // FIXME: use HTTP error codes try { - $this->sendEmail($user, $proceed); - } catch (EncryptedDataException $e){ - return $this->error('', array('encryption' => '1')); + $this->sendEmail($user); } catch (\Exception $e){ return $this->error($e->getMessage()); } @@ -121,15 +132,23 @@ class LostController extends Controller { return $this->success(); } - /** * @PublicPage + * @param string $token + * @param string $userId + * @param string $password + * @param boolean $proceed + * @return array */ - public function setPassword($token, $userId, $password) { + public function setPassword($token, $userId, $password, $proceed) { + if ($this->isDataEncrypted && !$proceed){ + return $this->error('', array('encryption' => true)); + } + try { $user = $this->userManager->get($userId); - if (!$this->checkToken($userId, $token)) { + if (!StringUtils::equals($this->config->getUserValue($userId, 'owncloud', 'lostpassword'), $token)) { throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid')); } @@ -137,9 +156,10 @@ class LostController extends Controller { throw new \Exception(); } - // FIXME: should be added to the all config at some point - \OC_Preferences::deleteKey($userId, 'owncloud', 'lostpassword'); - $this->userSession->unsetMagicInCookie(); + \OC_Hook::emit('\OC\Core\LostPassword\Controller\LostController', 'post_passwordReset', array('uid' => $userId, 'password' => $password)); + + $this->config->deleteUserValue($userId, 'owncloud', 'lostpassword'); + @\OC_User::unsetMagicInCookie(); } catch (\Exception $e){ return $this->error($e->getMessage()); @@ -148,36 +168,32 @@ class LostController extends Controller { return $this->success(); } - - protected function sendEmail($user, $proceed) { - if ($this->isDataEncrypted && !$proceed){ - throw new EncryptedDataException(); - } - + /** + * @param string $user + * @throws \Exception + */ + protected function sendEmail($user) { if (!$this->userManager->userExists($user)) { - throw new \Exception( - $this->l10n->t('Couldn\'t send reset email. Please make sure '. - 'your username is correct.')); + throw new \Exception($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.')); } - $token = hash('sha256', \OC_Util::generateRandomBytes(30)); - - // Hash the token again to prevent timing attacks - $this->config->setUserValue( - $user, 'owncloud', 'lostpassword', hash('sha256', $token) - ); - $email = $this->config->getUserValue($user, 'settings', 'email'); if (empty($email)) { throw new \Exception( $this->l10n->t('Couldn\'t send reset email because there is no '. - 'email address for this username. Please ' . - 'contact your administrator.') + 'email address for this username. Please ' . + 'contact your administrator.') ); } - $link = $this->getLink('core.lost.resetform', $user, $token); + $token = $this->secureRandom->getMediumStrengthGenerator()->generate(21, + ISecureRandom::CHAR_DIGITS. + ISecureRandom::CHAR_LOWER. + ISecureRandom::CHAR_UPPER); + $this->config->setUserValue($user, 'owncloud', 'lostpassword', $token); + + $link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', array('userId' => $user, 'token' => $token)); $tmpl = new \OC_Template('core/lostpassword', 'email'); $tmpl->assign('link', $link, false); @@ -200,23 +216,4 @@ class LostController extends Controller { } } - - protected function getLink($route, $user, $token){ - $parameters = array( - 'token' => $token, - 'userId' => $user - ); - $link = $this->urlGenerator->linkToRoute($route, $parameters); - - return $this->urlGenerator->getAbsoluteUrl($link); - } - - - protected function checkToken($user, $token) { - return $this->config->getUserValue( - $user, 'owncloud', 'lostpassword' - ) === hash('sha256', $token); - } - - } diff --git a/core/lostpassword/css/resetpassword.css b/core/lostpassword/css/resetpassword.css index 012af672d97..29a7e875537 100644 --- a/core/lostpassword/css/resetpassword.css +++ b/core/lostpassword/css/resetpassword.css @@ -2,6 +2,10 @@ position: relative; } +.text-center { + text-align: center; +} + #password-icon { top: 20px; } diff --git a/core/lostpassword/encrypteddataexception.php b/core/lostpassword/encrypteddataexception.php deleted file mode 100644 index 99d19445b6c..00000000000 --- a/core/lostpassword/encrypteddataexception.php +++ /dev/null @@ -1,14 +0,0 @@ -<?php -/** - * @author Victor Dubiniuk - * @copyright 2013 Victor Dubiniuk victor.dubiniuk@gmail.com - * - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -namespace OC\Core\LostPassword; - -class EncryptedDataException extends \Exception{ -} diff --git a/core/lostpassword/templates/lostpassword.php b/core/lostpassword/templates/lostpassword.php deleted file mode 100644 index 00dd139e71f..00000000000 --- a/core/lostpassword/templates/lostpassword.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php -//load the file we need -OCP\Util::addStyle('lostpassword', 'lostpassword'); ?> -<form action="<?php print_unescaped($_['link']) ?>" method="post"> - <fieldset> - <div class="update"><?php p($l->t('You will receive a link to reset your password via Email.')); ?></div> - <p> - <input type="text" name="user" id="user" placeholder="<?php p($l->t( 'Username' )); ?>" value="" autocomplete="off" required autofocus /> - <label for="user" class="infield"><?php p($l->t( 'Username' )); ?></label> - <img class="svg" src="<?php print_unescaped(image_path('', 'actions/user.svg')); ?>" alt=""/> - <?php if ($_['isEncrypted']): ?> - <br /> - <p class="warning"><?php p($l->t("Your files are encrypted. If you haven't enabled the recovery key, there will be no way to get your data back after your password is reset. If you are not sure what to do, please contact your administrator before you continue. Do you really want to continue?")); ?><br /> - <input type="checkbox" name="continue" value="Yes" /> - <?php p($l->t('Yes, I really want to reset my password now')); ?></p> - <?php endif; ?> - </p> - <input type="submit" id="submit" value="<?php p($l->t('Reset')); ?>" /> - </fieldset> -</form> diff --git a/core/lostpassword/templates/resetpassword.php b/core/lostpassword/templates/resetpassword.php index 118fe787116..498c692f12e 100644 --- a/core/lostpassword/templates/resetpassword.php +++ b/core/lostpassword/templates/resetpassword.php @@ -1,4 +1,10 @@ -<?php OCP\Util::addStyle('lostpassword', 'resetpassword'); ?> +<?php +/** @var array $_ */ +/** @var $l OC_L10N */ +style('lostpassword', 'resetpassword'); +script('core', 'lostpassword'); +?> + <form action="<?php print_unescaped($_['link']) ?>" id="reset-password" method="post"> <fieldset> <p> @@ -7,6 +13,8 @@ <img class="svg" id="password-icon" src="<?php print_unescaped(image_path('', 'actions/password.svg')); ?>" alt=""/> </p> <input type="submit" id="submit" value="<?php p($l->t('Reset password')); ?>" /> + <p class="text-center"> + <img class="hidden" id="float-spinner" src="<?php p(\OCP\Util::imagePath('core', 'loading-dark.gif'));?>"/> + </p> </fieldset> </form> -<?php OCP\Util::addScript('core', 'lostpassword'); ?> diff --git a/core/routes.php b/core/routes.php index 92545d0322e..ced70898f50 100644 --- a/core/routes.php +++ b/core/routes.php @@ -95,9 +95,22 @@ $this->create('core_avatar_post_cropped', '/avatar/cropped') ->action('OC\Core\Avatar\Controller', 'postCroppedAvatar'); // Sharing routes -$this->create('core_share_show_share', '/s/{token}') - ->get() - ->action('OC\Core\Share\Controller', 'showShare'); +$this->create('files_sharing.sharecontroller.showShare', '/s/{token}')->action(function($urlParams) { + $app = new \OCA\Files_Sharing\Application($urlParams); + $app->dispatch('ShareController', 'showShare'); +}); +$this->create('files_sharing.sharecontroller.authenticate', '/s/{token}/authenticate')->post()->action(function($urlParams) { + $app = new \OCA\Files_Sharing\Application($urlParams); + $app->dispatch('ShareController', 'authenticate'); +}); +$this->create('files_sharing.sharecontroller.showAuthenticate', '/s/{token}/authenticate')->get()->action(function($urlParams) { + $app = new \OCA\Files_Sharing\Application($urlParams); + $app->dispatch('ShareController', 'showAuthenticate'); +}); +$this->create('files_sharing.sharecontroller.downloadShare', '/s/{token}/download')->get()->action(function($urlParams) { + $app = new \OCA\Files_Sharing\Application($urlParams); + $app->dispatch('ShareController', 'downloadShare'); +}); // used for heartbeat $this->create('heartbeat', '/heartbeat')->action(function(){ diff --git a/core/share/controller.php b/core/share/controller.php deleted file mode 100644 index c1741af0d98..00000000000 --- a/core/share/controller.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php -/** - * Copyright (c) 2014 Christopher Schäpers <christopher@schaepers.it> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -namespace OC\Core\Share; - -class Controller { - public static function showShare($args) { - \OC_Util::checkAppEnabled('files_sharing'); - - $token = $args['token']; - - \OC_App::loadApp('files_sharing'); - \OC_User::setIncognitoMode(true); - - require_once \OC_App::getAppPath('files_sharing') .'/public.php'; - } -} -?> diff --git a/lib/base.php b/lib/base.php index 3cbab52ed7c..d365a4a306f 100644 --- a/lib/base.php +++ b/lib/base.php @@ -229,11 +229,18 @@ class OC { public static function checkSSL() { // redirect to https site if configured - if (OC_Config::getValue("forcessl", false)) { - header('Strict-Transport-Security: max-age=31536000'); - ini_set("session.cookie_secure", "on"); + if (\OC::$server->getConfig()->getSystemValue('forcessl', false)) { + // Default HSTS policy + $header = 'Strict-Transport-Security: max-age=31536000'; + + // If SSL for subdomains is enabled add "; includeSubDomains" to the header + if(\OC::$server->getConfig()->getSystemValue('forceSSLforSubdomains', false)) { + $header .= '; includeSubDomains'; + } + header($header); + ini_set('session.cookie_secure', 'on'); if (OC_Request::serverProtocol() <> 'https' and !OC::$CLI) { - $url = "https://" . OC_Request::serverHost() . OC_Request::requestUri(); + $url = 'https://' . OC_Request::serverHost() . OC_Request::requestUri(); header("Location: $url"); exit(); } diff --git a/lib/l10n/af_ZA.js b/lib/l10n/af_ZA.js index fd0ff979e2c..af812fe1e97 100644 --- a/lib/l10n/af_ZA.js +++ b/lib/l10n/af_ZA.js @@ -9,6 +9,7 @@ OC.L10N.register( "Unknown filetype" : "Onbekende leertipe", "Invalid image" : "Ongeldige prent", "web services under your control" : "webdienste onder jou beheer", + "seconds ago" : "sekondes gelede", "_%n minute ago_::_%n minutes ago_" : ["",""], "_%n hour ago_::_%n hours ago_" : ["","%n ure gelede"], "today" : "vandag", diff --git a/lib/l10n/af_ZA.json b/lib/l10n/af_ZA.json index 0a2bd668866..b3dedd54188 100644 --- a/lib/l10n/af_ZA.json +++ b/lib/l10n/af_ZA.json @@ -7,6 +7,7 @@ "Unknown filetype" : "Onbekende leertipe", "Invalid image" : "Ongeldige prent", "web services under your control" : "webdienste onder jou beheer", + "seconds ago" : "sekondes gelede", "_%n minute ago_::_%n minutes ago_" : ["",""], "_%n hour ago_::_%n hours ago_" : ["","%n ure gelede"], "today" : "vandag", diff --git a/lib/l10n/bg_BG.js b/lib/l10n/bg_BG.js index 82f0f3e51fc..a0c0dc3b8e7 100644 --- a/lib/l10n/bg_BG.js +++ b/lib/l10n/bg_BG.js @@ -17,6 +17,8 @@ OC.L10N.register( "No app name specified" : "Не е зададено име на преложението", "Unknown filetype" : "Непознат тип файл.", "Invalid image" : "Невалидно изображение.", + "Database Error" : "Грешка в базата данни", + "Please contact your system administrator." : "Моля, свържи се с админстратора.", "web services under your control" : "уеб услуги под твой контрол", "App directory already exists" : "Папката на приложението вече съществува.", "Can't create app folder. Please fix permissions. %s" : "Неуспешно създаване на папката за приложението. Моля, оправете разрешенията. %s", diff --git a/lib/l10n/bg_BG.json b/lib/l10n/bg_BG.json index 62c0ea60f07..aedb28be19e 100644 --- a/lib/l10n/bg_BG.json +++ b/lib/l10n/bg_BG.json @@ -15,6 +15,8 @@ "No app name specified" : "Не е зададено име на преложението", "Unknown filetype" : "Непознат тип файл.", "Invalid image" : "Невалидно изображение.", + "Database Error" : "Грешка в базата данни", + "Please contact your system administrator." : "Моля, свържи се с админстратора.", "web services under your control" : "уеб услуги под твой контрол", "App directory already exists" : "Папката на приложението вече съществува.", "Can't create app folder. Please fix permissions. %s" : "Неуспешно създаване на папката за приложението. Моля, оправете разрешенията. %s", diff --git a/lib/l10n/cs_CZ.js b/lib/l10n/cs_CZ.js index 113f32d40c5..b4419c8ef99 100644 --- a/lib/l10n/cs_CZ.js +++ b/lib/l10n/cs_CZ.js @@ -17,6 +17,8 @@ OC.L10N.register( "No app name specified" : "Nebyl zadan název aplikace", "Unknown filetype" : "Neznámý typ souboru", "Invalid image" : "Chybný obrázek", + "Database Error" : "Chyba databáze", + "Please contact your system administrator." : "Kontaktujte prosím svého správce systému.", "web services under your control" : "webové služby pod Vaší kontrolou", "App directory already exists" : "Adresář aplikace již existuje", "Can't create app folder. Please fix permissions. %s" : "Nelze vytvořit složku aplikace. Opravte práva souborů. %s", @@ -83,7 +85,7 @@ OC.L10N.register( "_%n hour ago_::_%n hours ago_" : ["před %n hodinou","před %n hodinami","před %n hodinami"], "today" : "dnes", "yesterday" : "včera", - "_%n day go_::_%n days ago_" : ["před %n dnem","před %n dny","před %n dny"], + "_%n day go_::_%n days ago_" : ["včera","před %n dny","před %n dny"], "last month" : "minulý měsíc", "_%n month ago_::_%n months ago_" : ["před %n měsícem","před %n měsíci","před %n měsíci"], "last year" : "minulý rok", @@ -101,16 +103,16 @@ OC.L10N.register( "This can usually be fixed by <a href=\"%s\" target=\"_blank\">giving the webserver write access to the root directory</a>." : "To lze obvykle vyřešit <a href=\"%s\" target=\"_blank\">povolením zápisu webovému serveru do kořenového adresáře</a>.", "Setting locale to %s failed" : "Nastavení jazyka na %s selhalo", "Please install one of these locales on your system and restart your webserver." : "Prosím nainstalujte alespoň jeden z těchto jazyků do svého systému a restartujte webový server.", - "Please ask your server administrator to install the module." : "Požádejte svého administrátora o instalaci tohoto modulu.", + "Please ask your server administrator to install the module." : "Požádejte svého správce systému o instalaci tohoto modulu.", "PHP module %s not installed." : "PHP modul %s není nainstalován.", "PHP %s or higher is required." : "Je vyžadováno PHP %s nebo vyšší.", - "Please ask your server administrator to update PHP to the latest version. Your PHP version is no longer supported by ownCloud and the PHP community." : "Požádejte svého administrátora o aktualizaci PHP na nejnovější verzi. Vaše verze PHP již není podporována komunitami ownCloud a PHP.", + "Please ask your server administrator to update PHP to the latest version. Your PHP version is no longer supported by ownCloud and the PHP community." : "Požádejte svého správce systému o aktualizaci PHP na nejnovější verzi. Vaše verze PHP již není podporována komunitami ownCloud a PHP.", "PHP Safe Mode is enabled. ownCloud requires that it is disabled to work properly." : "Je zapnut PHP Safe Mode. Pro správnou funkčnost ownCloud je třeba toto vypnout.", - "PHP Safe Mode is a deprecated and mostly useless setting that should be disabled. Please ask your server administrator to disable it in php.ini or in your webserver config." : "PHP Safe Mode je zastaralé a většinou zbytečné nastavení, které je třeba vypnout. Požádejte prosím svého administrátora o zakázání v php.ini nebo v konfiguraci webového serveru.", + "PHP Safe Mode is a deprecated and mostly useless setting that should be disabled. Please ask your server administrator to disable it in php.ini or in your webserver config." : "PHP Safe Mode je zastaralé a většinou zbytečné nastavení, které je třeba vypnout. Požádejte prosím správce systému o jeho zákaz v php.ini nebo v konfiguraci webového serveru.", "Magic Quotes is enabled. ownCloud requires that it is disabled to work properly." : "Je povoleno nastavení Magic Quotes. Pro správnou funkčnost ownCloud je třeba toto vypnout.", - "Magic Quotes is a deprecated and mostly useless setting that should be disabled. Please ask your server administrator to disable it in php.ini or in your webserver config." : "Magic Quotes je zastaralé a většinou zbytečné nastavení, které je třeba vypnout. Požádejte prosím svého administrátora o zakázání v php.ini nebo v konfiguraci webového serveru.", + "Magic Quotes is a deprecated and mostly useless setting that should be disabled. Please ask your server administrator to disable it in php.ini or in your webserver config." : "Magic Quotes je zastaralé a většinou zbytečné nastavení, které je třeba vypnout. Požádejte prosím správce systému o jeho zákaz v php.ini nebo v konfiguraci webového serveru.", "PHP modules have been installed, but they are still listed as missing?" : "PHP moduly jsou nainstalovány, ale stále se tváří jako chybějící?", - "Please ask your server administrator to restart the web server." : "Požádejte svého administrátora o restart webového serveru.", + "Please ask your server administrator to restart the web server." : "Požádejte svého správce systému o restart webového serveru.", "PostgreSQL >= 9 required" : "Je vyžadováno PostgreSQL >= 9", "Please upgrade your database version" : "Aktualizujte prosím verzi své databáze", "Error occurred while checking PostgreSQL version" : "Při zjišťování verze PostgreSQL došlo k chybě", diff --git a/lib/l10n/cs_CZ.json b/lib/l10n/cs_CZ.json index e8806f406ae..a487b849291 100644 --- a/lib/l10n/cs_CZ.json +++ b/lib/l10n/cs_CZ.json @@ -15,6 +15,8 @@ "No app name specified" : "Nebyl zadan název aplikace", "Unknown filetype" : "Neznámý typ souboru", "Invalid image" : "Chybný obrázek", + "Database Error" : "Chyba databáze", + "Please contact your system administrator." : "Kontaktujte prosím svého správce systému.", "web services under your control" : "webové služby pod Vaší kontrolou", "App directory already exists" : "Adresář aplikace již existuje", "Can't create app folder. Please fix permissions. %s" : "Nelze vytvořit složku aplikace. Opravte práva souborů. %s", @@ -81,7 +83,7 @@ "_%n hour ago_::_%n hours ago_" : ["před %n hodinou","před %n hodinami","před %n hodinami"], "today" : "dnes", "yesterday" : "včera", - "_%n day go_::_%n days ago_" : ["před %n dnem","před %n dny","před %n dny"], + "_%n day go_::_%n days ago_" : ["včera","před %n dny","před %n dny"], "last month" : "minulý měsíc", "_%n month ago_::_%n months ago_" : ["před %n měsícem","před %n měsíci","před %n měsíci"], "last year" : "minulý rok", @@ -99,16 +101,16 @@ "This can usually be fixed by <a href=\"%s\" target=\"_blank\">giving the webserver write access to the root directory</a>." : "To lze obvykle vyřešit <a href=\"%s\" target=\"_blank\">povolením zápisu webovému serveru do kořenového adresáře</a>.", "Setting locale to %s failed" : "Nastavení jazyka na %s selhalo", "Please install one of these locales on your system and restart your webserver." : "Prosím nainstalujte alespoň jeden z těchto jazyků do svého systému a restartujte webový server.", - "Please ask your server administrator to install the module." : "Požádejte svého administrátora o instalaci tohoto modulu.", + "Please ask your server administrator to install the module." : "Požádejte svého správce systému o instalaci tohoto modulu.", "PHP module %s not installed." : "PHP modul %s není nainstalován.", "PHP %s or higher is required." : "Je vyžadováno PHP %s nebo vyšší.", - "Please ask your server administrator to update PHP to the latest version. Your PHP version is no longer supported by ownCloud and the PHP community." : "Požádejte svého administrátora o aktualizaci PHP na nejnovější verzi. Vaše verze PHP již není podporována komunitami ownCloud a PHP.", + "Please ask your server administrator to update PHP to the latest version. Your PHP version is no longer supported by ownCloud and the PHP community." : "Požádejte svého správce systému o aktualizaci PHP na nejnovější verzi. Vaše verze PHP již není podporována komunitami ownCloud a PHP.", "PHP Safe Mode is enabled. ownCloud requires that it is disabled to work properly." : "Je zapnut PHP Safe Mode. Pro správnou funkčnost ownCloud je třeba toto vypnout.", - "PHP Safe Mode is a deprecated and mostly useless setting that should be disabled. Please ask your server administrator to disable it in php.ini or in your webserver config." : "PHP Safe Mode je zastaralé a většinou zbytečné nastavení, které je třeba vypnout. Požádejte prosím svého administrátora o zakázání v php.ini nebo v konfiguraci webového serveru.", + "PHP Safe Mode is a deprecated and mostly useless setting that should be disabled. Please ask your server administrator to disable it in php.ini or in your webserver config." : "PHP Safe Mode je zastaralé a většinou zbytečné nastavení, které je třeba vypnout. Požádejte prosím správce systému o jeho zákaz v php.ini nebo v konfiguraci webového serveru.", "Magic Quotes is enabled. ownCloud requires that it is disabled to work properly." : "Je povoleno nastavení Magic Quotes. Pro správnou funkčnost ownCloud je třeba toto vypnout.", - "Magic Quotes is a deprecated and mostly useless setting that should be disabled. Please ask your server administrator to disable it in php.ini or in your webserver config." : "Magic Quotes je zastaralé a většinou zbytečné nastavení, které je třeba vypnout. Požádejte prosím svého administrátora o zakázání v php.ini nebo v konfiguraci webového serveru.", + "Magic Quotes is a deprecated and mostly useless setting that should be disabled. Please ask your server administrator to disable it in php.ini or in your webserver config." : "Magic Quotes je zastaralé a většinou zbytečné nastavení, které je třeba vypnout. Požádejte prosím správce systému o jeho zákaz v php.ini nebo v konfiguraci webového serveru.", "PHP modules have been installed, but they are still listed as missing?" : "PHP moduly jsou nainstalovány, ale stále se tváří jako chybějící?", - "Please ask your server administrator to restart the web server." : "Požádejte svého administrátora o restart webového serveru.", + "Please ask your server administrator to restart the web server." : "Požádejte svého správce systému o restart webového serveru.", "PostgreSQL >= 9 required" : "Je vyžadováno PostgreSQL >= 9", "Please upgrade your database version" : "Aktualizujte prosím verzi své databáze", "Error occurred while checking PostgreSQL version" : "Při zjišťování verze PostgreSQL došlo k chybě", diff --git a/lib/l10n/da.js b/lib/l10n/da.js index 6c49ba9b038..af85c3e93d1 100644 --- a/lib/l10n/da.js +++ b/lib/l10n/da.js @@ -17,6 +17,8 @@ OC.L10N.register( "No app name specified" : "Intet app-navn angivet", "Unknown filetype" : "Ukendt filtype", "Invalid image" : "Ugyldigt billede", + "Database Error" : "Databasefejl", + "Please contact your system administrator." : "Kontakt venligst din systemadministrator.", "web services under your control" : "Webtjenester under din kontrol", "App directory already exists" : "App-mappe findes allerede", "Can't create app folder. Please fix permissions. %s" : "Kan ikke oprette app-mappe. Ret tilladelser. %s", diff --git a/lib/l10n/da.json b/lib/l10n/da.json index fe2858f182d..59ff0e87b98 100644 --- a/lib/l10n/da.json +++ b/lib/l10n/da.json @@ -15,6 +15,8 @@ "No app name specified" : "Intet app-navn angivet", "Unknown filetype" : "Ukendt filtype", "Invalid image" : "Ugyldigt billede", + "Database Error" : "Databasefejl", + "Please contact your system administrator." : "Kontakt venligst din systemadministrator.", "web services under your control" : "Webtjenester under din kontrol", "App directory already exists" : "App-mappe findes allerede", "Can't create app folder. Please fix permissions. %s" : "Kan ikke oprette app-mappe. Ret tilladelser. %s", diff --git a/lib/l10n/de.js b/lib/l10n/de.js index e512c9d1d4c..215052da7f9 100644 --- a/lib/l10n/de.js +++ b/lib/l10n/de.js @@ -17,6 +17,8 @@ OC.L10N.register( "No app name specified" : "Es wurde kein Applikation-Name angegeben", "Unknown filetype" : "Unbekannter Dateityp", "Invalid image" : "Ungültiges Bild", + "Database Error" : "Datenbankfehler", + "Please contact your system administrator." : "Bitte kontaktiere Deinen Systemadministrator.", "web services under your control" : "Web-Services unter Deiner Kontrolle", "App directory already exists" : "Das Applikationsverzeichnis existiert bereits", "Can't create app folder. Please fix permissions. %s" : "Es kann kein Applikationsordner erstellt werden. Bitte passe die Berechtigungen an. %s", diff --git a/lib/l10n/de.json b/lib/l10n/de.json index 27dd6781ae7..086fc888986 100644 --- a/lib/l10n/de.json +++ b/lib/l10n/de.json @@ -15,6 +15,8 @@ "No app name specified" : "Es wurde kein Applikation-Name angegeben", "Unknown filetype" : "Unbekannter Dateityp", "Invalid image" : "Ungültiges Bild", + "Database Error" : "Datenbankfehler", + "Please contact your system administrator." : "Bitte kontaktiere Deinen Systemadministrator.", "web services under your control" : "Web-Services unter Deiner Kontrolle", "App directory already exists" : "Das Applikationsverzeichnis existiert bereits", "Can't create app folder. Please fix permissions. %s" : "Es kann kein Applikationsordner erstellt werden. Bitte passe die Berechtigungen an. %s", diff --git a/lib/l10n/de_DE.js b/lib/l10n/de_DE.js index 48f236f3e04..6d99b090604 100644 --- a/lib/l10n/de_DE.js +++ b/lib/l10n/de_DE.js @@ -17,6 +17,8 @@ OC.L10N.register( "No app name specified" : "Es wurde kein Applikation-Name angegeben", "Unknown filetype" : "Unbekannter Dateityp", "Invalid image" : "Ungültiges Bild", + "Database Error" : "Datenbankfehler", + "Please contact your system administrator." : "Bitte kontaktieren Sie Ihren Systemadministrator.", "web services under your control" : "Web-Services unter Ihrer Kontrolle", "App directory already exists" : "Der Ordner für die Anwendung ist bereits vorhanden.", "Can't create app folder. Please fix permissions. %s" : "Der Ordner für die Anwendung konnte nicht angelegt werden. Bitte überprüfen Sie die Ordner- und Dateirechte und passen Sie diese entsprechend an. %s", diff --git a/lib/l10n/de_DE.json b/lib/l10n/de_DE.json index e67d2ccc57c..fd16f063b78 100644 --- a/lib/l10n/de_DE.json +++ b/lib/l10n/de_DE.json @@ -15,6 +15,8 @@ "No app name specified" : "Es wurde kein Applikation-Name angegeben", "Unknown filetype" : "Unbekannter Dateityp", "Invalid image" : "Ungültiges Bild", + "Database Error" : "Datenbankfehler", + "Please contact your system administrator." : "Bitte kontaktieren Sie Ihren Systemadministrator.", "web services under your control" : "Web-Services unter Ihrer Kontrolle", "App directory already exists" : "Der Ordner für die Anwendung ist bereits vorhanden.", "Can't create app folder. Please fix permissions. %s" : "Der Ordner für die Anwendung konnte nicht angelegt werden. Bitte überprüfen Sie die Ordner- und Dateirechte und passen Sie diese entsprechend an. %s", diff --git a/lib/l10n/en_GB.js b/lib/l10n/en_GB.js index 43f7edb5258..9e5400deb2d 100644 --- a/lib/l10n/en_GB.js +++ b/lib/l10n/en_GB.js @@ -17,6 +17,8 @@ OC.L10N.register( "No app name specified" : "No app name specified", "Unknown filetype" : "Unknown filetype", "Invalid image" : "Invalid image", + "Database Error" : "Database Error", + "Please contact your system administrator." : "Please contact your system administrator.", "web services under your control" : "web services under your control", "App directory already exists" : "App directory already exists", "Can't create app folder. Please fix permissions. %s" : "Can't create app folder. Please fix permissions. %s", diff --git a/lib/l10n/en_GB.json b/lib/l10n/en_GB.json index 7e7756cec9c..e3a44ec8e9b 100644 --- a/lib/l10n/en_GB.json +++ b/lib/l10n/en_GB.json @@ -15,6 +15,8 @@ "No app name specified" : "No app name specified", "Unknown filetype" : "Unknown filetype", "Invalid image" : "Invalid image", + "Database Error" : "Database Error", + "Please contact your system administrator." : "Please contact your system administrator.", "web services under your control" : "web services under your control", "App directory already exists" : "App directory already exists", "Can't create app folder. Please fix permissions. %s" : "Can't create app folder. Please fix permissions. %s", diff --git a/lib/l10n/es.js b/lib/l10n/es.js index 76a44a4bed7..9cdd328e974 100644 --- a/lib/l10n/es.js +++ b/lib/l10n/es.js @@ -17,6 +17,8 @@ OC.L10N.register( "No app name specified" : "No se ha especificado nombre de la aplicación", "Unknown filetype" : "Tipo de archivo desconocido", "Invalid image" : "Imagen inválida", + "Database Error" : "Error en la base de datos", + "Please contact your system administrator." : "Por favor contacte al administrador del sistema.", "web services under your control" : "Servicios web bajo su control", "App directory already exists" : "El directorio de la aplicación ya existe", "Can't create app folder. Please fix permissions. %s" : "No se puede crear la carpeta de la aplicación. Corrija los permisos. %s", diff --git a/lib/l10n/es.json b/lib/l10n/es.json index a6bee7f24db..c14b03c15df 100644 --- a/lib/l10n/es.json +++ b/lib/l10n/es.json @@ -15,6 +15,8 @@ "No app name specified" : "No se ha especificado nombre de la aplicación", "Unknown filetype" : "Tipo de archivo desconocido", "Invalid image" : "Imagen inválida", + "Database Error" : "Error en la base de datos", + "Please contact your system administrator." : "Por favor contacte al administrador del sistema.", "web services under your control" : "Servicios web bajo su control", "App directory already exists" : "El directorio de la aplicación ya existe", "Can't create app folder. Please fix permissions. %s" : "No se puede crear la carpeta de la aplicación. Corrija los permisos. %s", diff --git a/lib/l10n/fi_FI.js b/lib/l10n/fi_FI.js index f387090da60..1097dd20850 100644 --- a/lib/l10n/fi_FI.js +++ b/lib/l10n/fi_FI.js @@ -16,6 +16,8 @@ OC.L10N.register( "No app name specified" : "Sovelluksen nimeä ei määritelty", "Unknown filetype" : "Tuntematon tiedostotyyppi", "Invalid image" : "Virheellinen kuva", + "Database Error" : "Tietokantavirhe", + "Please contact your system administrator." : "Ole yhteydessä järjestelmän ylläpitäjään.", "web services under your control" : "verkkopalvelut hallinnassasi", "App directory already exists" : "Sovelluskansio on jo olemassa", "Can't create app folder. Please fix permissions. %s" : "Sovelluskansion luominen ei onnistu. Korjaa käyttöoikeudet. %s", diff --git a/lib/l10n/fi_FI.json b/lib/l10n/fi_FI.json index 7c26af25f66..2bd73df0379 100644 --- a/lib/l10n/fi_FI.json +++ b/lib/l10n/fi_FI.json @@ -14,6 +14,8 @@ "No app name specified" : "Sovelluksen nimeä ei määritelty", "Unknown filetype" : "Tuntematon tiedostotyyppi", "Invalid image" : "Virheellinen kuva", + "Database Error" : "Tietokantavirhe", + "Please contact your system administrator." : "Ole yhteydessä järjestelmän ylläpitäjään.", "web services under your control" : "verkkopalvelut hallinnassasi", "App directory already exists" : "Sovelluskansio on jo olemassa", "Can't create app folder. Please fix permissions. %s" : "Sovelluskansion luominen ei onnistu. Korjaa käyttöoikeudet. %s", diff --git a/lib/l10n/fr.js b/lib/l10n/fr.js index becc21ab649..ec7e949abcc 100644 --- a/lib/l10n/fr.js +++ b/lib/l10n/fr.js @@ -17,13 +17,15 @@ OC.L10N.register( "No app name specified" : "Aucun nom d'application spécifié", "Unknown filetype" : "Type de fichier inconnu", "Invalid image" : "Image non valable", + "Database Error" : "Erreur dans la base de données", + "Please contact your system administrator." : "Veuillez contacter votre administrateur système.", "web services under your control" : "services web sous votre contrôle", "App directory already exists" : "Le dossier de l'application existe déjà", "Can't create app folder. Please fix permissions. %s" : "Impossible de créer le dossier de l'application. Corrigez les droits d'accès. %s", "No source specified when installing app" : "Aucune source spécifiée pour installer l'application", "No href specified when installing app from http" : "Aucun href spécifié pour installer l'application par http", "No path specified when installing app from local file" : "Aucun chemin spécifié pour installer l'application depuis un fichier local", - "Archives of type %s are not supported" : "Les archives de type %s ne sont pas supportées", + "Archives of type %s are not supported" : "Les archives de type %s ne sont pas prises en charge", "Failed to open archive when installing app" : "Échec de l'ouverture de l'archive lors de l'installation de l'application", "App does not provide an info.xml file" : "L'application ne fournit pas de fichier info.xml", "App can't be installed because of not allowed code in the App" : "L'application ne peut être installée car elle contient du code non-autorisé", @@ -104,7 +106,7 @@ OC.L10N.register( "Please ask your server administrator to install the module." : "Veuillez demander à votre administrateur d’installer le module.", "PHP module %s not installed." : "Le module PHP %s n’est pas installé.", "PHP %s or higher is required." : "PHP %s ou supérieur est requis.", - "Please ask your server administrator to update PHP to the latest version. Your PHP version is no longer supported by ownCloud and the PHP community." : "Veuillez demander à votre administrateur de mettre à jour PHP vers sa dernière version disponible. La vôtre n’est plus supportée par ownCloud, de même que par la communauté PHP.", + "Please ask your server administrator to update PHP to the latest version. Your PHP version is no longer supported by ownCloud and the PHP community." : "Veuillez demander à votre administrateur de mettre à jour PHP vers sa dernière version disponible. La vôtre n’est plus prise en charge par ownCloud ni par la communauté PHP.", "PHP Safe Mode is enabled. ownCloud requires that it is disabled to work properly." : "PHP Safe Mode est activé. ownCloud requiert sa désactivation afin de fonctionner correctement.", "PHP Safe Mode is a deprecated and mostly useless setting that should be disabled. Please ask your server administrator to disable it in php.ini or in your webserver config." : "PHP Safe Mode est déprécié, inutile la plupart du temps, et doit être désactivé. Veuillez demander à votre administrateur serveur de le désactiver dans le fichier php.ini ou dans votre configuration du serveur web.", "Magic Quotes is enabled. ownCloud requires that it is disabled to work properly." : "Magic Quotes est activé. ownCloud requiert sa désactivation afin de fonctionner correctement.", diff --git a/lib/l10n/fr.json b/lib/l10n/fr.json index 51452abce9e..ecba239d076 100644 --- a/lib/l10n/fr.json +++ b/lib/l10n/fr.json @@ -15,13 +15,15 @@ "No app name specified" : "Aucun nom d'application spécifié", "Unknown filetype" : "Type de fichier inconnu", "Invalid image" : "Image non valable", + "Database Error" : "Erreur dans la base de données", + "Please contact your system administrator." : "Veuillez contacter votre administrateur système.", "web services under your control" : "services web sous votre contrôle", "App directory already exists" : "Le dossier de l'application existe déjà", "Can't create app folder. Please fix permissions. %s" : "Impossible de créer le dossier de l'application. Corrigez les droits d'accès. %s", "No source specified when installing app" : "Aucune source spécifiée pour installer l'application", "No href specified when installing app from http" : "Aucun href spécifié pour installer l'application par http", "No path specified when installing app from local file" : "Aucun chemin spécifié pour installer l'application depuis un fichier local", - "Archives of type %s are not supported" : "Les archives de type %s ne sont pas supportées", + "Archives of type %s are not supported" : "Les archives de type %s ne sont pas prises en charge", "Failed to open archive when installing app" : "Échec de l'ouverture de l'archive lors de l'installation de l'application", "App does not provide an info.xml file" : "L'application ne fournit pas de fichier info.xml", "App can't be installed because of not allowed code in the App" : "L'application ne peut être installée car elle contient du code non-autorisé", @@ -102,7 +104,7 @@ "Please ask your server administrator to install the module." : "Veuillez demander à votre administrateur d’installer le module.", "PHP module %s not installed." : "Le module PHP %s n’est pas installé.", "PHP %s or higher is required." : "PHP %s ou supérieur est requis.", - "Please ask your server administrator to update PHP to the latest version. Your PHP version is no longer supported by ownCloud and the PHP community." : "Veuillez demander à votre administrateur de mettre à jour PHP vers sa dernière version disponible. La vôtre n’est plus supportée par ownCloud, de même que par la communauté PHP.", + "Please ask your server administrator to update PHP to the latest version. Your PHP version is no longer supported by ownCloud and the PHP community." : "Veuillez demander à votre administrateur de mettre à jour PHP vers sa dernière version disponible. La vôtre n’est plus prise en charge par ownCloud ni par la communauté PHP.", "PHP Safe Mode is enabled. ownCloud requires that it is disabled to work properly." : "PHP Safe Mode est activé. ownCloud requiert sa désactivation afin de fonctionner correctement.", "PHP Safe Mode is a deprecated and mostly useless setting that should be disabled. Please ask your server administrator to disable it in php.ini or in your webserver config." : "PHP Safe Mode est déprécié, inutile la plupart du temps, et doit être désactivé. Veuillez demander à votre administrateur serveur de le désactiver dans le fichier php.ini ou dans votre configuration du serveur web.", "Magic Quotes is enabled. ownCloud requires that it is disabled to work properly." : "Magic Quotes est activé. ownCloud requiert sa désactivation afin de fonctionner correctement.", diff --git a/lib/l10n/it.js b/lib/l10n/it.js index 2874653823b..eb25f2fc086 100644 --- a/lib/l10n/it.js +++ b/lib/l10n/it.js @@ -17,6 +17,8 @@ OC.L10N.register( "No app name specified" : "Il nome dell'applicazione non è specificato", "Unknown filetype" : "Tipo di file sconosciuto", "Invalid image" : "Immagine non valida", + "Database Error" : "Errore del database", + "Please contact your system administrator." : "Contatta il tuo amministratore di sistema.", "web services under your control" : "servizi web nelle tue mani", "App directory already exists" : "La cartella dell'applicazione esiste già", "Can't create app folder. Please fix permissions. %s" : "Impossibile creare la cartella dell'applicazione. Correggi i permessi. %s", diff --git a/lib/l10n/it.json b/lib/l10n/it.json index ca5beb1b802..ef4ae9ab370 100644 --- a/lib/l10n/it.json +++ b/lib/l10n/it.json @@ -15,6 +15,8 @@ "No app name specified" : "Il nome dell'applicazione non è specificato", "Unknown filetype" : "Tipo di file sconosciuto", "Invalid image" : "Immagine non valida", + "Database Error" : "Errore del database", + "Please contact your system administrator." : "Contatta il tuo amministratore di sistema.", "web services under your control" : "servizi web nelle tue mani", "App directory already exists" : "La cartella dell'applicazione esiste già", "Can't create app folder. Please fix permissions. %s" : "Impossibile creare la cartella dell'applicazione. Correggi i permessi. %s", diff --git a/lib/l10n/ja.js b/lib/l10n/ja.js index 38aa3de36d6..e6b0b3240f1 100644 --- a/lib/l10n/ja.js +++ b/lib/l10n/ja.js @@ -17,6 +17,8 @@ OC.L10N.register( "No app name specified" : "アプリ名が未指定", "Unknown filetype" : "不明なファイルタイプ", "Invalid image" : "無効な画像", + "Database Error" : "データベースエラー", + "Please contact your system administrator." : "システム管理者に問い合わせてください。", "web services under your control" : "あなたの管理下のウェブサービス", "App directory already exists" : "アプリディレクトリはすでに存在します", "Can't create app folder. Please fix permissions. %s" : "アプリフォルダーを作成できませんでした。%s のパーミッションを修正してください。", diff --git a/lib/l10n/ja.json b/lib/l10n/ja.json index 8a0db934683..722f5235c6f 100644 --- a/lib/l10n/ja.json +++ b/lib/l10n/ja.json @@ -15,6 +15,8 @@ "No app name specified" : "アプリ名が未指定", "Unknown filetype" : "不明なファイルタイプ", "Invalid image" : "無効な画像", + "Database Error" : "データベースエラー", + "Please contact your system administrator." : "システム管理者に問い合わせてください。", "web services under your control" : "あなたの管理下のウェブサービス", "App directory already exists" : "アプリディレクトリはすでに存在します", "Can't create app folder. Please fix permissions. %s" : "アプリフォルダーを作成できませんでした。%s のパーミッションを修正してください。", diff --git a/lib/l10n/nl.js b/lib/l10n/nl.js index e8b560b730f..1a5b51de2b5 100644 --- a/lib/l10n/nl.js +++ b/lib/l10n/nl.js @@ -17,6 +17,8 @@ OC.L10N.register( "No app name specified" : "Geen app naam opgegeven.", "Unknown filetype" : "Onbekend bestandsformaat", "Invalid image" : "Ongeldige afbeelding", + "Database Error" : "Database fout", + "Please contact your system administrator." : "Neem contact op met uw systeembeheerder.", "web services under your control" : "Webdiensten in eigen beheer", "App directory already exists" : "App directory bestaat al", "Can't create app folder. Please fix permissions. %s" : "Kan de app map niet aanmaken, Herstel de permissies. %s", diff --git a/lib/l10n/nl.json b/lib/l10n/nl.json index 887ad23b35d..432915aa2f2 100644 --- a/lib/l10n/nl.json +++ b/lib/l10n/nl.json @@ -15,6 +15,8 @@ "No app name specified" : "Geen app naam opgegeven.", "Unknown filetype" : "Onbekend bestandsformaat", "Invalid image" : "Ongeldige afbeelding", + "Database Error" : "Database fout", + "Please contact your system administrator." : "Neem contact op met uw systeembeheerder.", "web services under your control" : "Webdiensten in eigen beheer", "App directory already exists" : "App directory bestaat al", "Can't create app folder. Please fix permissions. %s" : "Kan de app map niet aanmaken, Herstel de permissies. %s", diff --git a/lib/l10n/pt_BR.js b/lib/l10n/pt_BR.js index 8537b31d543..370bff17480 100644 --- a/lib/l10n/pt_BR.js +++ b/lib/l10n/pt_BR.js @@ -17,6 +17,8 @@ OC.L10N.register( "No app name specified" : "O nome do aplicativo não foi especificado.", "Unknown filetype" : "Tipo de arquivo desconhecido", "Invalid image" : "Imagem inválida", + "Database Error" : "Erro no Banco de Dados", + "Please contact your system administrator." : "Por favor cotactar seu administrador do sistema.", "web services under your control" : "serviços web sob seu controle", "App directory already exists" : "Diretório App já existe", "Can't create app folder. Please fix permissions. %s" : "Não é possível criar pasta app. Corrija as permissões. %s", diff --git a/lib/l10n/pt_BR.json b/lib/l10n/pt_BR.json index a9e272afc18..465d0d2bf29 100644 --- a/lib/l10n/pt_BR.json +++ b/lib/l10n/pt_BR.json @@ -15,6 +15,8 @@ "No app name specified" : "O nome do aplicativo não foi especificado.", "Unknown filetype" : "Tipo de arquivo desconhecido", "Invalid image" : "Imagem inválida", + "Database Error" : "Erro no Banco de Dados", + "Please contact your system administrator." : "Por favor cotactar seu administrador do sistema.", "web services under your control" : "serviços web sob seu controle", "App directory already exists" : "Diretório App já existe", "Can't create app folder. Please fix permissions. %s" : "Não é possível criar pasta app. Corrija as permissões. %s", diff --git a/lib/l10n/pt_PT.js b/lib/l10n/pt_PT.js index c70e373a11c..0bbac09c9b1 100644 --- a/lib/l10n/pt_PT.js +++ b/lib/l10n/pt_PT.js @@ -17,6 +17,8 @@ OC.L10N.register( "No app name specified" : "O nome da aplicação não foi especificado", "Unknown filetype" : "Ficheiro desconhecido", "Invalid image" : "Imagem inválida", + "Database Error" : "Erro da Base de Dados", + "Please contact your system administrator." : "Por favor contacte o administrador do sistema.", "web services under your control" : "serviços web sob o seu controlo", "App directory already exists" : "A directoria da aplicação já existe", "Can't create app folder. Please fix permissions. %s" : "Não foi possível criar a pasta da aplicação. Por favor verifique as permissões. %s", diff --git a/lib/l10n/pt_PT.json b/lib/l10n/pt_PT.json index 85461b0fae6..067dc4b9751 100644 --- a/lib/l10n/pt_PT.json +++ b/lib/l10n/pt_PT.json @@ -15,6 +15,8 @@ "No app name specified" : "O nome da aplicação não foi especificado", "Unknown filetype" : "Ficheiro desconhecido", "Invalid image" : "Imagem inválida", + "Database Error" : "Erro da Base de Dados", + "Please contact your system administrator." : "Por favor contacte o administrador do sistema.", "web services under your control" : "serviços web sob o seu controlo", "App directory already exists" : "A directoria da aplicação já existe", "Can't create app folder. Please fix permissions. %s" : "Não foi possível criar a pasta da aplicação. Por favor verifique as permissões. %s", diff --git a/lib/l10n/ru.js b/lib/l10n/ru.js index 20ed5013853..490a3f6a1e2 100644 --- a/lib/l10n/ru.js +++ b/lib/l10n/ru.js @@ -17,6 +17,8 @@ OC.L10N.register( "No app name specified" : "Не указано имя приложения", "Unknown filetype" : "Неизвестный тип файла", "Invalid image" : "Изображение повреждено", + "Database Error" : "Ошибка базы данных", + "Please contact your system administrator." : "Пожалуйста, свяжитесь с вашим администратором.", "web services under your control" : "веб-сервисы под вашим управлением", "App directory already exists" : "Папка приложения уже существует", "Can't create app folder. Please fix permissions. %s" : "Не удалось создать директорию. Исправьте права доступа. %s", diff --git a/lib/l10n/ru.json b/lib/l10n/ru.json index a8636cf4c35..103121a374a 100644 --- a/lib/l10n/ru.json +++ b/lib/l10n/ru.json @@ -15,6 +15,8 @@ "No app name specified" : "Не указано имя приложения", "Unknown filetype" : "Неизвестный тип файла", "Invalid image" : "Изображение повреждено", + "Database Error" : "Ошибка базы данных", + "Please contact your system administrator." : "Пожалуйста, свяжитесь с вашим администратором.", "web services under your control" : "веб-сервисы под вашим управлением", "App directory already exists" : "Папка приложения уже существует", "Can't create app folder. Please fix permissions. %s" : "Не удалось создать директорию. Исправьте права доступа. %s", diff --git a/lib/l10n/tr.js b/lib/l10n/tr.js index 0f6a40a7ef2..17a97c31e8a 100644 --- a/lib/l10n/tr.js +++ b/lib/l10n/tr.js @@ -17,6 +17,8 @@ OC.L10N.register( "No app name specified" : "Uygulama adı belirtilmedi", "Unknown filetype" : "Bilinmeyen dosya türü", "Invalid image" : "Geçersiz resim", + "Database Error" : "Veritabanı Hatası", + "Please contact your system administrator." : "Lütfen sistem yöneticiniz ile iletişime geçin.", "web services under your control" : "denetiminizdeki web hizmetleri", "App directory already exists" : "Uygulama dizini zaten mevcut", "Can't create app folder. Please fix permissions. %s" : "Uygulama dizini oluşturulamıyor. Lütfen izinleri düzeltin. %s", diff --git a/lib/l10n/tr.json b/lib/l10n/tr.json index 52bad09e9cf..b6023ba4e08 100644 --- a/lib/l10n/tr.json +++ b/lib/l10n/tr.json @@ -15,6 +15,8 @@ "No app name specified" : "Uygulama adı belirtilmedi", "Unknown filetype" : "Bilinmeyen dosya türü", "Invalid image" : "Geçersiz resim", + "Database Error" : "Veritabanı Hatası", + "Please contact your system administrator." : "Lütfen sistem yöneticiniz ile iletişime geçin.", "web services under your control" : "denetiminizdeki web hizmetleri", "App directory already exists" : "Uygulama dizini zaten mevcut", "Can't create app folder. Please fix permissions. %s" : "Uygulama dizini oluşturulamıyor. Lütfen izinleri düzeltin. %s", diff --git a/lib/l10n/uk.js b/lib/l10n/uk.js index 6e742fc0b98..5afce6b2ced 100644 --- a/lib/l10n/uk.js +++ b/lib/l10n/uk.js @@ -76,6 +76,12 @@ OC.L10N.register( "last year" : "минулого року", "years ago" : "роки тому", "A valid username must be provided" : "Потрібно задати вірне ім'я користувача", - "A valid password must be provided" : "Потрібно задати вірний пароль" + "A valid password must be provided" : "Потрібно задати вірний пароль", + "No database drivers (sqlite, mysql, or postgresql) installed." : "Не встановлено драйвер бази даних (sqlite, mysql, or postgresql).", + "Cannot write into \"config\" directory" : "Не можу писати у теку \"config\"", + "Cannot write into \"apps\" directory" : "Не можу писати у теку \"apps\"", + "Please ask your server administrator to install the module." : "Будь ласка, зверніться до адміністратора, щоб встановити модуль.", + "PHP module %s not installed." : "%s модуль PHP не встановлено.", + "Please ask your server administrator to restart the web server." : "Будь ласка, зверніться до адміністратора, щоб перезавантажити сервер." }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/lib/l10n/uk.json b/lib/l10n/uk.json index a08191e745a..9c632437ac2 100644 --- a/lib/l10n/uk.json +++ b/lib/l10n/uk.json @@ -74,6 +74,12 @@ "last year" : "минулого року", "years ago" : "роки тому", "A valid username must be provided" : "Потрібно задати вірне ім'я користувача", - "A valid password must be provided" : "Потрібно задати вірний пароль" + "A valid password must be provided" : "Потрібно задати вірний пароль", + "No database drivers (sqlite, mysql, or postgresql) installed." : "Не встановлено драйвер бази даних (sqlite, mysql, or postgresql).", + "Cannot write into \"config\" directory" : "Не можу писати у теку \"config\"", + "Cannot write into \"apps\" directory" : "Не можу писати у теку \"apps\"", + "Please ask your server administrator to install the module." : "Будь ласка, зверніться до адміністратора, щоб встановити модуль.", + "PHP module %s not installed." : "%s модуль PHP не встановлено.", + "Please ask your server administrator to restart the web server." : "Будь ласка, зверніться до адміністратора, щоб перезавантажити сервер." },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" }
\ No newline at end of file diff --git a/lib/l10n/zh_TW.js b/lib/l10n/zh_TW.js index ffb82213e7d..18fcfe06de9 100644 --- a/lib/l10n/zh_TW.js +++ b/lib/l10n/zh_TW.js @@ -12,6 +12,7 @@ OC.L10N.register( "Settings" : "設定", "Users" : "使用者", "Admin" : "管理", + "Recommended" : "建議", "App \\\"%s\\\" can't be installed because it is not compatible with this version of ownCloud." : "無法安裝應用程式 %s 因為它和此版本的 ownCloud 不相容。", "No app name specified" : "沒有指定應用程式名稱", "Unknown filetype" : "未知的檔案類型", diff --git a/lib/l10n/zh_TW.json b/lib/l10n/zh_TW.json index 6c6b572dd50..f6befb07d0a 100644 --- a/lib/l10n/zh_TW.json +++ b/lib/l10n/zh_TW.json @@ -10,6 +10,7 @@ "Settings" : "設定", "Users" : "使用者", "Admin" : "管理", + "Recommended" : "建議", "App \\\"%s\\\" can't be installed because it is not compatible with this version of ownCloud." : "無法安裝應用程式 %s 因為它和此版本的 ownCloud 不相容。", "No app name specified" : "沒有指定應用程式名稱", "Unknown filetype" : "未知的檔案類型", diff --git a/lib/private/app.php b/lib/private/app.php index 73576088d15..bc9ca0351ea 100644 --- a/lib/private/app.php +++ b/lib/private/app.php @@ -1180,10 +1180,6 @@ class OC_App { * @return bool */ public static function updateApp($appId) { - if (file_exists(self::getAppPath($appId) . '/appinfo/preupdate.php')) { - self::loadApp($appId, false); - include self::getAppPath($appId) . '/appinfo/preupdate.php'; - } if (file_exists(self::getAppPath($appId) . '/appinfo/database.xml')) { OC_DB::updateDbFromStructure(self::getAppPath($appId) . '/appinfo/database.xml'); } diff --git a/lib/private/app/appmanager.php b/lib/private/app/appmanager.php new file mode 100644 index 00000000000..6d9aa0bfe37 --- /dev/null +++ b/lib/private/app/appmanager.php @@ -0,0 +1,138 @@ +<?php + +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\App; + +use OCP\App\IAppManager; +use OCP\IAppConfig; +use OCP\IGroupManager; +use OCP\IUserSession; + +class AppManager implements IAppManager { + /** + * @var \OCP\IUserSession + */ + private $userSession; + + /** + * @var \OCP\IAppConfig + */ + private $appConfig; + + /** + * @var \OCP\IGroupManager + */ + private $groupManager; + + /** + * @var string[] $appId => $enabled + */ + private $installedAppsCache; + + /** + * @param \OCP\IUserSession $userSession + * @param \OCP\IAppConfig $appConfig + * @param \OCP\IGroupManager $groupManager + */ + public function __construct(IUserSession $userSession, IAppConfig $appConfig, IGroupManager $groupManager) { + $this->userSession = $userSession; + $this->appConfig = $appConfig; + $this->groupManager = $groupManager; + } + + /** + * @return string[] $appId => $enabled + */ + private function getInstalledApps() { + if (!$this->installedAppsCache) { + $values = $this->appConfig->getValues(false, 'enabled'); + $this->installedAppsCache = array_filter($values, function ($value) { + return $value !== 'no'; + }); + ksort($this->installedAppsCache); + } + return $this->installedAppsCache; + } + + /** + * Check if an app is enabled for user + * + * @param string $appId + * @param \OCP\IUser $user (optional) if not defined, the currently logged in user will be used + * @return bool + */ + public function isEnabledForUser($appId, $user = null) { + if (is_null($user)) { + $user = $this->userSession->getUser(); + } + $installedApps = $this->getInstalledApps(); + if (isset($installedApps[$appId])) { + $enabled = $installedApps[$appId]; + if ($enabled === 'yes') { + return true; + } elseif (is_null($user)) { + return false; + } else { + $groupIds = json_decode($enabled); + $userGroups = $this->groupManager->getUserGroupIds($user); + foreach ($userGroups as $groupId) { + if (array_search($groupId, $groupIds) !== false) { + return true; + } + } + return false; + } + } else { + return false; + } + } + + /** + * Check if an app is installed in the instance + * + * @param string $appId + * @return bool + */ + public function isInstalled($appId) { + $installedApps = $this->getInstalledApps(); + return isset($installedApps[$appId]); + } + + /** + * Enable an app for every user + * + * @param string $appId + */ + public function enableApp($appId) { + $this->appConfig->setValue($appId, 'enabled', 'yes'); + } + + /** + * Enable an app only for specific groups + * + * @param string $appId + * @param \OCP\IGroup[] $groups + */ + public function enableAppForGroups($appId, $groups) { + $groupIds = array_map(function ($group) { + /** @var \OCP\IGroup $group */ + return $group->getGID(); + }, $groups); + $this->appConfig->setValue($appId, 'enabled', json_encode($groupIds)); + } + + /** + * Disable an app for every user + * + * @param string $appId + */ + public function disableApp($appId) { + $this->appConfig->setValue($appId, 'enabled', 'no'); + } +} diff --git a/lib/private/appframework/middleware/security/securitymiddleware.php b/lib/private/appframework/middleware/security/securitymiddleware.php index 948a43ce0f4..8c5ca5891ad 100644 --- a/lib/private/appframework/middleware/security/securitymiddleware.php +++ b/lib/private/appframework/middleware/security/securitymiddleware.php @@ -34,6 +34,8 @@ use OCP\INavigationManager; use OCP\IURLGenerator; use OCP\IRequest; use OCP\ILogger; +use OCP\AppFramework\Controller; +use OCP\Util; /** @@ -110,12 +112,24 @@ class SecurityMiddleware extends Middleware { } } + // CSRF check - also registers the CSRF token since the session may be closed later + Util::callRegister(); if(!$this->reflector->hasAnnotation('NoCSRFRequired')) { if(!$this->request->passesCSRFCheck()) { throw new SecurityException('CSRF check failed', Http::STATUS_PRECONDITION_FAILED); } } + /** + * FIXME: Use DI once available + * Checks if app is enabled (also inclues a check whether user is allowed to access the resource) + * The getAppPath() check is here since components such as settings also use the AppFramework and + * therefore won't pass this check. + */ + if(\OC_App::getAppPath($this->appName) !== false && !\OC_App::isEnabled($this->appName)) { + throw new SecurityException('App is not enabled', Http::STATUS_PRECONDITION_FAILED); + } + } diff --git a/lib/private/appframework/utility/simplecontainer.php b/lib/private/appframework/utility/simplecontainer.php index c6effed5b4b..55b9cf7a977 100644 --- a/lib/private/appframework/utility/simplecontainer.php +++ b/lib/private/appframework/utility/simplecontainer.php @@ -35,7 +35,7 @@ class SimpleContainer extends \Pimple\Container implements \OCP\IContainer { * @param bool $shared */ function registerService($name, \Closure $closure, $shared = true) { - if (!empty($this[$name])) { + if (isset($this[$name])) { unset($this[$name]); } if ($shared) { diff --git a/lib/private/config.php b/lib/private/config.php index f0548442ab5..cc07d6a1ed1 100644 --- a/lib/private/config.php +++ b/lib/private/config.php @@ -138,12 +138,12 @@ class Config { // Include file and merge config foreach ($configFiles as $file) { - if($file === $this->configFilePath && !@touch($file)) { - // Writing to the main config might not be possible, e.g. if the wrong + $filePointer = @fopen($file, 'r'); + if($file === $this->configFilePath && $filePointer === false) { + // Opening the main config might not be possible, e.g. if the wrong // permissions are set (likely on a new installation) continue; } - $filePointer = fopen($file, 'r'); // Try to acquire a file lock if(!flock($filePointer, LOCK_SH)) { diff --git a/lib/private/connector/sabre/appenabledplugin.php b/lib/private/connector/sabre/appenabledplugin.php new file mode 100644 index 00000000000..61f5170658d --- /dev/null +++ b/lib/private/connector/sabre/appenabledplugin.php @@ -0,0 +1,75 @@ +<?php + +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Connector\Sabre; + +use OCP\App\IAppManager; +use Sabre\DAV\Exception\Forbidden; +use Sabre\DAV\ServerPlugin; + +/** + * Plugin to check if an app is enabled for the current user + */ +class AppEnabledPlugin extends ServerPlugin { + + /** + * Reference to main server object + * + * @var \Sabre\DAV\Server + */ + private $server; + + /** + * @var string + */ + private $app; + + /** + * @var \OCP\App\IAppManager + */ + private $appManager; + + /** + * @param string $app + * @param \OCP\App\IAppManager $appManager + */ + public function __construct($app, IAppManager $appManager) { + $this->app = $app; + $this->appManager = $appManager; + } + + /** + * This initializes the plugin. + * + * This function is called by \Sabre\DAV\Server, after + * addPlugin is called. + * + * This method should set up the required event subscriptions. + * + * @param \Sabre\DAV\Server $server + * @return void + */ + public function initialize(\Sabre\DAV\Server $server) { + + $this->server = $server; + $this->server->subscribeEvent('beforeMethod', array($this, 'checkAppEnabled'), 30); + } + + /** + * This method is called before any HTTP after auth and checks if the user has access to the app + * + * @throws \Sabre\DAV\Exception\Forbidden + * @return bool + */ + public function checkAppEnabled() { + if (!$this->appManager->isEnabledForUser($this->app)) { + throw new Forbidden(); + } + } +} diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php index 3705d299bfc..d93b8e68eb6 100644 --- a/lib/private/connector/sabre/file.php +++ b/lib/private/connector/sabre/file.php @@ -219,6 +219,10 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements \Sabre\ public function getContentType() { $mimeType = $this->info->getMimetype(); + // PROPFIND needs to return the correct mime type, for consistency with the web UI + if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'PROPFIND' ) { + return $mimeType; + } return \OC_Helper::getSecureMimeType($mimeType); } diff --git a/lib/private/davclient.php b/lib/private/davclient.php deleted file mode 100644 index 6a544d27068..00000000000 --- a/lib/private/davclient.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php -/** - * ownCloud - * - * @author Vincent Petry - * @copyright 2013 Vincent Petry <pvince81@owncloud.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - * - */ - -/** - * This class extends the SabreDAV client with additional functionality - * like request timeout. - */ - -class OC_DAVClient extends \Sabre\DAV\Client { - - protected $requestTimeout; - - protected $verifyHost; - - /** - * Sets the request timeout or 0 to disable timeout. - * @param integer $timeout in seconds or 0 to disable - */ - public function setRequestTimeout($timeout) { - $this->requestTimeout = (int)$timeout; - } - - /** - * Sets the CURLOPT_SSL_VERIFYHOST setting - * @param integer $value value to set CURLOPT_SSL_VERIFYHOST to - */ - public function setVerifyHost($value) { - $this->verifyHost = $value; - } - - protected function curlRequest($url, $settings) { - if ($this->requestTimeout > 0) { - $settings[CURLOPT_TIMEOUT] = $this->requestTimeout; - } - if (!is_null($this->verifyHost)) { - $settings[CURLOPT_SSL_VERIFYHOST] = $this->verifyHost; - } - return parent::curlRequest($url, $settings); - } -} diff --git a/lib/private/db/adapter.php b/lib/private/db/adapter.php index 972008776f6..58b3514b922 100644 --- a/lib/private/db/adapter.php +++ b/lib/private/db/adapter.php @@ -43,6 +43,7 @@ class Adapter { * insert the @input values when they do not exist yet * @param string $table name * @param array $input key->value pair, key has to be sanitized properly + * @throws \OC\HintException * @return int count of inserted rows */ public function insertIfNotExist($table, $input) { @@ -70,8 +71,13 @@ class Adapter { $entry = 'DB Error: "'.$e->getMessage() . '"<br />'; $entry .= 'Offending command was: ' . $query.'<br />'; \OC_Log::write('core', $entry, \OC_Log::FATAL); - error_log('DB error: ' . $entry); - \OC_Template::printErrorPage( $entry ); + $l = \OC::$server->getL10N('lib'); + throw new \OC\HintException( + $l->t('Database Error'), + $l->t('Please contact your system administrator.'), + 0, + $e + ); } } } diff --git a/lib/private/db/adaptersqlite.php b/lib/private/db/adaptersqlite.php index 3471fcf4042..c5dfa85aaac 100644 --- a/lib/private/db/adaptersqlite.php +++ b/lib/private/db/adaptersqlite.php @@ -41,8 +41,13 @@ class AdapterSqlite extends Adapter { $entry = 'DB Error: "'.$e->getMessage() . '"<br />'; $entry .= 'Offending command was: ' . $query . '<br />'; \OC_Log::write('core', $entry, \OC_Log::FATAL); - error_log('DB error: '.$entry); - \OC_Template::printErrorPage( $entry ); + $l = \OC::$server->getL10N('lib'); + throw new \OC\HintException( + $l->t('Database Error'), + $l->t('Please contact your system administrator.'), + 0, + $e + ); } if ($stmt->fetchColumn() === '0') { @@ -60,8 +65,13 @@ class AdapterSqlite extends Adapter { $entry = 'DB Error: "'.$e->getMessage() . '"<br />'; $entry .= 'Offending command was: ' . $query.'<br />'; \OC_Log::write('core', $entry, \OC_Log::FATAL); - error_log('DB error: ' . $entry); - \OC_Template::printErrorPage( $entry ); + $l = \OC::$server->getL10N('lib'); + throw new \OC\HintException( + $l->t('Database Error'), + $l->t('Please contact your system administrator.'), + 0, + $e + ); } return $result; diff --git a/lib/private/db/oracleconnection.php b/lib/private/db/oracleconnection.php index e2fc4644f47..4cec7bc4ae4 100644 --- a/lib/private/db/oracleconnection.php +++ b/lib/private/db/oracleconnection.php @@ -20,7 +20,7 @@ class OracleConnection extends Connection { return $return; } - /* + /** * {@inheritDoc} */ public function insert($tableName, array $data, array $types = array()) { @@ -29,7 +29,7 @@ class OracleConnection extends Connection { return parent::insert($tableName, $data, $types); } - /* + /** * {@inheritDoc} */ public function update($tableName, array $data, array $identifier, array $types = array()) { @@ -39,11 +39,11 @@ class OracleConnection extends Connection { return parent::update($tableName, $data, $identifier, $types); } - /* + /** * {@inheritDoc} */ - public function delete($tableName, array $identifier) { - $tableName = $this->quoteIdentifier($tableName); + public function delete($tableExpression, array $identifier, array $types = array()) { + $tableName = $this->quoteIdentifier($tableExpression); $identifier = $this->quoteKeys($identifier); return parent::delete($tableName, $identifier); } diff --git a/lib/private/db/statementwrapper.php b/lib/private/db/statementwrapper.php index ad63de98e93..a85c0167e0b 100644 --- a/lib/private/db/statementwrapper.php +++ b/lib/private/db/statementwrapper.php @@ -64,7 +64,7 @@ class OC_DB_StatementWrapper { } else { $result = $this->statement->execute(); } - + if ($result === false) { return false; } @@ -158,14 +158,16 @@ class OC_DB_StatementWrapper { OC_Log::write('core', $entry, OC_Log::FATAL); OC_User::setUserId(null); - // send http status 503 - header('HTTP/1.1 503 Service Temporarily Unavailable'); - header('Status: 503 Service Temporarily Unavailable'); - OC_Template::printErrorPage('Failed to connect to database'); - die ($entry); + $l = \OC::$server->getL10N('lib'); + throw new \OC\HintException( + $l->t('Database Error'), + $l->t('Please contact your system administrator.'), + 0, + $e + ); } } - + /** * provide an alias for fetch * diff --git a/lib/private/files/fileinfo.php b/lib/private/files/fileinfo.php index 8457a2d160f..d6d6a245e44 100644 --- a/lib/private/files/fileinfo.php +++ b/lib/private/files/fileinfo.php @@ -122,7 +122,7 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { * @return int */ public function getSize() { - return $this->data['size']; + return isset($this->data['size']) ? $this->data['size'] : 0; } /** diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php index c7dc99c55cb..6c8fa8c90ba 100644 --- a/lib/private/files/filesystem.php +++ b/lib/private/files/filesystem.php @@ -698,13 +698,22 @@ class Filesystem { * @param bool $stripTrailingSlash * @return string */ - public static function normalizePath($path, $stripTrailingSlash = true) { + public static function normalizePath($path, $stripTrailingSlash = true, $isAbsolutePath = false) { if ($path == '') { return '/'; } + //no windows style slashes $path = str_replace('\\', '/', $path); + // When normalizing an absolute path, we need to ensure that the drive-letter + // is still at the beginning on windows + $windows_drive_letter = ''; + if ($isAbsolutePath && \OC_Util::runningOnWindows() && preg_match('#^([a-zA-Z])$#', $path[0]) && $path[1] == ':' && $path[2] == '/') { + $windows_drive_letter = substr($path, 0, 2); + $path = substr($path, 2); + } + //add leading slash if ($path[0] !== '/') { $path = '/' . $path; @@ -733,7 +742,7 @@ class Filesystem { //normalize unicode if possible $path = \OC_Util::normalizeUnicode($path); - return $path; + return $windows_drive_letter . $path; } /** diff --git a/lib/private/files/storage/dav.php b/lib/private/files/storage/dav.php index 7f53704e94f..26fa69408a8 100644 --- a/lib/private/files/storage/dav.php +++ b/lib/private/files/storage/dav.php @@ -433,6 +433,7 @@ class DAV extends \OC\Files\Storage\Common { public function getPermissions($path) { $this->init(); + $path = $this->cleanPath($path); $response = $this->client->propfind($this->encodePath($path), array('{http://owncloud.org/ns}permissions')); if (isset($response['{http://owncloud.org/ns}permissions'])) { return $this->parsePermissions($response['{http://owncloud.org/ns}permissions']); @@ -477,6 +478,7 @@ class DAV extends \OC\Files\Storage\Common { */ public function hasUpdated($path, $time) { $this->init(); + $path = $this->cleanPath($path); try { $response = $this->client->propfind($this->encodePath($path), array( '{DAV:}getlastmodified', diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 0e4da30f7b9..19676524a0e 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -676,10 +676,6 @@ class View { $this->mkdir($filePath); } - if (!$tmpFile) { - debug_print_backtrace(); - } - $source = fopen($tmpFile, 'r'); if ($source) { $this->file_put_contents($path, $source); diff --git a/lib/private/group/database.php b/lib/private/group/database.php index 8aebefabd27..6bad55c8d5e 100644 --- a/lib/private/group/database.php +++ b/lib/private/group/database.php @@ -84,6 +84,10 @@ class OC_Group_Database extends OC_Group_Backend { $stmt = OC_DB::prepare( "DELETE FROM `*PREFIX*group_user` WHERE `gid` = ?" ); $stmt->execute( array( $gid )); + // Delete the group-groupadmin relation + $stmt = OC_DB::prepare( "DELETE FROM `*PREFIX*group_admin` WHERE `gid` = ?" ); + $stmt->execute( array( $gid )); + return true; } diff --git a/lib/private/preview.php b/lib/private/preview.php index dbbe173bf80..f50bdcb4c9e 100644 --- a/lib/private/preview.php +++ b/lib/private/preview.php @@ -48,6 +48,7 @@ class Preview { //filemapper used for deleting previews // index is path, value is fileinfo static public $deleteFileMapper = array(); + static public $deleteChildrenMapper = array(); /** * preview images object @@ -189,6 +190,21 @@ class Preview { return $this->info; } + + /** + * @return array|null + */ + private function getChildren() { + $absPath = $this->fileView->getAbsolutePath($this->file); + $absPath = Files\Filesystem::normalizePath($absPath); + + if (array_key_exists($absPath, self::$deleteChildrenMapper)) { + return self::$deleteChildrenMapper[$absPath]; + } + + return null; + } + /** * set the path of the file you want a thumbnail from * @param string $file @@ -269,6 +285,10 @@ class Preview { return $this; } + /** + * @param bool $keepAspect + * @return $this + */ public function setKeepAspect($keepAspect) { $this->keepAspect = $keepAspect; return $this; @@ -312,20 +332,25 @@ class Preview { /** * deletes all previews of a file - * @return bool */ public function deleteAllPreviews() { $file = $this->getFile(); $fileInfo = $this->getFileInfo($file); - if($fileInfo !== null && $fileInfo !== false) { - $fileId = $fileInfo->getId(); - $previewPath = $this->getPreviewPath($fileId); - $this->userView->deleteAll($previewPath); - return $this->userView->rmdir($previewPath); + $toDelete = $this->getChildren(); + $toDelete[] = $fileInfo; + + foreach ($toDelete as $delete) { + if ($delete !== null && $delete !== false) { + /** @var \OCP\Files\FileInfo $delete */ + $fileId = $delete->getId(); + + $previewPath = $this->getPreviewPath($fileId); + $this->userView->deleteAll($previewPath); + $this->userView->rmdir($previewPath); + } } - return false; } /** @@ -667,8 +692,8 @@ class Preview { } /** - * Register a new preview provider to be used - * @param $class + * register a new preview provider to be used + * @param string $class * @param array $options */ public static function registerProvider($class, $options = array()) { @@ -737,14 +762,24 @@ class Preview { } + /** + * @param array $args + */ public static function post_write($args) { self::post_delete($args, 'files/'); } + /** + * @param array $args + */ public static function prepare_delete_files($args) { self::prepare_delete($args, 'files/'); } + /** + * @param array $args + * @param string $prefix + */ public static function prepare_delete($args, $prefix='') { $path = $args['path']; if (substr($path, 0, 1) === '/') { @@ -752,20 +787,63 @@ class Preview { } $view = new \OC\Files\View('/' . \OC_User::getUser() . '/' . $prefix); - $info = $view->getFileInfo($path); - \OC\Preview::$deleteFileMapper = array_merge( - \OC\Preview::$deleteFileMapper, - array( - Files\Filesystem::normalizePath($view->getAbsolutePath($path)) => $info, - ) - ); + $absPath = Files\Filesystem::normalizePath($view->getAbsolutePath($path)); + self::addPathToDeleteFileMapper($absPath, $view->getFileInfo($path)); + if ($view->is_dir($path)) { + $children = self::getAllChildren($view, $path); + self::$deleteChildrenMapper[$absPath] = $children; + } + } + + /** + * @param string $absolutePath + * @param \OCP\Files\FileInfo $info + */ + private static function addPathToDeleteFileMapper($absolutePath, $info) { + self::$deleteFileMapper[$absolutePath] = $info; + } + + /** + * @param \OC\Files\View $view + * @param string $path + * @return array + */ + private static function getAllChildren($view, $path) { + $children = $view->getDirectoryContent($path); + $childrensFiles = array(); + + $fakeRootLength = strlen($view->getRoot()); + + for ($i = 0; $i < count($children); $i++) { + $child = $children[$i]; + + $childsPath = substr($child->getPath(), $fakeRootLength); + + if ($view->is_dir($childsPath)) { + $children = array_merge( + $children, + $view->getDirectoryContent($childsPath) + ); + } else { + $childrensFiles[] = $child; + } + } + + return $childrensFiles; } + /** + * @param array $args + */ public static function post_delete_files($args) { self::post_delete($args, 'files/'); } + /** + * @param array $args + * @param string $prefix + */ public static function post_delete($args, $prefix='') { $path = Files\Filesystem::normalizePath($args['path']); diff --git a/lib/private/preview/office-cl.php b/lib/private/preview/office-cl.php index 42d2cbf34fc..f5c791e37f2 100644 --- a/lib/private/preview/office-cl.php +++ b/lib/private/preview/office-cl.php @@ -29,7 +29,7 @@ if (!\OC_Util::runningOnWindows()) { $tmpDir = get_temp_dir(); - $defaultParameters = ' -env:UserInstallation=file://' . escapeshellarg($tmpDir . '/owncloud-' . \OC_Util::getInstanceId().'/') . ' --headless --nologo --nofirststartwizard --invisible --norestore -convert-to pdf -outdir '; + $defaultParameters = ' -env:UserInstallation=file://' . escapeshellarg($tmpDir . '/owncloud-' . \OC_Util::getInstanceId().'/') . ' --headless --nologo --nofirststartwizard --invisible --norestore --convert-to pdf --outdir '; $clParameters = \OCP\Config::getSystemValue('preview_office_cl_parameters', $defaultParameters); $exec = $this->cmd . $clParameters . escapeshellarg($tmpDir) . ' ' . escapeshellarg($absPath); diff --git a/lib/private/route/router.php b/lib/private/route/router.php index 645d6141964..5d6f621dc38 100644 --- a/lib/private/route/router.php +++ b/lib/private/route/router.php @@ -243,7 +243,6 @@ class Router implements IRouter { if (isset($parameters['action'])) { $action = $parameters['action']; if (!is_callable($action)) { - var_dump($action); throw new \Exception('not a callable action'); } unset($parameters['action']); diff --git a/lib/private/security/certificatemanager.php b/lib/private/security/certificatemanager.php index cae9730eb26..a2a4c8b83d2 100644 --- a/lib/private/security/certificatemanager.php +++ b/lib/private/security/certificatemanager.php @@ -49,6 +49,7 @@ class CertificateManager implements ICertificateManager { } catch(\Exception $e) {} } } + closedir($handle); return $result; } diff --git a/lib/private/server.php b/lib/private/server.php index f43613e8188..c413ee8bf6d 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -237,6 +237,12 @@ class Server extends SimpleContainer implements IServerContainer { /** @var Server $c */ return new TempManager(get_temp_dir(), $c->getLogger()); }); + $this->registerService('AppManager', function(Server $c) { + $userSession = $c->getUserSession(); + $appConfig = $c->getAppConfig(); + $groupManager = $c->getGroupManager(); + return new \OC\App\AppManager($userSession, $appConfig, $groupManager); + }); } /** @@ -616,4 +622,13 @@ class Server extends SimpleContainer implements IServerContainer { function getTempManager() { return $this->query('TempManager'); } + + /** + * Get the app manager + * + * @return \OCP\App\IAppManager + */ + function getAppManager() { + return $this->query('AppManager'); + } } diff --git a/lib/private/share/share.php b/lib/private/share/share.php index b7b05dab8ef..cd5decf6f71 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -288,9 +288,10 @@ class Share extends \OC\Share\Constants { * @param string $itemType * @param string $itemSource * @param string $user User user to whom the item was shared + * @param int $shareType only look for a specific share type * @return array Return list of items with file_target, permissions and expiration */ - public static function getItemSharedWithUser($itemType, $itemSource, $user) { + public static function getItemSharedWithUser($itemType, $itemSource, $user, $shareType = null) { $shares = array(); $fileDependend = false; @@ -314,6 +315,11 @@ class Share extends \OC\Share\Constants { $arguments[] = $user; } + if ($shareType !== null) { + $where .= ' AND `share_type` = ? '; + $arguments[] = $shareType; + } + $query = \OC_DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` '. $where); $result = \OC_DB::executeAudited($query, $arguments); @@ -697,7 +703,7 @@ class Share extends \OC\Share\Constants { // check if it is a valid itemType self::getBackend($itemType); - $items = self::getItemSharedWithUser($itemType, $itemSource, $shareWith); + $items = self::getItemSharedWithUser($itemType, $itemSource, $shareWith, $shareType); $toDelete = array(); $newParent = null; @@ -1308,14 +1314,18 @@ class Share extends \OC\Share\Constants { if (isset($shareType)) { // Include all user and group items if ($shareType == self::$shareTypeUserAndGroups && isset($shareWith)) { - $where .= ' AND `share_type` IN (?,?,?)'; + $where .= ' AND ((`share_type` in (?, ?) AND `share_with` = ?) '; $queryArgs[] = self::SHARE_TYPE_USER; - $queryArgs[] = self::SHARE_TYPE_GROUP; $queryArgs[] = self::$shareTypeGroupUserUnique; - $userAndGroups = array_merge(array($shareWith), \OC_Group::getUserGroups($shareWith)); - $placeholders = join(',', array_fill(0, count($userAndGroups), '?')); - $where .= ' AND `share_with` IN ('.$placeholders.')'; - $queryArgs = array_merge($queryArgs, $userAndGroups); + $queryArgs[] = $shareWith; + $groups = \OC_Group::getUserGroups($shareWith); + if (!empty($groups)) { + $placeholders = join(',', array_fill(0, count($groups), '?')); + $where .= ' OR (`share_type` = ? AND `share_with` IN ('.$placeholders.')) '; + $queryArgs[] = self::SHARE_TYPE_GROUP; + $queryArgs = array_merge($queryArgs, $groups); + } + $where .= ')'; // Don't include own group shares $where .= ' AND `uid_owner` != ?'; $queryArgs[] = $shareWith; @@ -1506,8 +1516,11 @@ class Share extends \OC\Share\Constants { $row['permissions'] &= ~\OCP\PERMISSION_SHARE; } // Add display names to result - if ( isset($row['share_with']) && $row['share_with'] != '') { + if ( isset($row['share_with']) && $row['share_with'] != '' && + isset($row['share_with']) && $row['share_type'] === self::SHARE_TYPE_USER) { $row['share_with_displayname'] = \OCP\User::getDisplayName($row['share_with']); + } else { + $row['share_with_displayname'] = $row['share_with']; } if ( isset($row['uid_owner']) && $row['uid_owner'] != '') { $row['displayname_owner'] = \OCP\User::getDisplayName($row['uid_owner']); diff --git a/lib/private/template.php b/lib/private/template.php index 9ad9d5466db..bda802fd2e2 100644 --- a/lib/private/template.php +++ b/lib/private/template.php @@ -50,16 +50,13 @@ class OC_Template extends \OC\Template\Base { // Read the selected theme from the config file $theme = OC_Util::getTheme(); - // Read the detected formfactor and use the right file name. - $fext = self::getFormFactorExtension(); - $requesttoken = (OC::$server->getSession() and $registerCall) ? OC_Util::callRegister() : ''; $parts = explode('/', $app); // fix translation when app is something like core/lostpassword $l10n = \OC::$server->getL10N($parts[0]); $themeDefaults = new OC_Defaults(); - list($path, $template) = $this->findTemplate($theme, $app, $name, $fext); + list($path, $template) = $this->findTemplate($theme, $app, $name); // Set the private data $this->renderas = $renderas; @@ -70,85 +67,23 @@ class OC_Template extends \OC\Template\Base { } /** - * autodetect the formfactor of the used device - * default -> the normal desktop browser interface - * mobile -> interface for smartphones - * tablet -> interface for tablets - * standalone -> the default interface but without header, footer and - * sidebar, just the application. Useful to use just a specific - * app on the desktop in a standalone window. - */ - public static function detectFormfactor() { - // please add more useragent strings for other devices - if(isset($_SERVER['HTTP_USER_AGENT'])) { - if(stripos($_SERVER['HTTP_USER_AGENT'], 'ipad')>0) { - $mode='tablet'; - }elseif(stripos($_SERVER['HTTP_USER_AGENT'], 'iphone')>0) { - $mode='mobile'; - }elseif((stripos($_SERVER['HTTP_USER_AGENT'], 'N9')>0) - and (stripos($_SERVER['HTTP_USER_AGENT'], 'nokia')>0)) { - $mode='mobile'; - }else{ - $mode='default'; - } - }else{ - $mode='default'; - } - return($mode); - } - - /** - * Returns the formfactor extension for current formfactor - */ - static public function getFormFactorExtension() - { - if (!\OC::$server->getSession()) { - return ''; - } - // if the formfactor is not yet autodetected do the - // autodetection now. For possible formfactors check the - // detectFormfactor documentation - if (!\OC::$server->getSession()->exists('formfactor')) { - \OC::$server->getSession()->set('formfactor', self::detectFormfactor()); - } - // allow manual override via GET parameter - if(isset($_GET['formfactor'])) { - \OC::$server->getSession()->set('formfactor', $_GET['formfactor']); - } - $formfactor = \OC::$server->getSession()->get('formfactor'); - if($formfactor==='default') { - $fext=''; - }elseif($formfactor==='mobile') { - $fext='.mobile'; - }elseif($formfactor==='tablet') { - $fext='.tablet'; - }elseif($formfactor==='standalone') { - $fext='.standalone'; - }else{ - $fext=''; - } - return $fext; - } - - /** * find the template with the given name * @param string $name of the template file (without suffix) * - * Will select the template file for the selected theme and formfactor. + * Will select the template file for the selected theme. * Checking all the possible locations. * @param string $theme * @param string $app - * @param string $fext * @return array */ - protected function findTemplate($theme, $app, $name, $fext) { + protected function findTemplate($theme, $app, $name) { // Check if it is a app template or not. if( $app !== '' ) { $dirs = $this->getAppTemplateDirs($theme, $app, OC::$SERVERROOT, OC_App::getAppPath($app)); } else { $dirs = $this->getCoreTemplateDirs($theme, OC::$SERVERROOT); } - $locator = new \OC\Template\TemplateFileLocator( $fext, $dirs ); + $locator = new \OC\Template\TemplateFileLocator( $dirs ); $template = $locator->find($name); $path = $locator->getPath(); return array($path, $template); diff --git a/lib/private/template/cssresourcelocator.php b/lib/private/template/cssresourcelocator.php index e26daa25827..cb129261b51 100644 --- a/lib/private/template/cssresourcelocator.php +++ b/lib/private/template/cssresourcelocator.php @@ -12,9 +12,7 @@ class CSSResourceLocator extends ResourceLocator { public function doFind( $style ) { if (strpos($style, '3rdparty') === 0 && $this->appendIfExist($this->thirdpartyroot, $style.'.css') - || $this->appendIfExist($this->serverroot, $style.$this->form_factor.'.css') || $this->appendIfExist($this->serverroot, $style.'.css') - || $this->appendIfExist($this->serverroot, 'core/'.$style.$this->form_factor.'.css') || $this->appendIfExist($this->serverroot, 'core/'.$style.'.css') ) { return; @@ -23,8 +21,7 @@ class CSSResourceLocator extends ResourceLocator { $style = substr($style, strpos($style, '/')+1); $app_path = \OC_App::getAppPath($app); $app_url = \OC_App::getAppWebPath($app); - if ($this->appendIfExist($app_path, $style.$this->form_factor.'.css', $app_url) - || $this->appendIfExist($app_path, $style.'.css', $app_url) + if ($this->appendIfExist($app_path, $style.'.css', $app_url) ) { return; } @@ -33,11 +30,8 @@ class CSSResourceLocator extends ResourceLocator { public function doFindTheme( $style ) { $theme_dir = 'themes/'.$this->theme.'/'; - $this->appendIfExist($this->serverroot, $theme_dir.'apps/'.$style.$this->form_factor.'.css') - || $this->appendIfExist($this->serverroot, $theme_dir.'apps/'.$style.'.css') - || $this->appendIfExist($this->serverroot, $theme_dir.$style.$this->form_factor.'.css') + $this->appendIfExist($this->serverroot, $theme_dir.'apps/'.$style.'.css') || $this->appendIfExist($this->serverroot, $theme_dir.$style.'.css') - || $this->appendIfExist($this->serverroot, $theme_dir.'core/'.$style.$this->form_factor.'.css') || $this->appendIfExist($this->serverroot, $theme_dir.'core/'.$style.'.css'); } } diff --git a/lib/private/template/jsresourcelocator.php b/lib/private/template/jsresourcelocator.php index 507f31327a6..5a6672429cf 100644 --- a/lib/private/template/jsresourcelocator.php +++ b/lib/private/template/jsresourcelocator.php @@ -13,15 +13,10 @@ class JSResourceLocator extends ResourceLocator { $theme_dir = 'themes/'.$this->theme.'/'; if (strpos($script, '3rdparty') === 0 && $this->appendIfExist($this->thirdpartyroot, $script.'.js') - || $this->appendIfExist($this->serverroot, $theme_dir.'apps/'.$script.$this->form_factor.'.js') || $this->appendIfExist($this->serverroot, $theme_dir.'apps/'.$script.'.js') - || $this->appendIfExist($this->serverroot, $theme_dir.$script.$this->form_factor.'.js') || $this->appendIfExist($this->serverroot, $theme_dir.$script.'.js') - || $this->appendIfExist($this->serverroot, $script.$this->form_factor.'.js') || $this->appendIfExist($this->serverroot, $script.'.js') - || $this->appendIfExist($this->serverroot, $theme_dir.'core/'.$script.$this->form_factor.'.js') || $this->appendIfExist($this->serverroot, $theme_dir.'core/'.$script.'.js') - || $this->appendIfExist($this->serverroot, 'core/'.$script.$this->form_factor.'.js') || $this->appendIfExist($this->serverroot, 'core/'.$script.'.js') ) { return; @@ -30,9 +25,7 @@ class JSResourceLocator extends ResourceLocator { $script = substr($script, strpos($script, '/')+1); $app_path = \OC_App::getAppPath($app); $app_url = \OC_App::getAppWebPath($app); - if ($this->appendIfExist($app_path, $script.$this->form_factor.'.js', $app_url) - || $this->appendIfExist($app_path, $script.'.js', $app_url) - ) { + if ($this->appendIfExist($app_path, $script.'.js', $app_url)) { return; } // missing translations files fill be ignored diff --git a/lib/private/template/resourcelocator.php b/lib/private/template/resourcelocator.php index 7976c415922..919665df704 100644 --- a/lib/private/template/resourcelocator.php +++ b/lib/private/template/resourcelocator.php @@ -10,7 +10,6 @@ namespace OC\Template; abstract class ResourceLocator { protected $theme; - protected $form_factor; protected $mapping; protected $serverroot; @@ -21,11 +20,9 @@ abstract class ResourceLocator { /** * @param string $theme - * @param string $form_factor */ - public function __construct( $theme, $form_factor, $core_map, $party_map ) { + public function __construct( $theme, $core_map, $party_map ) { $this->theme = $theme; - $this->form_factor = $form_factor; $this->mapping = $core_map + $party_map; $this->serverroot = key($core_map); $this->thirdpartyroot = key($party_map); @@ -46,8 +43,7 @@ abstract class ResourceLocator { } } } catch (\Exception $e) { - throw new \Exception($e->getMessage().' formfactor:'.$this->form_factor - .' serverroot:'.$this->serverroot); + throw new \Exception($e->getMessage().' serverroot:'.$this->serverroot); } } diff --git a/lib/private/template/templatefilelocator.php b/lib/private/template/templatefilelocator.php index 8e9f3bd8100..042298389c8 100644 --- a/lib/private/template/templatefilelocator.php +++ b/lib/private/template/templatefilelocator.php @@ -9,16 +9,13 @@ namespace OC\Template; class TemplateFileLocator { - protected $form_factor; protected $dirs; private $path; /** * @param string[] $dirs - * @param string $form_factor */ - public function __construct( $form_factor, $dirs ) { - $this->form_factor = $form_factor; + public function __construct( $dirs ) { $this->dirs = $dirs; } @@ -33,18 +30,13 @@ class TemplateFileLocator { } foreach($this->dirs as $dir) { - $file = $dir.$template.$this->form_factor.'.php'; - if (is_file($file)) { - $this->path = $dir; - return $file; - } $file = $dir.$template.'.php'; if (is_file($file)) { $this->path = $dir; return $file; } } - throw new \Exception('template file not found: template:'.$template.' formfactor:'.$this->form_factor); + throw new \Exception('template file not found: template:'.$template); } public function getPath() { diff --git a/lib/private/templatelayout.php b/lib/private/templatelayout.php index a93449f202f..a066f90bb23 100644 --- a/lib/private/templatelayout.php +++ b/lib/private/templatelayout.php @@ -131,10 +131,7 @@ class OC_TemplateLayout extends OC_Template { // Read the selected theme from the config file $theme = OC_Util::getTheme(); - // Read the detected form factor and use the right file name. - $formFactorExt = self::getFormFactorExtension(); - - $locator = new \OC\Template\CSSResourceLocator( $theme, $formFactorExt, + $locator = new \OC\Template\CSSResourceLocator( $theme, array( OC::$SERVERROOT => OC::$WEBROOT ), array( OC::$THIRDPARTYROOT => OC::$THIRDPARTYWEBROOT )); $locator->find($styles); @@ -149,10 +146,7 @@ class OC_TemplateLayout extends OC_Template { // Read the selected theme from the config file $theme = OC_Util::getTheme(); - // Read the detected form factor and use the right file name. - $formFactorExt = self::getFormFactorExtension(); - - $locator = new \OC\Template\JSResourceLocator( $theme, $formFactorExt, + $locator = new \OC\Template\JSResourceLocator( $theme, array( OC::$SERVERROOT => OC::$WEBROOT ), array( OC::$THIRDPARTYROOT => OC::$THIRDPARTYWEBROOT )); $locator->find($scripts); diff --git a/lib/private/updater.php b/lib/private/updater.php index c4c70a3cc4a..e07ff03ffc4 100644 --- a/lib/private/updater.php +++ b/lib/private/updater.php @@ -245,7 +245,6 @@ class Updater extends BasicEmitter { protected function checkAppUpgrade($version) { $apps = \OC_App::getEnabledApps(); - foreach ($apps as $appId) { if ($version) { $info = \OC_App::getAppInfo($appId); @@ -255,6 +254,15 @@ class Updater extends BasicEmitter { } if ($compatible && \OC_App::shouldUpgrade($appId)) { + /** + * FIXME: The preupdate check is performed before the database migration, otherwise database changes + * are not possible anymore within it. - Consider this when touching the code. + * @link https://github.com/owncloud/core/issues/10980 + * @see \OC_App::updateApp + */ + if (file_exists(\OC_App::getAppPath($appId) . '/appinfo/preupdate.php')) { + $this->includePreUpdate($appId); + } if (file_exists(\OC_App::getAppPath($appId) . '/appinfo/database.xml')) { \OC_DB::simulateUpdateDbFromStructure(\OC_App::getAppPath($appId) . '/appinfo/database.xml'); } @@ -264,6 +272,14 @@ class Updater extends BasicEmitter { $this->emit('\OC\Updater', 'appUpgradeCheck'); } + /** + * Includes the pre-update file. Done here to prevent namespace mixups. + * @param string $appId + */ + private function includePreUpdate($appId) { + include \OC_App::getAppPath($appId) . '/appinfo/preupdate.php'; + } + protected function doAppUpgrade() { $apps = \OC_App::getEnabledApps(); diff --git a/lib/private/user/user.php b/lib/private/user/user.php index 452261a75ff..729abdc6227 100644 --- a/lib/private/user/user.php +++ b/lib/private/user/user.php @@ -115,7 +115,7 @@ class User implements IUser { */ public function setDisplayName($displayName) { $displayName = trim($displayName); - if ($this->canChangeDisplayName() && !empty($displayName)) { + if ($this->backend->implementsActions(\OC_USER_BACKEND_SET_DISPLAYNAME) && !empty($displayName)) { $this->displayName = $displayName; $result = $this->backend->setDisplayName($this->uid, $displayName); return $result !== false; diff --git a/lib/public/app/iappmanager.php b/lib/public/app/iappmanager.php new file mode 100644 index 00000000000..ebd84a1ce9d --- /dev/null +++ b/lib/public/app/iappmanager.php @@ -0,0 +1,51 @@ +<?php + +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCP\App; + +interface IAppManager { + /** + * Check if an app is enabled for user + * + * @param string $appId + * @param \OCP\IUser $user (optional) if not defined, the currently loggedin user will be used + * @return bool + */ + public function isEnabledForUser($appId, $user = null); + + /** + * Check if an app is installed in the instance + * + * @param string $appId + * @return bool + */ + public function isInstalled($appId); + + /** + * Enable an app for every user + * + * @param string $appId + */ + public function enableApp($appId); + + /** + * Enable an app only for specific groups + * + * @param string $appId + * @param \OCP\IGroup[] $groups + */ + public function enableAppForGroups($appId, $groups); + + /** + * Disable an app for every user + * + * @param string $appId + */ + public function disableApp($appId); +} diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php index 794bba6bfb6..b734d1b4161 100644 --- a/lib/public/iservercontainer.php +++ b/lib/public/iservercontainer.php @@ -291,4 +291,11 @@ interface IServerContainer { * @return \OCP\ITempManager */ function getTempManager(); + + /** + * Get the app manager + * + * @return \OCP\App\IAppManager + */ + function getAppManager(); } diff --git a/public.php b/public.php index 0e04db66da7..c5c227ef460 100644 --- a/public.php +++ b/public.php @@ -37,7 +37,9 @@ try { OC_App::loadApps(array('authentication')); OC_App::loadApps(array('filesystem', 'logging')); - OC_Util::checkAppEnabled($app); + if (!\OC::$server->getAppManager()->isInstalled($app)) { + throw new Exception('App not installed: ' . $app); + } OC_App::loadApp($app); OC_User::setIncognitoMode(true); diff --git a/remote.php b/remote.php index d854b1d65a6..7993566afec 100644 --- a/remote.php +++ b/remote.php @@ -43,7 +43,9 @@ try { $file = OC::$SERVERROOT .'/'. $file; break; default: - OC_Util::checkAppEnabled($app); + if (!\OC::$server->getAppManager()->isInstalled($app)) { + throw new Exception('App not installed: ' . $app); + } OC_App::loadApp($app); $file = OC_App::getAppPath($app) .'/'. $parts[1]; break; diff --git a/settings/admin.php b/settings/admin.php index d58b9a597b9..d1ed6e75f50 100644 --- a/settings/admin.php +++ b/settings/admin.php @@ -53,7 +53,8 @@ $template->assign('shareExcludedGroupsList', implode('|', $excludedGroupsList)); // Check if connected using HTTPS $template->assign('isConnectedViaHTTPS', OC_Request::serverProtocol() === 'https'); -$template->assign('enforceHTTPSEnabled', $config->getSystemValue("forcessl", false)); +$template->assign('enforceHTTPSEnabled', $config->getSystemValue('forcessl', false)); +$template->assign('forceSSLforSubdomainsEnabled', $config->getSystemValue('forceSSLforSubdomains', false)); // If the current web root is non-empty but the web root from the config is, // and system cron is used, the URL generator fails to build valid URLs. @@ -92,7 +93,7 @@ $formsMap = array_map(function ($form) { $anchor = str_replace(' ', '-', $anchor); return array( - 'anchor' => $anchor, + 'anchor' => 'goto-' . $anchor, 'section-name' => $sectionName, 'form' => $form ); diff --git a/settings/ajax/setsecurity.php b/settings/ajax/setsecurity.php deleted file mode 100644 index f1f737a4943..00000000000 --- a/settings/ajax/setsecurity.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php -/** - * Copyright (c) 2013-2014, Lukas Reschke <lukas@owncloud.com> - * This file is licensed under the Affero General Public License version 3 or later. - * See the COPYING-README file. - */ - -OC_Util::checkAdminUser(); -OCP\JSON::callCheck(); - -if(isset($_POST['enforceHTTPS'])) { - \OC::$server->getConfig()->setSystemValue('forcessl', filter_var($_POST['enforceHTTPS'], FILTER_VALIDATE_BOOLEAN)); -} - -if(isset($_POST['trustedDomain'])) { - $trustedDomains = \OC::$server->getConfig()->getSystemValue('trusted_domains'); - $trustedDomains[] = $_POST['trustedDomain']; - \OC::$server->getConfig()->setSystemValue('trusted_domains', $trustedDomains); -} - -echo 'true'; diff --git a/settings/application.php b/settings/application.php index 99d78aff2cc..64aa4671228 100644 --- a/settings/application.php +++ b/settings/application.php @@ -13,6 +13,7 @@ namespace OC\Settings; use OC\AppFramework\Utility\SimpleContainer; use OC\Settings\Controller\AppSettingsController; use OC\Settings\Controller\MailSettingsController; +use OC\Settings\Controller\SecuritySettingsController; use \OCP\AppFramework\App; use \OCP\Util; @@ -53,6 +54,14 @@ class Application extends App { $c->query('Config') ); }); + $container->registerService('SecuritySettingsController', function(SimpleContainer $c) { + return new SecuritySettingsController( + $c->query('AppName'), + $c->query('Request'), + $c->query('Config') + ); + }); + /** * Core class wrappers */ diff --git a/settings/controller/securitysettingscontroller.php b/settings/controller/securitysettingscontroller.php new file mode 100644 index 00000000000..af60df8dc3b --- /dev/null +++ b/settings/controller/securitysettingscontroller.php @@ -0,0 +1,95 @@ +<?php +/** + * @author Lukas Reschke + * @copyright 2014 Lukas Reschke lukas@owncloud.com + * + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Settings\Controller; + +use \OCP\AppFramework\Controller; +use OCP\IRequest; +use OCP\IConfig; + +/** + * @package OC\Settings\Controller + */ +class SecuritySettingsController extends Controller { + /** @var \OCP\IConfig */ + private $config; + + /** + * @param string $appName + * @param IRequest $request + * @param IConfig $config + */ + public function __construct($appName, + IRequest $request, + IConfig $config) { + parent::__construct($appName, $request); + $this->config = $config; + } + + /** + * @return array + */ + protected function returnSuccess() { + return array( + 'status' => 'success' + ); + } + + /** + * @return array + */ + protected function returnError() { + return array( + 'status' => 'error' + ); + } + + /** + * Enforce or disable the enforcement of SSL + * @param boolean $enforceHTTPS Whether SSL should be enforced + * @return array + */ + public function enforceSSL($enforceHTTPS = false) { + if(!is_bool($enforceHTTPS)) { + return $this->returnError(); + } + $this->config->setSystemValue('forcessl', $enforceHTTPS); + + return $this->returnSuccess(); + } + + /** + * Enforce or disable the enforcement for SSL on subdomains + * @param bool $forceSSLforSubdomains Whether SSL on subdomains should be enforced + * @return array + */ + public function enforceSSLForSubdomains($forceSSLforSubdomains = false) { + if(!is_bool($forceSSLforSubdomains)) { + return $this->returnError(); + } + $this->config->setSystemValue('forceSSLforSubdomains', $forceSSLforSubdomains); + + return $this->returnSuccess(); + } + + /** + * Add a new trusted domain + * @param string $newTrustedDomain The newly to add trusted domain + * @return array + */ + public function trustedDomains($newTrustedDomain) { + $trustedDomains = $this->config->getSystemValue('trusted_domains'); + $trustedDomains[] = $newTrustedDomain; + $this->config->setSystemValue('trusted_domains', $trustedDomains); + + return $this->returnSuccess(); + } + +} diff --git a/settings/js/admin.js b/settings/js/admin.js index e3a092f71b0..059e48ebabe 100644 --- a/settings/js/admin.js +++ b/settings/js/admin.js @@ -9,8 +9,8 @@ $(document).ready(function(){ if(answer) { $.ajax({ type: 'POST', - url: OC.generateUrl('settings/ajax/setsecurity.php'), - data: { trustedDomain: params.trustDomain } + url: OC.generateUrl('settings/admin/security/trustedDomains'), + data: { newTrustedDomain: params.trustDomain } }).done(function() { window.location.replace(OC.generateUrl('settings/admin')); }); @@ -73,10 +73,32 @@ $(document).ready(function(){ $('#setDefaultExpireDate').toggleClass('hidden', !(this.checked && $('#shareapiDefaultExpireDate')[0].checked)); }); - $('#security').change(function(){ - $.post(OC.filePath('settings','ajax','setsecurity.php'), { enforceHTTPS: $('#forcessl').val() },function(){} ); + $('#forcessl').change(function(){ + $(this).val(($(this).val() !== 'true')); + var forceSSLForSubdomain = $('#forceSSLforSubdomainsSpan'); + + $.post(OC.generateUrl('settings/admin/security/ssl'), { + enforceHTTPS: $(this).val() + },function(){} ); + + if($(this).val() === 'true') { + forceSSLForSubdomain.prop('disabled', false); + forceSSLForSubdomain.removeClass('hidden'); + } else { + forceSSLForSubdomain.prop('disabled', true); + forceSSLForSubdomain.addClass('hidden'); + } }); + $('#forceSSLforSubdomains').change(function(){ + $(this).val(($(this).val() !== 'true')); + + $.post(OC.generateUrl('settings/admin/security/ssl/subdomains'), { + forceSSLforSubdomains: $(this).val() + },function(){} ); + }); + + $('#mail_smtpauth').change(function() { if (!this.checked) { $('#mail_credentials').addClass('hidden'); diff --git a/settings/l10n/ast.js b/settings/l10n/ast.js index c2c64a38fff..d3e52d6c8f8 100644 --- a/settings/l10n/ast.js +++ b/settings/l10n/ast.js @@ -206,7 +206,6 @@ OC.L10N.register( "Create" : "Crear", "Admin Recovery Password" : "Recuperación de la contraseña d'alministración", "Enter the recovery password in order to recover the users files during password change" : "Introduz la contraseña de recuperación col envís de recuperar los ficheros de los usuarios mientres el cambéu de contraseña.", - "Search Users and Groups" : "Guetar Usuarios y Grupos", "Add Group" : "Amestar grupu", "Group" : "Grupu", "Everyone" : "Toos", diff --git a/settings/l10n/ast.json b/settings/l10n/ast.json index c903f1d1203..268ca485abe 100644 --- a/settings/l10n/ast.json +++ b/settings/l10n/ast.json @@ -204,7 +204,6 @@ "Create" : "Crear", "Admin Recovery Password" : "Recuperación de la contraseña d'alministración", "Enter the recovery password in order to recover the users files during password change" : "Introduz la contraseña de recuperación col envís de recuperar los ficheros de los usuarios mientres el cambéu de contraseña.", - "Search Users and Groups" : "Guetar Usuarios y Grupos", "Add Group" : "Amestar grupu", "Group" : "Grupu", "Everyone" : "Toos", diff --git a/settings/l10n/bg_BG.js b/settings/l10n/bg_BG.js index a7040874a96..238dd8cc6bf 100644 --- a/settings/l10n/bg_BG.js +++ b/settings/l10n/bg_BG.js @@ -144,6 +144,8 @@ OC.L10N.register( "These groups will still be able to receive shares, but not to initiate them." : "Тези групи ще могат да получават споделения, но няма да могат самите те да споделят.", "Enforce HTTPS" : "Изисквай HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Задължава клиента да се свързва с %s през криптирана връзка.", + "Enforce HTTPS for subdomains" : "Изисквай HTTPS за под домейни", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Задължава клиента да се свързва с %s и негови под домейни през криптирана връзка.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Моля свържи се с твоя %s през HTTPS, за да включиш или изключиш SSL задължаването.", "This is used for sending out notifications." : "Това се използва за изпращане на уведомления.", "Send mode" : "Режим на изпращане", @@ -220,7 +222,6 @@ OC.L10N.register( "Create" : "Създаване", "Admin Recovery Password" : "Възстановяване на Администраторска Парола", "Enter the recovery password in order to recover the users files during password change" : "Въведи паролата за възстановяване, за да възстановиш файловете на потребителите при промяна на паролата.", - "Search Users and Groups" : "Търси Потребители и Групи", "Add Group" : "Добави Група", "Group" : "Група", "Everyone" : "Всички", diff --git a/settings/l10n/bg_BG.json b/settings/l10n/bg_BG.json index cbc1d1352b9..b31ce6717f1 100644 --- a/settings/l10n/bg_BG.json +++ b/settings/l10n/bg_BG.json @@ -142,6 +142,8 @@ "These groups will still be able to receive shares, but not to initiate them." : "Тези групи ще могат да получават споделения, но няма да могат самите те да споделят.", "Enforce HTTPS" : "Изисквай HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Задължава клиента да се свързва с %s през криптирана връзка.", + "Enforce HTTPS for subdomains" : "Изисквай HTTPS за под домейни", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Задължава клиента да се свързва с %s и негови под домейни през криптирана връзка.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Моля свържи се с твоя %s през HTTPS, за да включиш или изключиш SSL задължаването.", "This is used for sending out notifications." : "Това се използва за изпращане на уведомления.", "Send mode" : "Режим на изпращане", @@ -218,7 +220,6 @@ "Create" : "Създаване", "Admin Recovery Password" : "Възстановяване на Администраторска Парола", "Enter the recovery password in order to recover the users files during password change" : "Въведи паролата за възстановяване, за да възстановиш файловете на потребителите при промяна на паролата.", - "Search Users and Groups" : "Търси Потребители и Групи", "Add Group" : "Добави Група", "Group" : "Група", "Everyone" : "Всички", diff --git a/settings/l10n/ca.js b/settings/l10n/ca.js index 166269d39fd..dd481f1379b 100644 --- a/settings/l10n/ca.js +++ b/settings/l10n/ca.js @@ -194,7 +194,6 @@ OC.L10N.register( "Create" : "Crea", "Admin Recovery Password" : "Recuperació de contrasenya d'administrador", "Enter the recovery password in order to recover the users files during password change" : "Escriviu la contrasenya de recuperació per a poder recuperar els fitxers dels usuaris en canviar la contrasenya", - "Search Users and Groups" : "Cerca usuaris i grups", "Add Group" : "Afegeix grup", "Group" : "Grup", "Everyone" : "Tothom", diff --git a/settings/l10n/ca.json b/settings/l10n/ca.json index 42e2f9bc17e..3212069cbea 100644 --- a/settings/l10n/ca.json +++ b/settings/l10n/ca.json @@ -192,7 +192,6 @@ "Create" : "Crea", "Admin Recovery Password" : "Recuperació de contrasenya d'administrador", "Enter the recovery password in order to recover the users files during password change" : "Escriviu la contrasenya de recuperació per a poder recuperar els fitxers dels usuaris en canviar la contrasenya", - "Search Users and Groups" : "Cerca usuaris i grups", "Add Group" : "Afegeix grup", "Group" : "Grup", "Everyone" : "Tothom", diff --git a/settings/l10n/cs_CZ.js b/settings/l10n/cs_CZ.js index ddec3824154..18406a70e24 100644 --- a/settings/l10n/cs_CZ.js +++ b/settings/l10n/cs_CZ.js @@ -13,17 +13,17 @@ OC.L10N.register( "Group already exists" : "Skupina již existuje", "Unable to add group" : "Nelze přidat skupinu", "Files decrypted successfully" : "Soubory úspěšně dešifrovány", - "Couldn't decrypt your files, please check your owncloud.log or ask your administrator" : "Nebylo možno dešifrovat soubory, zkontroluje prosím owncloud.log nebo kontaktujte svého administrátora", + "Couldn't decrypt your files, please check your owncloud.log or ask your administrator" : "Nebylo možno dešifrovat soubory, zkontroluje prosím owncloud.log nebo kontaktujte svého správce systému", "Couldn't decrypt your files, check your password and try again" : "Nebylo možno dešifrovat soubory, zkontrolujte své heslo a zkuste znovu", "Encryption keys deleted permanently" : "Šifrovací klíče trvale smazány", - "Couldn't permanently delete your encryption keys, please check your owncloud.log or ask your administrator" : "Nebylo možno trvale smazat vaše šifrovací klíče, zkontrolujte prosím owncloud.log nebo kontaktujte svého administrátora", + "Couldn't permanently delete your encryption keys, please check your owncloud.log or ask your administrator" : "Nebylo možno trvale smazat vaše šifrovací klíče, zkontrolujte prosím owncloud.log nebo kontaktujte svého správce systému", "Couldn't remove app." : "Nepodařilo se odebrat aplikaci.", "Email saved" : "E-mail uložen", "Invalid email" : "Neplatný e-mail", "Unable to delete group" : "Nelze smazat skupinu", "Unable to delete user" : "Nelze smazat uživatele", "Backups restored successfully" : "Zálohy úspěšně obnoveny", - "Couldn't restore your encryption keys, please check your owncloud.log or ask your administrator" : "Nebylo možno obnovit vaše šifrovací klíče, zkontrolujte prosím owncloud.log nebo kontaktujte svého administrátora", + "Couldn't restore your encryption keys, please check your owncloud.log or ask your administrator" : "Nebylo možno obnovit vaše šifrovací klíče, zkontrolujte prosím owncloud.log nebo kontaktujte svého správce systému", "Language changed" : "Jazyk byl změněn", "Invalid request" : "Neplatný požadavek", "Admins can't remove themself from the admin group" : "Správci se nemohou odebrat sami ze skupiny správců", @@ -144,6 +144,8 @@ OC.L10N.register( "These groups will still be able to receive shares, but not to initiate them." : "Těmto skupinám bude stále možno sdílet, nemohou ale sami sdílet ostatním.", "Enforce HTTPS" : "Vynutit HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Vynutí připojování klientů k %s šifrovaným spojením.", + "Enforce HTTPS for subdomains" : "Vynutit HTTPS pro subdomény", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Vynutí připojování klientů k %s a subdoménám šifrovaným spojením.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Připojte se k %s přes HTTPS pro povolení nebo zakázání vynucení SSL.", "This is used for sending out notifications." : "Toto se používá pro odesílání upozornění.", "Send mode" : "Mód odesílání", @@ -220,7 +222,6 @@ OC.L10N.register( "Create" : "Vytvořit", "Admin Recovery Password" : "Heslo obnovy správce", "Enter the recovery password in order to recover the users files during password change" : "Zadejte heslo obnovy pro obnovení souborů uživatele při změně hesla", - "Search Users and Groups" : "Prohledat uživatele a skupiny", "Add Group" : "Přidat skupinu", "Group" : "Skupina", "Everyone" : "Všichni", @@ -229,7 +230,7 @@ OC.L10N.register( "Please enter storage quota (ex: \"512 MB\" or \"12 GB\")" : "Zvolte prosím kvótu pro úložiště (např. \"512 MB\" nebo \"12 GB\")", "Unlimited" : "Neomezeně", "Other" : "Jiný", - "Group Admin for" : "Administrátor skupiny ", + "Group Admin for" : "Správce skupiny ", "Quota" : "Kvóta", "Storage Location" : "Umístění úložiště", "Last Login" : "Poslední přihlášení", diff --git a/settings/l10n/cs_CZ.json b/settings/l10n/cs_CZ.json index fe9c860fbdb..376d1007771 100644 --- a/settings/l10n/cs_CZ.json +++ b/settings/l10n/cs_CZ.json @@ -11,17 +11,17 @@ "Group already exists" : "Skupina již existuje", "Unable to add group" : "Nelze přidat skupinu", "Files decrypted successfully" : "Soubory úspěšně dešifrovány", - "Couldn't decrypt your files, please check your owncloud.log or ask your administrator" : "Nebylo možno dešifrovat soubory, zkontroluje prosím owncloud.log nebo kontaktujte svého administrátora", + "Couldn't decrypt your files, please check your owncloud.log or ask your administrator" : "Nebylo možno dešifrovat soubory, zkontroluje prosím owncloud.log nebo kontaktujte svého správce systému", "Couldn't decrypt your files, check your password and try again" : "Nebylo možno dešifrovat soubory, zkontrolujte své heslo a zkuste znovu", "Encryption keys deleted permanently" : "Šifrovací klíče trvale smazány", - "Couldn't permanently delete your encryption keys, please check your owncloud.log or ask your administrator" : "Nebylo možno trvale smazat vaše šifrovací klíče, zkontrolujte prosím owncloud.log nebo kontaktujte svého administrátora", + "Couldn't permanently delete your encryption keys, please check your owncloud.log or ask your administrator" : "Nebylo možno trvale smazat vaše šifrovací klíče, zkontrolujte prosím owncloud.log nebo kontaktujte svého správce systému", "Couldn't remove app." : "Nepodařilo se odebrat aplikaci.", "Email saved" : "E-mail uložen", "Invalid email" : "Neplatný e-mail", "Unable to delete group" : "Nelze smazat skupinu", "Unable to delete user" : "Nelze smazat uživatele", "Backups restored successfully" : "Zálohy úspěšně obnoveny", - "Couldn't restore your encryption keys, please check your owncloud.log or ask your administrator" : "Nebylo možno obnovit vaše šifrovací klíče, zkontrolujte prosím owncloud.log nebo kontaktujte svého administrátora", + "Couldn't restore your encryption keys, please check your owncloud.log or ask your administrator" : "Nebylo možno obnovit vaše šifrovací klíče, zkontrolujte prosím owncloud.log nebo kontaktujte svého správce systému", "Language changed" : "Jazyk byl změněn", "Invalid request" : "Neplatný požadavek", "Admins can't remove themself from the admin group" : "Správci se nemohou odebrat sami ze skupiny správců", @@ -142,6 +142,8 @@ "These groups will still be able to receive shares, but not to initiate them." : "Těmto skupinám bude stále možno sdílet, nemohou ale sami sdílet ostatním.", "Enforce HTTPS" : "Vynutit HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Vynutí připojování klientů k %s šifrovaným spojením.", + "Enforce HTTPS for subdomains" : "Vynutit HTTPS pro subdomény", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Vynutí připojování klientů k %s a subdoménám šifrovaným spojením.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Připojte se k %s přes HTTPS pro povolení nebo zakázání vynucení SSL.", "This is used for sending out notifications." : "Toto se používá pro odesílání upozornění.", "Send mode" : "Mód odesílání", @@ -218,7 +220,6 @@ "Create" : "Vytvořit", "Admin Recovery Password" : "Heslo obnovy správce", "Enter the recovery password in order to recover the users files during password change" : "Zadejte heslo obnovy pro obnovení souborů uživatele při změně hesla", - "Search Users and Groups" : "Prohledat uživatele a skupiny", "Add Group" : "Přidat skupinu", "Group" : "Skupina", "Everyone" : "Všichni", @@ -227,7 +228,7 @@ "Please enter storage quota (ex: \"512 MB\" or \"12 GB\")" : "Zvolte prosím kvótu pro úložiště (např. \"512 MB\" nebo \"12 GB\")", "Unlimited" : "Neomezeně", "Other" : "Jiný", - "Group Admin for" : "Administrátor skupiny ", + "Group Admin for" : "Správce skupiny ", "Quota" : "Kvóta", "Storage Location" : "Umístění úložiště", "Last Login" : "Poslední přihlášení", diff --git a/settings/l10n/da.js b/settings/l10n/da.js index 11df1b2aed2..fa39a3a4657 100644 --- a/settings/l10n/da.js +++ b/settings/l10n/da.js @@ -144,6 +144,8 @@ OC.L10N.register( "These groups will still be able to receive shares, but not to initiate them." : "Disse grupper vil stadig kunne modtage delefiler, dog ikke skabe dem.", "Enforce HTTPS" : "Gennemtving HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Tving klienten til at forbinde til %s via en kryptetet forbindelse.", + "Enforce HTTPS for subdomains" : "Gennemtving HTTPS for subdomæner", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Tving klienterne til at tilslutte til %s og subdomæner via en krypteret forbindelse.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Forbind venligst til din %s via HTTPS for at aktivere eller deaktivere SSL tvang.", "This is used for sending out notifications." : "Dette anvendes til udsendelse af notifikationer.", "Send mode" : "Tilstand for afsendelse", @@ -220,7 +222,6 @@ OC.L10N.register( "Create" : "Ny", "Admin Recovery Password" : "Administrator gendannelse kodeord", "Enter the recovery password in order to recover the users files during password change" : "Indtast et gendannelse kodeord for, at kunne gendanne brugerens filer ved ændring af kodeord", - "Search Users and Groups" : "Søg efter brugere og grupper", "Add Group" : "Tilføj Gruppe", "Group" : "Gruppe", "Everyone" : "Alle", diff --git a/settings/l10n/da.json b/settings/l10n/da.json index 973db1815ed..f2b0c136368 100644 --- a/settings/l10n/da.json +++ b/settings/l10n/da.json @@ -142,6 +142,8 @@ "These groups will still be able to receive shares, but not to initiate them." : "Disse grupper vil stadig kunne modtage delefiler, dog ikke skabe dem.", "Enforce HTTPS" : "Gennemtving HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Tving klienten til at forbinde til %s via en kryptetet forbindelse.", + "Enforce HTTPS for subdomains" : "Gennemtving HTTPS for subdomæner", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Tving klienterne til at tilslutte til %s og subdomæner via en krypteret forbindelse.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Forbind venligst til din %s via HTTPS for at aktivere eller deaktivere SSL tvang.", "This is used for sending out notifications." : "Dette anvendes til udsendelse af notifikationer.", "Send mode" : "Tilstand for afsendelse", @@ -218,7 +220,6 @@ "Create" : "Ny", "Admin Recovery Password" : "Administrator gendannelse kodeord", "Enter the recovery password in order to recover the users files during password change" : "Indtast et gendannelse kodeord for, at kunne gendanne brugerens filer ved ændring af kodeord", - "Search Users and Groups" : "Søg efter brugere og grupper", "Add Group" : "Tilføj Gruppe", "Group" : "Gruppe", "Everyone" : "Alle", diff --git a/settings/l10n/de.js b/settings/l10n/de.js index 52fb6674b2c..01c1495a535 100644 --- a/settings/l10n/de.js +++ b/settings/l10n/de.js @@ -144,6 +144,8 @@ OC.L10N.register( "These groups will still be able to receive shares, but not to initiate them." : "Diese Gruppen können weiterhin Freigaben empfangen, aber selbst keine mehr initiieren.", "Enforce HTTPS" : "Erzwinge HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Zwingt die clientseitigen Anwendungen, verschlüsselte Verbindungen zu %s herzustellen.", + "Enforce HTTPS for subdomains" : "HTTPS für Subdomains erzwingen", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Zwingt die Clients, sich über eine verschlüsselte Verbindung zu %s und Subdomains zu verbinden.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Bitte verbinde dich zu deinem %s über HTTPS um die SSL-Erzwingung zu aktivieren oder zu deaktivieren.", "This is used for sending out notifications." : "Dies wird zum Senden von Benachrichtigungen verwendet.", "Send mode" : "Sende-Modus", @@ -220,7 +222,6 @@ OC.L10N.register( "Create" : "Anlegen", "Admin Recovery Password" : "Admin-Wiederherstellungspasswort", "Enter the recovery password in order to recover the users files during password change" : "Gib das Wiederherstellungspasswort ein, um die Benutzerdateien während Passwortänderung wiederherzustellen", - "Search Users and Groups" : "Nutzer und Gruppen suchen", "Add Group" : "Gruppe hinzufügen", "Group" : "Gruppe", "Everyone" : "Jeder", diff --git a/settings/l10n/de.json b/settings/l10n/de.json index 425197676db..9a01aa2dbd7 100644 --- a/settings/l10n/de.json +++ b/settings/l10n/de.json @@ -142,6 +142,8 @@ "These groups will still be able to receive shares, but not to initiate them." : "Diese Gruppen können weiterhin Freigaben empfangen, aber selbst keine mehr initiieren.", "Enforce HTTPS" : "Erzwinge HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Zwingt die clientseitigen Anwendungen, verschlüsselte Verbindungen zu %s herzustellen.", + "Enforce HTTPS for subdomains" : "HTTPS für Subdomains erzwingen", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Zwingt die Clients, sich über eine verschlüsselte Verbindung zu %s und Subdomains zu verbinden.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Bitte verbinde dich zu deinem %s über HTTPS um die SSL-Erzwingung zu aktivieren oder zu deaktivieren.", "This is used for sending out notifications." : "Dies wird zum Senden von Benachrichtigungen verwendet.", "Send mode" : "Sende-Modus", @@ -218,7 +220,6 @@ "Create" : "Anlegen", "Admin Recovery Password" : "Admin-Wiederherstellungspasswort", "Enter the recovery password in order to recover the users files during password change" : "Gib das Wiederherstellungspasswort ein, um die Benutzerdateien während Passwortänderung wiederherzustellen", - "Search Users and Groups" : "Nutzer und Gruppen suchen", "Add Group" : "Gruppe hinzufügen", "Group" : "Gruppe", "Everyone" : "Jeder", diff --git a/settings/l10n/de_DE.js b/settings/l10n/de_DE.js index ddda5017a5f..08726f1afc9 100644 --- a/settings/l10n/de_DE.js +++ b/settings/l10n/de_DE.js @@ -144,6 +144,8 @@ OC.L10N.register( "These groups will still be able to receive shares, but not to initiate them." : "Diese Gruppen können weiterhin Freigaben empfangen, aber selbst keine mehr initiieren.", "Enforce HTTPS" : "HTTPS erzwingen", "Forces the clients to connect to %s via an encrypted connection." : "Zwingt die clientseitigen Anwendungen, verschlüsselte Verbindungen zu %s herzustellen.", + "Enforce HTTPS for subdomains" : "HTTPS für Subdomains erzwingen", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Zwingt die Clients, sich über eine verschlüsselte Verbindung zu %s und Subdomains zu verbinden.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Bitte verbinden Sie sich zu Ihrem %s über HTTPS um die SSL-Erzwingung zu aktivieren oder zu deaktivieren.", "This is used for sending out notifications." : "Dies wird für das Senden von Benachrichtigungen verwendet.", "Send mode" : "Sendemodus", @@ -220,7 +222,6 @@ OC.L10N.register( "Create" : "Erstellen", "Admin Recovery Password" : "Admin-Passwort-Wiederherstellung", "Enter the recovery password in order to recover the users files during password change" : "Geben Sie das Wiederherstellungspasswort ein, um die Benutzerdateien während Passwortänderung wiederherzustellen", - "Search Users and Groups" : "Benutzer und Gruppen suchen", "Add Group" : "Gruppe hinzufügen", "Group" : "Gruppe", "Everyone" : "Jeder", diff --git a/settings/l10n/de_DE.json b/settings/l10n/de_DE.json index 03cd7ab8eb5..700d8c03a42 100644 --- a/settings/l10n/de_DE.json +++ b/settings/l10n/de_DE.json @@ -142,6 +142,8 @@ "These groups will still be able to receive shares, but not to initiate them." : "Diese Gruppen können weiterhin Freigaben empfangen, aber selbst keine mehr initiieren.", "Enforce HTTPS" : "HTTPS erzwingen", "Forces the clients to connect to %s via an encrypted connection." : "Zwingt die clientseitigen Anwendungen, verschlüsselte Verbindungen zu %s herzustellen.", + "Enforce HTTPS for subdomains" : "HTTPS für Subdomains erzwingen", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Zwingt die Clients, sich über eine verschlüsselte Verbindung zu %s und Subdomains zu verbinden.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Bitte verbinden Sie sich zu Ihrem %s über HTTPS um die SSL-Erzwingung zu aktivieren oder zu deaktivieren.", "This is used for sending out notifications." : "Dies wird für das Senden von Benachrichtigungen verwendet.", "Send mode" : "Sendemodus", @@ -218,7 +220,6 @@ "Create" : "Erstellen", "Admin Recovery Password" : "Admin-Passwort-Wiederherstellung", "Enter the recovery password in order to recover the users files during password change" : "Geben Sie das Wiederherstellungspasswort ein, um die Benutzerdateien während Passwortänderung wiederherzustellen", - "Search Users and Groups" : "Benutzer und Gruppen suchen", "Add Group" : "Gruppe hinzufügen", "Group" : "Gruppe", "Everyone" : "Jeder", diff --git a/settings/l10n/el.js b/settings/l10n/el.js index c10f68207ff..f6669e1bfcd 100644 --- a/settings/l10n/el.js +++ b/settings/l10n/el.js @@ -218,7 +218,6 @@ OC.L10N.register( "Create" : "Δημιουργία", "Admin Recovery Password" : "Κωδικός Επαναφοράς Διαχειριστή ", "Enter the recovery password in order to recover the users files during password change" : "Εισάγετε το συνθηματικό ανάκτησης ώστε να ανακτήσετε τα αρχεία χρηστών κατά την αλλαγή συνθηματικού", - "Search Users and Groups" : "Αναζήτηση Χρηστών και Ομάδων", "Add Group" : "Προσθήκη Ομάδας", "Group" : "Ομάδα", "Everyone" : "Όλοι", diff --git a/settings/l10n/el.json b/settings/l10n/el.json index 05388c7408f..8b0fdce6501 100644 --- a/settings/l10n/el.json +++ b/settings/l10n/el.json @@ -216,7 +216,6 @@ "Create" : "Δημιουργία", "Admin Recovery Password" : "Κωδικός Επαναφοράς Διαχειριστή ", "Enter the recovery password in order to recover the users files during password change" : "Εισάγετε το συνθηματικό ανάκτησης ώστε να ανακτήσετε τα αρχεία χρηστών κατά την αλλαγή συνθηματικού", - "Search Users and Groups" : "Αναζήτηση Χρηστών και Ομάδων", "Add Group" : "Προσθήκη Ομάδας", "Group" : "Ομάδα", "Everyone" : "Όλοι", diff --git a/settings/l10n/en_GB.js b/settings/l10n/en_GB.js index ec446af4288..2847fcd65a0 100644 --- a/settings/l10n/en_GB.js +++ b/settings/l10n/en_GB.js @@ -144,6 +144,8 @@ OC.L10N.register( "These groups will still be able to receive shares, but not to initiate them." : "These groups will still be able to receive shares, but not to initiate them.", "Enforce HTTPS" : "Enforce HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Forces the clients to connect to %s via an encrypted connection.", + "Enforce HTTPS for subdomains" : "Enforce HTTPS for subdomains", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Forces the clients to connect to %s and subdomains via an encrypted connection.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Please connect to your %s via HTTPS to enable or disable the SSL enforcement.", "This is used for sending out notifications." : "This is used for sending out notifications.", "Send mode" : "Send mode", @@ -220,7 +222,6 @@ OC.L10N.register( "Create" : "Create", "Admin Recovery Password" : "Admin Recovery Password", "Enter the recovery password in order to recover the users files during password change" : "Enter the recovery password in order to recover the user's files during password change", - "Search Users and Groups" : "Search Users and Groups", "Add Group" : "Add Group", "Group" : "Group", "Everyone" : "Everyone", diff --git a/settings/l10n/en_GB.json b/settings/l10n/en_GB.json index ab9bc6a6bb5..989044bafdb 100644 --- a/settings/l10n/en_GB.json +++ b/settings/l10n/en_GB.json @@ -142,6 +142,8 @@ "These groups will still be able to receive shares, but not to initiate them." : "These groups will still be able to receive shares, but not to initiate them.", "Enforce HTTPS" : "Enforce HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Forces the clients to connect to %s via an encrypted connection.", + "Enforce HTTPS for subdomains" : "Enforce HTTPS for subdomains", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Forces the clients to connect to %s and subdomains via an encrypted connection.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Please connect to your %s via HTTPS to enable or disable the SSL enforcement.", "This is used for sending out notifications." : "This is used for sending out notifications.", "Send mode" : "Send mode", @@ -218,7 +220,6 @@ "Create" : "Create", "Admin Recovery Password" : "Admin Recovery Password", "Enter the recovery password in order to recover the users files during password change" : "Enter the recovery password in order to recover the user's files during password change", - "Search Users and Groups" : "Search Users and Groups", "Add Group" : "Add Group", "Group" : "Group", "Everyone" : "Everyone", diff --git a/settings/l10n/eo.js b/settings/l10n/eo.js index ca5eeb55d71..ff757ce143c 100644 --- a/settings/l10n/eo.js +++ b/settings/l10n/eo.js @@ -137,7 +137,6 @@ OC.L10N.register( "Delete Encryption Keys" : "Forigi ĉifroklavojn", "Username" : "Uzantonomo", "Create" : "Krei", - "Search Users and Groups" : "Serĉi uzantojn kaj grupojn", "Add Group" : "Aldoni grupon", "Group" : "Grupo", "Everyone" : "Ĉiuj", diff --git a/settings/l10n/eo.json b/settings/l10n/eo.json index 584f1bbe127..35af2f7f22f 100644 --- a/settings/l10n/eo.json +++ b/settings/l10n/eo.json @@ -135,7 +135,6 @@ "Delete Encryption Keys" : "Forigi ĉifroklavojn", "Username" : "Uzantonomo", "Create" : "Krei", - "Search Users and Groups" : "Serĉi uzantojn kaj grupojn", "Add Group" : "Aldoni grupon", "Group" : "Grupo", "Everyone" : "Ĉiuj", diff --git a/settings/l10n/es.js b/settings/l10n/es.js index 5e86d9bbf02..eeae90c5e80 100644 --- a/settings/l10n/es.js +++ b/settings/l10n/es.js @@ -144,6 +144,8 @@ OC.L10N.register( "These groups will still be able to receive shares, but not to initiate them." : "Estos grupos aún podrán recibir contenidos compartidos, pero no podrán, pero no podrán iniciarlos.", "Enforce HTTPS" : "Forzar HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Forzar a los clientes a conectarse a %s por medio de una conexión cifrada.", + "Enforce HTTPS for subdomains" : "Forzar HTTPS para subdominios", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Obliga a los clientes a conectara %s y subdominios mediante una conexión cifrada.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Por favor, conéctese a su %s a través de HTTPS para habilitar o deshabilitar la aplicación de SSL.", "This is used for sending out notifications." : "Esto se usa para enviar notificaciones.", "Send mode" : "Modo de envío", @@ -220,7 +222,6 @@ OC.L10N.register( "Create" : "Crear", "Admin Recovery Password" : "Recuperación de la contraseña de administración", "Enter the recovery password in order to recover the users files during password change" : "Introduzca la contraseña de recuperación a fin de recuperar los archivos de los usuarios durante el cambio de contraseña.", - "Search Users and Groups" : "Buscar usuarios y grupos", "Add Group" : "Agregar grupo", "Group" : "Grupo", "Everyone" : "Todos", diff --git a/settings/l10n/es.json b/settings/l10n/es.json index 3f08f3573cd..2a80ccdde83 100644 --- a/settings/l10n/es.json +++ b/settings/l10n/es.json @@ -142,6 +142,8 @@ "These groups will still be able to receive shares, but not to initiate them." : "Estos grupos aún podrán recibir contenidos compartidos, pero no podrán, pero no podrán iniciarlos.", "Enforce HTTPS" : "Forzar HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Forzar a los clientes a conectarse a %s por medio de una conexión cifrada.", + "Enforce HTTPS for subdomains" : "Forzar HTTPS para subdominios", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Obliga a los clientes a conectara %s y subdominios mediante una conexión cifrada.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Por favor, conéctese a su %s a través de HTTPS para habilitar o deshabilitar la aplicación de SSL.", "This is used for sending out notifications." : "Esto se usa para enviar notificaciones.", "Send mode" : "Modo de envío", @@ -218,7 +220,6 @@ "Create" : "Crear", "Admin Recovery Password" : "Recuperación de la contraseña de administración", "Enter the recovery password in order to recover the users files during password change" : "Introduzca la contraseña de recuperación a fin de recuperar los archivos de los usuarios durante el cambio de contraseña.", - "Search Users and Groups" : "Buscar usuarios y grupos", "Add Group" : "Agregar grupo", "Group" : "Grupo", "Everyone" : "Todos", diff --git a/settings/l10n/et_EE.js b/settings/l10n/et_EE.js index e5851e5a66a..0fac182b7cd 100644 --- a/settings/l10n/et_EE.js +++ b/settings/l10n/et_EE.js @@ -144,6 +144,8 @@ OC.L10N.register( "These groups will still be able to receive shares, but not to initiate them." : "Need grupid saavad vastu võtta jagamisi, kuid ise jagamisi algatada ei saa.", "Enforce HTTPS" : "Sunni peale HTTPS-i kasutamine", "Forces the clients to connect to %s via an encrypted connection." : "Sunnib kliente %s ühenduma krüpteeritult.", + "Enforce HTTPS for subdomains" : "Sunni peale HTTPS-i kasutamine", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Sunnib kliente ühenduma domeeniga %s ja selle alamdomeenidega krüpteeritult.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Palun ühendu oma %s üle HTTPS või keela SSL kasutamine.", "This is used for sending out notifications." : "Seda kasutatakse teadete välja saatmiseks.", "Send mode" : "Saatmise viis", @@ -220,7 +222,6 @@ OC.L10N.register( "Create" : "Lisa", "Admin Recovery Password" : "Admini parooli taastamine", "Enter the recovery password in order to recover the users files during password change" : "Sisesta taasteparool kasutaja failide taastamiseks paroolivahetuse käigus", - "Search Users and Groups" : "Otsi kasutajaid ja gruppe", "Add Group" : "Lisa grupp", "Group" : "Grupp", "Everyone" : "Igaüks", diff --git a/settings/l10n/et_EE.json b/settings/l10n/et_EE.json index 93eb7405b76..a7fe59781dd 100644 --- a/settings/l10n/et_EE.json +++ b/settings/l10n/et_EE.json @@ -142,6 +142,8 @@ "These groups will still be able to receive shares, but not to initiate them." : "Need grupid saavad vastu võtta jagamisi, kuid ise jagamisi algatada ei saa.", "Enforce HTTPS" : "Sunni peale HTTPS-i kasutamine", "Forces the clients to connect to %s via an encrypted connection." : "Sunnib kliente %s ühenduma krüpteeritult.", + "Enforce HTTPS for subdomains" : "Sunni peale HTTPS-i kasutamine", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Sunnib kliente ühenduma domeeniga %s ja selle alamdomeenidega krüpteeritult.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Palun ühendu oma %s üle HTTPS või keela SSL kasutamine.", "This is used for sending out notifications." : "Seda kasutatakse teadete välja saatmiseks.", "Send mode" : "Saatmise viis", @@ -218,7 +220,6 @@ "Create" : "Lisa", "Admin Recovery Password" : "Admini parooli taastamine", "Enter the recovery password in order to recover the users files during password change" : "Sisesta taasteparool kasutaja failide taastamiseks paroolivahetuse käigus", - "Search Users and Groups" : "Otsi kasutajaid ja gruppe", "Add Group" : "Lisa grupp", "Group" : "Grupp", "Everyone" : "Igaüks", diff --git a/settings/l10n/eu.js b/settings/l10n/eu.js index 3a5ba67ed83..36e01cae8c1 100644 --- a/settings/l10n/eu.js +++ b/settings/l10n/eu.js @@ -213,7 +213,6 @@ OC.L10N.register( "Create" : "Sortu", "Admin Recovery Password" : "Administratzailearen pasahitza berreskuratzea", "Enter the recovery password in order to recover the users files during password change" : "Berreskuratze pasahitza idatzi pasahitz aldaketan erabiltzaileen fitxategiak berreskuratzeko", - "Search Users and Groups" : "Bilatu erabiltzaileak eta taldeak", "Add Group" : "Gehitu taldea", "Group" : "Taldea", "Everyone" : "Edonor", diff --git a/settings/l10n/eu.json b/settings/l10n/eu.json index 0668428251b..d5ea5f74dbc 100644 --- a/settings/l10n/eu.json +++ b/settings/l10n/eu.json @@ -211,7 +211,6 @@ "Create" : "Sortu", "Admin Recovery Password" : "Administratzailearen pasahitza berreskuratzea", "Enter the recovery password in order to recover the users files during password change" : "Berreskuratze pasahitza idatzi pasahitz aldaketan erabiltzaileen fitxategiak berreskuratzeko", - "Search Users and Groups" : "Bilatu erabiltzaileak eta taldeak", "Add Group" : "Gehitu taldea", "Group" : "Taldea", "Everyone" : "Edonor", diff --git a/settings/l10n/fa.js b/settings/l10n/fa.js index 45ece7beff6..624c124888b 100644 --- a/settings/l10n/fa.js +++ b/settings/l10n/fa.js @@ -170,7 +170,6 @@ OC.L10N.register( "Create" : "ایجاد کردن", "Admin Recovery Password" : "مدیریت بازیابی رمز عبور", "Enter the recovery password in order to recover the users files during password change" : "در حین تغییر رمز عبور به منظور بازیابی فایل های کاربران، رمز عبور بازیابی را وارد کنید", - "Search Users and Groups" : "جستجوی کاربران و گروه ها", "Add Group" : "افزودن گروه", "Group" : "گروه", "Everyone" : "همه", diff --git a/settings/l10n/fa.json b/settings/l10n/fa.json index c91afde0fdb..793551cfe56 100644 --- a/settings/l10n/fa.json +++ b/settings/l10n/fa.json @@ -168,7 +168,6 @@ "Create" : "ایجاد کردن", "Admin Recovery Password" : "مدیریت بازیابی رمز عبور", "Enter the recovery password in order to recover the users files during password change" : "در حین تغییر رمز عبور به منظور بازیابی فایل های کاربران، رمز عبور بازیابی را وارد کنید", - "Search Users and Groups" : "جستجوی کاربران و گروه ها", "Add Group" : "افزودن گروه", "Group" : "گروه", "Everyone" : "همه", diff --git a/settings/l10n/fi_FI.js b/settings/l10n/fi_FI.js index 46bfe9d8e2c..c031dcb043e 100644 --- a/settings/l10n/fi_FI.js +++ b/settings/l10n/fi_FI.js @@ -126,6 +126,7 @@ OC.L10N.register( "Use system's cron service to call the cron.php file every 15 minutes." : "Käytä järjestelmän cron-palvelua cron.php-tiedoston kutsumista varten 15 minuutin välein.", "Allow apps to use the Share API" : "Salli sovellusten käyttää jakamisen ohjelmointirajapintaa", "Allow users to share via link" : "Salli käyttäjien jakaa linkkien kautta", + "Enforce password protection" : "Pakota salasanasuojaus", "Allow public uploads" : "Salli julkiset lähetykset", "Set default expiration date" : "Aseta oletusvanhenemispäivä", "Expire after " : "Vanhenna", @@ -138,6 +139,8 @@ OC.L10N.register( "These groups will still be able to receive shares, but not to initiate them." : "Nämä ryhmät kykenevät vastaanottamaan jakoja, mutta eivät kuitenkaan itse pysty luoda jakoja.", "Enforce HTTPS" : "Pakota HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Pakottaa asiakasohjelmistot ottamaan yhteyden %siin salatun yhteyden kautta.", + "Enforce HTTPS for subdomains" : "Pakota HTTPS-suojaus alidomaineille", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Pakottaa asiakkaat yhdistämään kohteeseen %s ja sen alidomaineihin salattua yhteyttä käyttäen.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Yhdistä %siin HTTPS-yhteydellä ottaaksesi käyttöön tai poistaaksesi käytöstä SSL-pakotteen.", "This is used for sending out notifications." : "Tätä käytetään ilmoitusten lähettämiseen.", "Send mode" : "Lähetystila", @@ -211,7 +214,6 @@ OC.L10N.register( "Username" : "Käyttäjätunnus", "Create" : "Luo", "Admin Recovery Password" : "Ylläpitäjän palautussalasana", - "Search Users and Groups" : "Etsi käyttäjiä ja ryhmiä", "Add Group" : "Lisää ryhmä", "Group" : "Ryhmä", "Everyone" : "Kaikki", diff --git a/settings/l10n/fi_FI.json b/settings/l10n/fi_FI.json index a541d5c7b13..17bb06c2f4c 100644 --- a/settings/l10n/fi_FI.json +++ b/settings/l10n/fi_FI.json @@ -124,6 +124,7 @@ "Use system's cron service to call the cron.php file every 15 minutes." : "Käytä järjestelmän cron-palvelua cron.php-tiedoston kutsumista varten 15 minuutin välein.", "Allow apps to use the Share API" : "Salli sovellusten käyttää jakamisen ohjelmointirajapintaa", "Allow users to share via link" : "Salli käyttäjien jakaa linkkien kautta", + "Enforce password protection" : "Pakota salasanasuojaus", "Allow public uploads" : "Salli julkiset lähetykset", "Set default expiration date" : "Aseta oletusvanhenemispäivä", "Expire after " : "Vanhenna", @@ -136,6 +137,8 @@ "These groups will still be able to receive shares, but not to initiate them." : "Nämä ryhmät kykenevät vastaanottamaan jakoja, mutta eivät kuitenkaan itse pysty luoda jakoja.", "Enforce HTTPS" : "Pakota HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Pakottaa asiakasohjelmistot ottamaan yhteyden %siin salatun yhteyden kautta.", + "Enforce HTTPS for subdomains" : "Pakota HTTPS-suojaus alidomaineille", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Pakottaa asiakkaat yhdistämään kohteeseen %s ja sen alidomaineihin salattua yhteyttä käyttäen.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Yhdistä %siin HTTPS-yhteydellä ottaaksesi käyttöön tai poistaaksesi käytöstä SSL-pakotteen.", "This is used for sending out notifications." : "Tätä käytetään ilmoitusten lähettämiseen.", "Send mode" : "Lähetystila", @@ -209,7 +212,6 @@ "Username" : "Käyttäjätunnus", "Create" : "Luo", "Admin Recovery Password" : "Ylläpitäjän palautussalasana", - "Search Users and Groups" : "Etsi käyttäjiä ja ryhmiä", "Add Group" : "Lisää ryhmä", "Group" : "Ryhmä", "Everyone" : "Kaikki", diff --git a/settings/l10n/fr.js b/settings/l10n/fr.js index 3bd1be6c7a0..cf18809aa7d 100644 --- a/settings/l10n/fr.js +++ b/settings/l10n/fr.js @@ -34,7 +34,7 @@ OC.L10N.register( "No user supplied" : "Aucun utilisateur fourni", "Please provide an admin recovery password, otherwise all user data will be lost" : "Veuillez fournir un mot de passe administrateur de récupération de données, sinon toutes les données de l'utilisateur seront perdues", "Wrong admin recovery password. Please check the password and try again." : "Mot de passe administrateur de récupération de données non valable. Veuillez vérifier le mot de passe et essayer à nouveau.", - "Back-end doesn't support password change, but the users encryption key was successfully updated." : "L'infrastructure d'arrière-plan ne supporte pas la modification de mot de passe, mais la clef de chiffrement des utilisateurs a été mise à jour avec succès.", + "Back-end doesn't support password change, but the users encryption key was successfully updated." : "L'infrastructure d'arrière-plan ne permet pas la modification de mot de passe, mais la clef de chiffrement des utilisateurs a été mise à jour avec succès.", "Unable to change password" : "Impossible de modifier le mot de passe", "Enabled" : "Activées", "Not enabled" : "Désactivées", @@ -115,16 +115,16 @@ OC.L10N.register( "PHP charset is not set to UTF-8" : "Le jeu de caractères PHP n'est pas réglé sur UTF-8", "PHP charset is not set to UTF-8. This can cause major issues with non-ASCII characters in file names. We highly recommend to change the value of 'default_charset' php.ini to 'UTF-8'." : "Le jeu de caractères PHP n'est pas réglé sur UTF-8. Ceci peut entraîner des problèmes majeurs avec les noms de fichiers contenant des caractère non-ASCII. Nous recommandons fortement de changer la valeur de 'default_charset' dans php.ini par 'UTF-8'.", "Locale not working" : "Localisation non fonctionnelle", - "System locale can not be set to a one which supports UTF-8." : "Les paramètres régionaux ne peuvent pas être configurés avec un qui supporte UTF-8.", + "System locale can not be set to a one which supports UTF-8." : "Les paramètres régionaux ne peuvent pas être configurés avec prise en charge d'UTF-8.", "This means that there might be problems with certain characters in file names." : "Cela signifie qu'il pourrait y avoir des problèmes avec certains caractères dans les noms de fichier.", - "We strongly suggest to install the required packages on your system to support one of the following locales: %s." : "Nous conseillons vivement d'installer les paquets requis sur votre système pour supporter l'un des paramètres régionaux suivants : %s.", + "We strongly suggest to install the required packages on your system to support one of the following locales: %s." : "Nous conseillons vivement d'installer sur votre système les paquets nécessaires à la prise en charge de l'un des paramètres régionaux suivants : %s.", "URL generation in notification emails" : "Génération d'URL dans les mails de notification", "If your installation is not installed in the root of the domain and uses system cron, there can be issues with the URL generation. To avoid these problems, please set the \"overwritewebroot\" option in your config.php file to the webroot path of your installation (Suggested: \"%s\")" : "Si votre installation n'a pas été effectuée à la racine du domaine et qu'elle utilise le cron du système, il peut y avoir des problèmes avec la génération d'URL. Pour les éviter, veuillez configurer l'option \"overwritewebroot\" de votre fichier config.php avec le chemin de la racine de votre installation (suggéré : \"%s\")", "Connectivity Checks" : "Vérification de la connectivité", "No problems found" : "Aucun problème trouvé", "Please double check the <a href='%s'>installation guides</a>." : "Veuillez vous référer au <a href='%s'>guide d'installation</a>.", - "Last cron was executed at %s." : "Le dernier cron s'est exécuté à %s.", - "Last cron was executed at %s. This is more than an hour ago, something seems wrong." : "Le dernier cron s'est exécuté à %s. Cela fait plus d'une heure, quelque chose a du mal se passer.", + "Last cron was executed at %s." : "Le dernier cron s'est exécuté à la date suivante : %s.", + "Last cron was executed at %s. This is more than an hour ago, something seems wrong." : "Le dernier cron s'est exécuté à la date suivante : %s. Cela fait plus d'une heure, quelque chose a du mal se passer.", "Cron was not executed yet!" : "Le cron n'a pas encore été exécuté !", "Execute one task with each page loaded" : "Exécute une tâche à chaque chargement de page", "cron.php is registered at a webcron service to call cron.php every 15 minutes over http." : "cron.php est enregistré en tant que service webcron pour appeler cron.php toutes les 15 minutes via http.", @@ -144,6 +144,8 @@ OC.L10N.register( "These groups will still be able to receive shares, but not to initiate them." : "Ces groupes ne pourront plus initier de partage, mais ils pourront toujours rejoindre les partages faits par d'autres. ", "Enforce HTTPS" : "Forcer HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Forcer les clients à se connecter à %s via une connexion chiffrée.", + "Enforce HTTPS for subdomains" : "Forcer HTTPS pour les sous domaines", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Force les clients à se connecter à %s et aux sous domaines via une connexion chiffrée.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Veuillez vous connecter à cette instance %s via HTTPS pour activer ou désactiver SSL.", "This is used for sending out notifications." : "Ceci est utilisé pour l'envoi des notifications.", "Send mode" : "Mode d'envoi", @@ -219,8 +221,7 @@ OC.L10N.register( "Username" : "Nom d'utilisateur", "Create" : "Créer", "Admin Recovery Password" : "Récupération du mot de passe administrateur", - "Enter the recovery password in order to recover the users files during password change" : "Entrer le mot de passe de récupération dans le but de récupérer les fichiers utilisateurs pendant le changement de mot de passe", - "Search Users and Groups" : "Chercher parmi les utilisateurs et groupes", + "Enter the recovery password in order to recover the users files during password change" : "Entrez le mot de passe de récupération pour récupérer les fichiers utilisateurs pendant le changement de mot de passe", "Add Group" : "Ajouter un groupe", "Group" : "Groupe", "Everyone" : "Tout le monde", diff --git a/settings/l10n/fr.json b/settings/l10n/fr.json index b05ce31285a..d9e128e4d9e 100644 --- a/settings/l10n/fr.json +++ b/settings/l10n/fr.json @@ -32,7 +32,7 @@ "No user supplied" : "Aucun utilisateur fourni", "Please provide an admin recovery password, otherwise all user data will be lost" : "Veuillez fournir un mot de passe administrateur de récupération de données, sinon toutes les données de l'utilisateur seront perdues", "Wrong admin recovery password. Please check the password and try again." : "Mot de passe administrateur de récupération de données non valable. Veuillez vérifier le mot de passe et essayer à nouveau.", - "Back-end doesn't support password change, but the users encryption key was successfully updated." : "L'infrastructure d'arrière-plan ne supporte pas la modification de mot de passe, mais la clef de chiffrement des utilisateurs a été mise à jour avec succès.", + "Back-end doesn't support password change, but the users encryption key was successfully updated." : "L'infrastructure d'arrière-plan ne permet pas la modification de mot de passe, mais la clef de chiffrement des utilisateurs a été mise à jour avec succès.", "Unable to change password" : "Impossible de modifier le mot de passe", "Enabled" : "Activées", "Not enabled" : "Désactivées", @@ -113,16 +113,16 @@ "PHP charset is not set to UTF-8" : "Le jeu de caractères PHP n'est pas réglé sur UTF-8", "PHP charset is not set to UTF-8. This can cause major issues with non-ASCII characters in file names. We highly recommend to change the value of 'default_charset' php.ini to 'UTF-8'." : "Le jeu de caractères PHP n'est pas réglé sur UTF-8. Ceci peut entraîner des problèmes majeurs avec les noms de fichiers contenant des caractère non-ASCII. Nous recommandons fortement de changer la valeur de 'default_charset' dans php.ini par 'UTF-8'.", "Locale not working" : "Localisation non fonctionnelle", - "System locale can not be set to a one which supports UTF-8." : "Les paramètres régionaux ne peuvent pas être configurés avec un qui supporte UTF-8.", + "System locale can not be set to a one which supports UTF-8." : "Les paramètres régionaux ne peuvent pas être configurés avec prise en charge d'UTF-8.", "This means that there might be problems with certain characters in file names." : "Cela signifie qu'il pourrait y avoir des problèmes avec certains caractères dans les noms de fichier.", - "We strongly suggest to install the required packages on your system to support one of the following locales: %s." : "Nous conseillons vivement d'installer les paquets requis sur votre système pour supporter l'un des paramètres régionaux suivants : %s.", + "We strongly suggest to install the required packages on your system to support one of the following locales: %s." : "Nous conseillons vivement d'installer sur votre système les paquets nécessaires à la prise en charge de l'un des paramètres régionaux suivants : %s.", "URL generation in notification emails" : "Génération d'URL dans les mails de notification", "If your installation is not installed in the root of the domain and uses system cron, there can be issues with the URL generation. To avoid these problems, please set the \"overwritewebroot\" option in your config.php file to the webroot path of your installation (Suggested: \"%s\")" : "Si votre installation n'a pas été effectuée à la racine du domaine et qu'elle utilise le cron du système, il peut y avoir des problèmes avec la génération d'URL. Pour les éviter, veuillez configurer l'option \"overwritewebroot\" de votre fichier config.php avec le chemin de la racine de votre installation (suggéré : \"%s\")", "Connectivity Checks" : "Vérification de la connectivité", "No problems found" : "Aucun problème trouvé", "Please double check the <a href='%s'>installation guides</a>." : "Veuillez vous référer au <a href='%s'>guide d'installation</a>.", - "Last cron was executed at %s." : "Le dernier cron s'est exécuté à %s.", - "Last cron was executed at %s. This is more than an hour ago, something seems wrong." : "Le dernier cron s'est exécuté à %s. Cela fait plus d'une heure, quelque chose a du mal se passer.", + "Last cron was executed at %s." : "Le dernier cron s'est exécuté à la date suivante : %s.", + "Last cron was executed at %s. This is more than an hour ago, something seems wrong." : "Le dernier cron s'est exécuté à la date suivante : %s. Cela fait plus d'une heure, quelque chose a du mal se passer.", "Cron was not executed yet!" : "Le cron n'a pas encore été exécuté !", "Execute one task with each page loaded" : "Exécute une tâche à chaque chargement de page", "cron.php is registered at a webcron service to call cron.php every 15 minutes over http." : "cron.php est enregistré en tant que service webcron pour appeler cron.php toutes les 15 minutes via http.", @@ -142,6 +142,8 @@ "These groups will still be able to receive shares, but not to initiate them." : "Ces groupes ne pourront plus initier de partage, mais ils pourront toujours rejoindre les partages faits par d'autres. ", "Enforce HTTPS" : "Forcer HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Forcer les clients à se connecter à %s via une connexion chiffrée.", + "Enforce HTTPS for subdomains" : "Forcer HTTPS pour les sous domaines", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Force les clients à se connecter à %s et aux sous domaines via une connexion chiffrée.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Veuillez vous connecter à cette instance %s via HTTPS pour activer ou désactiver SSL.", "This is used for sending out notifications." : "Ceci est utilisé pour l'envoi des notifications.", "Send mode" : "Mode d'envoi", @@ -217,8 +219,7 @@ "Username" : "Nom d'utilisateur", "Create" : "Créer", "Admin Recovery Password" : "Récupération du mot de passe administrateur", - "Enter the recovery password in order to recover the users files during password change" : "Entrer le mot de passe de récupération dans le but de récupérer les fichiers utilisateurs pendant le changement de mot de passe", - "Search Users and Groups" : "Chercher parmi les utilisateurs et groupes", + "Enter the recovery password in order to recover the users files during password change" : "Entrez le mot de passe de récupération pour récupérer les fichiers utilisateurs pendant le changement de mot de passe", "Add Group" : "Ajouter un groupe", "Group" : "Groupe", "Everyone" : "Tout le monde", diff --git a/settings/l10n/gl.js b/settings/l10n/gl.js index 778020d821e..2dc00590d69 100644 --- a/settings/l10n/gl.js +++ b/settings/l10n/gl.js @@ -220,7 +220,6 @@ OC.L10N.register( "Create" : "Crear", "Admin Recovery Password" : "Contrasinal de recuperación do administrador", "Enter the recovery password in order to recover the users files during password change" : "Introduza o contrasinal de recuperación para recuperar os ficheiros dos usuarios durante o cambio de contrasinal", - "Search Users and Groups" : "Buscar usuarios e grupos", "Add Group" : "Engadir un grupo", "Group" : "Grupo", "Everyone" : "Todos", diff --git a/settings/l10n/gl.json b/settings/l10n/gl.json index 3ceb32390dd..18d57342f8f 100644 --- a/settings/l10n/gl.json +++ b/settings/l10n/gl.json @@ -218,7 +218,6 @@ "Create" : "Crear", "Admin Recovery Password" : "Contrasinal de recuperación do administrador", "Enter the recovery password in order to recover the users files during password change" : "Introduza o contrasinal de recuperación para recuperar os ficheiros dos usuarios durante o cambio de contrasinal", - "Search Users and Groups" : "Buscar usuarios e grupos", "Add Group" : "Engadir un grupo", "Group" : "Grupo", "Everyone" : "Todos", diff --git a/settings/l10n/hr.js b/settings/l10n/hr.js index 806ec98e984..618d757078e 100644 --- a/settings/l10n/hr.js +++ b/settings/l10n/hr.js @@ -207,7 +207,6 @@ OC.L10N.register( "Create" : "Kreirajte", "Admin Recovery Password" : "Admin lozinka za oporavak", "Enter the recovery password in order to recover the users files during password change" : "Unesite lozinku za oporavak da biste oporavili korisničke datoteke tijekom promjene lozinke", - "Search Users and Groups" : "Pretražite korisnike i grupe", "Add Group" : "Dodajte grupu", "Group" : "Grupa", "Everyone" : "Svi", diff --git a/settings/l10n/hr.json b/settings/l10n/hr.json index 258a54c6f64..3ebd6ae2d1a 100644 --- a/settings/l10n/hr.json +++ b/settings/l10n/hr.json @@ -205,7 +205,6 @@ "Create" : "Kreirajte", "Admin Recovery Password" : "Admin lozinka za oporavak", "Enter the recovery password in order to recover the users files during password change" : "Unesite lozinku za oporavak da biste oporavili korisničke datoteke tijekom promjene lozinke", - "Search Users and Groups" : "Pretražite korisnike i grupe", "Add Group" : "Dodajte grupu", "Group" : "Grupa", "Everyone" : "Svi", diff --git a/settings/l10n/hu_HU.js b/settings/l10n/hu_HU.js index 5b7c2f97771..828922fbebc 100644 --- a/settings/l10n/hu_HU.js +++ b/settings/l10n/hu_HU.js @@ -201,7 +201,6 @@ OC.L10N.register( "Create" : "Létrehozás", "Admin Recovery Password" : "Adminisztrátori jelszó az állományok visszanyerésére", "Enter the recovery password in order to recover the users files during password change" : "Adja meg az adatok visszanyeréséhez szükséges jelszót arra az esetre, ha a felhasználók megváltoztatják a jelszavukat", - "Search Users and Groups" : "Keresés a felhasználók és a csoportok között", "Add Group" : "Csoport létrehozása", "Group" : "Csoport", "Everyone" : "Mindenki", diff --git a/settings/l10n/hu_HU.json b/settings/l10n/hu_HU.json index 46616b5291b..d4db40c1d61 100644 --- a/settings/l10n/hu_HU.json +++ b/settings/l10n/hu_HU.json @@ -199,7 +199,6 @@ "Create" : "Létrehozás", "Admin Recovery Password" : "Adminisztrátori jelszó az állományok visszanyerésére", "Enter the recovery password in order to recover the users files during password change" : "Adja meg az adatok visszanyeréséhez szükséges jelszót arra az esetre, ha a felhasználók megváltoztatják a jelszavukat", - "Search Users and Groups" : "Keresés a felhasználók és a csoportok között", "Add Group" : "Csoport létrehozása", "Group" : "Csoport", "Everyone" : "Mindenki", diff --git a/settings/l10n/id.js b/settings/l10n/id.js index 74dfa4c9b0f..261734b9997 100644 --- a/settings/l10n/id.js +++ b/settings/l10n/id.js @@ -218,7 +218,6 @@ OC.L10N.register( "Create" : "Buat", "Admin Recovery Password" : "Sandi pemulihan Admin", "Enter the recovery password in order to recover the users files during password change" : "Masukkan sandi pemulihan untuk memulihkan berkas pengguna saat penggantian sandi", - "Search Users and Groups" : "Telusuri Pengguna dan Grup", "Add Group" : "Tambah Grup", "Group" : "Grup", "Everyone" : "Semua orang", diff --git a/settings/l10n/id.json b/settings/l10n/id.json index 326ab4c6bca..e64d574f932 100644 --- a/settings/l10n/id.json +++ b/settings/l10n/id.json @@ -216,7 +216,6 @@ "Create" : "Buat", "Admin Recovery Password" : "Sandi pemulihan Admin", "Enter the recovery password in order to recover the users files during password change" : "Masukkan sandi pemulihan untuk memulihkan berkas pengguna saat penggantian sandi", - "Search Users and Groups" : "Telusuri Pengguna dan Grup", "Add Group" : "Tambah Grup", "Group" : "Grup", "Everyone" : "Semua orang", diff --git a/settings/l10n/it.js b/settings/l10n/it.js index d5a7a3259df..522b2f2fb96 100644 --- a/settings/l10n/it.js +++ b/settings/l10n/it.js @@ -144,6 +144,8 @@ OC.L10N.register( "These groups will still be able to receive shares, but not to initiate them." : "Questi gruppi saranno in grado di ricevere condivisioni, ma non iniziarle.", "Enforce HTTPS" : "Forza HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Forza i client a connettersi a %s tramite una connessione cifrata.", + "Enforce HTTPS for subdomains" : "Forza HTTPS per i sottodomini", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Forza i client a connettersi a %s e ai sottodomini tramite una connessione cifrata.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Connettiti al tuo %s tramite HTTPS per abilitare o disabilitare l'applicazione di SSL.", "This is used for sending out notifications." : "Viene utilizzato per inviare le notifiche.", "Send mode" : "Modalità di invio", @@ -220,7 +222,6 @@ OC.L10N.register( "Create" : "Crea", "Admin Recovery Password" : "Password di ripristino amministrativa", "Enter the recovery password in order to recover the users files during password change" : "Digita la password di ripristino per recuperare i file degli utenti durante la modifica della password.", - "Search Users and Groups" : "Cerca utenti e gruppi", "Add Group" : "Aggiungi gruppo", "Group" : "Gruppo", "Everyone" : "Chiunque", diff --git a/settings/l10n/it.json b/settings/l10n/it.json index 228c98c6068..2ac61e1cb90 100644 --- a/settings/l10n/it.json +++ b/settings/l10n/it.json @@ -142,6 +142,8 @@ "These groups will still be able to receive shares, but not to initiate them." : "Questi gruppi saranno in grado di ricevere condivisioni, ma non iniziarle.", "Enforce HTTPS" : "Forza HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Forza i client a connettersi a %s tramite una connessione cifrata.", + "Enforce HTTPS for subdomains" : "Forza HTTPS per i sottodomini", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Forza i client a connettersi a %s e ai sottodomini tramite una connessione cifrata.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Connettiti al tuo %s tramite HTTPS per abilitare o disabilitare l'applicazione di SSL.", "This is used for sending out notifications." : "Viene utilizzato per inviare le notifiche.", "Send mode" : "Modalità di invio", @@ -218,7 +220,6 @@ "Create" : "Crea", "Admin Recovery Password" : "Password di ripristino amministrativa", "Enter the recovery password in order to recover the users files during password change" : "Digita la password di ripristino per recuperare i file degli utenti durante la modifica della password.", - "Search Users and Groups" : "Cerca utenti e gruppi", "Add Group" : "Aggiungi gruppo", "Group" : "Gruppo", "Everyone" : "Chiunque", diff --git a/settings/l10n/ja.js b/settings/l10n/ja.js index 693cc13039c..b50eb561ebc 100644 --- a/settings/l10n/ja.js +++ b/settings/l10n/ja.js @@ -144,6 +144,8 @@ OC.L10N.register( "These groups will still be able to receive shares, but not to initiate them." : "このグループでは、フォルダー共有を開始することはできませんが、共有されたフォルダーを参照することはできます。", "Enforce HTTPS" : "常にHTTPSを使用する", "Forces the clients to connect to %s via an encrypted connection." : "クライアントから %sへの接続を常に暗号化します。", + "Enforce HTTPS for subdomains" : "サブドメインのHTTPSを強制する", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "%s とサブドメインへの暗号化接続をクライアントに強制する。", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "強制的なSSL接続を有効/無効にするには、HTTPS経由で %s へ接続してください。", "This is used for sending out notifications." : "通知を送信する際に使用します。", "Send mode" : "送信モード", @@ -220,7 +222,6 @@ OC.L10N.register( "Create" : "作成", "Admin Recovery Password" : "管理者リカバリパスワード", "Enter the recovery password in order to recover the users files during password change" : "パスワード変更時のユーザーのファイルを回復するため、リカバリパスワードを入力してください", - "Search Users and Groups" : "ユーザーとグループを検索", "Add Group" : "グループを追加", "Group" : "グループ", "Everyone" : "すべてのユーザー", diff --git a/settings/l10n/ja.json b/settings/l10n/ja.json index 894a535d445..0668e178753 100644 --- a/settings/l10n/ja.json +++ b/settings/l10n/ja.json @@ -142,6 +142,8 @@ "These groups will still be able to receive shares, but not to initiate them." : "このグループでは、フォルダー共有を開始することはできませんが、共有されたフォルダーを参照することはできます。", "Enforce HTTPS" : "常にHTTPSを使用する", "Forces the clients to connect to %s via an encrypted connection." : "クライアントから %sへの接続を常に暗号化します。", + "Enforce HTTPS for subdomains" : "サブドメインのHTTPSを強制する", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "%s とサブドメインへの暗号化接続をクライアントに強制する。", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "強制的なSSL接続を有効/無効にするには、HTTPS経由で %s へ接続してください。", "This is used for sending out notifications." : "通知を送信する際に使用します。", "Send mode" : "送信モード", @@ -218,7 +220,6 @@ "Create" : "作成", "Admin Recovery Password" : "管理者リカバリパスワード", "Enter the recovery password in order to recover the users files during password change" : "パスワード変更時のユーザーのファイルを回復するため、リカバリパスワードを入力してください", - "Search Users and Groups" : "ユーザーとグループを検索", "Add Group" : "グループを追加", "Group" : "グループ", "Everyone" : "すべてのユーザー", diff --git a/settings/l10n/ko.js b/settings/l10n/ko.js index f669d5d1b25..b8239d32215 100644 --- a/settings/l10n/ko.js +++ b/settings/l10n/ko.js @@ -157,7 +157,6 @@ OC.L10N.register( "Create" : "만들기", "Admin Recovery Password" : "관리자 복구 암호", "Enter the recovery password in order to recover the users files during password change" : "암호 변경 시 변경된 사용자 파일을 복구하려면 복구 암호를 입력하십시오", - "Search Users and Groups" : "사용자와 그룹 검색", "Add Group" : "그룹 추가", "Group" : "그룹", "Admins" : "관리자", diff --git a/settings/l10n/ko.json b/settings/l10n/ko.json index bde465dddc9..095ac5adedd 100644 --- a/settings/l10n/ko.json +++ b/settings/l10n/ko.json @@ -155,7 +155,6 @@ "Create" : "만들기", "Admin Recovery Password" : "관리자 복구 암호", "Enter the recovery password in order to recover the users files during password change" : "암호 변경 시 변경된 사용자 파일을 복구하려면 복구 암호를 입력하십시오", - "Search Users and Groups" : "사용자와 그룹 검색", "Add Group" : "그룹 추가", "Group" : "그룹", "Admins" : "관리자", diff --git a/settings/l10n/mk.js b/settings/l10n/mk.js index c331bab6c8d..57245605ae0 100644 --- a/settings/l10n/mk.js +++ b/settings/l10n/mk.js @@ -148,7 +148,6 @@ OC.L10N.register( "Username" : "Корисничко име", "Create" : "Создај", "Admin Recovery Password" : "Обновување на Admin лозинката", - "Search Users and Groups" : "Барај корисници и групи", "Add Group" : "Додади група", "Group" : "Група", "Everyone" : "Секој", diff --git a/settings/l10n/mk.json b/settings/l10n/mk.json index bcc0841a398..4445c65d6ec 100644 --- a/settings/l10n/mk.json +++ b/settings/l10n/mk.json @@ -146,7 +146,6 @@ "Username" : "Корисничко име", "Create" : "Создај", "Admin Recovery Password" : "Обновување на Admin лозинката", - "Search Users and Groups" : "Барај корисници и групи", "Add Group" : "Додади група", "Group" : "Група", "Everyone" : "Секој", diff --git a/settings/l10n/nb_NO.js b/settings/l10n/nb_NO.js index feb8c9bb372..03c8b3f53f6 100644 --- a/settings/l10n/nb_NO.js +++ b/settings/l10n/nb_NO.js @@ -208,7 +208,6 @@ OC.L10N.register( "Create" : "Opprett", "Admin Recovery Password" : "Administrativt gjenopprettingspassord", "Enter the recovery password in order to recover the users files during password change" : "Legg inn gjenopprettingspassordet for å gjenopprette brukerfilene når passordet endres", - "Search Users and Groups" : "Søk i brukere og grupper", "Add Group" : "Legg til gruppe", "Group" : "Gruppe", "Everyone" : "Alle", diff --git a/settings/l10n/nb_NO.json b/settings/l10n/nb_NO.json index 593bc0d2e07..a422cd25590 100644 --- a/settings/l10n/nb_NO.json +++ b/settings/l10n/nb_NO.json @@ -206,7 +206,6 @@ "Create" : "Opprett", "Admin Recovery Password" : "Administrativt gjenopprettingspassord", "Enter the recovery password in order to recover the users files during password change" : "Legg inn gjenopprettingspassordet for å gjenopprette brukerfilene når passordet endres", - "Search Users and Groups" : "Søk i brukere og grupper", "Add Group" : "Legg til gruppe", "Group" : "Gruppe", "Everyone" : "Alle", diff --git a/settings/l10n/nl.js b/settings/l10n/nl.js index dd97ce0faf5..8bc46cc45ae 100644 --- a/settings/l10n/nl.js +++ b/settings/l10n/nl.js @@ -144,6 +144,8 @@ OC.L10N.register( "These groups will still be able to receive shares, but not to initiate them." : "Deze groepen kunnen gedeelde mappen bestanden ontvangen, maar kunnen ze niet starten.", "Enforce HTTPS" : "Afdwingen HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Dwingt de clients om een versleutelde verbinding te maken met %s", + "Enforce HTTPS for subdomains" : "HTTPS afdwingen voor subdomeinen", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Dwingt de clients om een versleutelde verbinding te maken met %s en de subdomeinen.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Maak verbinding naar uw %s via HTTPS om een geforceerde versleutelde verbinding in- of uit te schakelen.", "This is used for sending out notifications." : "Dit wordt gestuurd voor het verzenden van meldingen.", "Send mode" : "Verstuurmodus", @@ -220,7 +222,6 @@ OC.L10N.register( "Create" : "Aanmaken", "Admin Recovery Password" : "Beheer herstel wachtwoord", "Enter the recovery password in order to recover the users files during password change" : "Voer het herstel wachtwoord in om de gebruikersbestanden terug te halen bij wachtwoordwijziging", - "Search Users and Groups" : "Zoeken naar gebruikers en groepen", "Add Group" : "Toevoegen groep", "Group" : "Groep", "Everyone" : "Iedereen", diff --git a/settings/l10n/nl.json b/settings/l10n/nl.json index 4d9e405c12a..72bece28415 100644 --- a/settings/l10n/nl.json +++ b/settings/l10n/nl.json @@ -142,6 +142,8 @@ "These groups will still be able to receive shares, but not to initiate them." : "Deze groepen kunnen gedeelde mappen bestanden ontvangen, maar kunnen ze niet starten.", "Enforce HTTPS" : "Afdwingen HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Dwingt de clients om een versleutelde verbinding te maken met %s", + "Enforce HTTPS for subdomains" : "HTTPS afdwingen voor subdomeinen", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Dwingt de clients om een versleutelde verbinding te maken met %s en de subdomeinen.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Maak verbinding naar uw %s via HTTPS om een geforceerde versleutelde verbinding in- of uit te schakelen.", "This is used for sending out notifications." : "Dit wordt gestuurd voor het verzenden van meldingen.", "Send mode" : "Verstuurmodus", @@ -218,7 +220,6 @@ "Create" : "Aanmaken", "Admin Recovery Password" : "Beheer herstel wachtwoord", "Enter the recovery password in order to recover the users files during password change" : "Voer het herstel wachtwoord in om de gebruikersbestanden terug te halen bij wachtwoordwijziging", - "Search Users and Groups" : "Zoeken naar gebruikers en groepen", "Add Group" : "Toevoegen groep", "Group" : "Groep", "Everyone" : "Iedereen", diff --git a/settings/l10n/pl.js b/settings/l10n/pl.js index 14108c49ae2..ec78dbd3d45 100644 --- a/settings/l10n/pl.js +++ b/settings/l10n/pl.js @@ -217,7 +217,6 @@ OC.L10N.register( "Create" : "Utwórz", "Admin Recovery Password" : "Odzyskiwanie hasła administratora", "Enter the recovery password in order to recover the users files during password change" : "Wpisz hasło odzyskiwania, aby odzyskać pliki użytkowników podczas zmiany hasła", - "Search Users and Groups" : "Przeszukuj użytkowników i grupy", "Add Group" : "Dodaj grupę", "Group" : "Grupa", "Everyone" : "Wszyscy", diff --git a/settings/l10n/pl.json b/settings/l10n/pl.json index b30513d8a8a..e3eeee75e16 100644 --- a/settings/l10n/pl.json +++ b/settings/l10n/pl.json @@ -215,7 +215,6 @@ "Create" : "Utwórz", "Admin Recovery Password" : "Odzyskiwanie hasła administratora", "Enter the recovery password in order to recover the users files during password change" : "Wpisz hasło odzyskiwania, aby odzyskać pliki użytkowników podczas zmiany hasła", - "Search Users and Groups" : "Przeszukuj użytkowników i grupy", "Add Group" : "Dodaj grupę", "Group" : "Grupa", "Everyone" : "Wszyscy", diff --git a/settings/l10n/pt_BR.js b/settings/l10n/pt_BR.js index 3d1f3906ed1..30346ed6e58 100644 --- a/settings/l10n/pt_BR.js +++ b/settings/l10n/pt_BR.js @@ -144,6 +144,8 @@ OC.L10N.register( "These groups will still be able to receive shares, but not to initiate them." : "Esses grupos ainda serão capazes de receber compartilhamentos, mas não para iniciá-los.", "Enforce HTTPS" : "Forçar HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Obrigar os clientes que se conectem a %s através de uma conexão criptografada.", + "Enforce HTTPS for subdomains" : "Forçar HTTPS para subdomínios", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Força os clientes se conectem a %s e subdomínios através de uma conexão criptografada.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Por favor, se conectar ao seu %s via HTTPS para forçar ativar ou desativar SSL.", "This is used for sending out notifications." : "Isto é usado para o envio de notificações.", "Send mode" : "Modo enviar", @@ -220,7 +222,6 @@ OC.L10N.register( "Create" : "Criar", "Admin Recovery Password" : "Recuperação da Senha do Administrador", "Enter the recovery password in order to recover the users files during password change" : "Digite a senha de recuperação para recuperar os arquivos dos usuários durante a mudança de senha.", - "Search Users and Groups" : "Pesquisar Usuários e Grupos", "Add Group" : "Adicionar Grupo", "Group" : "Grupo", "Everyone" : "Para todos", diff --git a/settings/l10n/pt_BR.json b/settings/l10n/pt_BR.json index 12684951f9a..0d89f75f1d1 100644 --- a/settings/l10n/pt_BR.json +++ b/settings/l10n/pt_BR.json @@ -142,6 +142,8 @@ "These groups will still be able to receive shares, but not to initiate them." : "Esses grupos ainda serão capazes de receber compartilhamentos, mas não para iniciá-los.", "Enforce HTTPS" : "Forçar HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Obrigar os clientes que se conectem a %s através de uma conexão criptografada.", + "Enforce HTTPS for subdomains" : "Forçar HTTPS para subdomínios", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Força os clientes se conectem a %s e subdomínios através de uma conexão criptografada.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Por favor, se conectar ao seu %s via HTTPS para forçar ativar ou desativar SSL.", "This is used for sending out notifications." : "Isto é usado para o envio de notificações.", "Send mode" : "Modo enviar", @@ -218,7 +220,6 @@ "Create" : "Criar", "Admin Recovery Password" : "Recuperação da Senha do Administrador", "Enter the recovery password in order to recover the users files during password change" : "Digite a senha de recuperação para recuperar os arquivos dos usuários durante a mudança de senha.", - "Search Users and Groups" : "Pesquisar Usuários e Grupos", "Add Group" : "Adicionar Grupo", "Group" : "Grupo", "Everyone" : "Para todos", diff --git a/settings/l10n/pt_PT.js b/settings/l10n/pt_PT.js index 4161f7f6cae..8a5b941d8c7 100644 --- a/settings/l10n/pt_PT.js +++ b/settings/l10n/pt_PT.js @@ -144,6 +144,8 @@ OC.L10N.register( "These groups will still be able to receive shares, but not to initiate them." : "Estes grupos poderão receber partilhas, mas não poderão iniciá-las.", "Enforce HTTPS" : "Forçar HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Forçar os clientes a ligar a %s através de uma ligação encriptada", + "Enforce HTTPS for subdomains" : "Forçar HTTPS para subdomínios", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Força os clientes a ligar a %s e a subdomínios via uma ligação encriptada.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Por favor ligue-se a %s através de uma ligação HTTPS para ligar/desligar o uso de ligação por SSL", "This is used for sending out notifications." : "Isto é utilizado para enviar notificações", "Send mode" : "Modo de Envio", @@ -220,7 +222,6 @@ OC.L10N.register( "Create" : "Criar", "Admin Recovery Password" : "Recuperar password de administrador", "Enter the recovery password in order to recover the users files during password change" : "Digite a senha de recuperação, a fim de recuperar os arquivos de usuários durante a mudança de senha", - "Search Users and Groups" : "Pesquisa Utilizadores e Grupos", "Add Group" : "Adicionar grupo", "Group" : "Grupo", "Everyone" : "Para todos", diff --git a/settings/l10n/pt_PT.json b/settings/l10n/pt_PT.json index a94848a2c5e..8a3882cd7b1 100644 --- a/settings/l10n/pt_PT.json +++ b/settings/l10n/pt_PT.json @@ -142,6 +142,8 @@ "These groups will still be able to receive shares, but not to initiate them." : "Estes grupos poderão receber partilhas, mas não poderão iniciá-las.", "Enforce HTTPS" : "Forçar HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Forçar os clientes a ligar a %s através de uma ligação encriptada", + "Enforce HTTPS for subdomains" : "Forçar HTTPS para subdomínios", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Força os clientes a ligar a %s e a subdomínios via uma ligação encriptada.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Por favor ligue-se a %s através de uma ligação HTTPS para ligar/desligar o uso de ligação por SSL", "This is used for sending out notifications." : "Isto é utilizado para enviar notificações", "Send mode" : "Modo de Envio", @@ -218,7 +220,6 @@ "Create" : "Criar", "Admin Recovery Password" : "Recuperar password de administrador", "Enter the recovery password in order to recover the users files during password change" : "Digite a senha de recuperação, a fim de recuperar os arquivos de usuários durante a mudança de senha", - "Search Users and Groups" : "Pesquisa Utilizadores e Grupos", "Add Group" : "Adicionar grupo", "Group" : "Grupo", "Everyone" : "Para todos", diff --git a/settings/l10n/ru.js b/settings/l10n/ru.js index e776aeb220d..d792a7e1094 100644 --- a/settings/l10n/ru.js +++ b/settings/l10n/ru.js @@ -144,9 +144,11 @@ OC.L10N.register( "These groups will still be able to receive shares, but not to initiate them." : "Эти группы смогут получать общие файлы, но не смогут отправлять их.", "Enforce HTTPS" : "HTTPS соединение обязательно", "Forces the clients to connect to %s via an encrypted connection." : "Принудить клиентов подключаться к %s через шифрованное соединение.", + "Enforce HTTPS for subdomains" : "HTTPS соединение обязательно для субдоменов", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Принудить клиентов подключаться к %s и субдоменам через шифрованное соединение.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Пожалуйста, подключитесь к %s используя HTTPS чтобы включить или отключить обязательные SSL подключения.", "This is used for sending out notifications." : "Используется для отправки уведомлений.", - "Send mode" : "Отправить сообщение", + "Send mode" : "Способ отправки", "From address" : "Адрес отправителя", "mail" : "почта", "Authentication method" : "Метод проверки подлинности", @@ -156,9 +158,9 @@ OC.L10N.register( "Credentials" : "Учётные данные", "SMTP Username" : "Пользователь SMTP", "SMTP Password" : "Пароль SMTP", - "Store credentials" : "Хранить учётные данные", + "Store credentials" : "Сохранить учётные данные", "Test email settings" : "Проверить настройки почты", - "Send email" : "Отправить сообщение", + "Send email" : "Отправить email", "Log level" : "Уровень детализации журнала", "More" : "Больше", "Less" : "Меньше", @@ -166,7 +168,7 @@ OC.L10N.register( "Developed by the <a href=\"http://ownCloud.org/contact\" target=\"_blank\">ownCloud community</a>, the <a href=\"https://github.com/owncloud\" target=\"_blank\">source code</a> is licensed under the <a href=\"http://www.gnu.org/licenses/agpl-3.0.html\" target=\"_blank\"><abbr title=\"Affero General Public License\">AGPL</abbr></a>." : "Разрабатывается <a href=\"http://ownCloud.org/contact\" target=\"_blank\">сообществом ownCloud</a>, <a href=\"https://github.com/owncloud\" target=\"_blank\">исходный код</a> доступен под лицензией <a href=\"http://www.gnu.org/licenses/agpl-3.0.html\" target=\"_blank\"><abbr title=\"Affero General Public License\">AGPL</abbr></a>.", "More apps" : "Ещё приложения", "Add your app" : "Добавить своё приложение", - "by" : ":", + "by" : "автор", "licensed" : "Лицензировано", "Documentation:" : "Документация:", "User Documentation" : "Пользовательская документация", @@ -220,7 +222,6 @@ OC.L10N.register( "Create" : "Создать", "Admin Recovery Password" : "Восстановление пароля администратора", "Enter the recovery password in order to recover the users files during password change" : "Введите пароль для того, чтобы восстановить файлы пользователей при смене пароля", - "Search Users and Groups" : "Искать пользователей и групп", "Add Group" : "Добавить группу", "Group" : "Группа", "Everyone" : "Все", diff --git a/settings/l10n/ru.json b/settings/l10n/ru.json index 44661eed3e2..56dfc80cffd 100644 --- a/settings/l10n/ru.json +++ b/settings/l10n/ru.json @@ -142,9 +142,11 @@ "These groups will still be able to receive shares, but not to initiate them." : "Эти группы смогут получать общие файлы, но не смогут отправлять их.", "Enforce HTTPS" : "HTTPS соединение обязательно", "Forces the clients to connect to %s via an encrypted connection." : "Принудить клиентов подключаться к %s через шифрованное соединение.", + "Enforce HTTPS for subdomains" : "HTTPS соединение обязательно для субдоменов", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Принудить клиентов подключаться к %s и субдоменам через шифрованное соединение.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Пожалуйста, подключитесь к %s используя HTTPS чтобы включить или отключить обязательные SSL подключения.", "This is used for sending out notifications." : "Используется для отправки уведомлений.", - "Send mode" : "Отправить сообщение", + "Send mode" : "Способ отправки", "From address" : "Адрес отправителя", "mail" : "почта", "Authentication method" : "Метод проверки подлинности", @@ -154,9 +156,9 @@ "Credentials" : "Учётные данные", "SMTP Username" : "Пользователь SMTP", "SMTP Password" : "Пароль SMTP", - "Store credentials" : "Хранить учётные данные", + "Store credentials" : "Сохранить учётные данные", "Test email settings" : "Проверить настройки почты", - "Send email" : "Отправить сообщение", + "Send email" : "Отправить email", "Log level" : "Уровень детализации журнала", "More" : "Больше", "Less" : "Меньше", @@ -164,7 +166,7 @@ "Developed by the <a href=\"http://ownCloud.org/contact\" target=\"_blank\">ownCloud community</a>, the <a href=\"https://github.com/owncloud\" target=\"_blank\">source code</a> is licensed under the <a href=\"http://www.gnu.org/licenses/agpl-3.0.html\" target=\"_blank\"><abbr title=\"Affero General Public License\">AGPL</abbr></a>." : "Разрабатывается <a href=\"http://ownCloud.org/contact\" target=\"_blank\">сообществом ownCloud</a>, <a href=\"https://github.com/owncloud\" target=\"_blank\">исходный код</a> доступен под лицензией <a href=\"http://www.gnu.org/licenses/agpl-3.0.html\" target=\"_blank\"><abbr title=\"Affero General Public License\">AGPL</abbr></a>.", "More apps" : "Ещё приложения", "Add your app" : "Добавить своё приложение", - "by" : ":", + "by" : "автор", "licensed" : "Лицензировано", "Documentation:" : "Документация:", "User Documentation" : "Пользовательская документация", @@ -218,7 +220,6 @@ "Create" : "Создать", "Admin Recovery Password" : "Восстановление пароля администратора", "Enter the recovery password in order to recover the users files during password change" : "Введите пароль для того, чтобы восстановить файлы пользователей при смене пароля", - "Search Users and Groups" : "Искать пользователей и групп", "Add Group" : "Добавить группу", "Group" : "Группа", "Everyone" : "Все", diff --git a/settings/l10n/sk_SK.js b/settings/l10n/sk_SK.js index 36dc76b6358..b94ada408f8 100644 --- a/settings/l10n/sk_SK.js +++ b/settings/l10n/sk_SK.js @@ -220,7 +220,6 @@ OC.L10N.register( "Create" : "Vytvoriť", "Admin Recovery Password" : "Obnovenie hesla administrátora", "Enter the recovery password in order to recover the users files during password change" : "Zadajte heslo pre obnovenie súborov používateľa pri zmene hesla", - "Search Users and Groups" : "Prehľadať používateľov a skupiny", "Add Group" : "Pridať skupinu", "Group" : "Skupina", "Everyone" : "Všetci", diff --git a/settings/l10n/sk_SK.json b/settings/l10n/sk_SK.json index fa42832c52e..3af85642551 100644 --- a/settings/l10n/sk_SK.json +++ b/settings/l10n/sk_SK.json @@ -218,7 +218,6 @@ "Create" : "Vytvoriť", "Admin Recovery Password" : "Obnovenie hesla administrátora", "Enter the recovery password in order to recover the users files during password change" : "Zadajte heslo pre obnovenie súborov používateľa pri zmene hesla", - "Search Users and Groups" : "Prehľadať používateľov a skupiny", "Add Group" : "Pridať skupinu", "Group" : "Skupina", "Everyone" : "Všetci", diff --git a/settings/l10n/sl.js b/settings/l10n/sl.js index fad7b286870..2a8cab07011 100644 --- a/settings/l10n/sl.js +++ b/settings/l10n/sl.js @@ -138,6 +138,8 @@ OC.L10N.register( "These groups will still be able to receive shares, but not to initiate them." : "Te skupine lahko sprejemajo mape v souporabo, ne morejo pa souporabe dovoliti", "Enforce HTTPS" : "Zahtevaj uporabo HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Vsili povezavo odjemalca z %s preko šifrirane povezave.", + "Enforce HTTPS for subdomains" : "Vsili protokol HTTPS za podrejene domene", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Vsili povezavo odjemalcev na naslovu %s in na vseh podrejenih domenah preko šifrirane povezave. ", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Za nastavljanje šifriranja SSL je treba vzpostaviti povezavo z mestom %s preko protokola HTTPS.", "This is used for sending out notifications." : "Možnost je uporabljena za omogočanje pošiljanja obvestil.", "Send mode" : "Način pošiljanja", @@ -210,7 +212,6 @@ OC.L10N.register( "Create" : "Ustvari", "Admin Recovery Password" : "Obnovitev skrbniškega gesla", "Enter the recovery password in order to recover the users files during password change" : "Vnesite geslo, ki omogoča obnovitev uporabniških datotek med spreminjanjem gesla", - "Search Users and Groups" : "Iskanje uporabnikov in skupin", "Add Group" : "Dodaj skupino", "Group" : "Skupina", "Everyone" : "Vsi", diff --git a/settings/l10n/sl.json b/settings/l10n/sl.json index 9f148233534..9d9090e0571 100644 --- a/settings/l10n/sl.json +++ b/settings/l10n/sl.json @@ -136,6 +136,8 @@ "These groups will still be able to receive shares, but not to initiate them." : "Te skupine lahko sprejemajo mape v souporabo, ne morejo pa souporabe dovoliti", "Enforce HTTPS" : "Zahtevaj uporabo HTTPS", "Forces the clients to connect to %s via an encrypted connection." : "Vsili povezavo odjemalca z %s preko šifrirane povezave.", + "Enforce HTTPS for subdomains" : "Vsili protokol HTTPS za podrejene domene", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "Vsili povezavo odjemalcev na naslovu %s in na vseh podrejenih domenah preko šifrirane povezave. ", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "Za nastavljanje šifriranja SSL je treba vzpostaviti povezavo z mestom %s preko protokola HTTPS.", "This is used for sending out notifications." : "Možnost je uporabljena za omogočanje pošiljanja obvestil.", "Send mode" : "Način pošiljanja", @@ -208,7 +210,6 @@ "Create" : "Ustvari", "Admin Recovery Password" : "Obnovitev skrbniškega gesla", "Enter the recovery password in order to recover the users files during password change" : "Vnesite geslo, ki omogoča obnovitev uporabniških datotek med spreminjanjem gesla", - "Search Users and Groups" : "Iskanje uporabnikov in skupin", "Add Group" : "Dodaj skupino", "Group" : "Skupina", "Everyone" : "Vsi", diff --git a/settings/l10n/sq.js b/settings/l10n/sq.js index 40697726184..ec4d9667170 100644 --- a/settings/l10n/sq.js +++ b/settings/l10n/sq.js @@ -101,7 +101,6 @@ OC.L10N.register( "Create" : "Krijo", "Admin Recovery Password" : "Rigjetja e fjalëkalimit të Admin", "Enter the recovery password in order to recover the users files during password change" : "Jepni fjalëkalimin e rigjetjes për të rigjetur skedarët e përdoruesit gjatë ndryshimit të fjalëkalimit", - "Search Users and Groups" : "Kërko Përdorues apo Grupe", "Add Group" : "Shto Grup", "Group" : "Grup", "Everyone" : "Të gjithë", diff --git a/settings/l10n/sq.json b/settings/l10n/sq.json index e3671303a3b..4c8a590d48c 100644 --- a/settings/l10n/sq.json +++ b/settings/l10n/sq.json @@ -99,7 +99,6 @@ "Create" : "Krijo", "Admin Recovery Password" : "Rigjetja e fjalëkalimit të Admin", "Enter the recovery password in order to recover the users files during password change" : "Jepni fjalëkalimin e rigjetjes për të rigjetur skedarët e përdoruesit gjatë ndryshimit të fjalëkalimit", - "Search Users and Groups" : "Kërko Përdorues apo Grupe", "Add Group" : "Shto Grup", "Group" : "Grup", "Everyone" : "Të gjithë", diff --git a/settings/l10n/sv.js b/settings/l10n/sv.js index 0487e5efd8b..842e47beebe 100644 --- a/settings/l10n/sv.js +++ b/settings/l10n/sv.js @@ -198,7 +198,6 @@ OC.L10N.register( "Create" : "Skapa", "Admin Recovery Password" : "Admin återställningslösenord", "Enter the recovery password in order to recover the users files during password change" : "Ange återställningslösenordet för att återställa användarnas filer vid lösenordsbyte", - "Search Users and Groups" : "Sök Användare och Grupper", "Add Group" : "Lägg till Grupp", "Group" : "Grupp", "Everyone" : "Alla", diff --git a/settings/l10n/sv.json b/settings/l10n/sv.json index 03b1899ce1e..d1f02536e4e 100644 --- a/settings/l10n/sv.json +++ b/settings/l10n/sv.json @@ -196,7 +196,6 @@ "Create" : "Skapa", "Admin Recovery Password" : "Admin återställningslösenord", "Enter the recovery password in order to recover the users files during password change" : "Ange återställningslösenordet för att återställa användarnas filer vid lösenordsbyte", - "Search Users and Groups" : "Sök Användare och Grupper", "Add Group" : "Lägg till Grupp", "Group" : "Grupp", "Everyone" : "Alla", diff --git a/settings/l10n/tr.js b/settings/l10n/tr.js index 0a33a604e4c..0a493f28e86 100644 --- a/settings/l10n/tr.js +++ b/settings/l10n/tr.js @@ -144,6 +144,8 @@ OC.L10N.register( "These groups will still be able to receive shares, but not to initiate them." : "Bu gruplar hala paylaşımları alabilecek, ancak başlatamayacaktır.", "Enforce HTTPS" : "HTTPS bağlantısına zorla", "Forces the clients to connect to %s via an encrypted connection." : "İstemcileri %s'a şifreli bir bağlantı ile bağlanmaya zorlar.", + "Enforce HTTPS for subdomains" : "Alt alan adları için HTTPS bağlantısına zorla", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "İstemcileri %s ve alt alan adlarına şifreli bir bağlantı ile bağlanmaya zorlar.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "SSL zorlamasını etkinleştirmek ya da devre dışı bırakmak için lütfen %s'a HTTPS ile bağlanın.", "This is used for sending out notifications." : "Bu, bildirimler gönderilirken kullanılır.", "Send mode" : "Gönderme kipi", @@ -220,7 +222,6 @@ OC.L10N.register( "Create" : "Oluştur", "Admin Recovery Password" : "Yönetici Kurtarma Parolası", "Enter the recovery password in order to recover the users files during password change" : "Parola değiştirme sırasında kullanıcı dosyalarını kurtarmak için kurtarma parolasını girin", - "Search Users and Groups" : "Kullanıcı ve Grupları Ara", "Add Group" : "Grup Ekle", "Group" : "Grup", "Everyone" : "Herkes", diff --git a/settings/l10n/tr.json b/settings/l10n/tr.json index b281d97834f..255c271496e 100644 --- a/settings/l10n/tr.json +++ b/settings/l10n/tr.json @@ -142,6 +142,8 @@ "These groups will still be able to receive shares, but not to initiate them." : "Bu gruplar hala paylaşımları alabilecek, ancak başlatamayacaktır.", "Enforce HTTPS" : "HTTPS bağlantısına zorla", "Forces the clients to connect to %s via an encrypted connection." : "İstemcileri %s'a şifreli bir bağlantı ile bağlanmaya zorlar.", + "Enforce HTTPS for subdomains" : "Alt alan adları için HTTPS bağlantısına zorla", + "Forces the clients to connect to %s and subdomains via an encrypted connection." : "İstemcileri %s ve alt alan adlarına şifreli bir bağlantı ile bağlanmaya zorlar.", "Please connect to your %s via HTTPS to enable or disable the SSL enforcement." : "SSL zorlamasını etkinleştirmek ya da devre dışı bırakmak için lütfen %s'a HTTPS ile bağlanın.", "This is used for sending out notifications." : "Bu, bildirimler gönderilirken kullanılır.", "Send mode" : "Gönderme kipi", @@ -218,7 +220,6 @@ "Create" : "Oluştur", "Admin Recovery Password" : "Yönetici Kurtarma Parolası", "Enter the recovery password in order to recover the users files during password change" : "Parola değiştirme sırasında kullanıcı dosyalarını kurtarmak için kurtarma parolasını girin", - "Search Users and Groups" : "Kullanıcı ve Grupları Ara", "Add Group" : "Grup Ekle", "Group" : "Grup", "Everyone" : "Herkes", diff --git a/settings/l10n/uk.js b/settings/l10n/uk.js index 76c5cca1490..b51ffda2258 100644 --- a/settings/l10n/uk.js +++ b/settings/l10n/uk.js @@ -1,6 +1,7 @@ OC.L10N.register( "settings", { + "Security & Setup Warnings" : "Попередження Налаштувань та Безпеки", "Cron" : "Cron", "Sharing" : "Спільний доступ", "Security" : "Безпека", @@ -119,6 +120,7 @@ OC.L10N.register( "We strongly suggest to install the required packages on your system to support one of the following locales: %s." : "Ми наполегливо рекомендуємо встановити необхідні пакети в систему, для підтримки наступних локалей: %s.", "URL generation in notification emails" : "Генерування URL для повідомлень в електроних листах", "If your installation is not installed in the root of the domain and uses system cron, there can be issues with the URL generation. To avoid these problems, please set the \"overwritewebroot\" option in your config.php file to the webroot path of your installation (Suggested: \"%s\")" : "Якщо ваша копія ownCloud встановлена не в корені домену та використовує систему планування CRON, можливі проблеми з генерацією правильних URL. Щоб уникнути цього, встановіть опцію overwritewebroot файла config.php відповідно до теки розташування установки (Ймовірніше за все, це \"%s\")", + "Connectivity Checks" : "Перевірка З'єднання", "No problems found" : "Проблем не виявленно", "Please double check the <a href='%s'>installation guides</a>." : "Будь ласка, перевірте <a href='%s'>інструкції по встановленню</a>.", "Last cron was executed at %s." : "Останню cron-задачу було запущено: %s.", @@ -218,7 +220,6 @@ OC.L10N.register( "Create" : "Створити", "Admin Recovery Password" : "Пароль адміністратора для відновлення", "Enter the recovery password in order to recover the users files during password change" : "Введіть пароль для того, щоб відновити файли користувачів при зміні паролю", - "Search Users and Groups" : "Шукати користувачів та групи", "Add Group" : "Додати групу", "Group" : "Група", "Everyone" : "Всі", diff --git a/settings/l10n/uk.json b/settings/l10n/uk.json index 4d5eb45f51f..08cbdcdd3a5 100644 --- a/settings/l10n/uk.json +++ b/settings/l10n/uk.json @@ -1,4 +1,5 @@ { "translations": { + "Security & Setup Warnings" : "Попередження Налаштувань та Безпеки", "Cron" : "Cron", "Sharing" : "Спільний доступ", "Security" : "Безпека", @@ -117,6 +118,7 @@ "We strongly suggest to install the required packages on your system to support one of the following locales: %s." : "Ми наполегливо рекомендуємо встановити необхідні пакети в систему, для підтримки наступних локалей: %s.", "URL generation in notification emails" : "Генерування URL для повідомлень в електроних листах", "If your installation is not installed in the root of the domain and uses system cron, there can be issues with the URL generation. To avoid these problems, please set the \"overwritewebroot\" option in your config.php file to the webroot path of your installation (Suggested: \"%s\")" : "Якщо ваша копія ownCloud встановлена не в корені домену та використовує систему планування CRON, можливі проблеми з генерацією правильних URL. Щоб уникнути цього, встановіть опцію overwritewebroot файла config.php відповідно до теки розташування установки (Ймовірніше за все, це \"%s\")", + "Connectivity Checks" : "Перевірка З'єднання", "No problems found" : "Проблем не виявленно", "Please double check the <a href='%s'>installation guides</a>." : "Будь ласка, перевірте <a href='%s'>інструкції по встановленню</a>.", "Last cron was executed at %s." : "Останню cron-задачу було запущено: %s.", @@ -216,7 +218,6 @@ "Create" : "Створити", "Admin Recovery Password" : "Пароль адміністратора для відновлення", "Enter the recovery password in order to recover the users files during password change" : "Введіть пароль для того, щоб відновити файли користувачів при зміні паролю", - "Search Users and Groups" : "Шукати користувачів та групи", "Add Group" : "Додати групу", "Group" : "Група", "Everyone" : "Всі", diff --git a/settings/l10n/zh_CN.js b/settings/l10n/zh_CN.js index af5b786c789..ddb0bea6a4d 100644 --- a/settings/l10n/zh_CN.js +++ b/settings/l10n/zh_CN.js @@ -209,7 +209,6 @@ OC.L10N.register( "Create" : "创建", "Admin Recovery Password" : "管理恢复密码", "Enter the recovery password in order to recover the users files during password change" : "输入恢复密码来在更改密码的时候恢复用户文件", - "Search Users and Groups" : "搜索用户和组", "Add Group" : "增加组", "Group" : "分组", "Everyone" : "所有人", diff --git a/settings/l10n/zh_CN.json b/settings/l10n/zh_CN.json index 35d784f8a3f..847d4293791 100644 --- a/settings/l10n/zh_CN.json +++ b/settings/l10n/zh_CN.json @@ -207,7 +207,6 @@ "Create" : "创建", "Admin Recovery Password" : "管理恢复密码", "Enter the recovery password in order to recover the users files during password change" : "输入恢复密码来在更改密码的时候恢复用户文件", - "Search Users and Groups" : "搜索用户和组", "Add Group" : "增加组", "Group" : "分组", "Everyone" : "所有人", diff --git a/settings/l10n/zh_TW.js b/settings/l10n/zh_TW.js index 95e5a44791f..c32238afb7c 100644 --- a/settings/l10n/zh_TW.js +++ b/settings/l10n/zh_TW.js @@ -31,6 +31,7 @@ OC.L10N.register( "Back-end doesn't support password change, but the users encryption key was successfully updated." : "後端不支援變更密碼,但成功更新使用者的加密金鑰", "Unable to change password" : "無法修改密碼", "Enabled" : "已啓用", + "Recommended" : "建議", "Saved" : "已儲存", "test email settings" : "測試郵件設定", "If you received this email, the settings seem to be correct." : "假如您收到這個郵件,此設定看起來是正確的。", diff --git a/settings/l10n/zh_TW.json b/settings/l10n/zh_TW.json index b07a305a422..a493cbf7d41 100644 --- a/settings/l10n/zh_TW.json +++ b/settings/l10n/zh_TW.json @@ -29,6 +29,7 @@ "Back-end doesn't support password change, but the users encryption key was successfully updated." : "後端不支援變更密碼,但成功更新使用者的加密金鑰", "Unable to change password" : "無法修改密碼", "Enabled" : "已啓用", + "Recommended" : "建議", "Saved" : "已儲存", "test email settings" : "測試郵件設定", "If you received this email, the settings seem to be correct." : "假如您收到這個郵件,此設定看起來是正確的。", diff --git a/settings/personal.php b/settings/personal.php index 9c27f77ccd3..bef800ae7f1 100644 --- a/settings/personal.php +++ b/settings/personal.php @@ -114,7 +114,7 @@ $formsMap = array_map(function($form){ $anchor = str_replace(' ', '-', $anchor); return array( - 'anchor' => $anchor, + 'anchor' => 'goto-' . $anchor, 'section-name' => $sectionName, 'form' => $form ); diff --git a/settings/routes.php b/settings/routes.php index 82167ea6396..7ca33fc2745 100644 --- a/settings/routes.php +++ b/settings/routes.php @@ -14,7 +14,11 @@ $application->registerRoutes($this, array('routes' =>array( array('name' => 'MailSettings#storeCredentials', 'url' => '/settings/admin/mailsettings/credentials', 'verb' => 'POST'), array('name' => 'MailSettings#sendTestMail', 'url' => '/settings/admin/mailtest', 'verb' => 'POST'), array('name' => 'AppSettings#listCategories', 'url' => '/settings/apps/categories', 'verb' => 'GET'), - array('name' => 'AppSettings#listApps', 'url' => '/settings/apps/list', 'verb' => 'GET') + array('name' => 'AppSettings#listApps', 'url' => '/settings/apps/list', 'verb' => 'GET'), + array('name' => 'SecuritySettings#enforceSSL', 'url' => '/settings/admin/security/ssl', 'verb' => 'POST'), + array('name' => 'SecuritySettings#enforceSSLForSubdomains', 'url' => '/settings/admin/security/ssl/subdomains', 'verb' => 'POST'), + array('name' => 'SecuritySettings#trustedDomains', 'url' => '/settings/admin/security/trustedDomains', 'verb' => 'POST'), + ))); /** @var $this \OCP\Route\IRouter */ @@ -95,8 +99,6 @@ $this->create('settings_ajax_getlog', '/settings/ajax/getlog.php') ->actionInclude('settings/ajax/getlog.php'); $this->create('settings_ajax_setloglevel', '/settings/ajax/setloglevel.php') ->actionInclude('settings/ajax/setloglevel.php'); -$this->create('settings_ajax_setsecurity', '/settings/ajax/setsecurity.php') - ->actionInclude('settings/ajax/setsecurity.php'); $this->create('settings_ajax_excludegroups', '/settings/ajax/excludegroups.php') ->actionInclude('settings/ajax/excludegroups.php'); $this->create('settings_ajax_checksetup', '/settings/ajax/checksetup') diff --git a/settings/templates/admin.php b/settings/templates/admin.php index 0033845c74e..ddac77508c7 100644 --- a/settings/templates/admin.php +++ b/settings/templates/admin.php @@ -336,9 +336,9 @@ if ($_['suggestedOverwriteWebroot']) { <input type="checkbox" name="forcessl" id="forcessl" <?php if ($_['enforceHTTPSEnabled']) { print_unescaped('checked="checked" '); - print_unescaped('value="false"'); - } else { print_unescaped('value="true"'); + } else { + print_unescaped('value="false"'); } ?> <?php if (!$_['isConnectedViaHTTPS']) p('disabled'); ?> /> @@ -346,7 +346,23 @@ if ($_['suggestedOverwriteWebroot']) { <em><?php p($l->t( 'Forces the clients to connect to %s via an encrypted connection.', $theme->getName() - )); ?></em> + )); ?></em><br/> + <span id="forceSSLforSubdomainsSpan" <?php if(!$_['enforceHTTPSEnabled']) { print_unescaped('class="hidden"'); } ?>> + <input type="checkbox" name="forceSSLforSubdomains" id="forceSSLforSubdomains" + <?php if ($_['forceSSLforSubdomainsEnabled']) { + print_unescaped('checked="checked" '); + print_unescaped('value="true"'); + } else { + print_unescaped('value="false"'); + } + ?> + <?php if (!$_['isConnectedViaHTTPS']) { p('disabled'); } ?> /> + <label for="forceSSLforSubdomains"><?php p($l->t('Enforce HTTPS for subdomains'));?></label><br/> + <em><?php p($l->t( + 'Forces the clients to connect to %s and subdomains via an encrypted connection.', + $theme->getName() + )); ?></em> + </span> <?php if (!$_['isConnectedViaHTTPS']) { print_unescaped("<br/><em>"); p($l->t( diff --git a/settings/templates/users/part.createuser.php b/settings/templates/users/part.createuser.php index 20528964f68..d3ebbfb987a 100644 --- a/settings/templates/users/part.createuser.php +++ b/settings/templates/users/part.createuser.php @@ -29,6 +29,6 @@ </div> <?php endif; ?> <form autocomplete="off" id="usersearchform"> - <input type="text" class="input userFilter" placeholder="<?php p($l->t('Search Users and Groups')); ?>" /> + <input type="text" class="input userFilter" placeholder="<?php p($l->t('Search Users')); ?>" /> </form> </div> diff --git a/tests/core/lostpassword/controller/lostcontrollertest.php b/tests/core/lostpassword/controller/lostcontrollertest.php new file mode 100644 index 00000000000..5da9e5ce48d --- /dev/null +++ b/tests/core/lostpassword/controller/lostcontrollertest.php @@ -0,0 +1,195 @@ +<?php +/** + * Copyright (c) 2014 Lukas Reschke <lukas@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Core\LostPassword\Controller; +use OC\Core\Application; +use OCP\AppFramework\Http\TemplateResponse; + +/** + * Class LostControllerTest + * + * @package OC\Core\LostPassword\Controller + */ +class LostControllerTest extends \PHPUnit_Framework_TestCase { + + private $container; + /** @var LostController */ + private $lostController; + + protected function setUp() { + $app = new Application(); + $this->container = $app->getContainer(); + $this->container['AppName'] = 'core'; + $this->container['Config'] = $this->getMockBuilder('\OCP\IConfig') + ->disableOriginalConstructor()->getMock(); + $this->container['L10N'] = $this->getMockBuilder('\OCP\IL10N') + ->disableOriginalConstructor()->getMock(); + $this->container['Defaults'] = $this->getMockBuilder('\OC_Defaults') + ->disableOriginalConstructor()->getMock(); + $this->container['UserManager'] = $this->getMockBuilder('\OCP\IUserManager') + ->disableOriginalConstructor()->getMock(); + $this->container['Config'] = $this->getMockBuilder('\OCP\IConfig') + ->disableOriginalConstructor()->getMock(); + $this->container['URLGenerator'] = $this->getMockBuilder('\OCP\IURLGenerator') + ->disableOriginalConstructor()->getMock(); + $this->container['SecureRandom'] = $this->getMockBuilder('\OCP\Security\ISecureRandom') + ->disableOriginalConstructor()->getMock(); + $this->container['IsEncryptionEnabled'] = true; + $this->lostController = $this->container['LostController']; + } + + public function testResetFormUnsuccessful() { + $userId = 'admin'; + $token = 'MySecretToken'; + + $this->container['URLGenerator'] + ->expects($this->once()) + ->method('linkToRouteAbsolute') + ->with('core.lost.setPassword', array('userId' => 'admin', 'token' => 'MySecretToken')) + ->will($this->returnValue('https://ownCloud.com/index.php/lostpassword/')); + + $response = $this->lostController->resetform($token, $userId); + $expectedResponse = new TemplateResponse('core/lostpassword', + 'resetpassword', + array( + 'link' => 'https://ownCloud.com/index.php/lostpassword/', + ), + 'guest'); + $this->assertEquals($expectedResponse, $response); + } + + public function testEmailUnsucessful() { + $existingUser = 'ExistingUser'; + $nonExistingUser = 'NonExistingUser'; + $this->container['UserManager'] + ->expects($this->any()) + ->method('userExists') + ->will($this->returnValueMap(array( + array(true, $existingUser), + array(false, $nonExistingUser) + ))); + $this->container['L10N'] + ->expects($this->any()) + ->method('t') + ->will( + $this->returnValueMap( + array( + array('Couldn\'t send reset email. Please make sure your username is correct.', array(), + 'Couldn\'t send reset email. Please make sure your username is correct.'), + + ) + )); + + // With a non existing user + $response = $this->lostController->email($nonExistingUser); + $expectedResponse = array('status' => 'error', 'msg' => 'Couldn\'t send reset email. Please make sure your username is correct.'); + $this->assertSame($expectedResponse, $response); + + // With no mail address + $this->container['Config'] + ->expects($this->any()) + ->method('getUserValue') + ->with($existingUser, 'settings', 'email') + ->will($this->returnValue(null)); + $response = $this->lostController->email($existingUser); + $expectedResponse = array('status' => 'error', 'msg' => 'Couldn\'t send reset email. Please make sure your username is correct.'); + $this->assertSame($expectedResponse, $response); + } + + public function testEmailSuccessful() { + $randomToken = $this->container['SecureRandom']; + $this->container['SecureRandom'] + ->expects($this->once()) + ->method('generate') + ->with('21') + ->will($this->returnValue('ThisIsMaybeANotSoSecretToken!')); + $this->container['UserManager'] + ->expects($this->once()) + ->method('userExists') + ->with('ExistingUser') + ->will($this->returnValue(true)); + $this->container['Config'] + ->expects($this->once()) + ->method('getUserValue') + ->with('ExistingUser', 'settings', 'email') + ->will($this->returnValue('test@example.com')); + $this->container['SecureRandom'] + ->expects($this->once()) + ->method('getMediumStrengthGenerator') + ->will($this->returnValue($randomToken)); + $this->container['Config'] + ->expects($this->once()) + ->method('setUserValue') + ->with('ExistingUser', 'owncloud', 'lostpassword', 'ThisIsMaybeANotSoSecretToken!'); + $this->container['URLGenerator'] + ->expects($this->once()) + ->method('linkToRouteAbsolute') + ->with('core.lost.resetform', array('userId' => 'ExistingUser', 'token' => 'ThisIsMaybeANotSoSecretToken!')) + ->will($this->returnValue('https://ownCloud.com/index.php/lostpassword/')); + + $response = $this->lostController->email('ExistingUser'); + $expectedResponse = array('status' => 'success'); + $this->assertSame($expectedResponse, $response); + } + + public function testSetPasswordUnsuccessful() { + $this->container['L10N'] + ->expects($this->any()) + ->method('t') + ->will( + $this->returnValueMap( + array( + array('Couldn\'t reset password because the token is invalid', array(), + 'Couldn\'t reset password because the token is invalid'), + ) + )); + $this->container['Config'] + ->expects($this->once()) + ->method('getUserValue') + ->with('InvalidTokenUser', 'owncloud', 'lostpassword') + ->will($this->returnValue('TheOnlyAndOnlyOneTokenToResetThePassword')); + + // With an invalid token + $userName = 'InvalidTokenUser'; + $response = $this->lostController->setPassword('wrongToken', $userName, 'NewPassword', true); + $expectedResponse = array('status' => 'error', 'msg' => 'Couldn\'t reset password because the token is invalid'); + $this->assertSame($expectedResponse, $response); + + // With a valid token and no proceed + $response = $this->lostController->setPassword('TheOnlyAndOnlyOneTokenToResetThePassword!', $userName, 'NewPassword', false); + $expectedResponse = array('status' => 'error', 'msg' => '', 'encryption' => true); + $this->assertSame($expectedResponse, $response); + } + + public function testSetPasswordSuccessful() { + $this->container['Config'] + ->expects($this->once()) + ->method('getUserValue') + ->with('ValidTokenUser', 'owncloud', 'lostpassword') + ->will($this->returnValue('TheOnlyAndOnlyOneTokenToResetThePassword')); + $user = $this->getMockBuilder('\OCP\IUser') + ->disableOriginalConstructor()->getMock(); + $user->expects($this->once()) + ->method('setPassword') + ->with('NewPassword') + ->will($this->returnValue(true)); + $this->container['UserManager'] + ->expects($this->once()) + ->method('get') + ->with('ValidTokenUser') + ->will($this->returnValue($user)); + $this->container['Config'] + ->expects($this->once()) + ->method('deleteUserValue') + ->with('ValidTokenUser', 'owncloud', 'lostpassword'); + + $response = $this->lostController->setPassword('TheOnlyAndOnlyOneTokenToResetThePassword', 'ValidTokenUser', 'NewPassword', true); + $expectedResponse = array('status' => 'success'); + $this->assertSame($expectedResponse, $response); + } +} diff --git a/tests/lib/app.php b/tests/lib/app.php index 5bce3b8c3e6..6ae548759ed 100644 --- a/tests/lib/app.php +++ b/tests/lib/app.php @@ -455,6 +455,9 @@ class Test_App extends PHPUnit_Framework_TestCase { \OC::$server->registerService('AppConfig', function ($c) use ($oldService){ return $oldService; }); + + // Remove the cache of the mocked apps list with a forceRefresh + \OC_App::getEnabledApps(true); } } diff --git a/tests/lib/app/manager.php b/tests/lib/app/manager.php new file mode 100644 index 00000000000..4c0555b501f --- /dev/null +++ b/tests/lib/app/manager.php @@ -0,0 +1,195 @@ +<?php + +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\App; + +use OC\Group\Group; +use OC\User\User; + +class Manager extends \PHPUnit_Framework_TestCase { + /** + * @return \OCP\IAppConfig | \PHPUnit_Framework_MockObject_MockObject + */ + protected function getAppConfig() { + $appConfig = array(); + $config = $this->getMockBuilder('\OCP\IAppConfig') + ->disableOriginalConstructor() + ->getMock(); + + $config->expects($this->any()) + ->method('getValue') + ->will($this->returnCallback(function ($app, $key, $default) use (&$appConfig) { + return (isset($appConfig[$app]) and isset($appConfig[$app][$key])) ? $appConfig[$app][$key] : $default; + })); + $config->expects($this->any()) + ->method('setValue') + ->will($this->returnCallback(function ($app, $key, $value) use (&$appConfig) { + if (!isset($appConfig[$app])) { + $appConfig[$app] = array(); + } + $appConfig[$app][$key] = $value; + })); + $config->expects($this->any()) + ->method('getValues') + ->will($this->returnCallback(function ($app, $key) use (&$appConfig) { + if ($app) { + return $appConfig[$app]; + } else { + $values = array(); + foreach ($appConfig as $app => $appData) { + if (isset($appData[$key])) { + $values[$app] = $appData[$key]; + } + } + return $values; + } + })); + + return $config; + } + + public function testEnableApp() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $manager->enableApp('test'); + $this->assertEquals('yes', $appConfig->getValue('test', 'enabled', 'no')); + } + + public function testDisableApp() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $manager->disableApp('test'); + $this->assertEquals('no', $appConfig->getValue('test', 'enabled', 'no')); + } + + public function testEnableAppForGroups() { + $groups = array( + new Group('group1', array(), null), + new Group('group2', array(), null) + ); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $userSession = $this->getMock('\OCP\IUserSession'); + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $manager->enableAppForGroups('test', $groups); + $this->assertEquals('["group1","group2"]', $appConfig->getValue('test', 'enabled', 'no')); + } + + public function testIsInstalledEnabled() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $appConfig->setValue('test', 'enabled', 'yes'); + $this->assertTrue($manager->isInstalled('test')); + } + + public function testIsInstalledDisabled() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $appConfig->setValue('test', 'enabled', 'no'); + $this->assertFalse($manager->isInstalled('test')); + } + + public function testIsInstalledEnabledForGroups() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $appConfig->setValue('test', 'enabled', '["foo"]'); + $this->assertTrue($manager->isInstalled('test')); + } + + public function testIsEnabledForUserEnabled() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $appConfig->setValue('test', 'enabled', 'yes'); + $user = new User('user1', null); + $this->assertTrue($manager->isEnabledForUser('test', $user)); + } + + public function testIsEnabledForUserDisabled() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $appConfig->setValue('test', 'enabled', 'no'); + $user = new User('user1', null); + $this->assertFalse($manager->isEnabledForUser('test', $user)); + } + + public function testIsEnabledForUserEnabledForGroup() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $user = new User('user1', null); + + $groupManager->expects($this->once()) + ->method('getUserGroupIds') + ->with($user) + ->will($this->returnValue(array('foo', 'bar'))); + + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $appConfig->setValue('test', 'enabled', '["foo"]'); + $this->assertTrue($manager->isEnabledForUser('test', $user)); + } + + public function testIsEnabledForUserDisabledForGroup() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $user = new User('user1', null); + + $groupManager->expects($this->once()) + ->method('getUserGroupIds') + ->with($user) + ->will($this->returnValue(array('bar'))); + + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $appConfig->setValue('test', 'enabled', '["foo"]'); + $this->assertFalse($manager->isEnabledForUser('test', $user)); + } + + public function testIsEnabledForUserLoggedOut() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $appConfig->setValue('test', 'enabled', '["foo"]'); + $this->assertFalse($manager->IsEnabledForUser('test')); + } + + public function testIsEnabledForUserLoggedIn() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $user = new User('user1', null); + + $userSession->expects($this->once()) + ->method('getUser') + ->will($this->returnValue($user)); + $groupManager->expects($this->once()) + ->method('getUserGroupIds') + ->with($user) + ->will($this->returnValue(array('foo', 'bar'))); + + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $appConfig->setValue('test', 'enabled', '["foo"]'); + $this->assertTrue($manager->isEnabledForUser('test')); + } +} diff --git a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php index 74fc7907fb5..cc7704f4d1a 100644 --- a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php +++ b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php @@ -77,7 +77,7 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { $this->navigationManager, $this->urlGenerator, $this->logger, - 'test', + 'files', $isLoggedIn, $isAdminUser ); @@ -91,7 +91,7 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { public function testSetNavigationEntry(){ $this->navigationManager->expects($this->once()) ->method('setActiveEntry') - ->with($this->equalTo('test')); + ->with($this->equalTo('files')); $this->reader->reflect(__CLASS__, __FUNCTION__); $this->middleware->beforeController(__CLASS__, __FUNCTION__); diff --git a/tests/lib/archive/tar.php b/tests/lib/archive/tar.php index 5b9089b32e1..99f7fb30e2b 100644 --- a/tests/lib/archive/tar.php +++ b/tests/lib/archive/tar.php @@ -9,7 +9,7 @@ class Test_Archive_TAR extends Test_Archive { public function setUp() { if (OC_Util::runningOnWindows()) { - $this->markTestSkipped('tar archives are not supported on windows'); + $this->markTestSkipped('[Windows] tar archives are not supported on Windows'); } parent::setUp(); } diff --git a/tests/lib/cache/file.php b/tests/lib/cache/file.php index 0e19c105cd1..8cc45c85405 100644 --- a/tests/lib/cache/file.php +++ b/tests/lib/cache/file.php @@ -23,8 +23,12 @@ namespace Test\Cache; class FileCache extends \Test_Cache { + /** @var string */ private $user; + /** @var string */ private $datadir; + /** @var \OC\Files\Storage\Storage */ + private $storage; function skip() { //$this->skipUnless(OC_User::isLoggedIn()); @@ -42,6 +46,7 @@ class FileCache extends \Test_Cache { //} //set up temporary storage + $this->storage = \OC\Files\Filesystem::getStorage('/'); \OC\Files\Filesystem::clearMounts(); $storage = new \OC\Files\Storage\Temporary(array()); \OC\Files\Filesystem::mount($storage,array(),'/'); @@ -68,5 +73,11 @@ class FileCache extends \Test_Cache { public function tearDown() { \OC_User::setUserId($this->user); \OC_Config::setValue('cachedirectory', $this->datadir); + + // Restore the original mount point + \OC\Files\Filesystem::clearMounts(); + \OC\Files\Filesystem::mount($this->storage, array(), '/'); + + parent::tearDown(); } } diff --git a/tests/lib/cache/usercache.php b/tests/lib/cache/usercache.php index a1b6af1c55d..8a23a805ebe 100644 --- a/tests/lib/cache/usercache.php +++ b/tests/lib/cache/usercache.php @@ -23,8 +23,12 @@ namespace Test\Cache; class UserCache extends \Test_Cache { + /** @var string */ private $user; + /** @var string */ private $datadir; + /** @var \OC\Files\Storage\Storage */ + private $storage; public function setUp() { //clear all proxies and hooks so we can do clean testing @@ -38,6 +42,7 @@ class UserCache extends \Test_Cache { //} //set up temporary storage + $this->storage = \OC\Files\Filesystem::getStorage('/'); \OC\Files\Filesystem::clearMounts(); $storage = new \OC\Files\Storage\Temporary(array()); \OC\Files\Filesystem::mount($storage,array(),'/'); @@ -63,5 +68,12 @@ class UserCache extends \Test_Cache { public function tearDown() { \OC_User::setUserId($this->user); + \OC_Config::setValue('cachedirectory', $this->datadir); + + // Restore the original mount point + \OC\Files\Filesystem::clearMounts(); + \OC\Files\Filesystem::mount($this->storage, array(), '/'); + + parent::tearDown(); } } diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php index 96b4207ad43..9e7330db20c 100644 --- a/tests/lib/files/cache/updater.php +++ b/tests/lib/files/cache/updater.php @@ -33,7 +33,13 @@ class Updater extends \PHPUnit_Framework_TestCase { */ protected $updater; - public function setUp() { + /** @var \OC\Files\Storage\Storage */ + private $originalStorage; + + protected function setUp() { + parent::setUp(); + + $this->originalStorage = Filesystem::getStorage('/'); $this->storage = new Temporary(array()); Filesystem::clearMounts(); Filesystem::mount($this->storage, array(), '/'); @@ -42,6 +48,13 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->cache = $this->storage->getCache(); } + protected function tearDown() { + Filesystem::clearMounts(); + Filesystem::mount($this->originalStorage, array(), '/'); + + parent::tearDown(); + } + public function testNewFile() { $this->storage->file_put_contents('foo.txt', 'bar'); $this->assertFalse($this->cache->inCache('foo.txt')); diff --git a/tests/lib/files/cache/updaterlegacy.php b/tests/lib/files/cache/updaterlegacy.php index c80c3168ad6..d16a062fcca 100644 --- a/tests/lib/files/cache/updaterlegacy.php +++ b/tests/lib/files/cache/updaterlegacy.php @@ -29,6 +29,9 @@ class UpdaterLegacy extends \PHPUnit_Framework_TestCase { */ private $cache; + /** @var \OC\Files\Storage\Storage */ + private $originalStorage; + private static $user; public function setUp() { @@ -51,7 +54,8 @@ class UpdaterLegacy extends \PHPUnit_Framework_TestCase { $this->scanner->scan(''); $this->cache = $this->storage->getCache(); - \OC\Files\Filesystem::tearDown(); + $this->originalStorage = Filesystem::getStorage('/'); + Filesystem::tearDown(); if (!self::$user) { self::$user = uniqid(); } @@ -59,7 +63,7 @@ class UpdaterLegacy extends \PHPUnit_Framework_TestCase { \OC_User::createUser(self::$user, 'password'); \OC_User::setUserId(self::$user); - \OC\Files\Filesystem::init(self::$user, '/' . self::$user . '/files'); + Filesystem::init(self::$user, '/' . self::$user . '/files'); Filesystem::clearMounts(); Filesystem::mount($this->storage, array(), '/' . self::$user . '/files'); @@ -74,6 +78,7 @@ class UpdaterLegacy extends \PHPUnit_Framework_TestCase { $result = \OC_User::deleteUser(self::$user); $this->assertTrue($result); Filesystem::tearDown(); + Filesystem::mount($this->originalStorage, array(), '/'); // reset app files_encryption if ($this->stateFilesEncryption) { \OC_App::enable('files_encryption'); diff --git a/tests/lib/files/cache/watcher.php b/tests/lib/files/cache/watcher.php index 22c11b9a4e0..0b04b9e7058 100644 --- a/tests/lib/files/cache/watcher.php +++ b/tests/lib/files/cache/watcher.php @@ -15,16 +15,27 @@ class Watcher extends \PHPUnit_Framework_TestCase { */ private $storages = array(); - public function setUp() { + /** @var \OC\Files\Storage\Storage */ + private $originalStorage; + + protected function setUp() { + parent::setUp(); + + $this->originalStorage = \OC\Files\Filesystem::getStorage('/'); \OC\Files\Filesystem::clearMounts(); } - public function tearDown() { + protected function tearDown() { foreach ($this->storages as $storage) { $cache = $storage->getCache(); $ids = $cache->getAll(); $cache->clear(); } + + \OC\Files\Filesystem::clearMounts(); + \OC\Files\Filesystem::mount($this->originalStorage, array(), '/'); + + parent::tearDown(); } /** diff --git a/tests/lib/files/etagtest.php b/tests/lib/files/etagtest.php index b5dec107e79..8f29ed0bc63 100644 --- a/tests/lib/files/etagtest.php +++ b/tests/lib/files/etagtest.php @@ -11,7 +11,7 @@ namespace Test\Files; use OC\Files\Filesystem; use OCP\Share; -class EtagTest extends \PHPUnit_Framework_TestCase { +class EtagTest extends \Test\TestCase { private $datadir; private $tmpDir; @@ -23,7 +23,12 @@ class EtagTest extends \PHPUnit_Framework_TestCase { */ private $userBackend; - public function setUp() { + /** @var \OC\Files\Storage\Storage */ + private $originalStorage; + + protected function setUp() { + parent::setUp(); + \OC_Hook::clear('OC_Filesystem', 'setup'); \OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup'); \OCP\Share::registerBackend('file', 'OC_Share_Backend_File'); @@ -37,13 +42,17 @@ class EtagTest extends \PHPUnit_Framework_TestCase { $this->userBackend = new \OC_User_Dummy(); \OC_User::useBackend($this->userBackend); + $this->originalStorage = \OC\Files\Filesystem::getStorage('/'); \OC_Util::tearDownFS(); } - public function tearDown() { + protected function tearDown() { \OC_Config::setValue('datadirectory', $this->datadir); \OC_User::setUserId($this->uid); \OC_Util::setupFS($this->uid); + \OC\Files\Filesystem::mount($this->originalStorage, array(), '/'); + + parent::tearDown(); } public function testNewUser() { diff --git a/tests/lib/files/filesystem.php b/tests/lib/files/filesystem.php index 930a252bcb2..f24d86b212d 100644 --- a/tests/lib/files/filesystem.php +++ b/tests/lib/files/filesystem.php @@ -22,12 +22,15 @@ namespace Test\Files; -class Filesystem extends \PHPUnit_Framework_TestCase { +class Filesystem extends \Test\TestCase { /** * @var array tmpDirs */ private $tmpDirs = array(); + /** @var \OC\Files\Storage\Storage */ + private $originalStorage; + /** * @return array */ @@ -37,19 +40,23 @@ class Filesystem extends \PHPUnit_Framework_TestCase { return array('datadir' => $dir); } - public function tearDown() { + protected function setUp() { + parent::setUp(); + + $this->originalStorage = \OC\Files\Filesystem::getStorage('/'); + \OC_User::setUserId(''); + \OC\Files\Filesystem::clearMounts(); + } + + protected function tearDown() { foreach ($this->tmpDirs as $dir) { \OC_Helper::rmdirr($dir); } \OC\Files\Filesystem::clearMounts(); + \OC\Files\Filesystem::mount($this->originalStorage, array(), '/'); \OC_User::setUserId(''); } - public function setUp() { - \OC_User::setUserId(''); - \OC\Files\Filesystem::clearMounts(); - } - public function testMount() { \OC\Files\Filesystem::mount('\OC\Files\Storage\Local', self::getStorageData(), '/'); $this->assertEquals('/', \OC\Files\Filesystem::getMountPoint('/')); @@ -68,71 +75,112 @@ class Filesystem extends \PHPUnit_Framework_TestCase { $this->assertEquals('folder', $internalPath); } - public function testNormalize() { - $this->assertEquals('/', \OC\Files\Filesystem::normalizePath('')); - $this->assertEquals('/', \OC\Files\Filesystem::normalizePath('/')); - $this->assertEquals('/', \OC\Files\Filesystem::normalizePath('/', false)); - $this->assertEquals('/', \OC\Files\Filesystem::normalizePath('//')); - $this->assertEquals('/', \OC\Files\Filesystem::normalizePath('//', false)); - $this->assertEquals('/path', \OC\Files\Filesystem::normalizePath('/path/')); - $this->assertEquals('/path/', \OC\Files\Filesystem::normalizePath('/path/', false)); - $this->assertEquals('/path', \OC\Files\Filesystem::normalizePath('path')); - $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('/foo//bar/')); - $this->assertEquals('/foo/bar/', \OC\Files\Filesystem::normalizePath('/foo//bar/', false)); - $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('/foo////bar')); - $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('/foo/////bar')); - $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('/foo/bar/.')); - $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('/foo/bar/./')); - $this->assertEquals('/foo/bar/', \OC\Files\Filesystem::normalizePath('/foo/bar/./', false)); - $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('/foo/bar/./.')); - $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('/foo/bar/././')); - $this->assertEquals('/foo/bar/', \OC\Files\Filesystem::normalizePath('/foo/bar/././', false)); - $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('/foo/./bar/')); - $this->assertEquals('/foo/bar/', \OC\Files\Filesystem::normalizePath('/foo/./bar/', false)); - $this->assertEquals('/foo/.bar', \OC\Files\Filesystem::normalizePath('/foo/.bar/')); - $this->assertEquals('/foo/.bar/', \OC\Files\Filesystem::normalizePath('/foo/.bar/', false)); - $this->assertEquals('/foo/.bar/tee', \OC\Files\Filesystem::normalizePath('/foo/.bar/tee')); - - // normalize does not resolve '..' (by design) - $this->assertEquals('/foo/..', \OC\Files\Filesystem::normalizePath('/foo/../')); - - if (class_exists('Patchwork\PHP\Shim\Normalizer')) { - $this->assertEquals("/foo/bar\xC3\xBC", \OC\Files\Filesystem::normalizePath("/foo/baru\xCC\x88")); + public function normalizePathData() { + return array( + array('/', ''), + array('/', '/'), + array('/', '//'), + array('/', '/', false), + array('/', '//', false), + + array('/path', '/path/'), + array('/path/', '/path/', false), + array('/path', 'path'), + + array('/foo/bar', '/foo//bar/'), + array('/foo/bar/', '/foo//bar/', false), + array('/foo/bar', '/foo////bar'), + array('/foo/bar', '/foo/////bar'), + array('/foo/bar', '/foo/bar/.'), + array('/foo/bar', '/foo/bar/./'), + array('/foo/bar/', '/foo/bar/./', false), + array('/foo/bar', '/foo/bar/./.'), + array('/foo/bar', '/foo/bar/././'), + array('/foo/bar/', '/foo/bar/././', false), + array('/foo/bar', '/foo/./bar/'), + array('/foo/bar/', '/foo/./bar/', false), + array('/foo/.bar', '/foo/.bar/'), + array('/foo/.bar/', '/foo/.bar/', false), + array('/foo/.bar/tee', '/foo/.bar/tee'), + + // Windows paths + array('/', ''), + array('/', '\\'), + array('/', '\\', false), + array('/', '\\\\'), + array('/', '\\\\', false), + + array('/path', '\\path'), + array('/path', '\\path', false), + array('/path', '\\path\\'), + array('/path/', '\\path\\', false), + + array('/foo/bar', '\\foo\\\\bar\\'), + array('/foo/bar/', '\\foo\\\\bar\\', false), + array('/foo/bar', '\\foo\\\\\\\\bar'), + array('/foo/bar', '\\foo\\\\\\\\\\bar'), + array('/foo/bar', '\\foo\\bar\\.'), + array('/foo/bar', '\\foo\\bar\\.\\'), + array('/foo/bar/', '\\foo\\bar\\.\\', false), + array('/foo/bar', '\\foo\\bar\\.\\.'), + array('/foo/bar', '\\foo\\bar\\.\\.\\'), + array('/foo/bar/', '\\foo\\bar\\.\\.\\', false), + array('/foo/bar', '\\foo\\.\\bar\\'), + array('/foo/bar/', '\\foo\\.\\bar\\', false), + array('/foo/.bar', '\\foo\\.bar\\'), + array('/foo/.bar/', '\\foo\\.bar\\', false), + array('/foo/.bar/tee', '\\foo\\.bar\\tee'), + + // Absolute windows paths NOT marked as absolute + array('/C:', 'C:\\'), + array('/C:/', 'C:\\', false), + array('/C:/tests', 'C:\\tests'), + array('/C:/tests', 'C:\\tests', false), + array('/C:/tests', 'C:\\tests\\'), + array('/C:/tests/', 'C:\\tests\\', false), + + // normalize does not resolve '..' (by design) + array('/foo/..', '/foo/../'), + array('/foo/..', '\\foo\\..\\'), + ); + } + + /** + * @dataProvider normalizePathData + */ + public function testNormalizePath($expected, $path, $stripTrailingSlash = true) { + $this->assertEquals($expected, \OC\Files\Filesystem::normalizePath($path, $stripTrailingSlash)); + } + + public function normalizePathWindowsAbsolutePathData() { + return array( + array('C:/', 'C:\\'), + array('C:/', 'C:\\', false), + array('C:/tests', 'C:\\tests'), + array('C:/tests', 'C:\\tests', false), + array('C:/tests', 'C:\\tests\\'), + array('C:/tests/', 'C:\\tests\\', false), + ); + } + + /** + * @dataProvider normalizePathWindowsAbsolutePathData + */ + public function testNormalizePathWindowsAbsolutePath($expected, $path, $stripTrailingSlash = true) { + if (!\OC_Util::runningOnWindows()) { + $this->markTestSkipped('This test is Windows only'); } + + $this->assertEquals($expected, \OC\Files\Filesystem::normalizePath($path, $stripTrailingSlash, true)); } - public function testNormalizeWindowsPaths() { - $this->assertEquals('/', \OC\Files\Filesystem::normalizePath('')); - $this->assertEquals('/', \OC\Files\Filesystem::normalizePath('\\')); - $this->assertEquals('/', \OC\Files\Filesystem::normalizePath('\\', false)); - $this->assertEquals('/', \OC\Files\Filesystem::normalizePath('\\\\')); - $this->assertEquals('/', \OC\Files\Filesystem::normalizePath('\\\\', false)); - $this->assertEquals('/path', \OC\Files\Filesystem::normalizePath('\\path')); - $this->assertEquals('/path', \OC\Files\Filesystem::normalizePath('\\path', false)); - $this->assertEquals('/path', \OC\Files\Filesystem::normalizePath('\\path\\')); - $this->assertEquals('/path/', \OC\Files\Filesystem::normalizePath('\\path\\', false)); - $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('\\foo\\\\bar\\')); - $this->assertEquals('/foo/bar/', \OC\Files\Filesystem::normalizePath('\\foo\\\\bar\\', false)); - $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('\\foo\\\\\\\\bar')); - $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('\\foo\\\\\\\\\\bar')); - $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('\\foo\\bar\\.')); - $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('\\foo\\bar\\.\\')); - $this->assertEquals('/foo/bar/', \OC\Files\Filesystem::normalizePath('\\foo\\bar\\.\\', false)); - $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('\\foo\\bar\\.\\.')); - $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('\\foo\\bar\\.\\.\\')); - $this->assertEquals('/foo/bar/', \OC\Files\Filesystem::normalizePath('\\foo\\bar\\.\\.\\', false)); - $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('\\foo\\.\\bar\\')); - $this->assertEquals('/foo/bar/', \OC\Files\Filesystem::normalizePath('\\foo\\.\\bar\\', false)); - $this->assertEquals('/foo/.bar', \OC\Files\Filesystem::normalizePath('\\foo\\.bar\\')); - $this->assertEquals('/foo/.bar/', \OC\Files\Filesystem::normalizePath('\\foo\\.bar\\', false)); - $this->assertEquals('/foo/.bar/tee', \OC\Files\Filesystem::normalizePath('\\foo\\.bar\\tee')); - - // normalize does not resolve '..' (by design) - $this->assertEquals('/foo/..', \OC\Files\Filesystem::normalizePath('\\foo\\..\\')); - - if (class_exists('Patchwork\PHP\Shim\Normalizer')) { - $this->assertEquals("/foo/bar\xC3\xBC", \OC\Files\Filesystem::normalizePath("\\foo\\baru\xCC\x88")); + public function testNormalizePathUTF8() { + if (!class_exists('Patchwork\PHP\Shim\Normalizer')) { + $this->markTestSkipped('UTF8 normalizer Patchwork was not found'); } + + $this->assertEquals("/foo/bar\xC3\xBC", \OC\Files\Filesystem::normalizePath("/foo/baru\xCC\x88")); + $this->assertEquals("/foo/bar\xC3\xBC", \OC\Files\Filesystem::normalizePath("\\foo\\baru\xCC\x88")); } public function testHooks() { diff --git a/tests/lib/files/node/integration.php b/tests/lib/files/node/integration.php index 319f2f9f5f7..cde2eb22b7b 100644 --- a/tests/lib/files/node/integration.php +++ b/tests/lib/files/node/integration.php @@ -20,6 +20,9 @@ class IntegrationTests extends \PHPUnit_Framework_TestCase { */ private $root; + /** @var \OC\Files\Storage\Storage */ + private $originalStorage; + /** * @var \OC\Files\Storage\Storage[] */ @@ -30,7 +33,10 @@ class IntegrationTests extends \PHPUnit_Framework_TestCase { */ private $view; - public function setUp() { + protected function setUp() { + parent::setUp(); + + $this->originalStorage = \OC\Files\Filesystem::getStorage('/'); \OC\Files\Filesystem::init('', ''); \OC\Files\Filesystem::clearMounts(); $manager = \OC\Files\Filesystem::getMountManager(); @@ -54,11 +60,15 @@ class IntegrationTests extends \PHPUnit_Framework_TestCase { $this->root->mount($subStorage, '/substorage/'); } - public function tearDown() { + protected function tearDown() { foreach ($this->storages as $storage) { $storage->getCache()->clear(); } \OC\Files\Filesystem::clearMounts(); + + \OC\Files\Filesystem::mount($this->originalStorage, array(), '/'); + + parent::tearDown(); } public function testBasicFile() { diff --git a/tests/lib/files/storage/home.php b/tests/lib/files/storage/home.php index 953fcfc8a6a..d085efe9c1c 100644 --- a/tests/lib/files/storage/home.php +++ b/tests/lib/files/storage/home.php @@ -75,7 +75,12 @@ class Home extends Storage { * Tests that the root path matches the data dir */ public function testRoot() { - $this->assertEquals($this->tmpDir, $this->instance->getLocalFolder('')); + if (\OC_Util::runningOnWindows()) { + // Windows removes trailing slashes when returning paths + $this->assertEquals(rtrim($this->tmpDir, '/'), $this->instance->getLocalFolder('')); + } else { + $this->assertEquals($this->tmpDir, $this->instance->getLocalFolder('')); + } } /** diff --git a/tests/lib/files/storage/local.php b/tests/lib/files/storage/local.php index 37462941d0c..490086c62f2 100644 --- a/tests/lib/files/storage/local.php +++ b/tests/lib/files/storage/local.php @@ -39,7 +39,7 @@ class Local extends Storage { public function testStableEtag() { if (\OC_Util::runningOnWindows()) { - $this->markTestSkipped('On Windows platform we have no stable etag generation - yet'); + $this->markTestSkipped('[Windows] On Windows platform we have no stable etag generation - yet'); } $this->instance->file_put_contents('test.txt', 'foobar'); @@ -50,7 +50,7 @@ class Local extends Storage { public function testEtagChange() { if (\OC_Util::runningOnWindows()) { - $this->markTestSkipped('On Windows platform we have no stable etag generation - yet'); + $this->markTestSkipped('[Windows] On Windows platform we have no stable etag generation - yet'); } $this->instance->file_put_contents('test.txt', 'foo'); diff --git a/tests/lib/files/storage/storage.php b/tests/lib/files/storage/storage.php index cf42523a5e2..960eb137ea0 100644 --- a/tests/lib/files/storage/storage.php +++ b/tests/lib/files/storage/storage.php @@ -340,10 +340,10 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { } public function testTouchCreateFile() { - $this->assertFalse($this->instance->file_exists('foo')); + $this->assertFalse($this->instance->file_exists('touch')); // returns true on success - $this->assertTrue($this->instance->touch('foo')); - $this->assertTrue($this->instance->file_exists('foo')); + $this->assertTrue($this->instance->touch('touch')); + $this->assertTrue($this->instance->file_exists('touch')); } public function testRecursiveRmdir() { diff --git a/tests/lib/files/utils/scanner.php b/tests/lib/files/utils/scanner.php index 27b9b8dd4f4..db6a3fa7842 100644 --- a/tests/lib/files/utils/scanner.php +++ b/tests/lib/files/utils/scanner.php @@ -38,7 +38,23 @@ class TestScanner extends \OC\Files\Utils\Scanner { } } -class Scanner extends \PHPUnit_Framework_TestCase { + +class Scanner extends \Test\TestCase { + /** @var \OC\Files\Storage\Storage */ + private $originalStorage; + + protected function setUp() { + parent::setUp(); + + $this->originalStorage = \OC\Files\Filesystem::getStorage('/'); + } + + protected function tearDown() { + \OC\Files\Filesystem::mount($this->originalStorage, array(), '/'); + + parent::tearDown(); + } + public function testReuseExistingRoot() { $storage = new Temporary(array()); $mount = new Mount($storage, ''); diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 086ac873bfb..44fea65e64e 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -23,9 +23,15 @@ class View extends \PHPUnit_Framework_TestCase { private $storages = array(); private $user; + /** @var \OC\Files\Storage\Storage */ private $tempStorage; - public function setUp() { + /** @var \OC\Files\Storage\Storage */ + private $originalStorage; + + protected function setUp() { + parent::setUp(); + \OC_User::clearBackends(); \OC_User::useBackend(new \OC_User_Dummy()); @@ -34,12 +40,13 @@ class View extends \PHPUnit_Framework_TestCase { $this->user = \OC_User::getUser(); \OC_User::setUserId('test'); + $this->originalStorage = \OC\Files\Filesystem::getStorage('/'); \OC\Files\Filesystem::clearMounts(); $this->tempStorage = null; } - public function tearDown() { + protected function tearDown() { \OC_User::setUserId($this->user); foreach ($this->storages as $storage) { $cache = $storage->getCache(); @@ -50,6 +57,11 @@ class View extends \PHPUnit_Framework_TestCase { if ($this->tempStorage && !\OC_Util::runningOnWindows()) { system('rm -rf ' . escapeshellarg($this->tempStorage->getDataDir())); } + + \OC\Files\Filesystem::clearMounts(); + \OC\Files\Filesystem::mount($this->originalStorage, array(), '/'); + + parent::tearDown(); } /** @@ -599,7 +611,7 @@ class View extends \PHPUnit_Framework_TestCase { $folderName = 'abcdefghijklmnopqrstuvwxyz012345678901234567890123456789'; $tmpdirLength = strlen(\OC_Helper::tmpFolder()); if (\OC_Util::runningOnWindows()) { - $this->markTestSkipped(); + $this->markTestSkipped('[Windows] '); $depth = ((260 - $tmpdirLength) / 57); }elseif(\OC_Util::runningOnMac()){ $depth = ((1024 - $tmpdirLength) / 57); diff --git a/tests/lib/group.php b/tests/lib/group.php index 724e723b187..795de695513 100644 --- a/tests/lib/group.php +++ b/tests/lib/group.php @@ -22,38 +22,39 @@ * */ -class Test_Group extends PHPUnit_Framework_TestCase { - function setUp() { +class Test_Group extends \Test\TestCase { + protected function setUp() { + parent::setUp(); OC_Group::clearBackends(); OC_User::clearBackends(); } - function testSingleBackend() { + public function testSingleBackend() { $userBackend = new \OC_User_Dummy(); \OC_User::getManager()->registerBackend($userBackend); OC_Group::useBackend(new OC_Group_Dummy()); - $group1 = uniqid(); - $group2 = uniqid(); + $group1 = $this->getUniqueID(); + $group2 = $this->getUniqueID(); OC_Group::createGroup($group1); OC_Group::createGroup($group2); - $user1 = uniqid(); - $user2 = uniqid(); + $user1 = $this->getUniqueID(); + $user2 = $this->getUniqueID(); $userBackend->createUser($user1, ''); $userBackend->createUser($user2, ''); - $this->assertFalse(OC_Group::inGroup($user1, $group1)); - $this->assertFalse(OC_Group::inGroup($user2, $group1)); - $this->assertFalse(OC_Group::inGroup($user1, $group2)); - $this->assertFalse(OC_Group::inGroup($user2, $group2)); + $this->assertFalse(OC_Group::inGroup($user1, $group1), 'Asserting that user1 is not in group1'); + $this->assertFalse(OC_Group::inGroup($user2, $group1), 'Asserting that user2 is not in group1'); + $this->assertFalse(OC_Group::inGroup($user1, $group2), 'Asserting that user1 is not in group2'); + $this->assertFalse(OC_Group::inGroup($user2, $group2), 'Asserting that user2 is not in group2'); $this->assertTrue(OC_Group::addToGroup($user1, $group1)); - $this->assertTrue(OC_Group::inGroup($user1, $group1)); - $this->assertFalse(OC_Group::inGroup($user2, $group1)); - $this->assertFalse(OC_Group::inGroup($user1, $group2)); - $this->assertFalse(OC_Group::inGroup($user2, $group2)); + $this->assertTrue(OC_Group::inGroup($user1, $group1), 'Asserting that user1 is in group1'); + $this->assertFalse(OC_Group::inGroup($user2, $group1), 'Asserting that user2 is not in group1'); + $this->assertFalse(OC_Group::inGroup($user1, $group2), 'Asserting that user1 is not in group2'); + $this->assertFalse(OC_Group::inGroup($user2, $group2), 'Asserting that user2 is not in group2'); $this->assertTrue(OC_Group::addToGroup($user1, $group1)); @@ -80,7 +81,7 @@ class Test_Group extends PHPUnit_Framework_TestCase { public function testNoGroupsTwice() { OC_Group::useBackend(new OC_Group_Dummy()); - $group = uniqid(); + $group = $this->getUniqueID(); OC_Group::createGroup($group); $groupCopy = $group; @@ -103,7 +104,7 @@ class Test_Group extends PHPUnit_Framework_TestCase { public function testDontAddUserToNonexistentGroup() { OC_Group::useBackend(new OC_Group_Dummy()); $groupNonExistent = 'notExistent'; - $user = uniqid(); + $user = $this->getUniqueID(); $this->assertEquals(false, OC_Group::addToGroup($user, $groupNonExistent)); $this->assertEquals(array(), OC_Group::getGroups()); @@ -114,12 +115,12 @@ class Test_Group extends PHPUnit_Framework_TestCase { $userBackend = new \OC_User_Dummy(); \OC_User::getManager()->registerBackend($userBackend); - $group1 = uniqid(); - $group2 = uniqid(); - $group3 = uniqid(); - $user1 = uniqid(); - $user2 = uniqid(); - $user3 = uniqid(); + $group1 = $this->getUniqueID(); + $group2 = $this->getUniqueID(); + $group3 = $this->getUniqueID(); + $user1 = $this->getUniqueID(); + $user2 = $this->getUniqueID(); + $user3 = $this->getUniqueID(); OC_Group::createGroup($group1); OC_Group::createGroup($group2); OC_Group::createGroup($group3); @@ -139,8 +140,7 @@ class Test_Group extends PHPUnit_Framework_TestCase { // FIXME: needs more parameter variation } - - function testMultiBackend() { + public function testMultiBackend() { $userBackend = new \OC_User_Dummy(); \OC_User::getManager()->registerBackend($userBackend); $backend1 = new OC_Group_Dummy(); @@ -148,8 +148,8 @@ class Test_Group extends PHPUnit_Framework_TestCase { OC_Group::useBackend($backend1); OC_Group::useBackend($backend2); - $group1 = uniqid(); - $group2 = uniqid(); + $group1 = $this->getUniqueID(); + $group2 = $this->getUniqueID(); OC_Group::createGroup($group1); //groups should be added to the first registered backend @@ -166,8 +166,8 @@ class Test_Group extends PHPUnit_Framework_TestCase { $this->assertTrue(OC_Group::groupExists($group1)); $this->assertTrue(OC_Group::groupExists($group2)); - $user1 = uniqid(); - $user2 = uniqid(); + $user1 = $this->getUniqueID(); + $user2 = $this->getUniqueID(); $userBackend->createUser($user1, ''); $userBackend->createUser($user2, ''); diff --git a/tests/lib/group/backend.php b/tests/lib/group/backend.php index 95a5cf5f49c..62c189489d7 100644 --- a/tests/lib/group/backend.php +++ b/tests/lib/group/backend.php @@ -20,7 +20,7 @@ * */ -abstract class Test_Group_Backend extends PHPUnit_Framework_TestCase { +abstract class Test_Group_Backend extends \Test\TestCase { /** * @var OC_Group_Backend $backend */ @@ -33,7 +33,7 @@ abstract class Test_Group_Backend extends PHPUnit_Framework_TestCase { */ public function getGroupName($name = null) { if(is_null($name)) { - return uniqid('test_'); + return $this->getUniqueID('test_'); } else { return $name; } @@ -45,7 +45,7 @@ abstract class Test_Group_Backend extends PHPUnit_Framework_TestCase { * @return string */ public function getUserName() { - return uniqid('test_'); + return $this->getUniqueID('test_'); } public function testAddRemove() { @@ -138,6 +138,4 @@ abstract class Test_Group_Backend extends PHPUnit_Framework_TestCase { $result = $this->backend->countUsersInGroup($group, 'bar'); $this->assertSame(2, $result); } - - } diff --git a/tests/lib/group/database.php b/tests/lib/group/database.php index 9b39ac00452..10958a6ccdc 100644 --- a/tests/lib/group/database.php +++ b/tests/lib/group/database.php @@ -22,36 +22,27 @@ class Test_Group_Database extends Test_Group_Backend { private $groups=array(); - + /** * get a new unique group name * test cases can override this in order to clean up created groups * @return string */ public function getGroupName($name = null) { - if(is_null($name)) { - $name=uniqid('test_'); - } - $this->groups[]=$name; + $name = parent::getGroupName($name); + $this->groups[] = $name; return $name; } - /** - * get a new unique user name - * test cases can override this in order to clean up created user - * @return string - */ - public function getUserName() { - return uniqid('test_'); - } - - public function setUp() { + protected function setUp() { + parent::setUp(); $this->backend=new OC_Group_Database(); } - public function tearDown() { + protected function tearDown() { foreach($this->groups as $group) { $this->backend->deleteGroup($group); } + parent::tearDown(); } } diff --git a/tests/lib/group/dummy.php b/tests/lib/group/dummy.php index 287d6f1a977..b4456c8f7e1 100644 --- a/tests/lib/group/dummy.php +++ b/tests/lib/group/dummy.php @@ -21,7 +21,8 @@ */ class Test_Group_Dummy extends Test_Group_Backend { - public function setUp() { + protected function setUp() { + parent::setUp(); $this->backend=new OC_Group_Dummy(); } } diff --git a/tests/lib/helper.php b/tests/lib/helper.php index 520a3e0e669..57c72c11987 100644 --- a/tests/lib/helper.php +++ b/tests/lib/helper.php @@ -115,6 +115,10 @@ class Test_Helper extends PHPUnit_Framework_TestCase { } function testGetStringMimeType() { + if (\OC_Util::runningOnWindows()) { + $this->markTestSkipped('[Windows] Strings have mimetype application/octet-stream on Windows'); + } + $result = OC_Helper::getStringMimeType("/data/data.tar.gz"); $expected = 'text/plain; charset=us-ascii'; $this->assertEquals($result, $expected); diff --git a/tests/lib/helperstorage.php b/tests/lib/helperstorage.php index 4fdd9dd6b9b..9f3bd8824f7 100644 --- a/tests/lib/helperstorage.php +++ b/tests/lib/helperstorage.php @@ -9,14 +9,22 @@ /** * Test the storage functions of OC_Helper */ -class Test_Helper_Storage extends PHPUnit_Framework_TestCase { + +class Test_Helper_Storage extends \Test\TestCase { + /** @var string */ private $user; + /** @var \OC\Files\Storage\Storage */ private $storageMock; + /** @var \OC\Files\Storage\Storage */ + private $storage; + + protected function setUp() { + parent::setUp(); - public function setUp() { - $this->user = 'user_' . uniqid(); + $this->user = $this->getUniqueID('user_'); \OC_User::createUser($this->user, $this->user); + $this->storage = \OC\Files\Filesystem::getStorage('/'); \OC\Files\Filesystem::tearDown(); \OC_User::setUserId($this->user); \OC\Files\Filesystem::init($this->user, '/' . $this->user . '/files'); @@ -25,7 +33,7 @@ class Test_Helper_Storage extends PHPUnit_Framework_TestCase { $this->storageMock = null; } - public function tearDown() { + protected function tearDown() { $this->user = null; if ($this->storageMock) { @@ -33,10 +41,13 @@ class Test_Helper_Storage extends PHPUnit_Framework_TestCase { $this->storageMock = null; } \OC\Files\Filesystem::tearDown(); + \OC\Files\Filesystem::mount($this->storage, array(), '/'); \OC_User::setUserId(''); \OC_User::deleteUser($this->user); \OC_Preferences::deleteUser($this->user); + + parent::tearDown(); } /** diff --git a/tests/lib/image.php b/tests/lib/image.php index 795bc464159..a683c3d2c8b 100644 --- a/tests/lib/image.php +++ b/tests/lib/image.php @@ -62,14 +62,18 @@ class Test_Image extends PHPUnit_Framework_TestCase { $img = new \OC_Image(OC::$SERVERROOT.'/tests/data/testimage.png'); $this->assertEquals('image/png', $img->mimeType()); + $img = new \OC_Image(null); + $this->assertEquals('', $img->mimeType()); + + if (\OC_Util::runningOnWindows()) { + $this->markTestSkipped('[Windows] Images created with imagecreate() are pngs on windows'); + } + $img = new \OC_Image(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg')); $this->assertEquals('image/jpeg', $img->mimeType()); $img = new \OC_Image(base64_encode(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif'))); $this->assertEquals('image/gif', $img->mimeType()); - - $img = new \OC_Image(null); - $this->assertEquals('', $img->mimeType()); } public function testWidth() { diff --git a/tests/lib/largefilehelpergetfilesize.php b/tests/lib/largefilehelpergetfilesize.php index 58571d641e0..90ecc3dde70 100644 --- a/tests/lib/largefilehelpergetfilesize.php +++ b/tests/lib/largefilehelpergetfilesize.php @@ -13,58 +13,77 @@ namespace Test; * Large files are not considered yet. */ class LargeFileHelperGetFileSize extends \PHPUnit_Framework_TestCase { - protected $filename; - protected $fileSize; + /** @var \OC\LargeFileHelper */ protected $helper; public function setUp() { parent::setUp(); - $ds = DIRECTORY_SEPARATOR; - $this->filename = dirname(__DIR__) . "{$ds}data{$ds}strängé filename (duplicate #2).txt"; - $this->fileSize = 446; - $this->helper = new \OC\LargeFileHelper; + $this->helper = new \OC\LargeFileHelper(); } - public function testGetFileSizeViaCurl() { + public function dataFileNameProvider() { + $path = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR; + + $filePaths = array(array($path . 'lorem.txt', 446)); + if (!\OC_Util::runningOnWindows()) { + $filePaths[] = array($path . 'strängé filename (duplicate #2).txt', 446); + } + + return $filePaths; + } + + /** + * @dataProvider dataFileNameProvider + */ + public function testGetFileSizeViaCurl($filename, $fileSize) { if (!extension_loaded('curl')) { $this->markTestSkipped( 'The PHP curl extension is required for this test.' ); } $this->assertSame( - $this->fileSize, - $this->helper->getFileSizeViaCurl($this->filename) + $fileSize, + $this->helper->getFileSizeViaCurl($filename) ); } - public function testGetFileSizeViaCOM() { + /** + * @dataProvider dataFileNameProvider + */ + public function testGetFileSizeViaCOM($filename, $fileSize) { if (!extension_loaded('COM')) { $this->markTestSkipped( 'The PHP Windows COM extension is required for this test.' ); } $this->assertSame( - $this->fileSize, - $this->helper->getFileSizeViaCOM($this->filename) + $fileSize, + $this->helper->getFileSizeViaCOM($filename) ); } - public function testGetFileSizeViaExec() { + /** + * @dataProvider dataFileNameProvider + */ + public function testGetFileSizeViaExec($filename, $fileSize) { if (!\OC_Helper::is_function_enabled('exec')) { $this->markTestSkipped( 'The exec() function needs to be enabled for this test.' ); } $this->assertSame( - $this->fileSize, - $this->helper->getFileSizeViaExec($this->filename) + $fileSize, + $this->helper->getFileSizeViaExec($filename) ); } - public function testGetFileSizeNative() { + /** + * @dataProvider dataFileNameProvider + */ + public function testGetFileSizeNative($filename, $fileSize) { $this->assertSame( - $this->fileSize, - $this->helper->getFileSizeNative($this->filename) + $fileSize, + $this->helper->getFileSizeNative($filename) ); } } diff --git a/tests/lib/migrate.php b/tests/lib/migrate.php index c4442511e1f..3f87bbc1ac8 100644 --- a/tests/lib/migrate.php +++ b/tests/lib/migrate.php @@ -11,6 +11,28 @@ class Test_Migrate extends PHPUnit_Framework_TestCase { public $users; public $tmpfiles = array(); + /** @var \OC\Files\Storage\Storage */ + private $originalStorage; + + protected function setUp() { + parent::setUp(); + + $this->originalStorage = \OC\Files\Filesystem::getStorage('/'); + } + + protected function tearDown() { + $u = new OC_User(); + foreach($this->users as $user) { + $u->deleteUser($user); + } + foreach($this->tmpfiles as $file) { + \OC_Helper::rmdirr($file); + } + + \OC\Files\Filesystem::mount($this->originalStorage, array(), '/'); + parent::tearDown(); + } + /** * Generates a test user and sets up their file system * @return string the test users id @@ -73,18 +95,4 @@ class Test_Migrate extends PHPUnit_Framework_TestCase { // Validate the export $this->validateUserExport($user2, $user, json_decode($export)->data); } - - public function tearDown() { - $u = new OC_User(); - foreach($this->users as $user) { - $u->deleteUser($user); - } - foreach($this->tmpfiles as $file) { - \OC_Helper::rmdirr($file); - } - } - - - - } diff --git a/tests/lib/preview.php b/tests/lib/preview.php index 2febe524cba..288dd2aa417 100644 --- a/tests/lib/preview.php +++ b/tests/lib/preview.php @@ -8,7 +8,7 @@ namespace Test; -class Preview extends \PHPUnit_Framework_TestCase { +class Preview extends \Test\TestCase { /** * @var string @@ -20,14 +20,34 @@ class Preview extends \PHPUnit_Framework_TestCase { */ private $rootView; - public function setUp() { - $this->user = $this->initFS(); + /** @var \OC\Files\Storage\Storage */ + private $originalStorage; + + protected function setUp() { + parent::setUp(); + + $this->originalStorage = \OC\Files\Filesystem::getStorage('/'); + + // create a new user with his own filesystem view + // this gets called by each test in this test class + $this->user = $this->getUniqueID(); + \OC_User::setUserId($this->user); + \OC\Files\Filesystem::init($this->user, '/' . $this->user . '/files'); + + \OC\Files\Filesystem::mount('OC\Files\Storage\Temporary', array(), '/'); $this->rootView = new \OC\Files\View(''); $this->rootView->mkdir('/'.$this->user); $this->rootView->mkdir('/'.$this->user.'/files'); } + protected function tearDown() { + \OC\Files\Filesystem::clearMounts(); + \OC\Files\Filesystem::mount($this->originalStorage, array(), '/'); + + parent::tearDown(); + } + public function testIsPreviewDeleted() { $sampleFile = '/'.$this->user.'/files/test.txt'; @@ -184,16 +204,4 @@ class Preview extends \PHPUnit_Framework_TestCase { $this->assertEquals($this->user . '/' . \OC\Preview::THUMBNAILS_FOLDER . '/' . $fileId . '/150-150.png', $isCached); } */ - - private function initFS() { - // create a new user with his own filesystem view - // this gets called by each test in this test class - $user=uniqid(); - \OC_User::setUserId($user); - \OC\Files\Filesystem::init($user, '/'.$user.'/files'); - - \OC\Files\Filesystem::mount('OC\Files\Storage\Temporary', array(), '/'); - - return $user; - } } diff --git a/tests/lib/security/certificatemanager.php b/tests/lib/security/certificatemanager.php index 5baf9e16e81..01b3afb03ee 100644 --- a/tests/lib/security/certificatemanager.php +++ b/tests/lib/security/certificatemanager.php @@ -8,7 +8,7 @@ use \OC\Security\CertificateManager; -class CertificateManagerTest extends \PHPUnit_Framework_TestCase { +class CertificateManagerTest extends \Test\TestCase { /** @var CertificateManager */ private $certificateManager; @@ -18,8 +18,8 @@ class CertificateManagerTest extends \PHPUnit_Framework_TestCase { private $user; function setUp() { - $this->username = OC_Util::generateRandomBytes(20); - OC_User::createUser($this->username, OC_Util::generateRandomBytes(20)); + $this->username = $this->getUniqueID('', 20); + OC_User::createUser($this->username, $this->getUniqueID('', 20)); \OC_Util::tearDownFS(); \OC_User::setUserId(''); diff --git a/tests/lib/share/share.php b/tests/lib/share/share.php index 3d99883f2de..7644dadadc7 100644 --- a/tests/lib/share/share.php +++ b/tests/lib/share/share.php @@ -19,7 +19,7 @@ * License along with this library. If not, see <http://www.gnu.org/licenses/>. */ -class Test_Share extends PHPUnit_Framework_TestCase { +class Test_Share extends Test\TestCase { protected $itemType; protected $userBackend; @@ -27,6 +27,7 @@ class Test_Share extends PHPUnit_Framework_TestCase { protected $user2; protected $user3; protected $user4; + protected $groupAndUser; protected $groupBackend; protected $group1; protected $group2; @@ -34,29 +35,35 @@ class Test_Share extends PHPUnit_Framework_TestCase { protected $dateInFuture; protected $dateInPast; - public function setUp() { + protected function setUp() { + parent::setUp(); OC_User::clearBackends(); OC_User::useBackend('dummy'); - $this->user1 = uniqid('user1_'); - $this->user2 = uniqid('user2_'); - $this->user3 = uniqid('user3_'); - $this->user4 = uniqid('user4_'); + $this->user1 = $this->getUniqueID('user1_'); + $this->user2 = $this->getUniqueID('user2_'); + $this->user3 = $this->getUniqueID('user3_'); + $this->user4 = $this->getUniqueID('user4_'); + $this->groupAndUser = $this->getUniqueID('groupAndUser_'); OC_User::createUser($this->user1, 'pass'); OC_User::createUser($this->user2, 'pass'); OC_User::createUser($this->user3, 'pass'); OC_User::createUser($this->user4, 'pass'); + OC_User::createUser($this->groupAndUser, 'pass'); OC_User::setUserId($this->user1); OC_Group::clearBackends(); OC_Group::useBackend(new OC_Group_Dummy); - $this->group1 = uniqid('group1_'); - $this->group2 = uniqid('group2_'); + $this->group1 = $this->getUniqueID('group1_'); + $this->group2 = $this->getUniqueID('group2_'); OC_Group::createGroup($this->group1); OC_Group::createGroup($this->group2); + OC_Group::createGroup($this->groupAndUser); OC_Group::addToGroup($this->user1, $this->group1); OC_Group::addToGroup($this->user2, $this->group1); OC_Group::addToGroup($this->user3, $this->group1); OC_Group::addToGroup($this->user2, $this->group2); OC_Group::addToGroup($this->user4, $this->group2); + OC_Group::addToGroup($this->user2, $this->groupAndUser); + OC_Group::addToGroup($this->user3, $this->groupAndUser); OCP\Share::registerBackend('test', 'Test_Share_Backend'); OC_Hook::clear('OCP\\Share'); OC::registerShareHooks(); @@ -70,10 +77,11 @@ class Test_Share extends PHPUnit_Framework_TestCase { $this->dateInFuture = date($dateFormat, $now + 20 * 60); } - public function tearDown() { + protected function tearDown() { $query = OC_DB::prepare('DELETE FROM `*PREFIX*share` WHERE `item_type` = ?'); $query->execute(array('test')); OC_Appconfig::setValue('core', 'shareapi_allow_resharing', $this->resharing); + parent::tearDown(); } public function testShareInvalidShareType() { @@ -600,6 +608,41 @@ class Test_Share extends PHPUnit_Framework_TestCase { $this->assertEquals(array(), OCP\Share::getItemsShared('test')); } + + public function testShareWithGroupAndUserBothHaveTheSameId() { + + $this->shareUserTestFileWithUser($this->user1, $this->groupAndUser); + + OC_User::setUserId($this->groupAndUser); + + $this->assertEquals(array('test.txt'), OCP\Share::getItemSharedWith('test', 'test.txt', Test_Share_Backend::FORMAT_SOURCE), + '"groupAndUser"-User does not see the file but it was shared with him'); + + OC_User::setUserId($this->user2); + $this->assertEquals(array(), OCP\Share::getItemSharedWith('test', 'test.txt', Test_Share_Backend::FORMAT_SOURCE), + 'User2 sees test.txt but it was only shared with the user "groupAndUser" and not with group'); + + OC_User::setUserId($this->user1); + $this->assertTrue(OCP\Share::unshareAll('test', 'test.txt')); + + $this->assertTrue( + OCP\Share::shareItem('test', 'test.txt', OCP\Share::SHARE_TYPE_GROUP, $this->groupAndUser, OCP\PERMISSION_READ), + 'Failed asserting that user 1 successfully shared text.txt with group 1.' + ); + + OC_User::setUserId($this->groupAndUser); + $this->assertEquals(array(), OCP\Share::getItemSharedWith('test', 'test.txt', Test_Share_Backend::FORMAT_SOURCE), + '"groupAndUser"-User sees test.txt but it was only shared with the group "groupAndUser" and not with the user'); + + OC_User::setUserId($this->user2); + $this->assertEquals(array('test.txt'), OCP\Share::getItemSharedWith('test', 'test.txt', Test_Share_Backend::FORMAT_SOURCE), + 'User2 does not see test.txt but it was shared with the group "groupAndUser"'); + + OC_User::setUserId($this->user1); + $this->assertTrue(OCP\Share::unshareAll('test', 'test.txt')); + + } + /** * @param boolean|string $token */ diff --git a/tests/lib/streamwrappers.php b/tests/lib/streamwrappers.php index 1b61446f4dc..6f92f487037 100644 --- a/tests/lib/streamwrappers.php +++ b/tests/lib/streamwrappers.php @@ -65,7 +65,9 @@ class Test_StreamWrappers extends PHPUnit_Framework_TestCase { } public function testOC() { + $originalStorage = \OC\Files\Filesystem::getStorage('/'); \OC\Files\Filesystem::clearMounts(); + $storage = new \OC\Files\Storage\Temporary(array()); $storage->file_put_contents('foo.txt', 'asd'); \OC\Files\Filesystem::mount($storage, array(), '/'); @@ -91,5 +93,8 @@ class Test_StreamWrappers extends PHPUnit_Framework_TestCase { unlink('oc:///foo.txt'); $this->assertEquals(array('.', '..', 'bar.txt'), scandir('oc:///')); + + \OC\Files\Filesystem::clearMounts(); + \OC\Files\Filesystem::mount($originalStorage, array(), '/'); } } diff --git a/tests/lib/template/resourcelocator.php b/tests/lib/template/resourcelocator.php index 619560643fe..cd354df0036 100644 --- a/tests/lib/template/resourcelocator.php +++ b/tests/lib/template/resourcelocator.php @@ -10,19 +10,17 @@ class Test_ResourceLocator extends PHPUnit_Framework_TestCase { /** * @param string $theme - * @param string $form_factor */ - public function getResourceLocator( $theme, $form_factor, $core_map, $party_map, $appsroots ) { + public function getResourceLocator( $theme, $core_map, $party_map, $appsroots ) { return $this->getMockForAbstractClass('OC\Template\ResourceLocator', - array( $theme, $form_factor, $core_map, $party_map, $appsroots ), + array( $theme, $core_map, $party_map, $appsroots ), '', true, true, true, array()); } public function testConstructor() { - $locator = $this->getResourceLocator('theme', 'form_factor', + $locator = $this->getResourceLocator('theme', array('core'=>'map'), array('3rd'=>'party'), array('foo'=>'bar')); $this->assertAttributeEquals('theme', 'theme', $locator); - $this->assertAttributeEquals('form_factor', 'form_factor', $locator); $this->assertAttributeEquals('core', 'serverroot', $locator); $this->assertAttributeEquals(array('core'=>'map','3rd'=>'party'), 'mapping', $locator); $this->assertAttributeEquals('3rd', 'thirdpartyroot', $locator); @@ -31,7 +29,7 @@ class Test_ResourceLocator extends PHPUnit_Framework_TestCase { } public function testFind() { - $locator = $this->getResourceLocator('theme', 'form_factor', + $locator = $this->getResourceLocator('theme', array('core'=>'map'), array('3rd'=>'party'), array('foo'=>'bar')); $locator->expects($this->once()) ->method('doFind') @@ -41,7 +39,7 @@ class Test_ResourceLocator extends PHPUnit_Framework_TestCase { ->with('foo'); $locator->find(array('foo')); - $locator = $this->getResourceLocator('theme', 'form_factor', + $locator = $this->getResourceLocator('theme', array('core'=>'map'), array('3rd'=>'party'), array('foo'=>'bar')); $locator->expects($this->once()) ->method('doFind') @@ -50,12 +48,12 @@ class Test_ResourceLocator extends PHPUnit_Framework_TestCase { try { $locator->find(array('foo')); } catch (\Exception $e) { - $this->assertEquals('test formfactor:form_factor serverroot:core', $e->getMessage()); + $this->assertEquals('test serverroot:core', $e->getMessage()); } } public function testAppendIfExist() { - $locator = $this->getResourceLocator('theme', 'form_factor', + $locator = $this->getResourceLocator('theme', array(__DIR__=>'map'), array('3rd'=>'party'), array('foo'=>'bar')); $method = new ReflectionMethod($locator, 'appendIfExist'); $method->setAccessible(true); diff --git a/tests/lib/tempmanager.php b/tests/lib/tempmanager.php index f16fbce2c7c..85b94094393 100644 --- a/tests/lib/tempmanager.php +++ b/tests/lib/tempmanager.php @@ -122,6 +122,10 @@ class TempManager extends \PHPUnit_Framework_TestCase { } public function testLogCantCreateFile() { + if (\OC_Util::runningOnWindows()) { + $this->markTestSkipped('[Windows] chmod() does not work as intended on Windows.'); + } + $logger = $this->getMock('\Test\NullLogger'); $manager = $this->getManager($logger); chmod($this->baseDir, 0500); @@ -132,6 +136,10 @@ class TempManager extends \PHPUnit_Framework_TestCase { } public function testLogCantCreateFolder() { + if (\OC_Util::runningOnWindows()) { + $this->markTestSkipped('[Windows] chmod() does not work as intended on Windows.'); + } + $logger = $this->getMock('\Test\NullLogger'); $manager = $this->getManager($logger); chmod($this->baseDir, 0500); diff --git a/tests/lib/testcase.php b/tests/lib/testcase.php new file mode 100644 index 00000000000..a4b4b0103f0 --- /dev/null +++ b/tests/lib/testcase.php @@ -0,0 +1,33 @@ +<?php +/** + * ownCloud + * + * @author Joas Schilling + * @copyright 2014 Joas Schilling nickvergessen@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace Test; + +abstract class TestCase extends \PHPUnit_Framework_TestCase { + protected function getUniqueID($prefix = '', $length = 13) { + // Do not use dots and slashes as we use the value for file names + return $prefix . \OC::$server->getSecureRandom()->getLowStrengthGenerator()->generate( + $length, + '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' + ); + } +} diff --git a/tests/lib/user/backend.php b/tests/lib/user/backend.php index 0d3914c7ca6..c2040f4e3be 100644 --- a/tests/lib/user/backend.php +++ b/tests/lib/user/backend.php @@ -30,7 +30,7 @@ * For an example see /tests/lib/user/dummy.php */ -abstract class Test_User_Backend extends PHPUnit_Framework_TestCase { +abstract class Test_User_Backend extends \Test\TestCase { /** * @var OC_User_Backend $backend */ @@ -42,7 +42,7 @@ abstract class Test_User_Backend extends PHPUnit_Framework_TestCase { * @return string */ public function getUser() { - return uniqid('test_'); + return $this->getUniqueID('test_'); } public function testAddRemove() { @@ -68,29 +68,29 @@ abstract class Test_User_Backend extends PHPUnit_Framework_TestCase { $this->assertTrue((array_search($name1, $this->backend->getUsers())!==false)); $this->assertFalse((array_search($name2, $this->backend->getUsers())!==false)); } - + public function testLogin() { $name1=$this->getUser(); $name2=$this->getUser(); - + $this->assertFalse($this->backend->userExists($name1)); $this->assertFalse($this->backend->userExists($name2)); - + $this->backend->createUser($name1, 'pass1'); $this->backend->createUser($name2, 'pass2'); - + $this->assertTrue($this->backend->userExists($name1)); $this->assertTrue($this->backend->userExists($name2)); - + $this->assertSame($name1, $this->backend->checkPassword($name1, 'pass1')); $this->assertSame($name2, $this->backend->checkPassword($name2, 'pass2')); - + $this->assertFalse($this->backend->checkPassword($name1, 'pass2')); $this->assertFalse($this->backend->checkPassword($name2, 'pass1')); - + $this->assertFalse($this->backend->checkPassword($name1, 'dummy')); $this->assertFalse($this->backend->checkPassword($name2, 'foobar')); - + $this->backend->setPassword($name1, 'newpass1'); $this->assertFalse($this->backend->checkPassword($name1, 'pass1')); $this->assertSame($name1, $this->backend->checkPassword($name1, 'newpass1')); @@ -112,5 +112,4 @@ abstract class Test_User_Backend extends PHPUnit_Framework_TestCase { $result = $this->backend->getDisplayNames('bar'); $this->assertSame(2, count($result)); } - } diff --git a/tests/lib/user/database.php b/tests/lib/user/database.php index a8e497720c2..3a6be1ceee5 100644 --- a/tests/lib/user/database.php +++ b/tests/lib/user/database.php @@ -21,22 +21,27 @@ */ class Test_User_Database extends Test_User_Backend { + /** @var array */ + private $users; + public function getUser() { $user = parent::getUser(); $this->users[]=$user; return $user; } - - public function setUp() { + + protected function setUp() { + parent::setUp(); $this->backend=new OC_User_Database(); } - - public function tearDown() { + + protected function tearDown() { if(!isset($this->users)) { return; } foreach($this->users as $user) { $this->backend->deleteUser($user); } + parent::tearDown(); } } diff --git a/tests/lib/user/dummy.php b/tests/lib/user/dummy.php index e417fd97603..fcc921de4b1 100644 --- a/tests/lib/user/dummy.php +++ b/tests/lib/user/dummy.php @@ -21,7 +21,8 @@ */ class Test_User_Dummy extends Test_User_Backend { - public function setUp() { + protected function setUp() { + parent::setUp(); $this->backend=new OC_User_Dummy(); } } diff --git a/tests/lib/utilcheckserver.php b/tests/lib/utilcheckserver.php index be5596c1900..73a1d0e95a6 100644 --- a/tests/lib/utilcheckserver.php +++ b/tests/lib/utilcheckserver.php @@ -138,6 +138,10 @@ class Test_Util_CheckServer extends PHPUnit_Framework_TestCase { * Tests an error is given when the datadir is not writable */ public function testDataDirNotWritable() { + if (\OC_Util::runningOnWindows()) { + $this->markTestSkipped('[Windows] chmod() does not work as intended on Windows.'); + } + chmod($this->datadir, 0300); $result = \OC_Util::checkServer($this->getConfig(array( 'installed' => true, diff --git a/tests/phpunit-autotest.xml b/tests/phpunit-autotest.xml index 3805bb1ac79..282f5477c30 100644 --- a/tests/phpunit-autotest.xml +++ b/tests/phpunit-autotest.xml @@ -9,6 +9,7 @@ <testsuite name='ownCloud'> <directory suffix='.php'>lib/</directory> <directory suffix='.php'>settings/</directory> + <directory suffix='.php'>core/</directory> <file>apps.php</file> </testsuite> <!-- filters for code coverage --> diff --git a/tests/phpunit.xml.dist b/tests/phpunit.xml.dist index 21c63ea0469..95abe473965 100644 --- a/tests/phpunit.xml.dist +++ b/tests/phpunit.xml.dist @@ -2,6 +2,8 @@ <phpunit bootstrap="bootstrap.php"> <testsuite name='ownCloud'> <directory suffix='.php'>lib/</directory> + <directory suffix='.php'>settings/</directory> + <directory suffix='.php'>core/</directory> <file>apps.php</file> </testsuite> <!-- filters for code coverage --> diff --git a/tests/settings/controller/mailsettingscontrollertest.php b/tests/settings/controller/mailsettingscontrollertest.php index ff3d1d93a1b..789b6ce8fb0 100644 --- a/tests/settings/controller/mailsettingscontrollertest.php +++ b/tests/settings/controller/mailsettingscontrollertest.php @@ -14,7 +14,7 @@ use \OC\Settings\Application; /** * @package OC\Settings\Controller */ -class MailSettingscontrollerTest extends \PHPUnit_Framework_TestCase { +class MailSettingsControllerTest extends \PHPUnit_Framework_TestCase { private $container; @@ -147,6 +147,12 @@ class MailSettingscontrollerTest extends \PHPUnit_Framework_TestCase { } public function testSendTestMail() { + /** + * FIXME: Disabled due to missing DI on mail class. + * TODO: Re-enable when https://github.com/owncloud/core/pull/12085 is merged. + */ + $this->markTestSkipped('Disable test until OC_Mail is rewritten.'); + $user = $this->getMockBuilder('\OC\User\User') ->disableOriginalConstructor() ->getMock(); diff --git a/tests/settings/controller/securitysettingscontrollertest.php b/tests/settings/controller/securitysettingscontrollertest.php new file mode 100644 index 00000000000..d89e4932368 --- /dev/null +++ b/tests/settings/controller/securitysettingscontrollertest.php @@ -0,0 +1,138 @@ +<?php +/** + * @author Lukas Reschke + * @copyright 2014 Lukas Reschke lukas@owncloud.com + * + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +namespace OC\Settings\Controller; + +use \OC\Settings\Application; + +/** + * @package OC\Settings\Controller + */ +class SecuritySettingsControllerTest extends \PHPUnit_Framework_TestCase { + + /** @var \OCP\AppFramework\IAppContainer */ + private $container; + + /** @var SecuritySettingsController */ + private $securitySettingsController; + + protected function setUp() { + $app = new Application(); + $this->container = $app->getContainer(); + $this->container['Config'] = $this->getMockBuilder('\OCP\IConfig') + ->disableOriginalConstructor()->getMock(); + $this->container['AppName'] = 'settings'; + $this->securitySettingsController = $this->container['SecuritySettingsController']; + } + + + public function testEnforceSSLEmpty() { + $this->container['Config'] + ->expects($this->once()) + ->method('setSystemValue') + ->with('forcessl', false); + + $response = $this->securitySettingsController->enforceSSL(); + $expectedResponse = array('status' => 'success'); + + $this->assertSame($expectedResponse, $response); + } + + public function testEnforceSSL() { + $this->container['Config'] + ->expects($this->once()) + ->method('setSystemValue') + ->with('forcessl', true); + + $response = $this->securitySettingsController->enforceSSL(true); + $expectedResponse = array('status' => 'success'); + + $this->assertSame($expectedResponse, $response); + } + + public function testEnforceSSLInvalid() { + $this->container['Config'] + ->expects($this->exactly(0)) + ->method('setSystemValue'); + + $response = $this->securitySettingsController->enforceSSL('blah'); + $expectedResponse = array('status' => 'error'); + + $this->assertSame($expectedResponse, $response); + } + + public function testEnforceSSLForSubdomainsEmpty() { + $this->container['Config'] + ->expects($this->once()) + ->method('setSystemValue') + ->with('forceSSLforSubdomains', false); + + $response = $this->securitySettingsController->enforceSSLForSubdomains(); + $expectedResponse = array('status' => 'success'); + + $this->assertSame($expectedResponse, $response); + } + + public function testEnforceSSLForSubdomains() { + $this->container['Config'] + ->expects($this->once()) + ->method('setSystemValue') + ->with('forceSSLforSubdomains', true); + + $response = $this->securitySettingsController->enforceSSLForSubdomains(true); + $expectedResponse = array('status' => 'success'); + + $this->assertSame($expectedResponse, $response); + } + + public function testEnforceSSLForSubdomainsInvalid() { + $this->container['Config'] + ->expects($this->exactly(0)) + ->method('setSystemValue'); + + $response = $this->securitySettingsController->enforceSSLForSubdomains('blah'); + $expectedResponse = array('status' => 'error'); + + $this->assertSame($expectedResponse, $response); + } + + public function testTrustedDomainsWithExistingValues() { + $this->container['Config'] + ->expects($this->once()) + ->method('setSystemValue') + ->with('trusted_domains', array('owncloud.org', 'owncloud.com', 'newdomain.com')); + $this->container['Config'] + ->expects($this->once()) + ->method('getSystemValue') + ->with('trusted_domains') + ->will($this->returnValue(array('owncloud.org', 'owncloud.com'))); + + $response = $this->securitySettingsController->trustedDomains('newdomain.com'); + $expectedResponse = array('status' => 'success'); + + $this->assertSame($expectedResponse, $response); + } + + public function testTrustedDomainsEmpty() { + $this->container['Config'] + ->expects($this->once()) + ->method('setSystemValue') + ->with('trusted_domains', array('newdomain.com')); + $this->container['Config'] + ->expects($this->once()) + ->method('getSystemValue') + ->with('trusted_domains') + ->will($this->returnValue('')); + + $response = $this->securitySettingsController->trustedDomains('newdomain.com'); + $expectedResponse = array('status' => 'success'); + + $this->assertSame($expectedResponse, $response); + } +} |