diff options
Diffstat (limited to 'core/js/files/client.js')
-rw-r--r-- | core/js/files/client.js | 756 |
1 files changed, 0 insertions, 756 deletions
diff --git a/core/js/files/client.js b/core/js/files/client.js deleted file mode 100644 index 0bf5a69e19c..00000000000 --- a/core/js/files/client.js +++ /dev/null @@ -1,756 +0,0 @@ -/* - * Copyright (c) 2015 - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -/* global dav */ - -(function(OC, FileInfo) { - /** - * @class OC.Files.Client - * @classdesc Client to access files on the server - * - * @param {Object} options - * @param {String} options.host host name - * @param {int} [options.port] port - * @param {boolean} [options.useHTTPS] whether to use https - * @param {String} [options.root] root path - * @param {String} [options.userName] user name - * @param {String} [options.password] password - * - * @since 8.2 - */ - var Client = function(options) { - this._root = options.root; - if (this._root.charAt(this._root.length - 1) === '/') { - this._root = this._root.substr(0, this._root.length - 1); - } - - var url = 'http://'; - if (options.useHTTPS) { - url = 'https://'; - } - - url += options.host + this._root; - this._defaultHeaders = options.defaultHeaders || { - 'X-Requested-With': 'XMLHttpRequest', - 'requesttoken': OC.requestToken - }; - this._baseUrl = url; - - var clientOptions = { - baseUrl: this._baseUrl, - xmlNamespaces: { - 'DAV:': 'd', - 'http://owncloud.org/ns': 'oc' - } - }; - if (options.userName) { - clientOptions.userName = options.userName; - } - if (options.password) { - clientOptions.password = options.password; - } - this._client = new dav.Client(clientOptions); - this._client.xhrProvider = _.bind(this._xhrProvider, this); - }; - - Client.NS_OWNCLOUD = 'http://owncloud.org/ns'; - Client.NS_DAV = 'DAV:'; - Client._PROPFIND_PROPERTIES = [ - /** - * Modified time - */ - [Client.NS_DAV, 'getlastmodified'], - /** - * Etag - */ - [Client.NS_DAV, 'getetag'], - /** - * Mime type - */ - [Client.NS_DAV, 'getcontenttype'], - /** - * Resource type "collection" for folders, empty otherwise - */ - [Client.NS_DAV, 'resourcetype'], - /** - * File id - */ - [Client.NS_OWNCLOUD, 'fileid'], - /** - * Letter-coded permissions - */ - [Client.NS_OWNCLOUD, 'permissions'], - //[Client.NS_OWNCLOUD, 'downloadURL'], - /** - * Folder sizes - */ - [Client.NS_OWNCLOUD, 'size'], - /** - * File sizes - */ - [Client.NS_DAV, 'getcontentlength'] - ]; - - /** - * @memberof OC.Files - */ - Client.prototype = { - - /** - * Root path of the Webdav endpoint - * - * @type string - */ - _root: null, - - /** - * Client from the library - * - * @type dav.Client - */ - _client: null, - - /** - * Array of file info parsing functions. - * - * @type Array<OC.Files.Client~parseFileInfo> - */ - _fileInfoParsers: [], - - /** - * Returns the configured XHR provider for davclient - * @return {XMLHttpRequest} - */ - _xhrProvider: function() { - var headers = this._defaultHeaders; - var xhr = new XMLHttpRequest(); - var oldOpen = xhr.open; - // override open() method to add headers - xhr.open = function() { - var result = oldOpen.apply(this, arguments); - _.each(headers, function(value, key) { - xhr.setRequestHeader(key, value); - }); - return result; - }; - - OC.registerXHRForErrorProcessing(xhr); - return xhr; - }, - - /** - * Prepends the base url to the given path sections - * - * @param {...String} path sections - * - * @return {String} base url + joined path, any leading or trailing slash - * will be kept - */ - _buildUrl: function() { - var path = this._buildPath.apply(this, arguments); - if (path.charAt([path.length - 1]) === '/') { - path = path.substr(0, path.length - 1); - } - if (path.charAt(0) === '/') { - path = path.substr(1); - } - return this._baseUrl + '/' + path; - }, - - /** - * Append the path to the root and also encode path - * sections - * - * @param {...String} path sections - * - * @return {String} joined path, any leading or trailing slash - * will be kept - */ - _buildPath: function() { - var path = OC.joinPaths.apply(this, arguments); - var sections = path.split('/'); - var i; - for (i = 0; i < sections.length; i++) { - sections[i] = encodeURIComponent(sections[i]); - } - path = sections.join('/'); - return path; - }, - - /** - * Parse headers string into a map - * - * @param {string} headersString headers list as string - * - * @return {Object.<String,Array>} map of header name to header contents - */ - _parseHeaders: function(headersString) { - var headerRows = headersString.split('\n'); - var headers = {}; - for (var i = 0; i < headerRows.length; i++) { - var sepPos = headerRows[i].indexOf(':'); - if (sepPos < 0) { - continue; - } - - var headerName = headerRows[i].substr(0, sepPos); - var headerValue = headerRows[i].substr(sepPos + 2); - - if (!headers[headerName]) { - // make it an array - headers[headerName] = []; - } - - headers[headerName].push(headerValue); - } - return headers; - }, - - /** - * Parses the etag response which is in double quotes. - * - * @param {string} etag etag value in double quotes - * - * @return {string} etag without double quotes - */ - _parseEtag: function(etag) { - if (etag.charAt(0) === '"') { - return etag.split('"')[1]; - } - return etag; - }, - - /** - * Parse Webdav result - * - * @param {Object} response XML object - * - * @return {Array.<FileInfo>} array of file info - */ - _parseFileInfo: function(response) { - var path = response.href; - if (path.substr(0, this._root.length) === this._root) { - path = path.substr(this._root.length); - } - - if (path.charAt(path.length - 1) === '/') { - path = path.substr(0, path.length - 1); - } - - path = decodeURIComponent(path); - - if (response.propStat.length === 0 || response.propStat[0].status !== 'HTTP/1.1 200 OK') { - return null; - } - - var props = response.propStat[0].properties; - - var data = { - id: props['{' + Client.NS_OWNCLOUD + '}fileid'], - path: OC.dirname(path) || '/', - name: OC.basename(path), - mtime: (new Date(props['{' + Client.NS_DAV + '}getlastmodified'])).getTime() - }; - - var etagProp = props['{' + Client.NS_DAV + '}getetag']; - if (!_.isUndefined(etagProp)) { - data.etag = this._parseEtag(etagProp); - } - - var sizeProp = props['{' + Client.NS_DAV + '}getcontentlength']; - if (!_.isUndefined(sizeProp)) { - data.size = parseInt(sizeProp, 10); - } - - sizeProp = props['{' + Client.NS_OWNCLOUD + '}size']; - if (!_.isUndefined(sizeProp)) { - data.size = parseInt(sizeProp, 10); - } - - var contentType = props['{' + Client.NS_DAV + '}getcontenttype']; - if (!_.isUndefined(contentType)) { - data.mimetype = contentType; - } - - var resType = props['{' + Client.NS_DAV + '}resourcetype']; - var isFile = true; - if (!data.mimetype && resType) { - var xmlvalue = resType[0]; - if (xmlvalue.namespaceURI === Client.NS_DAV && xmlvalue.nodeName.split(':')[1] === 'collection') { - data.mimetype = 'httpd/unix-directory'; - isFile = false; - } - } - - data.permissions = OC.PERMISSION_READ; - var permissionProp = props['{' + Client.NS_OWNCLOUD + '}permissions']; - if (!_.isUndefined(permissionProp)) { - var permString = permissionProp || ''; - data.mountType = null; - for (var i = 0; i < permString.length; i++) { - var c = permString.charAt(i); - switch (c) { - // FIXME: twisted permissions - case 'C': - case 'K': - data.permissions |= OC.PERMISSION_CREATE; - if (!isFile) { - data.permissions |= OC.PERMISSION_UPDATE; - } - break; - case 'W': - data.permissions |= OC.PERMISSION_UPDATE; - break; - case 'D': - data.permissions |= OC.PERMISSION_DELETE; - break; - case 'R': - data.permissions |= OC.PERMISSION_SHARE; - break; - case 'M': - if (!data.mountType) { - // TODO: how to identify external-root ? - data.mountType = 'external'; - } - break; - case 'S': - // TODO: how to identify shared-root ? - data.mountType = 'shared'; - break; - } - } - } - - // extend the parsed data using the custom parsers - _.each(this._fileInfoParsers, function(parserFunction) { - _.extend(data, parserFunction(response) || {}); - }); - - return new FileInfo(data); - }, - - /** - * Parse Webdav multistatus - * - * @param {Array} responses - */ - _parseResult: function(responses) { - var self = this; - return _.map(responses, function(response) { - return self._parseFileInfo(response); - }); - }, - - /** - * Returns whether the given status code means success - * - * @param {int} status status code - * - * @return true if status code is between 200 and 299 included - */ - _isSuccessStatus: function(status) { - return status >= 200 && status <= 299; - }, - - /** - * Returns the default PROPFIND properties to use during a call. - * - * @return {Array.<Object>} array of properties - */ - getPropfindProperties: function() { - if (!this._propfindProperties) { - this._propfindProperties = _.map(Client._PROPFIND_PROPERTIES, function(propDef) { - return '{' + propDef[0] + '}' + propDef[1]; - }); - } - return this._propfindProperties; - }, - - /** - * Lists the contents of a directory - * - * @param {String} path path to retrieve - * @param {Object} [options] options - * @param {boolean} [options.includeParent=false] set to true to keep - * the parent folder in the result list - * @param {Array} [options.properties] list of Webdav properties to retrieve - * - * @return {Promise} promise - */ - getFolderContents: function(path, options) { - if (!path) { - path = ''; - } - options = options || {}; - var self = this; - var deferred = $.Deferred(); - var promise = deferred.promise(); - var properties; - if (_.isUndefined(options.properties)) { - properties = this.getPropfindProperties(); - } else { - properties = options.properties; - } - - this._client.propFind( - this._buildUrl(path), - properties, - 1 - ).then(function(result) { - if (self._isSuccessStatus(result.status)) { - var results = self._parseResult(result.body); - if (!options || !options.includeParent) { - // remove root dir, the first entry - results.shift(); - } - deferred.resolve(result.status, results); - } else { - deferred.reject(result.status); - } - }); - return promise; - }, - - /** - * Fetches a flat list of files filtered by a given filter criteria. - * (currently only system tags is supported) - * - * @param {Object} filter filter criteria - * @param {Object} [filter.systemTagIds] list of system tag ids to filter by - * @param {Object} [options] options - * @param {Array} [options.properties] list of Webdav properties to retrieve - * - * @return {Promise} promise - */ - getFilteredFiles: function(filter, options) { - options = options || {}; - var self = this; - var deferred = $.Deferred(); - var promise = deferred.promise(); - var properties; - if (_.isUndefined(options.properties)) { - properties = this.getPropfindProperties(); - } else { - properties = options.properties; - } - - if (!filter || !filter.systemTagIds || !filter.systemTagIds.length) { - throw 'Missing filter argument'; - } - - // root element with namespaces - var body = '<oc:filter-files '; - var namespace; - for (namespace in this._client.xmlNamespaces) { - body += ' xmlns:' + this._client.xmlNamespaces[namespace] + '="' + namespace + '"'; - } - body += '>\n'; - - // properties query - body += ' <' + this._client.xmlNamespaces['DAV:'] + ':prop>\n'; - _.each(properties, function(prop) { - var property = self._client.parseClarkNotation(prop); - body += ' <' + self._client.xmlNamespaces[property.namespace] + ':' + property.name + ' />\n'; - }); - - body += ' </' + this._client.xmlNamespaces['DAV:'] + ':prop>\n'; - - // rules block - body += ' <oc:filter-rules>\n'; - _.each(filter.systemTagIds, function(systemTagIds) { - body += ' <oc:systemtag>' + escapeHTML(systemTagIds) + '</oc:systemtag>\n'; - }); - body += ' </oc:filter-rules>\n'; - - // end of root - body += '</oc:filter-files>\n'; - - this._client.request( - 'REPORT', - this._buildUrl(), - {}, - body - ).then(function(result) { - if (self._isSuccessStatus(result.status)) { - var results = self._parseResult(result.body); - deferred.resolve(result.status, results); - } else { - deferred.reject(result.status); - } - }); - return promise; - }, - - /** - * Returns the file info of a given path. - * - * @param {String} path path - * @param {Array} [options.properties] list of Webdav properties to retrieve - * - * @return {Promise} promise - */ - getFileInfo: function(path, options) { - if (!path) { - path = ''; - } - options = options || {}; - var self = this; - var deferred = $.Deferred(); - var promise = deferred.promise(); - var properties; - if (_.isUndefined(options.properties)) { - properties = this.getPropfindProperties(); - } else { - properties = options.properties; - } - - // TODO: headers - this._client.propFind( - this._buildUrl(path), - properties, - 0 - ).then( - function(result) { - if (self._isSuccessStatus(result.status)) { - deferred.resolve(result.status, self._parseResult([result.body])[0]); - } else { - deferred.reject(result.status); - } - } - ); - return promise; - }, - - /** - * Returns the contents of the given file. - * - * @param {String} path path to file - * - * @return {Promise} - */ - getFileContents: function(path) { - if (!path) { - throw 'Missing argument "path"'; - } - var self = this; - var deferred = $.Deferred(); - var promise = deferred.promise(); - - this._client.request( - 'GET', - this._buildUrl(path) - ).then( - function(result) { - if (self._isSuccessStatus(result.status)) { - deferred.resolve(result.status, result.body); - } else { - deferred.reject(result.status); - } - } - ); - return promise; - }, - - /** - * Puts the given data into the given file. - * - * @param {String} path path to file - * @param {String} body file body - * @param {Object} [options] - * @param {String} [options.contentType='text/plain'] content type - * @param {bool} [options.overwrite=true] whether to overwrite an existing file - * - * @return {Promise} - */ - putFileContents: function(path, body, options) { - if (!path) { - throw 'Missing argument "path"'; - } - var self = this; - var deferred = $.Deferred(); - var promise = deferred.promise(); - options = options || {}; - var headers = {}; - var contentType = 'text/plain;charset=utf-8'; - if (options.contentType) { - contentType = options.contentType; - } - - headers['Content-Type'] = contentType; - - if (_.isUndefined(options.overwrite) || options.overwrite) { - // will trigger 412 precondition failed if a file already exists - headers['If-None-Match'] = '*'; - } - - this._client.request( - 'PUT', - this._buildUrl(path), - headers, - body || '' - ).then( - function(result) { - if (self._isSuccessStatus(result.status)) { - deferred.resolve(result.status); - } else { - deferred.reject(result.status); - } - } - ); - return promise; - }, - - _simpleCall: function(method, path) { - if (!path) { - throw 'Missing argument "path"'; - } - - var self = this; - var deferred = $.Deferred(); - var promise = deferred.promise(); - - this._client.request( - method, - this._buildUrl(path) - ).then( - function(result) { - if (self._isSuccessStatus(result.status)) { - deferred.resolve(result.status); - } else { - deferred.reject(result.status); - } - } - ); - return promise; - }, - - /** - * Creates a directory - * - * @param {String} path path to create - * - * @return {Promise} - */ - createDirectory: function(path) { - return this._simpleCall('MKCOL', path); - }, - - /** - * Deletes a file or directory - * - * @param {String} path path to delete - * - * @return {Promise} - */ - remove: function(path) { - return this._simpleCall('DELETE', path); - }, - - /** - * Moves path to another path - * - * @param {String} path path to move - * @param {String} destinationPath destination path - * @param {boolean} [allowOverwrite=false] true to allow overwriting, - * false otherwise - * - * @return {Promise} promise - */ - move: function(path, destinationPath, allowOverwrite) { - if (!path) { - throw 'Missing argument "path"'; - } - if (!destinationPath) { - throw 'Missing argument "destinationPath"'; - } - - var self = this; - var deferred = $.Deferred(); - var promise = deferred.promise(); - var headers = { - 'Destination' : this._buildUrl(destinationPath) - }; - - if (!allowOverwrite) { - headers['Overwrite'] = 'F'; - } - - this._client.request( - 'MOVE', - this._buildUrl(path), - headers - ).then( - function(response) { - if (self._isSuccessStatus(response.status)) { - deferred.resolve(response.status); - } else { - deferred.reject(response.status); - } - } - ); - return promise; - }, - - /** - * Add a file info parser function - * - * @param {OC.Files.Client~parseFileInfo>} - */ - addFileInfoParser: function(parserFunction) { - this._fileInfoParsers.push(parserFunction); - } - - }; - - /** - * File info parser function - * - * This function receives a list of Webdav properties as input and - * should return a hash array of parsed properties, if applicable. - * - * @callback OC.Files.Client~parseFileInfo - * @param {Object} XML Webdav properties - * @return {Array} array of parsed property values - */ - - if (!OC.Files) { - /** - * @namespace OC.Files - * - * @since 8.2 - */ - OC.Files = {}; - } - - /** - * Returns the default instance of the files client - * - * @return {OC.Files.Client} default client - * - * @since 8.2 - */ - OC.Files.getClient = function() { - if (OC.Files._defaultClient) { - return OC.Files._defaultClient; - } - - var client = new OC.Files.Client({ - host: OC.getHost(), - port: OC.getPort(), - root: OC.linkToRemoteBase('webdav'), - useHTTPS: OC.getProtocol() === 'https' - }); - OC.Files._defaultClient = client; - return client; - }; - - OC.Files.Client = Client; -})(OC, OC.Files.FileInfo); - |