added a security manager to control pad access on group pads
parent
3c99e07030
commit
d0e378f63a
|
@ -0,0 +1,235 @@
|
||||||
|
/**
|
||||||
|
* Controls the security of pad access
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 2011 Peter 'Pita' Martischka (Primary Technology Ltd)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS-IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var db = require("./DB").db;
|
||||||
|
var async = require("async");
|
||||||
|
var authorManager = require("./AuthorManager");
|
||||||
|
var padManager = require("./PadManager");
|
||||||
|
var sessionManager = require("./SessionManager");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function controlls the access to a pad, it checks if the user can access a pad.
|
||||||
|
* @param padID the pad the user wants to access
|
||||||
|
* @param sesssionID the session the user has (set via api)
|
||||||
|
* @param token the token of the author (randomly generated at client side, used for public pads)
|
||||||
|
* @param password the password the user has given to access this pad, can be null
|
||||||
|
* @param callback will be called with (err, {accessStatus: grant|deny|wrongPassword|needPassword, authorID: a.xxxxxx})
|
||||||
|
*/
|
||||||
|
exports.checkAccess = function (padID, sessionID, token, password, callback)
|
||||||
|
{
|
||||||
|
// 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];
|
||||||
|
var padExists = false;
|
||||||
|
var validSession = false;
|
||||||
|
var sessionAuthor;
|
||||||
|
var tokenAuthor;
|
||||||
|
var isPublic;
|
||||||
|
var isPasswordProtected;
|
||||||
|
var passwordStatus = password == null ? "notGiven" : "wrong"; // notGiven, correct, wrong
|
||||||
|
|
||||||
|
var statusObject;
|
||||||
|
|
||||||
|
async.series([
|
||||||
|
//get basic informations from the database
|
||||||
|
function(callback)
|
||||||
|
{
|
||||||
|
async.parallel([
|
||||||
|
//does pad exists
|
||||||
|
function(callback)
|
||||||
|
{
|
||||||
|
padManager.doesPadExists(padID, function(err, exists)
|
||||||
|
{
|
||||||
|
padExists = exists;
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//get informations about this session
|
||||||
|
function(callback)
|
||||||
|
{
|
||||||
|
sessionManager.getSessionInfo(sessionID, function(err, sessionInfo)
|
||||||
|
{
|
||||||
|
//skip session validation if the session doesn't exists
|
||||||
|
if(err && err.stop == "sessionID does not exist")
|
||||||
|
{
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(err) {callback(err); return}
|
||||||
|
|
||||||
|
var now = Math.floor(new Date().getTime()/1000);
|
||||||
|
|
||||||
|
//is it for this group? and is validUntil still ok? --> validSession
|
||||||
|
if(sessionInfo.groupID == groupID && sessionInfo.validUntil > now)
|
||||||
|
{
|
||||||
|
validSession = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionAuthor = sessionInfo.authorID;
|
||||||
|
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//get author for token
|
||||||
|
function(callback)
|
||||||
|
{
|
||||||
|
//get author for this token
|
||||||
|
authorManager.getAuthor4Token(token, function(err, author)
|
||||||
|
{
|
||||||
|
tokenAuthor = author;
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
], callback);
|
||||||
|
},
|
||||||
|
//get more informations of this pad, if avaiable
|
||||||
|
function(callback)
|
||||||
|
{
|
||||||
|
//skip this if the pad doesn't exists
|
||||||
|
if(padExists == false)
|
||||||
|
{
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
padManager.getPad(padID, function(err, pad)
|
||||||
|
{
|
||||||
|
if(err) {callback(err); return}
|
||||||
|
|
||||||
|
//is it a public pad?
|
||||||
|
isPublic = pad.getPublicStatus();
|
||||||
|
|
||||||
|
//is it password protected?
|
||||||
|
isPasswordProtected = pad.isPasswordProtected();
|
||||||
|
|
||||||
|
//is password correct?
|
||||||
|
if(isPasswordProtected && password && pad.isCorrectPassword(password))
|
||||||
|
{
|
||||||
|
passwordStatus = "correct";
|
||||||
|
}
|
||||||
|
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function(callback)
|
||||||
|
{
|
||||||
|
//- a valid session for this group is avaible AND pad exists
|
||||||
|
if(validSession && padExists)
|
||||||
|
{
|
||||||
|
//- the pad is not password protected
|
||||||
|
if(!isPasswordProtected)
|
||||||
|
{
|
||||||
|
//--> grant access
|
||||||
|
statusObject = {accessStatus: "grant", authorID: sessionAuthor};
|
||||||
|
}
|
||||||
|
//- the pad is password protected and password is correct
|
||||||
|
else if(isPasswordProtected && passwordStatus == "correct")
|
||||||
|
{
|
||||||
|
//--> grant access
|
||||||
|
statusObject = {accessStatus: "grant", authorID: sessionAuthor};
|
||||||
|
}
|
||||||
|
//- the pad is password protected but wrong password given
|
||||||
|
else if(isPasswordProtected && passwordStatus == "wrong")
|
||||||
|
{
|
||||||
|
//--> deny access, ask for new password and tell them that the password is wrong
|
||||||
|
statusObject = {accessStatus: "wrongPassword"};
|
||||||
|
}
|
||||||
|
//- the pad is password protected but no password given
|
||||||
|
else if(isPasswordProtected && passwordStatus == "notGiven")
|
||||||
|
{
|
||||||
|
//--> ask for password
|
||||||
|
statusObject = {accessStatus: "needPassword"};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Error("Ops, something wrong happend");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//- a valid session for this group avaible but pad doesn't exists
|
||||||
|
else if(validSession && !padExists)
|
||||||
|
{
|
||||||
|
//--> grant access
|
||||||
|
statusObject = {accessStatus: "grant", authorID: sessionAuthor};
|
||||||
|
}
|
||||||
|
// there is no valid session avaiable AND pad exists
|
||||||
|
else if(!validSession && padExists)
|
||||||
|
{
|
||||||
|
//-- its public and not password protected
|
||||||
|
if(isPublic && !isPasswordProtected)
|
||||||
|
{
|
||||||
|
//--> grant access, with author of token
|
||||||
|
statusObject = {accessStatus: "grant", authorID: tokenAuthor};
|
||||||
|
}
|
||||||
|
//- its public and password protected and password is correct
|
||||||
|
else if(isPublic && isPasswordProtected && passwordStatus == "correct")
|
||||||
|
{
|
||||||
|
//--> grant access, with author of token
|
||||||
|
statusObject = {accessStatus: "grant", authorID: tokenAuthor};
|
||||||
|
}
|
||||||
|
//- its public and the pad is password protected but wrong password given
|
||||||
|
else if(isPublic && isPasswordProtected && passwordStatus == "wrong")
|
||||||
|
{
|
||||||
|
//--> deny access, ask for new password and tell them that the password is wrong
|
||||||
|
statusObject = {accessStatus: "wrongPassword"};
|
||||||
|
}
|
||||||
|
//- its public and the pad is password protected but no password given
|
||||||
|
else if(isPublic && isPasswordProtected && passwordStatus == "notGiven")
|
||||||
|
{
|
||||||
|
//--> ask for password
|
||||||
|
statusObject = {accessStatus: "needPassword"};
|
||||||
|
}
|
||||||
|
//- its not public
|
||||||
|
else if(!isPublic)
|
||||||
|
{
|
||||||
|
//--> deny access
|
||||||
|
statusObject = {accessStatus: "deny"};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Error("Ops, something wrong happend");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// there is no valid session avaiable AND pad doesn't exists
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//--> deny access
|
||||||
|
statusObject = {accessStatus: "deny"};
|
||||||
|
}
|
||||||
|
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
], function(err)
|
||||||
|
{
|
||||||
|
callback(err, statusObject);
|
||||||
|
});
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ var AttributePoolFactory = require("../utils/AttributePoolFactory");
|
||||||
var authorManager = require("../db/AuthorManager");
|
var authorManager = require("../db/AuthorManager");
|
||||||
var readOnlyManager = require("../db/ReadOnlyManager");
|
var readOnlyManager = require("../db/ReadOnlyManager");
|
||||||
var settings = require('../utils/Settings');
|
var settings = require('../utils/Settings');
|
||||||
|
var securityManager = require("../db/SecurityManager");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A associative array that translates a session to a pad
|
* A associative array that translates a session to a pad
|
||||||
|
@ -585,14 +586,29 @@ function handleClientReady(client, message)
|
||||||
var chatMessages;
|
var chatMessages;
|
||||||
|
|
||||||
async.series([
|
async.series([
|
||||||
|
//check permissions
|
||||||
|
function(callback)
|
||||||
|
{
|
||||||
|
securityManager.checkAccess (message.padId, message.sessionID, message.token, message.password, function(err, statusObject)
|
||||||
|
{
|
||||||
|
if(err) {callback(err); return}
|
||||||
|
|
||||||
|
//access was granted
|
||||||
|
if(statusObject.accessStatus == "grant")
|
||||||
|
{
|
||||||
|
author = statusObject.authorID;
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
//no access, send the client a message that tell him why
|
||||||
|
else
|
||||||
|
{
|
||||||
|
client.send({accessStatus: statusObject.accessStatus})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
//get all authordata of this new user
|
//get all authordata of this new user
|
||||||
function(callback)
|
function(callback)
|
||||||
{
|
{
|
||||||
//Ask the author Manager for a author of this token.
|
|
||||||
authorManager.getAuthor4Token(message.token, function(err,value)
|
|
||||||
{
|
|
||||||
author = value;
|
|
||||||
|
|
||||||
async.parallel([
|
async.parallel([
|
||||||
//get colorId
|
//get colorId
|
||||||
function(callback)
|
function(callback)
|
||||||
|
@ -629,7 +645,6 @@ function handleClientReady(client, message)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
], callback);
|
], callback);
|
||||||
});
|
|
||||||
},
|
},
|
||||||
//these db requests all need the pad object
|
//these db requests all need the pad object
|
||||||
function(callback)
|
function(callback)
|
||||||
|
|
|
@ -105,10 +105,13 @@ function handshake()
|
||||||
createCookie("token", token, 60);
|
createCookie("token", token, 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sessionID = readCookie("sessionID");
|
||||||
|
|
||||||
var msg = {
|
var msg = {
|
||||||
"component": "pad",
|
"component": "pad",
|
||||||
"type": "CLIENT_READY",
|
"type": "CLIENT_READY",
|
||||||
"padId": padId,
|
"padId": padId,
|
||||||
|
"sessionID": sessionID,
|
||||||
"token": token,
|
"token": token,
|
||||||
"protocolVersion": 2
|
"protocolVersion": 2
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue