Skip to content

Commit

Permalink
Merge pull request #205 from prey/filebrowser-upload
Browse files Browse the repository at this point in the history
Filebrowser permissions
  • Loading branch information
javo committed May 31, 2016
2 parents e2f259c + 0268cfe commit 0f8a868
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 94 deletions.
123 changes: 39 additions & 84 deletions lib/agent/actions/fileretrieval/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,107 +13,62 @@ var fs = require('fs'),
common = require('./../../common'),
needle = require('needle'),
join = require('path').join,
api = require('./../../plugins/control-panel/api'),
files = require('./files_storage'),
EventEmitter = require('events').EventEmitter;
files = require('./storage'),
Emitter = require('events').EventEmitter;

var system = common.system,
config = common.config,
protocol = config._values['control-panel'].protocol,
host = config._values['control-panel'].host,
url = protocol + '://' + host,
node_bin = path.join(system.paths.current, 'bin', 'node'),
logger = common.logger,
os_name = process.platform.replace('darwin', 'mac').replace('win32', 'windows');
var system = common.system,
run_as_user = common.system.run_as_user,
node_bin = path.join(system.paths.current, 'bin', 'node'),
os_name = process.platform.replace('darwin', 'mac').replace('win32', 'windows'),
logger = common.logger;

var em,
cp;

var UPLOAD_SERVER = url + '/upload/upload',
RESUMABLE_HEADER = 'X-Prey-Upload-Resumable',
OPEN_TIMEOUT = 180000,
READ_TIMEOUT = 5000;
var path_arg,
name_arg;

// check_pending_files is used to resume any files that might been pending. It's called from
// filesagent/providers/network.
exports.check_pending_files = function() {
files.run_stored();
}

exports.start = function(options, cb) {
var file_path = options.path,
file_id = options.file_id,
file_size = parseInt(options.size),
user = options.user;

em = em || new EventEmitter();
if (cb) cb(null, em);

if (!options.resumable)
files.store(file_id, file_path, file_size, user);

var file = {
total: 0,
path: file_path,
user: user,
id: file_id,
size: file_size,
resumable: options.resumable
if (!options.resumable) {
options.resumable = false;
}

retrieve_file(file, function() {
files.del(file.id);
});
}

function retrieve_file(file, cb) {
if (file.resumable) {
var url = UPLOAD_SERVER + '?uploadID=' + file.id;
// Make a call to get the last byte processed by the upload server
// before the disconnection in order to resume the upload from that position
needle.request('get', url, null, function(err, res) {
if (err) return em.emit(err);
var data = JSON.parse(res.body);
file.total = data.Total;
get_file(file, cb);
})
return;
if (os_name == 'windows') {
path_arg = path.resolve(options.path);
name_arg = path.resolve(options.name);
} else {
path_arg = '"' + options.path + '"';
name_arg = '"' + options.name + '"';
}
get_file(file, cb);
}
var opts = {
user: options.user,
bin: node_bin,
type: 'exec',
args: [path.join(__dirname, 'upload.js'), path_arg, options.user, name_arg, options.size, options.file_id, options.resumable, options.port],
opts: {
env: process.env
}
};
em = em || new Emitter();

function get_file(file, cb) {
var buffsize = (file.size == 0) ? 1 : (file.size - file.total);
var buf = new Buffer(buffsize);
var fd = fs.openSync(file.path, "r");
files.store(options.file_id, options.path, options.size, options.user, options.name);

fs.read(fd, buf, 0, file.size - file.total, file.total, function(err, read, buf) {
if (err) return em.emit(err);
upload_file(file, buf, cb);
})
}

function upload_file(file, buf, cb) {
var options = {
open_timeout: OPEN_TIMEOUT,
read_timeout: READ_TIMEOUT
};

if (file.total > 0) {
RESUMABLE_HEADER = file.total;
}
var url = UPLOAD_SERVER + '?uploadID='+file.id;
needle.post(url, buf, options, function(err, res) {
run_as_user(opts, function(err, out) {
if (err) {
logger.error(err)
return em.emit(err);
logger.error("Upload error: " + err.message);
return;
}
logger.info("Ran as user: " + out);
if (out.indexOf("File succesfuly uploaded") != -1){
files.del(options.file_id);
}
var out = res.statusCode;
if (out !== 200 && out !== 201) {
var err = new Error('There was an error communicating with the server');
logger.error(err)
em.emit(err);
}
cb();
})
});
if (cb) cb(null, em);
em.emit('end');
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,22 @@ var exist = function(id, cb) {
var key = NAMESPACE + id;
storage.all(function(err, files) {
if (err)
return logger.error(err.message);
if (files[key])
return err.message;
if (files[key])
return cb(true);
return cb(false);
})
});
}

exports.store = function(id, path, size, user) {
exports.store = function(id, path, size, user, name) {
exist(id, function(cb) {
if (cb == false) {
logger.debug('Storing file_id in DB: ' + id);
var opts = {
path: path,
size: size,
user: user
user: user,
name: name
}
storage.set(NAMESPACE + id, opts);
}
Expand All @@ -49,18 +50,18 @@ exports.run_stored = function(cb) {
var count = Object.keys(files).length;
if (count <= 0)
return;

logger.warn('Re-uploading ' + count + ' pending files.');

for (key in files) {
if(key.indexOf(NAMESPACE) != 0) {
continue;
}
var opts = {
file_id: key.substring(3, key.length),
path: files[key].path,
user: files[key].user,
name: files[key].name,
size: files[key].size,
file_id: key.substring(3, key.length),
resumable: true
}
fileretrieval.start(opts, cb);
Expand Down
130 changes: 130 additions & 0 deletions lib/agent/actions/fileretrieval/upload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#!/usr/bin/env node

var fs = require('fs'),
path = require('path'),
mime = require('mime'),
common = require('./../../common'),
needle = require('needle');

var config = common.config,
protocol = config._values['control-panel'].protocol,
host = config._values['control-panel'].host,
url = protocol + '://' + host;

var UPLOAD_SERVER = url + '/upload/upload',
RESUMABLE_HEADER = 'X-Prey-Upload-Resumable',
OPEN_TIMEOUT = 180000,
READ_TIMEOUT = 2000;

var PATH = 2,
USER = 3,
NAME = 4,
SIZE = 5,
FILE_ID = 6,
RESUME = 7,
PORT = 8;

function main() {
var argv = process.argv;
var options = {
path: argv[PATH],
user: argv[USER],
name: argv[NAME],
size: argv[SIZE],
file_id: argv[FILE_ID],
resumable : argv[RESUME],
port: argv[PORT]
}
Main(options, function(err) {
if (err) {
console.error(err);
return;
}
});
}

function Main(options, cb) {
var file_path = options.path,
file_id = options.file_id,
file_size = parseInt(options.size),
file_name = options.name,
user = options.user;

console.log("Uploading file: ", file_path, file_id);

var file = {
total: 0,
path: file_path,
user: user,
id: file_id,
size: file_size,
resumable: options.resumable
}
retrieve_file(file, cb);
}

function retrieve_file(file, cb) {
if (file.resumable == 'true') {
console.log("Resumable file:", file.id);
var url = UPLOAD_SERVER + '?uploadID=' + file.id;
// Make a call to get the last byte processed by the upload server
// in order to resume the upload from that position.
needle.request('get', url, null, function(err, res) {
if (err) {
console.log(err);
cb(err);
return;
}
var data = JSON.parse(res.body);

file.total = data.Total;
get_file(file, cb);
})
return;
}
get_file(file, cb);
}

function get_file(file, cb) {
var buffsize = (file.size == 0) ? 1 : (file.size - file.total);
var buf = new Buffer(buffsize);
var fd = fs.openSync(file.path, "r");

fs.read(fd, buf, 0, file.size - file.total, file.total, function(err, read, buf) {
if (err) {
cb(err);
return;
}
upload_file(file, buf, cb);
})
}

function upload_file(file, buf, cb) {
var options = {
open_timeout: OPEN_TIMEOUT,
read_timeout: READ_TIMEOUT
}

if (file.total > 0) {
RESUMABLE_HEADER = file.total;
}
var url = UPLOAD_SERVER + '?uploadID=' + file.id;

needle.post(url, buf, options, function(err, res) {
if (err) {
console.log(err);
cb(err);
return;
}
var out = res.statusCode;
if (out !== 200 && out !== 201) {
var err = new Error('There was an error communicating with the server');
cb(err);
return;
}
console.log("File succesfuly uploaded:", file.id);
cb(null); // delete files
})
}

main();
2 changes: 1 addition & 1 deletion lib/agent/plugins/control-panel/api/push.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ exports.data = function(data, opts, cb) {

exports.report = function(data, opts, cb) {
check_keys();
var url = format_url(reports);
var url = format_url('reports');
post(url, data, opts, cb);
}

Expand Down
4 changes: 2 additions & 2 deletions lib/agent/providers/files/tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@

var fs = require('fs'),
path = require('path'),
mime = require('mime'),
winattr = require('winattr');
mime = require('mime');

var argv = process.argv,
p = argv[3],
Expand Down Expand Up @@ -110,6 +109,7 @@ directoryTreeToObj(p, cd, d, function(err, res) {

var checkIfHiddenFile = function(path, name, cb){
if (os_name == "windows") {
winattr = require('winattr');
winattr.get(path, function(err, attrs){
if (err)
return cb(false);
Expand Down

0 comments on commit 0f8a868

Please sign in to comment.