From 9850ba43ee5a41a3383e6eebc8b9be756e80b9ad Mon Sep 17 00:00:00 2001 From: Jordan Date: Mon, 21 Nov 2011 01:45:37 -0500 Subject: [PATCH 1/5] Implement a 'requireSession' mode, which requires any user to have a valid session --- node/db/SecurityManager.js | 35 ++++++++++++++++++++++++---------- node/server.js | 18 +++++++++++------ node/utils/Settings.js | 6 ++++++ settings.json.template | 3 +++ settings.json.template_windows | 3 +++ 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/node/db/SecurityManager.js b/node/db/SecurityManager.js index 7ad8f8d25..762931da0 100644 --- a/node/db/SecurityManager.js +++ b/node/db/SecurityManager.js @@ -23,6 +23,7 @@ var async = require("async"); var authorManager = require("./AuthorManager"); var padManager = require("./PadManager"); var sessionManager = require("./SessionManager"); +var settings = require("../utils/Settings") /** * This function controlls the access to a pad, it checks if the user can access a pad. @@ -34,18 +35,32 @@ var sessionManager = require("./SessionManager"); */ exports.checkAccess = function (padID, sessionID, token, password, callback) { - // it's not a group pad, means we can grant access - if(padID.indexOf("$") == -1) + // a valid session is required (api-only mode) + if(settings.requireSession) { - //get author for this token - authorManager.getAuthor4Token(token, function(err, author) + // no sessionID, access is denied + if(!sessionID) { - // grant access, with author of token - callback(err, {accessStatus: "grant", authorID: author}); - }) - - //don't continue - return; + callback(null, {accessStatus: "deny"}); + return; + } + } + // a session is not required, so we'll check if it's a public pad + else + { + // it's not a group pad, means we can grant access + if(padID.indexOf("$") == -1) + { + //get author for this token + authorManager.getAuthor4Token(token, function(err, author) + { + // grant access, with author of token + callback(err, {accessStatus: "grant", authorID: author}); + }) + + //don't continue + return; + } } var groupID = padID.split("$")[0]; diff --git a/node/server.js b/node/server.js index 1e0b6283c..fe3c40da4 100644 --- a/node/server.js +++ b/node/server.js @@ -210,9 +210,12 @@ async.waterfall([ return; } - res.header("Server", serverName); - var filePath = path.normalize(__dirname + "/../static/pad.html"); - res.sendfile(filePath, { maxAge: exports.maxAge }); + hasPadAccess(req, res, function() + { + res.header("Server", serverName); + var filePath = path.normalize(__dirname + "/../static/pad.html"); + res.sendfile(filePath, { maxAge: exports.maxAge }); + }); }); //serve timeslider.html under /p/$padname/timeslider @@ -225,9 +228,12 @@ async.waterfall([ return; } - res.header("Server", serverName); - var filePath = path.normalize(__dirname + "/../static/timeslider.html"); - res.sendfile(filePath, { maxAge: exports.maxAge }); + hasPadAccess(req, res, function() + { + res.header("Server", serverName); + var filePath = path.normalize(__dirname + "/../static/timeslider.html"); + res.sendfile(filePath, { maxAge: exports.maxAge }); + }); }); //serve timeslider.html under /p/$padname/timeslider diff --git a/node/utils/Settings.js b/node/utils/Settings.js index 1d855a53d..9f23d114c 100644 --- a/node/utils/Settings.js +++ b/node/utils/Settings.js @@ -42,6 +42,12 @@ exports.dbSettings = { "filename" : "../var/dirty.db" }; * The default Text of a new pad */ exports.defaultPadText = "Welcome to Etherpad Lite!\n\nThis pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!\n\nEtherpad Lite on Github: http:\/\/j.mp/ep-lite\n"; + +/** + * A flag that requires any user to have a valid session (via the api) before accessing a pad + */ +exports.requireSession = false; + /** * A flag that shows if minification is enabled or not */ diff --git a/settings.json.template b/settings.json.template index 199ac6d0b..f2d375c64 100644 --- a/settings.json.template +++ b/settings.json.template @@ -29,6 +29,9 @@ //the default text of a pad "defaultPadText" : "Welcome to Etherpad Lite!\n\nThis pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!\n\nEtherpad Lite on Github: http:\/\/j.mp/ep-lite\n", + /* Users must have a session to access pads. This effectively locks etherpad down to using only the API. */ + "requireSession" : false, + /* if true, all css & js will be minified before sending to the client. This will improve the loading performance massivly, but makes it impossible to debug the javascript/css */ "minify" : true, diff --git a/settings.json.template_windows b/settings.json.template_windows index 235ec71a3..560e62be9 100644 --- a/settings.json.template_windows +++ b/settings.json.template_windows @@ -28,6 +28,9 @@ //the default text of a pad "defaultPadText" : "Welcome to Etherpad Lite!\n\nThis pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!\n\nEtherpad Lite on Github: http:\/\/j.mp/ep-lite\n", + /* Users must have a session to access pads. This effectively locks etherpad down to using only the API. */ + "requireSession" : false, + /* if true, all css & js will be minified before sending to the client. This will improve the loading performance massivly, but makes it impossible to debug the javascript/css */ "minify" : false, From 5630889fb098d1289986a807f872e034836b066b Mon Sep 17 00:00:00 2001 From: Jordan Date: Mon, 21 Nov 2011 11:54:29 -0500 Subject: [PATCH 2/5] A more precise description of the requireSession setting --- settings.json.template | 2 +- settings.json.template_windows | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/settings.json.template b/settings.json.template index f2d375c64..5c0dffdaa 100644 --- a/settings.json.template +++ b/settings.json.template @@ -29,7 +29,7 @@ //the default text of a pad "defaultPadText" : "Welcome to Etherpad Lite!\n\nThis pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!\n\nEtherpad Lite on Github: http:\/\/j.mp/ep-lite\n", - /* Users must have a session to access pads. This effectively locks etherpad down to using only the API. */ + /* Users must have a session to access pads. This effectively allows only group pads to be accessed. */ "requireSession" : false, /* if true, all css & js will be minified before sending to the client. This will improve the loading performance massivly, diff --git a/settings.json.template_windows b/settings.json.template_windows index 560e62be9..d6f9ef14f 100644 --- a/settings.json.template_windows +++ b/settings.json.template_windows @@ -28,7 +28,7 @@ //the default text of a pad "defaultPadText" : "Welcome to Etherpad Lite!\n\nThis pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!\n\nEtherpad Lite on Github: http:\/\/j.mp/ep-lite\n", - /* Users must have a session to access pads. This effectively locks etherpad down to using only the API. */ + /* Users must have a session to access pads. This effectively allows only group pads to be accessed. */ "requireSession" : false, /* if true, all css & js will be minified before sending to the client. This will improve the loading performance massivly, From 5e7c5d5dd3048054e94021f10c284e71896dcb44 Mon Sep 17 00:00:00 2001 From: Jordan Date: Mon, 21 Nov 2011 12:44:33 -0500 Subject: [PATCH 3/5] Add editOnly option --- node/db/SecurityManager.js | 28 ++++++++++++++++++++++++---- node/utils/Settings.js | 5 +++++ settings.json.template | 3 +++ settings.json.template_windows | 3 +++ 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/node/db/SecurityManager.js b/node/db/SecurityManager.js index 762931da0..0f35d8735 100644 --- a/node/db/SecurityManager.js +++ b/node/db/SecurityManager.js @@ -35,6 +35,8 @@ var settings = require("../utils/Settings") */ exports.checkAccess = function (padID, sessionID, token, password, callback) { + var statusObject; + // a valid session is required (api-only mode) if(settings.requireSession) { @@ -54,8 +56,26 @@ exports.checkAccess = function (padID, sessionID, token, password, callback) //get author for this token authorManager.getAuthor4Token(token, function(err, author) { - // grant access, with author of token - callback(err, {accessStatus: "grant", authorID: author}); + // assume user has access + statusObject = {accessStatus: "grant", authorID: author}; + // user can't create pads + if(settings.editOnly) + { + // check if pad exists + padManager.doesPadExists(padID, function(err, exists) + { + // pad doesn't exist - user can't have access + if(!exists) statusObject.accessStatus = "deny"; + // grant or deny access, with author of token + callback(err, statusObject); + }); + } + // user may create new pads - no need to check anything + else + { + // grant access, with author of token + callback(err, statusObject); + } }) //don't continue @@ -72,8 +92,6 @@ exports.checkAccess = function (padID, sessionID, token, password, callback) var isPasswordProtected; var passwordStatus = password == null ? "notGiven" : "wrong"; // notGiven, correct, wrong - var statusObject; - async.series([ //get basic informations from the database function(callback) @@ -195,6 +213,8 @@ exports.checkAccess = function (padID, sessionID, token, password, callback) { //--> grant access statusObject = {accessStatus: "grant", authorID: sessionAuthor}; + //--> deny access if user isn't allowed to create the pad + if(settings.editOnly) statusObject.accessStatus = "deny"; } // there is no valid session avaiable AND pad exists else if(!validSession && padExists) diff --git a/node/utils/Settings.js b/node/utils/Settings.js index 9f23d114c..2aef834d6 100644 --- a/node/utils/Settings.js +++ b/node/utils/Settings.js @@ -48,6 +48,11 @@ exports.defaultPadText = "Welcome to Etherpad Lite!\n\nThis pad text is synchron */ exports.requireSession = false; +/** + * A flag that prevents users from creating new pads + */ +exports.editOnly = false; + /** * A flag that shows if minification is enabled or not */ diff --git a/settings.json.template b/settings.json.template index 5c0dffdaa..a453258fa 100644 --- a/settings.json.template +++ b/settings.json.template @@ -31,6 +31,9 @@ /* Users must have a session to access pads. This effectively allows only group pads to be accessed. */ "requireSession" : false, + + /* Users may edit pads but not create new ones. Pad creation is only via the API. This applies both to group pads and regular pads. */ + "editOnly" : true, /* if true, all css & js will be minified before sending to the client. This will improve the loading performance massivly, but makes it impossible to debug the javascript/css */ diff --git a/settings.json.template_windows b/settings.json.template_windows index d6f9ef14f..c3d6be2a8 100644 --- a/settings.json.template_windows +++ b/settings.json.template_windows @@ -30,6 +30,9 @@ /* Users must have a session to access pads. This effectively allows only group pads to be accessed. */ "requireSession" : false, + + /* Users may edit pads but not create new ones. Pad creation is only via the API. This applies both to group pads and regular pads. */ + "editOnly" : true, /* if true, all css & js will be minified before sending to the client. This will improve the loading performance massivly, but makes it impossible to debug the javascript/css */ From 6297e628eb9ece84518994111647e4b0e7177b71 Mon Sep 17 00:00:00 2001 From: Jordan Date: Mon, 21 Nov 2011 15:51:54 -0500 Subject: [PATCH 4/5] Permissions checks on pad and timeslider in server.js are redudant --- node/server.js | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/node/server.js b/node/server.js index fe3c40da4..1e0b6283c 100644 --- a/node/server.js +++ b/node/server.js @@ -210,12 +210,9 @@ async.waterfall([ return; } - hasPadAccess(req, res, function() - { - res.header("Server", serverName); - var filePath = path.normalize(__dirname + "/../static/pad.html"); - res.sendfile(filePath, { maxAge: exports.maxAge }); - }); + res.header("Server", serverName); + var filePath = path.normalize(__dirname + "/../static/pad.html"); + res.sendfile(filePath, { maxAge: exports.maxAge }); }); //serve timeslider.html under /p/$padname/timeslider @@ -228,12 +225,9 @@ async.waterfall([ return; } - hasPadAccess(req, res, function() - { - res.header("Server", serverName); - var filePath = path.normalize(__dirname + "/../static/timeslider.html"); - res.sendfile(filePath, { maxAge: exports.maxAge }); - }); + res.header("Server", serverName); + var filePath = path.normalize(__dirname + "/../static/timeslider.html"); + res.sendfile(filePath, { maxAge: exports.maxAge }); }); //serve timeslider.html under /p/$padname/timeslider From a49160048798eec08d60de24e0b39df75143bf9e Mon Sep 17 00:00:00 2001 From: Jordan Date: Fri, 25 Nov 2011 21:24:00 -0500 Subject: [PATCH 5/5] editOnly should default to false --- settings.json.template | 2 +- settings.json.template_windows | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/settings.json.template b/settings.json.template index a453258fa..da7b32a49 100644 --- a/settings.json.template +++ b/settings.json.template @@ -33,7 +33,7 @@ "requireSession" : false, /* Users may edit pads but not create new ones. Pad creation is only via the API. This applies both to group pads and regular pads. */ - "editOnly" : true, + "editOnly" : false, /* if true, all css & js will be minified before sending to the client. This will improve the loading performance massivly, but makes it impossible to debug the javascript/css */ diff --git a/settings.json.template_windows b/settings.json.template_windows index c3d6be2a8..61f14dcea 100644 --- a/settings.json.template_windows +++ b/settings.json.template_windows @@ -32,7 +32,7 @@ "requireSession" : false, /* Users may edit pads but not create new ones. Pad creation is only via the API. This applies both to group pads and regular pads. */ - "editOnly" : true, + "editOnly" : false, /* if true, all css & js will be minified before sending to the client. This will improve the loading performance massivly, but makes it impossible to debug the javascript/css */