Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@
"ua-parser-js": "^0.7.18",
"underscore": "^1.9.1",
"underscore.string": "^3.3.4",
"webdav": "^1.5.2",
"wolfy87-eventemitter": "^5.2.4",
"xml-crypto": "^0.10.1",
"xml2js": "^0.4.19",
Expand Down
62 changes: 62 additions & 0 deletions packages/rocketchat-file-upload/server/config/Webdav.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* globals FileUpload */

import _ from 'underscore';
import { FileUploadClass } from '../lib/FileUpload';
import '../../ufs/Webdav/server.js';

const get = function(file, req, res) {
this.store.getReadStream(file._id, file).pipe(res);
};

const copy = function(file, out) {
this.store.getReadStream(file._id, file).pipe(out);
};

const WebdavUploads = new FileUploadClass({
name: 'Webdav:Uploads',
get,
copy
// store setted bellow
});

const WebdavAvatars = new FileUploadClass({
name: 'Webdav:Avatars',
get,
copy
// store setted bellow
});

const WebdavUserDataFiles = new FileUploadClass({
name: 'Webdav:UserDataFiles',
get,
copy
// store setted bellow
});

const configure = _.debounce(function() {
const uploadFolderPath = RocketChat.settings.get('FileUpload_Webdav_Upload_Folder_Path');
const server = RocketChat.settings.get('FileUpload_Webdav_Server_URL');
const username = RocketChat.settings.get('FileUpload_Webdav_Username');
const password = RocketChat.settings.get('FileUpload_Webdav_Password');

if (!server || !username || !password) {
return;
}

const config = {
connection: {
credentials: {
server,
username,
password
}
},
uploadFolderPath
};

WebdavUploads.store = FileUpload.configureUploadsStore('Webdav', WebdavUploads.name, config);
WebdavAvatars.store = FileUpload.configureUploadsStore('Webdav', WebdavAvatars.name, config);
WebdavUserDataFiles.store = FileUpload.configureUploadsStore('Webdav', WebdavUserDataFiles.name, config);
}, 500);

RocketChat.settings.get(/^FileUpload_Webdav_/, configure);
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import './AmazonS3.js';
import './FileSystem.js';
import './GoogleStorage.js';
import './GridFS.js';
import './Webdav.js';
import './Slingshot_DEPRECATED.js';

const configStore = _.debounce(() => {
Expand Down
49 changes: 49 additions & 0 deletions packages/rocketchat-file-upload/server/startup/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ RocketChat.settings.addGroup('FileUpload', function() {
}, {
key: 'GoogleCloudStorage',
i18nLabel: 'GoogleCloudStorage'
}, {
key: 'Webdav',
i18nLabel: 'WebDAV'
}, {
key: 'FileSystem',
i18nLabel: 'FileSystem'
Expand Down Expand Up @@ -180,6 +183,52 @@ RocketChat.settings.addGroup('FileUpload', function() {
});
});

this.section('WebDAV', function() {
this.add('FileUpload_Webdav_Upload_Folder_Path', '', {
type: 'string',
enableQuery: {
_id: 'FileUpload_Storage_Type',
value: 'Webdav'
}
});
this.add('FileUpload_Webdav_Server_URL', '', {
type: 'string',
enableQuery: {
_id: 'FileUpload_Storage_Type',
value: 'Webdav'
}
});
this.add('FileUpload_Webdav_Username', '', {
type: 'string',
enableQuery: {
_id: 'FileUpload_Storage_Type',
value: 'Webdav'
}
});
this.add('FileUpload_Webdav_Password', '', {
type: 'password',
private: true,
enableQuery: {
_id: 'FileUpload_Storage_Type',
value: 'Webdav'
}
});
this.add('FileUpload_Webdav_Proxy_Avatars', false, {
type: 'boolean',
enableQuery: {
_id: 'FileUpload_Storage_Type',
value: 'Webdav'
}
});
this.add('FileUpload_Webdav_Proxy_Uploads', false, {
type: 'boolean',
enableQuery: {
_id: 'FileUpload_Storage_Type',
value: 'Webdav'
}
});
});

this.add('FileUpload_Enabled_Direct', true, {
type: 'boolean',
public: true
Expand Down
6 changes: 6 additions & 0 deletions packages/rocketchat-file-upload/ufs/Webdav/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import {UploadFS} from 'meteor/jalik:ufs';

export class WebdavStore extends UploadFS.Store {}

// Add store to UFS namespace
UploadFS.store.Webdav = WebdavStore;
135 changes: 135 additions & 0 deletions packages/rocketchat-file-upload/ufs/Webdav/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import {UploadFS} from 'meteor/jalik:ufs';
import Webdav from 'webdav';
import stream from 'stream';
/**
* WebDAV store
* @param options
* @constructor
*/
export class WebdavStore extends UploadFS.Store {

constructor(options) {

super(options);


const client = new Webdav(
options.connection.credentials.server,
options.connection.credentials.username,
options.connection.credentials.password,
);

options.getPath = function(file) {
if (options.uploadFolderPath[options.uploadFolderPath.length-1] !== '/') {
options.uploadFolderPath += '/';
}
return options.uploadFolderPath + file._id;
};

client.stat(options.uploadFolderPath).catch(function(err) {
if (err.status === '404') {
client.createDirectory(options.uploadFolderPath);
}
});

/**
* Returns the file path
* @param file
* @return {string}
*/
this.getPath = function(file) {
if (file.Webdav) {
return file.Webdav.path;
}
};

/**
* Creates the file in the col lection
* @param file
* @param callback
* @return {string}
*/
this.create = function(file, callback) {
check(file, Object);

if (file._id == null) {
file._id = Random.id();
}

file.Webdav = {
path: options.getPath(file)
};

file.store = this.options.name;
return this.getCollection().insert(file, callback);
};

/**
* Removes the file
* @param fileId
* @param callback
*/
this.delete = function(fileId, callback) {
const file = this.getCollection().findOne({_id: fileId});
client.deleteFile(this.getPath(file), (err, data) => {
if (err) {
console.error(err);
}

callback && callback(err, data);
});
};

/**
* Returns the file read stream
* @param fileId
* @param file
* @param options
* @return {*}
*/
this.getReadStream = function(fileId, file, options = {}) {
const range = {};

if (options.start != null) {
range.start = options.start;
}

if (options.end != null) {
range.end = options.end;
}
return client.createReadStream(this.getPath(file), options);
};

/**
* Returns the file write stream
* @param fileId
* @param file
* @return {*}
*/
this.getWriteStream = function(fileId, file) {
const writeStream = new stream.PassThrough();
const webdavStream = client.createWriteStream(this.getPath(file));

//TODO remove timeout when UploadFS bug resolved
const newListenerCallback = (event, listener) => {
if (event === 'finish') {
process.nextTick(() => {
writeStream.removeListener(event, listener);
writeStream.removeListener('newListener', newListenerCallback);
writeStream.on(event, function() {
setTimeout(listener, 500);
});
});
}
};
writeStream.on('newListener', newListenerCallback);

writeStream.pipe(webdavStream);
return writeStream;
};

}
}

// Add store to UFS namespace
UploadFS.store.Webdav = WebdavStore;
9 changes: 9 additions & 0 deletions packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,15 @@
"FileUpload_S3_URLExpiryTimeSpan": "URLs Expiration Timespan",
"FileUpload_S3_URLExpiryTimeSpan_Description": "Time after which Amazon S3 generated URLs will no longer be valid (in seconds). If set to less than 5 seconds, this field will be ignored.",
"FileUpload_Storage_Type": "Storage Type",
"FileUpload_Webdav_Upload_Folder_Path": "Upload Folder Path",
"FileUpload_Webdav_Upload_Folder_Path_Description": "WebDAV folder path which the files should be uploaded to",
"FileUpload_Webdav_Server_URL": "WebDAV Server Access URL",
"FileUpload_Webdav_Username": "WebDAV Username",
"FileUpload_Webdav_Password": "WebDAV Password",
"FileUpload_Webdav_Proxy_Avatars": "Proxy Avatars",
"FileUpload_Webdav_Proxy_Avatars_Description": "Proxy avatar file transmissions through your server instead of direct access to the asset's URL",
"FileUpload_Webdav_Proxy_Uploads": "Proxy Uploads",
"FileUpload_Webdav_Proxy_Uploads_Description": "Proxy upload file transmissions through your server instead of direct access to the asset's URL",
"Financial_Services": "Financial Services",
"First_Channel_After_Login": "First Channel After Login",
"Flags": "Flags",
Expand Down