1
0
Fork 0
mirror of https://github.com/seejohnrun/haste-server.git synced 2024-11-25 05:51:22 +00:00

Added remove route

Signed-off-by: Defman21 <i@defman.me>
This commit is contained in:
Defman21 2016-07-21 23:03:33 +03:00
parent 0209375865
commit eb0f868f75
No known key found for this signature in database
GPG key ID: AF04C6EC908CFF53
6 changed files with 141 additions and 10 deletions

View file

@ -47,6 +47,20 @@ DocumentHandler.prototype.handleRawGet = function(key, response, skipExpire) {
}, skipExpire); }, skipExpire);
}; };
DocumentHandler.prototype.handleDelete = function (key, secret, response) {
this.store.remove(key, secret, function (ret) {
if (ret) {
winston.verbose('removed document', { key: key });
response.writeHead(200, { 'content-type': 'application/json' });
response.end(JSON.stringify({ message: "Removed document " + key }));
} else {
winston.warn('invalid secret or document not found', { key: key, secret: secret });
response.writeHead(404, { 'content-type': 'application/json' });
response.end(JSON.stringify({ message: 'Document not found.' }));
}
});
};
// Handle adding a new Document // Handle adding a new Document
DocumentHandler.prototype.handlePost = function (request, response) { DocumentHandler.prototype.handlePost = function (request, response) {
var _this = this; var _this = this;
@ -67,11 +81,11 @@ DocumentHandler.prototype.handlePost = function (request, response) {
} }
// And then save if we should // And then save if we should
_this.chooseKey(function (key) { _this.chooseKey(function (key) {
_this.store.set(key, buffer, function (res) { _this.store.set(key, buffer, function (res, secret) {
if (res) { if (res) {
winston.verbose('added document', { key: key }); winston.verbose('added document', { key: key, secret: secret });
response.writeHead(200, { 'content-type': 'application/json' }); response.writeHead(200, { 'content-type': 'application/json' });
response.end(JSON.stringify({ key: key })); response.end(JSON.stringify({ key: key, secret: secret }));
} }
else { else {
winston.verbose('error adding document'); winston.verbose('error adding document');

View file

@ -12,6 +12,11 @@ var FileDocumentStore = function(options) {
this.expire = options.expire; this.expire = options.expire;
}; };
// Generate secret (10 chars)
FileDocumentStore.secret = function() {
return Math.random().toString(24).slice(-10);
};
// Generate md5 of a string // Generate md5 of a string
FileDocumentStore.md5 = function(str) { FileDocumentStore.md5 = function(str) {
var md5sum = crypto.createHash('md5'); var md5sum = crypto.createHash('md5');
@ -25,13 +30,17 @@ FileDocumentStore.prototype.set = function(key, data, callback, skipExpire) {
try { try {
var _this = this; var _this = this;
fs.mkdir(this.basePath, '700', function() { fs.mkdir(this.basePath, '700', function() {
var sc = FileDocumentStore.secret();
var fn = _this.basePath + '/' + FileDocumentStore.md5(key); var fn = _this.basePath + '/' + FileDocumentStore.md5(key);
var sfn = fn + "-" + sc;
fs.writeFile(fn, data, 'utf8', function(err) { fs.writeFile(fn, data, 'utf8', function(err) {
if (err) { if (err) {
callback(false); callback(false);
} }
else { else {
callback(true); fs.writeFile(sfn, "A validation file for " + fn, 'utf8', function (err) {
if (!err) callback(true, sc);
});
if (_this.expire && !skipExpire) { if (_this.expire && !skipExpire) {
winston.warn('file store cannot set expirations on keys'); winston.warn('file store cannot set expirations on keys');
} }
@ -43,6 +52,27 @@ FileDocumentStore.prototype.set = function(key, data, callback, skipExpire) {
} }
}; };
FileDocumentStore.prototype.remove = function(str, key, callback) {
var file = FileDocumentStore.md5(str);
var kfn = key;
fs.exists(this.basePath + "/" + file + "-" + kfn, function(exists) {
if (exists) {
try {
fs.unlink(this.basePath + "/" + file, function() {
fs.unlink(this.basePath + "/" + file + "-" + kfn, function() {
callback(true);
});
});
} catch(err) {
callback(false);
}
}
else {
callback(false);
}
});
};
// Get data from a file from key // Get data from a file from key
FileDocumentStore.prototype.get = function(key, callback, skipExpire) { FileDocumentStore.prototype.get = function(key, callback, skipExpire) {
var _this = this; var _this = this;

View file

@ -8,7 +8,9 @@ var MemcachedDocumentStore = function(options) {
MemcachedDocumentStore.connect(options); MemcachedDocumentStore.connect(options);
} }
}; };
MemcachedDocumentStore.secret = function() {
return Math.random().toString(24).slice(-10);
};
// Create a connection // Create a connection
MemcachedDocumentStore.connect = function(options) { MemcachedDocumentStore.connect = function(options) {
var host = options.host || '127.0.0.1'; var host = options.host || '127.0.0.1';
@ -27,7 +29,17 @@ MemcachedDocumentStore.connect = function(options) {
MemcachedDocumentStore.prototype.set = MemcachedDocumentStore.prototype.set =
function(key, data, callback, skipExpire) { function(key, data, callback, skipExpire) {
MemcachedDocumentStore.client.set(key, data, function(err, reply) { MemcachedDocumentStore.client.set(key, data, function(err, reply) {
err ? callback(false) : callback(true); if (!err) {
var sc = MemcachedDocumentStore.secret();
MemcachedDocumentStore.client.set(key + "-" + sc, "", function(err, reply) {
if (!err) {
callback(true, sc);
}
});
}
else {
callback(false);
}
}, skipExpire ? 0 : this.expire); }, skipExpire ? 0 : this.expire);
}; };
@ -42,4 +54,21 @@ MemcachedDocumentStore.prototype.get = function(key, callback, skipExpire) {
}); });
}; };
MemcachedDocumentStore.prototype.remove = function(key, secret, callback) {
MemcachedDocumentStore.client.get(key + "-" + secret, function(err, reply) {
if (!err) {
MemcachedDocumentStore.client.del(key, function(err, reply) {
if (err) return callback(false);
MemcachedDocumentStore.client.del(key + "-" + secret, function(err, reply) {
if (err) return callback(false);
callback(reply);
});
});
}
else {
callback(false);
}
});
};
module.exports = MemcachedDocumentStore; module.exports = MemcachedDocumentStore;

View file

@ -9,6 +9,7 @@ var winston = require('winston');
var PostgresDocumentStore = function (options) { var PostgresDocumentStore = function (options) {
this.expireJS = options.expire; this.expireJS = options.expire;
this.connectionUrl = process.env.DATABASE_URL || options.connectionUrl; this.connectionUrl = process.env.DATABASE_URL || options.connectionUrl;
this.secret = () => Math.random().toString(24).slice(-10);
}; };
PostgresDocumentStore.prototype = { PostgresDocumentStore.prototype = {
@ -19,16 +20,18 @@ PostgresDocumentStore.prototype = {
var that = this; var that = this;
this.safeConnect(function (err, client, done) { this.safeConnect(function (err, client, done) {
if (err) { return callback(false); } if (err) { return callback(false); }
client.query('INSERT INTO entries (key, value, expiration) VALUES ($1, $2, $3)', [ var sc = that.secret();
client.query('INSERT INTO entries (key, value, expiration, secret) VALUES ($1, $2, $3, $4)', [
key, key,
data, data,
that.expireJS && !skipExpire ? that.expireJS + now : null that.expireJS && !skipExpire ? that.expireJS + now : null,
sc
], function (err, result) { ], function (err, result) {
if (err) { if (err) {
winston.error('error persisting value to postgres', { error: err }); winston.error('error persisting value to postgres', { error: err });
return callback(false); return callback(false);
} }
callback(true); callback(true, sc);
done(); done();
}); });
}); });
@ -61,6 +64,32 @@ PostgresDocumentStore.prototype = {
}); });
}); });
}, },
remove: function (key, secret, callback) {
var now = Math.floor(new Date().getTime() / 1000);
this.safeConnect(function (err, client, done) {
if (err) { return callback(false); }
client.query('SELECT id,value,expiration,secret from entries where KEY = $1 and (expiration IS NULL or expiration > $2)', [key, now], function (err, result) {
if (err) {
winston.error('error retrieving value from postgres', { error: err });
return callback(false);
}
if (result.rows[0].secret == secret) {
client.query("DELETE FROM entries where KEY = $1", [key], function (err, result) {
if (err) {
winston.error('error removing an item from postgres', { error: err });
return callback(false);
}
else {
callback(true);
done();
}
});
}
done();
});
});
},
// A connection wrapper // A connection wrapper
safeConnect: function (callback) { safeConnect: function (callback) {

View file

@ -43,6 +43,11 @@ RedisDocumentStore.connect = function(options) {
}); });
}; };
// Generate secret (10 chars)
RedisDocumentStore.secret = function() {
return Math.random().toString(24).slice(-10);
};
// Save file in a key // Save file in a key
RedisDocumentStore.prototype.set = function(key, data, callback, skipExpire) { RedisDocumentStore.prototype.set = function(key, data, callback, skipExpire) {
var _this = this; var _this = this;
@ -54,7 +59,11 @@ RedisDocumentStore.prototype.set = function(key, data, callback, skipExpire) {
if (!skipExpire) { if (!skipExpire) {
_this.setExpiration(key); _this.setExpiration(key);
} }
callback(true); var sc = RedisDocumentStore.secret();
RedisDocumentStore.client.set(key + '-' + sc, "", function(err, reply) {
if (err) return callback(false);
callback(true, sc);
});
} }
}); });
}; };
@ -81,4 +90,21 @@ RedisDocumentStore.prototype.get = function(key, callback, skipExpire) {
}); });
}; };
RedisDocumentStore.prototype.remove = function(key, secret, callback) {
RedisDocumentStore.client.get(key + "-" + secret, function(err, reply) {
if (!err) {
RedisDocumentStore.client.del(key, function(err, reply) {
if (err) return callback(false);
RedisDocumentStore.client.del(key + "-" + secret, function(err, reply) {
if (err) return callback(false);
callback(reply);
});
});
}
else {
callback(false);
}
});
};
module.exports = RedisDocumentStore; module.exports = RedisDocumentStore;

View file

@ -131,6 +131,9 @@ app.use(route(function(router) {
skipExpire skipExpire
); );
}); });
router.get('/documents/:id/remove/:secret', function(request, response, next) {
return documentHandler.handleDelete(request.params.id, request.params.secret, response);
});
})); }));
// Otherwise, try to match static files // Otherwise, try to match static files