Merge pull request #1523 from ether/store-sessions-in-db

Store sessions in db
This commit is contained in:
John McLear 2013-02-26 18:03:54 -08:00
commit 18b6cf1534
8 changed files with 111 additions and 16 deletions

View File

@ -15,6 +15,10 @@
"ip": "0.0.0.0",
"port" : 9001,
// Session Key, used for reconnecting user sessions
// Set this to a secure string at least 10 characters long. Do not share this value.
"sessionKey" : "",
/*
// Node native SSL support
// this is disabled by default

View File

@ -253,9 +253,7 @@ exports.getHTML = function(padID, rev, callback)
exportHtml.getPadHTML(pad, undefined, function (err, html)
{
if(ERR(err, callback)) return;
data = {html: html};
callback(null, data);
});
}

View File

@ -1,5 +1,5 @@
/**
* The Session Manager provides functions to manage session in the database
* The Session Manager provides functions to manage session in the database, it only provides session management for sessions created by the API
*/
/*

View File

@ -0,0 +1,82 @@
/*
* Stores session data in the database
* Source; https://github.com/edy-b/SciFlowWriter/blob/develop/available_plugins/ep_sciflowwriter/db/DirtyStore.js
* This is not used for authors that are created via the API at current
*/
var Store = require('ep_etherpad-lite/node_modules/connect/lib/middleware/session/store'),
utils = require('ep_etherpad-lite/node_modules/connect/lib/utils'),
Session = require('ep_etherpad-lite/node_modules/connect/lib/middleware/session/session'),
db = require('ep_etherpad-lite/node/db/DB').db,
log4js = require('ep_etherpad-lite/node_modules/log4js'),
messageLogger = log4js.getLogger("SessionStore");
var SessionStore = module.exports = function SessionStore() {};
SessionStore.prototype.__proto__ = Store.prototype;
SessionStore.prototype.get = function(sid, fn){
messageLogger.debug('GET ' + sid);
var self = this;
db.get("sessionstorage:" + sid, function (err, sess)
{
if (sess) {
sess.cookie.expires = 'string' == typeof sess.cookie.expires ? new Date(sess.cookie.expires) : sess.cookie.expires;
if (!sess.cookie.expires || new Date() < expires) {
fn(null, sess);
} else {
self.destroy(sid, fn);
}
} else {
fn();
}
});
};
SessionStore.prototype.set = function(sid, sess, fn){
messageLogger.debug('SET ' + sid);
db.set("sessionstorage:" + sid, sess);
process.nextTick(function(){
if(fn) fn();
});
};
SessionStore.prototype.destroy = function(sid, fn){
messageLogger.debug('DESTROY ' + sid);
db.remove("sessionstorage:" + sid);
process.nextTick(function(){
if(fn) fn();
});
};
SessionStore.prototype.all = function(fn){
messageLogger.debug('ALL');
var sessions = [];
db.forEach(function(key, value){
if (key.substr(0,15) === "sessionstorage:") {
sessions.push(value);
}
});
fn(null, sessions);
};
SessionStore.prototype.clear = function(fn){
messageLogger.debug('CLEAR');
db.forEach(function(key, value){
if (key.substr(0,15) === "sessionstorage:") {
db.db.remove("session:" + key);
}
});
if(fn) fn();
};
SessionStore.prototype.length = function(fn){
messageLogger.debug('LENGTH');
var i = 0;
db.forEach(function(key, value){
if (key.substr(0,15) === "sessionstorage:") {
i++;
}
});
fn(null, i);
};

View File

@ -928,6 +928,8 @@ function handleClientReady(client, message)
//If this is a reconnect, we don't have to send the client the ClientVars again
if(message.reconnect == true)
{
//Join the pad and start receiving updates
client.join(padIds.padId);
//Save the revision in sessioninfos, we take the revision from the info the client send to us
sessioninfos[client.id].rev = message.client_rev;
}

View File

@ -4,7 +4,7 @@ var httpLogger = log4js.getLogger("http");
var settings = require('../../utils/Settings');
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
var ueberStore = require('../../db/SessionStore');
//checks for basic http auth
exports.basicAuth = function (req, res, next) {
@ -102,15 +102,14 @@ exports.expressConfigure = function (hook_name, args, cb) {
* handling it cleaner :) */
if (!exports.sessionStore) {
exports.sessionStore = new express.session.MemoryStore();
exports.secret = randomString(32);
exports.sessionStore = new ueberStore();
exports.secret = settings.sessionKey; // Isn't this being reset each time the server spawns?
}
args.app.use(express.cookieParser(exports.secret));
args.app.use(express.cookieParser(exports.secret));
args.app.sessionStore = exports.sessionStore;
args.app.use(express.session({store: args.app.sessionStore,
key: 'express_sid' }));
args.app.use(express.session({secret: exports.secret, store: args.app.sessionStore, key: 'express_sid' }));
args.app.use(exports.basicAuth);
}

View File

@ -26,6 +26,8 @@ var argv = require('./Cli').argv;
var npm = require("npm/lib/npm.js");
var vm = require('vm');
var log4js = require("log4js");
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
/* Root path of the installation */
exports.root = path.normalize(path.join(npm.dir, ".."));
@ -112,6 +114,11 @@ exports.loglevel = "INFO";
*/
exports.logconfig = { appenders: [{ type: "console" }]};
/*
* Session Key, do not sure this.
*/
exports.sessionKey = false;
/* This setting is used if you need authentication and/or
* authorization. Note: /admin always requires authentication, and
* either authorization by a module, or a user with is_admin set */
@ -132,8 +139,6 @@ exports.abiwordAvailable = function()
}
}
exports.reloadSettings = function reloadSettings() {
// Discover where the settings file lives
var settingsFilename = argv.settings || "settings.json";
@ -184,6 +189,11 @@ exports.reloadSettings = function reloadSettings() {
log4js.setGlobalLogLevel(exports.loglevel);//set loglevel
log4js.replaceConsole();
if(!exports.sessionKey){ // If the secretKey isn't set we also create yet another unique value here
exports.sessionKey = randomString(32);
console.warn("You need to set a sessionKey value in settings.json, this will allow your users to reconnect to your Etherpad Instance if your instance restarts");
}
if(exports.dbType === "dirty"){
console.warn("DirtyDB is used. This is fine for testing but not recommended for production.")
}

View File

@ -43,9 +43,8 @@ var padconnectionstatus = (function()
status = {
what: 'connected'
};
padmodals.showModal('connected');
padmodals.hideOverlay(500);
padmodals.hideOverlay();
},
reconnecting: function()
{
@ -54,7 +53,7 @@ var padconnectionstatus = (function()
};
padmodals.showModal('reconnecting');
padmodals.showOverlay(500);
padmodals.showOverlay();
},
disconnected: function(msg)
{
@ -73,10 +72,11 @@ var padconnectionstatus = (function()
}
padmodals.showModal(k);
padmodals.showOverlay(500);
padmodals.showOverlay();
},
isFullyConnected: function()
{
padmodals.hideOverlay();
return status.what == 'connected';
},
getStatus: function()