mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-05-05 22:57:11 -04:00
initial rewrite
This commit is contained in:
parent
e6e81135a7
commit
c19444f6c9
12 changed files with 777 additions and 697 deletions
|
@ -19,163 +19,167 @@
|
|||
*/
|
||||
|
||||
var ERR = require("async-stacktrace");
|
||||
var db = require("./DB").db;
|
||||
var async = require("async");
|
||||
|
||||
var randomString = require("../utils/randomstring");
|
||||
|
||||
var AuthorManager = function AuthorManager(db) {
|
||||
this.db = db;
|
||||
};
|
||||
|
||||
exports.AuthorManager = AuthorManager;
|
||||
|
||||
/**
|
||||
* Checks if the author exists
|
||||
*/
|
||||
exports.doesAuthorExists = function (authorID, callback)
|
||||
AuthorManager.prototype.doesAuthorExists = function (authorID, callback)
|
||||
{
|
||||
//check if the database entry of this author exists
|
||||
db.get("globalAuthor:" + authorID, function (err, author)
|
||||
this.db.get("globalAuthor:" + authorID, function (err, author)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
callback(null, author != null);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the AuthorID for a token.
|
||||
* @param {String} token The token
|
||||
* @param {Function} callback callback (err, author)
|
||||
* Returns the AuthorID for a token.
|
||||
* @param {String} token The token
|
||||
* @param {Function} callback callback (err, author)
|
||||
*/
|
||||
exports.getAuthor4Token = function (token, callback)
|
||||
AuthorManager.prototype.getAuthor4Token = function (token, callback)
|
||||
{
|
||||
mapAuthorWithDBKey("token2author", token, function(err, author)
|
||||
this.mapAuthorWithDBKey("token2author", token, function(err, author)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
//return only the sub value authorID
|
||||
callback(null, author ? author.authorID : author);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the AuthorID for a mapper.
|
||||
* Returns the AuthorID for a mapper.
|
||||
* @param {String} token The mapper
|
||||
* @param {Function} callback callback (err, author)
|
||||
* @param {Function} callback callback (err, author)
|
||||
*/
|
||||
exports.createAuthorIfNotExistsFor = function (authorMapper, name, callback)
|
||||
AuthorManager.prototype.createAuthorIfNotExistsFor = function (authorMapper, name, callback)
|
||||
{
|
||||
mapAuthorWithDBKey("mapper2author", authorMapper, function(err, author)
|
||||
var that = this;
|
||||
this.mapAuthorWithDBKey("mapper2author", authorMapper, function(err, author)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//set the name of this author
|
||||
if(name)
|
||||
exports.setAuthorName(author.authorID, name);
|
||||
|
||||
that.setAuthorName(author.authorID, name);
|
||||
|
||||
//return the authorID
|
||||
callback(null, author);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the AuthorID for a mapper. We can map using a mapperkey,
|
||||
* so far this is token2author and mapper2author
|
||||
* @param {String} mapperkey The database key name for this mapper
|
||||
* @param {String} mapperkey The database key name for this mapper
|
||||
* @param {String} mapper The mapper
|
||||
* @param {Function} callback callback (err, author)
|
||||
* @param {Function} callback callback (err, author)
|
||||
*/
|
||||
function mapAuthorWithDBKey (mapperkey, mapper, callback)
|
||||
{
|
||||
AuthorManager.prototype.mapAuthorWithDBKey = function mapAuthorWithDBKey (mapperkey, mapper, callback) {
|
||||
var that = this;
|
||||
//try to map to an author
|
||||
db.get(mapperkey + ":" + mapper, function (err, author)
|
||||
this.db.get(mapperkey + ":" + mapper, function (err, author)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//there is no author with this mapper, so create one
|
||||
if(author == null)
|
||||
{
|
||||
exports.createAuthor(null, function(err, author)
|
||||
{
|
||||
that.createAuthor(null, function(err, author) {
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//create the token2author relation
|
||||
db.set(mapperkey + ":" + mapper, author.authorID);
|
||||
|
||||
that.db.set(mapperkey + ":" + mapper, author.authorID);
|
||||
|
||||
//return the author
|
||||
callback(null, author);
|
||||
});
|
||||
}
|
||||
//there is a author with this mapper
|
||||
else
|
||||
{
|
||||
else {
|
||||
//update the timestamp of this author
|
||||
db.setSub("globalAuthor:" + author, ["timestamp"], new Date().getTime());
|
||||
|
||||
that.db.setSub("globalAuthor:" + author, ["timestamp"], new Date().getTime());
|
||||
|
||||
//return the author
|
||||
callback(null, {authorID: author});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal function that creates the database entry for an author
|
||||
* @param {String} name The name of the author
|
||||
* Internal function that creates the database entry for an author
|
||||
* @param {String} name The name of the author
|
||||
*/
|
||||
exports.createAuthor = function(name, callback)
|
||||
AuthorManager.prototype.createAuthor = function(name, callback)
|
||||
{
|
||||
//create the new author name
|
||||
var author = "a." + randomString(16);
|
||||
|
||||
|
||||
//create the globalAuthors db entry
|
||||
var authorObj = {"colorId" : Math.floor(Math.random()*32), "name": name, "timestamp": new Date().getTime()};
|
||||
|
||||
|
||||
//set the global author db entry
|
||||
db.set("globalAuthor:" + author, authorObj);
|
||||
|
||||
this.db.set("globalAuthor:" + author, authorObj);
|
||||
|
||||
callback(null, {authorID: author});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the Author Obj of the author
|
||||
* @param {String} author The id of the author
|
||||
* @param {Function} callback callback(err, authorObj)
|
||||
*/
|
||||
exports.getAuthor = function (author, callback)
|
||||
AuthorManager.prototype.getAuthor = function (author, callback)
|
||||
{
|
||||
db.get("globalAuthor:" + author, callback);
|
||||
}
|
||||
this.db.get("globalAuthor:" + author, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the color Id of the author
|
||||
* @param {String} author The id of the author
|
||||
* @param {Function} callback callback(err, colorId)
|
||||
*/
|
||||
exports.getAuthorColorId = function (author, callback)
|
||||
AuthorManager.prototype.getAuthorColorId = function (author, callback)
|
||||
{
|
||||
db.getSub("globalAuthor:" + author, ["colorId"], callback);
|
||||
}
|
||||
this.db.getSub("globalAuthor:" + author, ["colorId"], callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the color Id of the author
|
||||
* @param {String} author The id of the author
|
||||
* @param {Function} callback (optional)
|
||||
*/
|
||||
exports.setAuthorColorId = function (author, colorId, callback)
|
||||
AuthorManager.prototype.setAuthorColorId = function (author, colorId, callback)
|
||||
{
|
||||
db.setSub("globalAuthor:" + author, ["colorId"], colorId, callback);
|
||||
}
|
||||
this.db.setSub("globalAuthor:" + author, ["colorId"], colorId, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the name of the author
|
||||
* @param {String} author The id of the author
|
||||
* @param {Function} callback callback(err, name)
|
||||
*/
|
||||
exports.getAuthorName = function (author, callback)
|
||||
AuthorManager.prototype.getAuthorName = function (author, callback)
|
||||
{
|
||||
db.getSub("globalAuthor:" + author, ["name"], callback);
|
||||
}
|
||||
this.db.getSub("globalAuthor:" + author, ["name"], callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the name of the author
|
||||
* @param {String} author The id of the author
|
||||
* @param {Function} callback (optional)
|
||||
*/
|
||||
exports.setAuthorName = function (author, name, callback)
|
||||
AuthorManager.prototype.setAuthorName = function (author, name, callback)
|
||||
{
|
||||
db.setSub("globalAuthor:" + author, ["name"], name, callback);
|
||||
}
|
||||
this.db.setSub("globalAuthor:" + author, ["name"], name, callback);
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* The DB Module provides a database initalized with the settings
|
||||
* The DB Module provides a database initalized with the settings
|
||||
* provided by the settings module
|
||||
*/
|
||||
|
||||
|
@ -20,38 +20,25 @@
|
|||
*/
|
||||
|
||||
var ueberDB = require("ueberDB");
|
||||
var settings = require("../utils/Settings");
|
||||
var log4js = require('log4js');
|
||||
|
||||
//set database settings
|
||||
var db = new ueberDB.database(settings.dbType, settings.dbSettings, null, log4js.getLogger("ueberDB"));
|
||||
|
||||
/**
|
||||
* The UeberDB Object that provides the database functions
|
||||
*/
|
||||
exports.db = null;
|
||||
|
||||
/**
|
||||
* Initalizes the database with the settings provided by the settings module
|
||||
* @param {Function} callback
|
||||
* @param {Function} callback
|
||||
*/
|
||||
exports.init = function(callback)
|
||||
{
|
||||
//initalize the database async
|
||||
db.init(function(err)
|
||||
{
|
||||
//there was an error while initializing the database, output it and stop
|
||||
if(err)
|
||||
{
|
||||
console.error("ERROR: Problem while initalizing the database");
|
||||
console.error(err.stack ? err.stack : err);
|
||||
process.exit(1);
|
||||
}
|
||||
//everything ok
|
||||
else
|
||||
{
|
||||
exports.db = db;
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.init = function init(settings, callback) {
|
||||
//set database settings
|
||||
console.log(settings);
|
||||
var db = new ueberDB.database(settings.dbType, settings.dbSettings, null, log4js.getLogger("ueberDB"));
|
||||
|
||||
//initalize the database async
|
||||
db.init(function(error){
|
||||
//there was an error while initializing the database, output it and stop
|
||||
if(error) {
|
||||
callback(error, null);
|
||||
}
|
||||
else {
|
||||
callback(null, db);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -17,28 +17,35 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
var ERR = require("async-stacktrace");
|
||||
var customError = require("../utils/customError");
|
||||
var randomString = require("../utils/randomstring");
|
||||
var db = require("./DB").db;
|
||||
var async = require("async");
|
||||
var padManager = require("./PadManager");
|
||||
var sessionManager = require("./SessionManager");
|
||||
|
||||
exports.deleteGroup = function(groupID, callback)
|
||||
|
||||
var GroupManager = function GroupManager(db, padManager, SessionManager) {
|
||||
this.db = db;
|
||||
this.padManager = padManager;
|
||||
this.SessionManager = SessionManager;
|
||||
|
||||
};
|
||||
|
||||
exports.GroupManager = GroupManager;
|
||||
|
||||
GroupManager.prototype.deleteGroup = function(groupID, callback)
|
||||
{
|
||||
var group;
|
||||
var that = this;
|
||||
|
||||
async.series([
|
||||
//ensure group exists
|
||||
//ensure group exists
|
||||
function (callback)
|
||||
{
|
||||
//try to get the group entry
|
||||
db.get("group:" + groupID, function (err, _group)
|
||||
that.db.get("group:" + groupID, function (err, _group)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//group does not exist
|
||||
if(_group == null)
|
||||
{
|
||||
|
@ -61,14 +68,14 @@ exports.deleteGroup = function(groupID, callback)
|
|||
{
|
||||
padIDs.push(i);
|
||||
}
|
||||
|
||||
//loop trough all pads and delete them
|
||||
|
||||
//loop trough all pads and delete them
|
||||
async.forEach(padIDs, function(padID, callback)
|
||||
{
|
||||
padManager.getPad(padID, function(err, pad)
|
||||
that.padManager.getPad(padID, function(err, pad)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
pad.remove(callback);
|
||||
});
|
||||
}, callback);
|
||||
|
@ -77,21 +84,21 @@ exports.deleteGroup = function(groupID, callback)
|
|||
function(callback)
|
||||
{
|
||||
//try to get the group entry
|
||||
db.get("group2sessions:" + groupID, function (err, group2sessions)
|
||||
that.db.get("group2sessions:" + groupID, function (err, group2sessions)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//skip if there is no group2sessions entry
|
||||
if(group2sessions == null) {callback(); return}
|
||||
|
||||
|
||||
//collect all sessions in an array, that allows us to use async.forEach
|
||||
var sessions = [];
|
||||
for(var i in group2sessions.sessionsIDs)
|
||||
{
|
||||
sessions.push(i);
|
||||
}
|
||||
|
||||
//loop trough all sessions and delete them
|
||||
|
||||
//loop trough all sessions and delete them
|
||||
async.forEach(sessions, function(session, callback)
|
||||
{
|
||||
sessionManager.deleteSession(session, callback);
|
||||
|
@ -101,8 +108,8 @@ exports.deleteGroup = function(groupID, callback)
|
|||
//remove group and group2sessions entry
|
||||
function(callback)
|
||||
{
|
||||
db.remove("group2sessions:" + groupID);
|
||||
db.remove("group:" + groupID);
|
||||
that.db.remove("group2sessions:" + groupID);
|
||||
that.db.remove("group:" + groupID);
|
||||
callback();
|
||||
}
|
||||
], function(err)
|
||||
|
@ -110,52 +117,53 @@ exports.deleteGroup = function(groupID, callback)
|
|||
if(ERR(err, callback)) return;
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
exports.doesGroupExist = function(groupID, callback)
|
||||
};
|
||||
|
||||
GroupManager.prototype.doesGroupExist = function(groupID, callback)
|
||||
{
|
||||
//try to get the group entry
|
||||
db.get("group:" + groupID, function (err, group)
|
||||
this.db.get("group:" + groupID, function (err, group)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
callback(null, group != null);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
exports.createGroup = function(callback)
|
||||
GroupManager.prototype.createGroup = function(callback)
|
||||
{
|
||||
//search for non existing groupID
|
||||
var groupID = "g." + randomString(16);
|
||||
|
||||
//create the group
|
||||
db.set("group:" + groupID, {pads: {}});
|
||||
callback(null, {groupID: groupID});
|
||||
}
|
||||
|
||||
exports.createGroupIfNotExistsFor = function(groupMapper, callback)
|
||||
//create the group
|
||||
this.db.set("group:" + groupID, {pads: {}});
|
||||
callback(null, {groupID: groupID});
|
||||
};
|
||||
|
||||
GroupManager.prototype.createGroupIfNotExistsFor = function(groupMapper, callback)
|
||||
{
|
||||
var that = this;
|
||||
//ensure mapper is optional
|
||||
if(typeof groupMapper != "string")
|
||||
{
|
||||
callback(new customError("groupMapper is no string","apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//try to get a group for this mapper
|
||||
db.get("mapper2group:"+groupMapper, function(err, groupID)
|
||||
this.db.get("mapper2group:"+groupMapper, function(err, groupID)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//there is no group for this mapper, let's create a group
|
||||
if(groupID == null)
|
||||
{
|
||||
exports.createGroup(function(err, responseObj)
|
||||
that.createGroup(function(err, responseObj)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//create the mapper entry for this group
|
||||
db.set("mapper2group:"+groupMapper, responseObj.groupID);
|
||||
|
||||
that.db.set("mapper2group:"+groupMapper, responseObj.groupID);
|
||||
|
||||
callback(null, responseObj);
|
||||
});
|
||||
}
|
||||
|
@ -166,21 +174,22 @@ exports.createGroupIfNotExistsFor = function(groupMapper, callback)
|
|||
callback(null, {groupID: groupID});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
exports.createGroupPad = function(groupID, padName, text, callback)
|
||||
GroupManager.prototype.createGroupPad = function(groupID, padName, text, callback)
|
||||
{
|
||||
var that = this;
|
||||
//create the padID
|
||||
var padID = groupID + "$" + padName;
|
||||
|
||||
async.series([
|
||||
//ensure group exists
|
||||
//ensure group exists
|
||||
function (callback)
|
||||
{
|
||||
exports.doesGroupExist(groupID, function(err, exists)
|
||||
that.doesGroupExist(groupID, function(err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//group does not exist
|
||||
if(exists == false)
|
||||
{
|
||||
|
@ -196,12 +205,12 @@ exports.createGroupPad = function(groupID, padName, text, callback)
|
|||
//ensure pad does not exists
|
||||
function (callback)
|
||||
{
|
||||
padManager.doesPadExists(padID, function(err, exists)
|
||||
that.padManager.doesPadExists(padID, function(err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//pad exists already
|
||||
if(exists == true)
|
||||
if(exists)
|
||||
{
|
||||
callback(new customError("padName does already exist","apierror"));
|
||||
}
|
||||
|
@ -215,7 +224,7 @@ exports.createGroupPad = function(groupID, padName, text, callback)
|
|||
//create the pad
|
||||
function (callback)
|
||||
{
|
||||
padManager.getPad(padID, text, function(err)
|
||||
that.padManager.getPad(padID, text, function(err)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
callback();
|
||||
|
@ -224,7 +233,7 @@ exports.createGroupPad = function(groupID, padName, text, callback)
|
|||
//create an entry in the group for this pad
|
||||
function (callback)
|
||||
{
|
||||
db.setSub("group:" + groupID, ["pads", padID], 1);
|
||||
that.db.setSub("group:" + groupID, ["pads", padID], 1);
|
||||
callback();
|
||||
}
|
||||
], function(err)
|
||||
|
@ -232,27 +241,28 @@ exports.createGroupPad = function(groupID, padName, text, callback)
|
|||
if(ERR(err, callback)) return;
|
||||
callback(null, {padID: padID});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
exports.listPads = function(groupID, callback)
|
||||
GroupManager.prototype.listPads = function(groupID, callback)
|
||||
{
|
||||
exports.doesGroupExist(groupID, function(err, exists)
|
||||
var that = this;
|
||||
this.doesGroupExist(groupID, function(err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//group does not exist
|
||||
if(exists == false)
|
||||
if(!exists)
|
||||
{
|
||||
callback(new customError("groupID does not exist","apierror"));
|
||||
}
|
||||
//group exists, let's get the pads
|
||||
else
|
||||
{
|
||||
db.getSub("group:" + groupID, ["pads"], function(err, pads)
|
||||
that.db.getSub("group:" + groupID, ["pads"], function(err, pads)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
callback(null, {padIDs: pads});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
102
node/db/Pad.js
102
node/db/Pad.js
|
@ -1,17 +1,11 @@
|
|||
/**
|
||||
* The pad object, defined with joose
|
||||
* The pad object
|
||||
*/
|
||||
|
||||
var ERR = require("async-stacktrace");
|
||||
var Changeset = require("../utils/Changeset");
|
||||
var AttributePoolFactory = require("../utils/AttributePoolFactory");
|
||||
var db = require("./DB").db;
|
||||
var async = require("async");
|
||||
var settings = require('../utils/Settings');
|
||||
var authorManager = require("./AuthorManager");
|
||||
var padManager = require("./PadManager");
|
||||
var padMessageHandler = require("../handler/PadMessageHandler");
|
||||
var readOnlyManager = require("./ReadOnlyManager");
|
||||
var crypto = require("crypto");
|
||||
|
||||
/**
|
||||
|
@ -73,8 +67,8 @@ Pad.prototype.appendRevision = function appendRevision(aChangeset, author) {
|
|||
newRevData.meta.atext = this.atext;
|
||||
}
|
||||
|
||||
db.set("pad:"+this.id+":revs:"+newRev, newRevData);
|
||||
db.set("pad:"+this.id, {atext: this.atext,
|
||||
this.db.set("pad:"+this.id+":revs:"+newRev, newRevData);
|
||||
this.db.set("pad:"+this.id, {atext: this.atext,
|
||||
pool: this.pool.toJsonable(),
|
||||
head: this.head,
|
||||
chatHead: this.chatHead,
|
||||
|
@ -83,15 +77,15 @@ Pad.prototype.appendRevision = function appendRevision(aChangeset, author) {
|
|||
};
|
||||
|
||||
Pad.prototype.getRevisionChangeset = function getRevisionChangeset(revNum, callback) {
|
||||
db.getSub("pad:"+this.id+":revs:"+revNum, ["changeset"], callback);
|
||||
this.db.getSub("pad:"+this.id+":revs:"+revNum, ["changeset"], callback);
|
||||
};
|
||||
|
||||
Pad.prototype.getRevisionAuthor = function getRevisionAuthor(revNum, callback) {
|
||||
db.getSub("pad:"+this.id+":revs:"+revNum, ["meta", "author"], callback);
|
||||
this.db.getSub("pad:"+this.id+":revs:"+revNum, ["meta", "author"], callback);
|
||||
};
|
||||
|
||||
Pad.prototype.getRevisionDate = function getRevisionDate(revNum, callback) {
|
||||
db.getSub("pad:"+this.id+":revs:"+revNum, ["meta", "timestamp"], callback);
|
||||
this.db.getSub("pad:"+this.id+":revs:"+revNum, ["meta", "timestamp"], callback);
|
||||
};
|
||||
|
||||
Pad.prototype.getAllAuthors = function getAllAuthors() {
|
||||
|
@ -109,7 +103,7 @@ Pad.prototype.getAllAuthors = function getAllAuthors() {
|
|||
};
|
||||
|
||||
Pad.prototype.getInternalRevisionAText = function getInternalRevisionAText(targetRev, callback) {
|
||||
var _this = this;
|
||||
var that = this;
|
||||
|
||||
var keyRev = this.getKeyRevisionNumber(targetRev);
|
||||
var atext;
|
||||
|
@ -132,7 +126,7 @@ Pad.prototype.getInternalRevisionAText = function getInternalRevisionAText(targe
|
|||
//get the atext of the key revision
|
||||
function (callback)
|
||||
{
|
||||
db.getSub("pad:"+_this.id+":revs:"+keyRev, ["meta", "atext"], function(err, _atext)
|
||||
that.db.getSub("pad:"+that.id+":revs:"+keyRev, ["meta", "atext"], function(err, _atext)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
atext = Changeset.cloneAText(_atext);
|
||||
|
@ -144,7 +138,7 @@ Pad.prototype.getInternalRevisionAText = function getInternalRevisionAText(targe
|
|||
{
|
||||
async.forEach(neededChangesets, function(item, callback)
|
||||
{
|
||||
_this.getRevisionChangeset(item, function(err, changeset)
|
||||
that.getRevisionChangeset(item, function(err, changeset)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
changesets[item] = changeset;
|
||||
|
@ -157,7 +151,7 @@ Pad.prototype.getInternalRevisionAText = function getInternalRevisionAText(targe
|
|||
//apply all changesets to the key changeset
|
||||
function(callback)
|
||||
{
|
||||
var apool = _this.apool();
|
||||
var apool = that.apool();
|
||||
var curRev = keyRev;
|
||||
|
||||
while (curRev < targetRev)
|
||||
|
@ -200,20 +194,20 @@ Pad.prototype.setText = function setText(newText) {
|
|||
Pad.prototype.appendChatMessage = function appendChatMessage(text, userId, time) {
|
||||
this.chatHead++;
|
||||
//save the chat entry in the database
|
||||
db.set("pad:"+this.id+":chat:"+this.chatHead, {"text": text, "userId": userId, "time": time});
|
||||
this.db.set("pad:"+this.id+":chat:"+this.chatHead, {"text": text, "userId": userId, "time": time});
|
||||
//save the new chat head
|
||||
db.setSub("pad:"+this.id, ["chatHead"], this.chatHead);
|
||||
this.db.setSub("pad:"+this.id, ["chatHead"], this.chatHead);
|
||||
};
|
||||
|
||||
Pad.prototype.getChatMessage = function getChatMessage(entryNum, callback) {
|
||||
var _this = this;
|
||||
var that = this;
|
||||
var entry;
|
||||
|
||||
async.series([
|
||||
//get the chat entry
|
||||
function(callback)
|
||||
{
|
||||
db.get("pad:"+_this.id+":chat:"+entryNum, function(err, _entry)
|
||||
that.db.get("pad:"+that.id+":chat:"+entryNum, function(err, _entry)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
entry = _entry;
|
||||
|
@ -231,7 +225,7 @@ Pad.prototype.getChatMessage = function getChatMessage(entryNum, callback) {
|
|||
}
|
||||
|
||||
//get the authorName
|
||||
authorManager.getAuthorName(entry.userId, function(err, authorName)
|
||||
that.authorManager.getAuthorName(entry.userId, function(err, authorName)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
entry.userName = authorName;
|
||||
|
@ -253,7 +247,7 @@ Pad.prototype.getLastChatMessages = function getLastChatMessages(count, callback
|
|||
return;
|
||||
}
|
||||
|
||||
var _this = this;
|
||||
var that = this;
|
||||
|
||||
//works only if we decrement the amount, for some reason
|
||||
count--;
|
||||
|
@ -279,7 +273,7 @@ Pad.prototype.getLastChatMessages = function getLastChatMessages(count, callback
|
|||
var entries = [];
|
||||
async.forEach(neededEntries, function(entryObject, callback)
|
||||
{
|
||||
_this.getChatMessage(entryObject.entryNum, function(err, entry)
|
||||
that.getChatMessage(entryObject.entryNum, function(err, entry)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
entries[entryObject.order] = entry;
|
||||
|
@ -298,7 +292,7 @@ Pad.prototype.getLastChatMessages = function getLastChatMessages(count, callback
|
|||
if(entries[i]!=null)
|
||||
cleanedEntries.push(entries[i]);
|
||||
else
|
||||
console.warn("WARNING: Found broken chat entry in pad " + _this.id);
|
||||
console.warn("WARNING: Found broken chat entry in pad " + that.id);
|
||||
}
|
||||
|
||||
callback(null, cleanedEntries);
|
||||
|
@ -306,50 +300,45 @@ Pad.prototype.getLastChatMessages = function getLastChatMessages(count, callback
|
|||
};
|
||||
|
||||
Pad.prototype.init = function init(text, callback) {
|
||||
var _this = this;
|
||||
var that = this;
|
||||
|
||||
//replace text with default text if text isn't set
|
||||
if(text == null)
|
||||
{
|
||||
text = settings.defaultPadText;
|
||||
}
|
||||
|
||||
//try to load the pad
|
||||
db.get("pad:"+this.id, function(err, value)
|
||||
this.db.get("pad:"+this.id, function(err, value)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
//if this pad exists, load it
|
||||
if(value != null)
|
||||
{
|
||||
_this.head = value.head;
|
||||
_this.atext = value.atext;
|
||||
_this.pool = _this.pool.fromJsonable(value.pool);
|
||||
that.head = value.head;
|
||||
that.atext = value.atext;
|
||||
that.pool = that.pool.fromJsonable(value.pool);
|
||||
|
||||
//ensure we have a local chatHead variable
|
||||
if(value.chatHead != null)
|
||||
_this.chatHead = value.chatHead;
|
||||
that.chatHead = value.chatHead;
|
||||
else
|
||||
_this.chatHead = -1;
|
||||
that.chatHead = -1;
|
||||
|
||||
//ensure we have a local publicStatus variable
|
||||
if(value.publicStatus != null)
|
||||
_this.publicStatus = value.publicStatus;
|
||||
that.publicStatus = value.publicStatus;
|
||||
else
|
||||
_this.publicStatus = false;
|
||||
that.publicStatus = false;
|
||||
|
||||
//ensure we have a local passwordHash variable
|
||||
if(value.passwordHash != null)
|
||||
_this.passwordHash = value.passwordHash;
|
||||
that.passwordHash = value.passwordHash;
|
||||
else
|
||||
_this.passwordHash = null;
|
||||
that.passwordHash = null;
|
||||
}
|
||||
//this pad doesn't exist, so create it
|
||||
else
|
||||
{
|
||||
var firstChangeset = Changeset.makeSplice("\n", 0, 0, exports.cleanText(text));
|
||||
|
||||
_this.appendRevision(firstChangeset, '');
|
||||
that.appendRevision(firstChangeset, '');
|
||||
}
|
||||
|
||||
callback(null);
|
||||
|
@ -358,10 +347,11 @@ Pad.prototype.init = function init(text, callback) {
|
|||
|
||||
Pad.prototype.remove = function remove(callback) {
|
||||
var padID = this.id;
|
||||
var _this = this;
|
||||
var that = this;
|
||||
|
||||
//kick everyone from this pad
|
||||
padMessageHandler.kickSessionsFromPad(padID);
|
||||
//FIXME do this in the api or somewhere else
|
||||
//padMessageHandler.kickSessionsFromPad(padID);
|
||||
|
||||
async.series([
|
||||
//delete all relations
|
||||
|
@ -376,7 +366,7 @@ Pad.prototype.remove = function remove(callback) {
|
|||
{
|
||||
var groupID = padID.substring(0,padID.indexOf("$"));
|
||||
|
||||
db.get("group:" + groupID, function (err, group)
|
||||
that.db.get("group:" + groupID, function (err, group)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
@ -384,7 +374,7 @@ Pad.prototype.remove = function remove(callback) {
|
|||
delete group.pads[padID];
|
||||
|
||||
//set the new value
|
||||
db.set("group:" + groupID, group);
|
||||
that.db.set("group:" + groupID, group);
|
||||
|
||||
callback();
|
||||
});
|
||||
|
@ -398,12 +388,12 @@ Pad.prototype.remove = function remove(callback) {
|
|||
//remove the readonly entries
|
||||
function(callback)
|
||||
{
|
||||
readOnlyManager.getReadOnlyId(padID, function(err, readonlyID)
|
||||
that.readOnlyManager.getReadOnlyId(padID, function(err, readonlyID)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
db.remove("pad2readonly:" + padID);
|
||||
db.remove("readonly2pad:" + readonlyID);
|
||||
that.db.remove("pad2readonly:" + padID);
|
||||
that.db.remove("readonly2pad:" + readonlyID);
|
||||
|
||||
callback();
|
||||
});
|
||||
|
@ -411,11 +401,11 @@ Pad.prototype.remove = function remove(callback) {
|
|||
//delete all chat messages
|
||||
function(callback)
|
||||
{
|
||||
var chatHead = _this.chatHead;
|
||||
var chatHead = that.chatHead;
|
||||
|
||||
for(var i=0;i<=chatHead;i++)
|
||||
{
|
||||
db.remove("pad:"+padID+":chat:"+i);
|
||||
that.db.remove("pad:"+padID+":chat:"+i);
|
||||
}
|
||||
|
||||
callback();
|
||||
|
@ -423,11 +413,11 @@ Pad.prototype.remove = function remove(callback) {
|
|||
//delete all revisions
|
||||
function(callback)
|
||||
{
|
||||
var revHead = _this.head;
|
||||
var revHead = that.head;
|
||||
|
||||
for(var i=0;i<=revHead;i++)
|
||||
{
|
||||
db.remove("pad:"+padID+":revs:"+i);
|
||||
that.db.remove("pad:"+padID+":revs:"+i);
|
||||
}
|
||||
|
||||
callback();
|
||||
|
@ -437,8 +427,8 @@ Pad.prototype.remove = function remove(callback) {
|
|||
//delete the pad entry and delete pad from padManager
|
||||
function(callback)
|
||||
{
|
||||
db.remove("pad:"+padID);
|
||||
padManager.unloadPad(padID);
|
||||
that.db.remove("pad:"+padID);
|
||||
that.padManager.unloadPad(padID);
|
||||
callback();
|
||||
}
|
||||
], function(err)
|
||||
|
@ -450,12 +440,12 @@ Pad.prototype.remove = function remove(callback) {
|
|||
//set in db
|
||||
Pad.prototype.setPublicStatus = function setPublicStatus(publicStatus) {
|
||||
this.publicStatus = publicStatus;
|
||||
db.setSub("pad:"+this.id, ["publicStatus"], this.publicStatus);
|
||||
this.db.setSub("pad:"+this.id, ["publicStatus"], this.publicStatus);
|
||||
};
|
||||
|
||||
Pad.prototype.setPassword = function setPassword(password) {
|
||||
this.passwordHash = password == null ? null : hash(password, generateSalt());
|
||||
db.setSub("pad:"+this.id, ["passwordHash"], this.passwordHash);
|
||||
this.db.setSub("pad:"+this.id, ["passwordHash"], this.passwordHash);
|
||||
};
|
||||
|
||||
Pad.prototype.isCorrectPassword = function isCorrectPassword(password) {
|
||||
|
|
|
@ -21,9 +21,8 @@
|
|||
var ERR = require("async-stacktrace");
|
||||
var customError = require("../utils/customError");
|
||||
var Pad = require("../db/Pad").Pad;
|
||||
var db = require("./DB").db;
|
||||
|
||||
/**
|
||||
/**
|
||||
* An Object containing all known Pads. Provides "get" and "set" functions,
|
||||
* which should be used instead of indexing with brackets. These prepend a
|
||||
* colon to the key, to avoid conflicting with built-in Object methods or with
|
||||
|
@ -32,12 +31,23 @@ var db = require("./DB").db;
|
|||
* If this is needed in other places, it would be wise to make this a prototype
|
||||
* that's defined somewhere more sensible.
|
||||
*/
|
||||
var globalPads = {
|
||||
get: function (name) { return this[':'+name]; },
|
||||
set: function (name, value) { this[':'+name] = value; },
|
||||
remove: function (name) { delete this[':'+name]; }
|
||||
|
||||
var PadManager = function PadManager(settings, db, authorManager, readOnlyManager) {
|
||||
this.settings = settings;
|
||||
this.db = db;
|
||||
this.authorManager = authorManager;
|
||||
this.readOnlyManager = readOnlyManager;
|
||||
|
||||
this.globalPads = {
|
||||
get: function (name) { return this[':'+name]; },
|
||||
set: function (name, value) { this[':'+name] = value; },
|
||||
remove: function (name) { delete this[':'+name]; }
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
exports.PadManager = PadManager;
|
||||
|
||||
/**
|
||||
* An array of padId transformations. These represent changes in pad name policy over
|
||||
* time, and allow us to "play back" these changes so legacy padIds can be found.
|
||||
|
@ -49,24 +59,27 @@ var padIdTransforms = [
|
|||
/**
|
||||
* Returns a Pad Object with the callback
|
||||
* @param id A String with the id of the pad
|
||||
* @param {Function} callback
|
||||
* @param {Function} callback
|
||||
*/
|
||||
exports.getPad = function(id, text, callback)
|
||||
{
|
||||
PadManager.prototype.getPad = function getPad(id, text, callback)
|
||||
{
|
||||
var that = this;
|
||||
|
||||
//TODO remove api specific shit
|
||||
//check if this is a valid padId
|
||||
if(!exports.isValidPadId(id))
|
||||
if(!this.isValidPadId(id))
|
||||
{
|
||||
callback(new customError(id + " is not a valid padId","apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//make text an optional parameter
|
||||
if(typeof text == "function")
|
||||
{
|
||||
callback = text;
|
||||
text = null;
|
||||
}
|
||||
|
||||
|
||||
//check if this is a valid text
|
||||
if(text != null)
|
||||
{
|
||||
|
@ -76,7 +89,7 @@ exports.getPad = function(id, text, callback)
|
|||
callback(new customError("text is not a string","apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//check if text is less than 100k chars
|
||||
if(text.length > 100000)
|
||||
{
|
||||
|
@ -84,42 +97,50 @@ exports.getPad = function(id, text, callback)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var pad = globalPads.get(id);
|
||||
|
||||
|
||||
var pad = this.globalPads.get(id);
|
||||
|
||||
//return pad if its already loaded
|
||||
if(pad != null)
|
||||
{
|
||||
if(pad != null) {
|
||||
callback(null, pad);
|
||||
}
|
||||
//try to load pad
|
||||
else
|
||||
{
|
||||
else {
|
||||
pad = new Pad(id);
|
||||
|
||||
|
||||
//add some references
|
||||
//TODO is this realy nice?
|
||||
pad.padManager = this;
|
||||
pad.db = this.db;
|
||||
pad.readOnlyManager = this.readOnlyManager;
|
||||
pad.authorManager = this.authorManager;
|
||||
|
||||
//initalize the pad
|
||||
pad.init(text, function(err)
|
||||
{
|
||||
if(!text) {
|
||||
text = this.settings.defaultPadText;
|
||||
}
|
||||
pad.init(text, function(err) {
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
globalPads.set(id, pad);
|
||||
|
||||
that.globalPads.set(id, pad);
|
||||
callback(null, pad);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//checks if a pad exists
|
||||
exports.doesPadExists = function(padId, callback)
|
||||
PadManager.prototype.doesPadExists = function doesPadExists(padId, callback)
|
||||
{
|
||||
db.get("pad:"+padId, function(err, value)
|
||||
this.db.get("pad:"+padId, function(err, value)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
callback(null, value != null);
|
||||
callback(null, value != null);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//returns a sanitized padId, respecting legacy pad id formats
|
||||
exports.sanitizePadId = function(padId, callback) {
|
||||
PadManager.prototype.sanitizePadId = function sanitizePadId(padId, callback) {
|
||||
var that = this;
|
||||
var transform_index = arguments[2] || 0;
|
||||
//we're out of possible transformations, so just return it
|
||||
if(transform_index >= padIdTransforms.length)
|
||||
|
@ -129,7 +150,7 @@ exports.sanitizePadId = function(padId, callback) {
|
|||
//check if padId exists
|
||||
else
|
||||
{
|
||||
exports.doesPadExists(padId, function(junk, exists)
|
||||
this.doesPadExists(padId, function(junk, exists)
|
||||
{
|
||||
if(exists)
|
||||
{
|
||||
|
@ -145,20 +166,18 @@ exports.sanitizePadId = function(padId, callback) {
|
|||
transform_index += 1;
|
||||
}
|
||||
//check the next transform
|
||||
exports.sanitizePadId(transformedPadId, callback, transform_index);
|
||||
that.sanitizePadId(transformedPadId, callback, transform_index);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.isValidPadId = function(padId)
|
||||
{
|
||||
return /^(g.[a-zA-Z0-9]{16}\$)?[^$]{1,50}$/.test(padId);
|
||||
}
|
||||
PadManager.prototype.isValidPadId = function(padId) {
|
||||
return (/^(g.[a-zA-Z0-9]{16}\$)?[^$]{1,50}$/).test(padId);
|
||||
};
|
||||
|
||||
//removes a pad from the array
|
||||
exports.unloadPad = function(padId)
|
||||
{
|
||||
if(globalPads.get(padId))
|
||||
globalPads.remove(padId);
|
||||
}
|
||||
Pad.prototype.unloadPad = function unloadPad(padId) {
|
||||
if(this.globalPads.get(padId))
|
||||
this.globalPads.remove(padId);
|
||||
};
|
||||
|
|
|
@ -19,24 +19,31 @@
|
|||
*/
|
||||
|
||||
var ERR = require("async-stacktrace");
|
||||
var db = require("./DB").db;
|
||||
var async = require("async");
|
||||
|
||||
var randomString = require("../utils/randomstring");
|
||||
|
||||
|
||||
var ReadOnlyManager = function ReadOnlyManager(db) {
|
||||
this.db = db;
|
||||
};
|
||||
|
||||
exports.ReadOnlyManager = ReadOnlyManager;
|
||||
|
||||
/**
|
||||
* returns a read only id for a pad
|
||||
* @param {String} padId the id of the pad
|
||||
*/
|
||||
exports.getReadOnlyId = function (padId, callback)
|
||||
{
|
||||
ReadOnlyManager.prototype.getReadOnlyId = function getReadOnlyId(padId, callback) {
|
||||
var that = this;
|
||||
|
||||
var readOnlyId;
|
||||
|
||||
|
||||
async.waterfall([
|
||||
//check if there is a pad2readonly entry
|
||||
function(callback)
|
||||
{
|
||||
db.get("pad2readonly:" + padId, callback);
|
||||
that.db.get("pad2readonly:" + padId, callback);
|
||||
},
|
||||
function(dbReadOnlyId, callback)
|
||||
{
|
||||
|
@ -44,16 +51,16 @@ exports.getReadOnlyId = function (padId, callback)
|
|||
if(dbReadOnlyId == null)
|
||||
{
|
||||
readOnlyId = "r." + randomString(16);
|
||||
|
||||
db.set("pad2readonly:" + padId, readOnlyId);
|
||||
db.set("readonly2pad:" + readOnlyId, padId);
|
||||
|
||||
that.db.set("pad2readonly:" + padId, readOnlyId);
|
||||
that.db.set("readonly2pad:" + readOnlyId, padId);
|
||||
}
|
||||
//there is a readOnly Entry in the database, let's take this one
|
||||
else
|
||||
{
|
||||
readOnlyId = dbReadOnlyId;
|
||||
}
|
||||
|
||||
|
||||
callback();
|
||||
}
|
||||
], function(err)
|
||||
|
@ -61,14 +68,13 @@ exports.getReadOnlyId = function (padId, callback)
|
|||
if(ERR(err, callback)) return;
|
||||
//return the results
|
||||
callback(null, readOnlyId);
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* returns a the padId for a read only id
|
||||
* @param {String} readOnlyId read only id
|
||||
*/
|
||||
exports.getPadId = function(readOnlyId, callback)
|
||||
{
|
||||
db.get("readonly2pad:" + readOnlyId, callback);
|
||||
}
|
||||
ReadOnlyManager.prototype.getPadId = function(readOnlyId, callback) {
|
||||
this.db.get("readonly2pad:" + readOnlyId, callback);
|
||||
};
|
||||
|
|
|
@ -19,15 +19,20 @@
|
|||
*/
|
||||
|
||||
var ERR = require("async-stacktrace");
|
||||
var db = require("./DB").db;
|
||||
var async = require("async");
|
||||
var authorManager = require("./AuthorManager");
|
||||
var padManager = require("./PadManager");
|
||||
var sessionManager = require("./SessionManager");
|
||||
var settings = require("../utils/Settings")
|
||||
|
||||
var randomString = require("../utils/randomstring");
|
||||
|
||||
var SecurityManager = function SecurityManager(settings, db, authorManager, padManager, sessionManager) {
|
||||
this.db = db;
|
||||
this.settings = settings;
|
||||
this.authorManager = authorManager;
|
||||
this.padManager = padManager;
|
||||
this.sessionManager = sessionManager;
|
||||
};
|
||||
|
||||
exports.SecurityManager = SecurityManager;
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -36,12 +41,13 @@ var randomString = require("../utils/randomstring");
|
|||
* @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)
|
||||
SecurityManager.prototype.checkAccess = function checkAccess(padID, sessionID, token, password, callback)
|
||||
{
|
||||
var that = this;
|
||||
var statusObject;
|
||||
|
||||
// a valid session is required (api-only mode)
|
||||
if(settings.requireSession)
|
||||
if(this.settings.requireSession)
|
||||
{
|
||||
// no sessionID, access is denied
|
||||
if(!sessionID)
|
||||
|
@ -57,17 +63,17 @@ exports.checkAccess = function (padID, sessionID, token, password, callback)
|
|||
if(padID.indexOf("$") == -1)
|
||||
{
|
||||
//get author for this token
|
||||
authorManager.getAuthor4Token(token, function(err, author)
|
||||
this.authorManager.getAuthor4Token(token, function(err, author)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
// assume user has access
|
||||
statusObject = {accessStatus: "grant", authorID: author};
|
||||
// user can't create pads
|
||||
if(settings.editOnly)
|
||||
if(that.settings.editOnly)
|
||||
{
|
||||
// check if pad exists
|
||||
padManager.doesPadExists(padID, function(err, exists)
|
||||
that.padManager.doesPadExists(padID, function(err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
@ -107,7 +113,7 @@ exports.checkAccess = function (padID, sessionID, token, password, callback)
|
|||
//does pad exists
|
||||
function(callback)
|
||||
{
|
||||
padManager.doesPadExists(padID, function(err, exists)
|
||||
that.padManager.doesPadExists(padID, function(err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
padExists = exists;
|
||||
|
@ -117,7 +123,7 @@ exports.checkAccess = function (padID, sessionID, token, password, callback)
|
|||
//get informations about this session
|
||||
function(callback)
|
||||
{
|
||||
sessionManager.getSessionInfo(sessionID, function(err, sessionInfo)
|
||||
that.sessionManager.getSessionInfo(sessionID, function(err, sessionInfo)
|
||||
{
|
||||
//skip session validation if the session doesn't exists
|
||||
if(err && err.message == "sessionID does not exist")
|
||||
|
@ -145,7 +151,7 @@ exports.checkAccess = function (padID, sessionID, token, password, callback)
|
|||
function(callback)
|
||||
{
|
||||
//get author for this token
|
||||
authorManager.getAuthor4Token(token, function(err, author)
|
||||
that.authorManager.getAuthor4Token(token, function(err, author)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
tokenAuthor = author;
|
||||
|
@ -164,7 +170,7 @@ exports.checkAccess = function (padID, sessionID, token, password, callback)
|
|||
return;
|
||||
}
|
||||
|
||||
padManager.getPad(padID, function(err, pad)
|
||||
that.padManager.getPad(padID, function(err, pad)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
@ -223,7 +229,7 @@ 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";
|
||||
if(that.settings.editOnly) statusObject.accessStatus = "deny";
|
||||
}
|
||||
// there is no valid session avaiable AND pad exists
|
||||
else if(!validSession && padExists)
|
||||
|
@ -277,4 +283,4 @@ exports.checkAccess = function (padID, sessionID, token, password, callback)
|
|||
if(ERR(err, callback)) return;
|
||||
callback(null, statusObject);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -17,40 +17,47 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
var ERR = require("async-stacktrace");
|
||||
var customError = require("../utils/customError");
|
||||
var randomString = require("../utils/randomstring");
|
||||
var db = require("./DB").db;
|
||||
var async = require("async");
|
||||
var groupMangager = require("./GroupManager");
|
||||
var authorMangager = require("./AuthorManager");
|
||||
|
||||
exports.doesSessionExist = function(sessionID, callback)
|
||||
|
||||
|
||||
var SessionManager = function SessionManager(db, groupManager, authorManager) {
|
||||
this.db = db;
|
||||
this.groupManager = groupManager;
|
||||
this.authorManager = authorManager;
|
||||
};
|
||||
|
||||
exports.SessionManager = SessionManager;
|
||||
|
||||
SessionManager.prototype.doesSessionExist = function(sessionID, callback)
|
||||
{
|
||||
//check if the database entry of this session exists
|
||||
db.get("session:" + sessionID, function (err, session)
|
||||
this.db.get("session:" + sessionID, function (err, session)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
callback(null, session != null);
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new session between an author and a group
|
||||
*/
|
||||
exports.createSession = function(groupID, authorID, validUntil, callback)
|
||||
SessionManager.prototype.createSession = function(groupID, authorID, validUntil, callback)
|
||||
{
|
||||
var sessionID;
|
||||
var that = this;
|
||||
|
||||
async.series([
|
||||
//check if group exists
|
||||
function(callback)
|
||||
{
|
||||
groupMangager.doesGroupExist(groupID, function(err, exists)
|
||||
that.groupMangager.doesGroupExist(groupID, function(err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//group does not exist
|
||||
if(exists == false)
|
||||
{
|
||||
|
@ -66,10 +73,10 @@ exports.createSession = function(groupID, authorID, validUntil, callback)
|
|||
//check if author exists
|
||||
function(callback)
|
||||
{
|
||||
authorMangager.doesAuthorExists(authorID, function(err, exists)
|
||||
that.authorMangager.doesAuthorExists(authorID, function(err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//author does not exist
|
||||
if(exists == false)
|
||||
{
|
||||
|
@ -99,56 +106,56 @@ exports.createSession = function(groupID, authorID, validUntil, callback)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//ensure this is not a negativ number
|
||||
if(validUntil < 0)
|
||||
{
|
||||
callback(new customError("validUntil is a negativ number","apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//ensure this is not a float value
|
||||
if(!is_int(validUntil))
|
||||
{
|
||||
callback(new customError("validUntil is a float value","apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//check if validUntil is in the future
|
||||
if(Math.floor(new Date().getTime()/1000) > validUntil)
|
||||
{
|
||||
callback(new customError("validUntil is in the past","apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//generate sessionID
|
||||
sessionID = "s." + randomString(16);
|
||||
|
||||
|
||||
//set the session into the database
|
||||
db.set("session:" + sessionID, {"groupID": groupID, "authorID": authorID, "validUntil": validUntil});
|
||||
|
||||
that.db.set("session:" + sessionID, {"groupID": groupID, "authorID": authorID, "validUntil": validUntil});
|
||||
|
||||
callback();
|
||||
},
|
||||
//set the group2sessions entry
|
||||
function(callback)
|
||||
{
|
||||
//get the entry
|
||||
db.get("group2sessions:" + groupID, function(err, group2sessions)
|
||||
that.db.get("group2sessions:" + groupID, function(err, group2sessions)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//the entry doesn't exist so far, let's create it
|
||||
if(group2sessions == null)
|
||||
{
|
||||
group2sessions = {sessionIDs : {}};
|
||||
}
|
||||
|
||||
|
||||
//add the entry for this session
|
||||
group2sessions.sessionIDs[sessionID] = 1;
|
||||
|
||||
|
||||
//save the new element back
|
||||
db.set("group2sessions:" + groupID, group2sessions);
|
||||
|
||||
that.db.set("group2sessions:" + groupID, group2sessions);
|
||||
|
||||
callback();
|
||||
});
|
||||
},
|
||||
|
@ -156,45 +163,45 @@ exports.createSession = function(groupID, authorID, validUntil, callback)
|
|||
function(callback)
|
||||
{
|
||||
//get the entry
|
||||
db.get("author2sessions:" + authorID, function(err, author2sessions)
|
||||
that.db.get("author2sessions:" + authorID, function(err, author2sessions)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//the entry doesn't exist so far, let's create it
|
||||
if(author2sessions == null)
|
||||
{
|
||||
author2sessions = {sessionIDs : {}};
|
||||
}
|
||||
|
||||
|
||||
//add the entry for this session
|
||||
author2sessions.sessionIDs[sessionID] = 1;
|
||||
|
||||
|
||||
//save the new element back
|
||||
db.set("author2sessions:" + authorID, author2sessions);
|
||||
|
||||
that.db.set("author2sessions:" + authorID, author2sessions);
|
||||
|
||||
callback();
|
||||
});
|
||||
}
|
||||
], function(err)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//return error and sessionID
|
||||
callback(null, {sessionID: sessionID});
|
||||
})
|
||||
}
|
||||
|
||||
exports.getSessionInfo = function(sessionID, callback)
|
||||
SessionManager.prototype.getSessionInfo = function(sessionID, callback)
|
||||
{
|
||||
//check if the database entry of this session exists
|
||||
db.get("session:" + sessionID, function (err, session)
|
||||
this.db.get("session:" + sessionID, function (err, session)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//session does not exists
|
||||
if(session == null)
|
||||
{
|
||||
callback(new customError("sessionID does not exist","apierror"))
|
||||
callback(new customError("sessionID does not exist","apierror"));
|
||||
}
|
||||
//everything is fine, return the sessioninfos
|
||||
else
|
||||
|
@ -202,7 +209,7 @@ exports.getSessionInfo = function(sessionID, callback)
|
|||
callback(null, session);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes a session
|
||||
|
@ -211,15 +218,16 @@ exports.deleteSession = function(sessionID, callback)
|
|||
{
|
||||
var authorID, groupID;
|
||||
var group2sessions, author2sessions;
|
||||
var that = this;
|
||||
|
||||
async.series([
|
||||
function(callback)
|
||||
{
|
||||
//get the session entry
|
||||
db.get("session:" + sessionID, function (err, session)
|
||||
that.db.get("session:" + sessionID, function (err, session)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//session does not exists
|
||||
if(session == null)
|
||||
{
|
||||
|
@ -230,7 +238,7 @@ exports.deleteSession = function(sessionID, callback)
|
|||
{
|
||||
authorID = session.authorID;
|
||||
groupID = session.groupID;
|
||||
|
||||
|
||||
callback();
|
||||
}
|
||||
});
|
||||
|
@ -238,7 +246,7 @@ exports.deleteSession = function(sessionID, callback)
|
|||
//get the group2sessions entry
|
||||
function(callback)
|
||||
{
|
||||
db.get("group2sessions:" + groupID, function (err, _group2sessions)
|
||||
that.db.get("group2sessions:" + groupID, function (err, _group2sessions)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
group2sessions = _group2sessions;
|
||||
|
@ -248,7 +256,7 @@ exports.deleteSession = function(sessionID, callback)
|
|||
//get the author2sessions entry
|
||||
function(callback)
|
||||
{
|
||||
db.get("author2sessions:" + authorID, function (err, _author2sessions)
|
||||
that.db.get("author2sessions:" + authorID, function (err, _author2sessions)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
author2sessions = _author2sessions;
|
||||
|
@ -259,16 +267,16 @@ exports.deleteSession = function(sessionID, callback)
|
|||
function(callback)
|
||||
{
|
||||
//remove the session
|
||||
db.remove("session:" + sessionID);
|
||||
|
||||
that.db.remove("session:" + sessionID);
|
||||
|
||||
//remove session from group2sessions
|
||||
delete group2sessions.sessionIDs[sessionID];
|
||||
db.set("group2sessions:" + groupID, group2sessions);
|
||||
|
||||
that.db.set("group2sessions:" + groupID, group2sessions);
|
||||
|
||||
//remove session from author2sessions
|
||||
delete author2sessions.sessionIDs[sessionID];
|
||||
db.set("author2sessions:" + authorID, author2sessions);
|
||||
|
||||
that.db.set("author2sessions:" + authorID, author2sessions);
|
||||
|
||||
callback();
|
||||
}
|
||||
], function(err)
|
||||
|
@ -276,14 +284,15 @@ exports.deleteSession = function(sessionID, callback)
|
|||
if(ERR(err, callback)) return;
|
||||
callback();
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
exports.listSessionsOfGroup = function(groupID, callback)
|
||||
SessionManager.prototype.listSessionsOfGroup = function(groupID, callback)
|
||||
{
|
||||
groupMangager.doesGroupExist(groupID, function(err, exists)
|
||||
var that = this;
|
||||
this.groupMangager.doesGroupExist(groupID, function(err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//group does not exist
|
||||
if(exists == false)
|
||||
{
|
||||
|
@ -292,17 +301,18 @@ exports.listSessionsOfGroup = function(groupID, callback)
|
|||
//everything is fine, continue
|
||||
else
|
||||
{
|
||||
listSessionsWithDBKey("group2sessions:" + groupID, callback);
|
||||
that.listSessionsWithDBKey("group2sessions:" + groupID, callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
exports.listSessionsOfAuthor = function(authorID, callback)
|
||||
{
|
||||
authorMangager.doesAuthorExists(authorID, function(err, exists)
|
||||
SessionManager.prototype.listSessionsOfAuthor = function(authorID, callback)
|
||||
{
|
||||
var that = this;
|
||||
this.authorMangager.doesAuthorExists(authorID, function(err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//group does not exist
|
||||
if(exists == false)
|
||||
{
|
||||
|
@ -311,21 +321,21 @@ exports.listSessionsOfAuthor = function(authorID, callback)
|
|||
//everything is fine, continue
|
||||
else
|
||||
{
|
||||
listSessionsWithDBKey("author2sessions:" + authorID, callback);
|
||||
that.listSessionsWithDBKey("author2sessions:" + authorID, callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//this function is basicly the code listSessionsOfAuthor and listSessionsOfGroup has in common
|
||||
function listSessionsWithDBKey (dbkey, callback)
|
||||
SessionManager.prototype.listSessionsWithDBKey = function listSessionsWithDBKey (dbkey, callback)
|
||||
{
|
||||
var sessions;
|
||||
|
||||
var that = this;
|
||||
async.series([
|
||||
function(callback)
|
||||
{
|
||||
//get the group2sessions entry
|
||||
db.get(dbkey, function(err, sessionObject)
|
||||
that.db.get(dbkey, function(err, sessionObject)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
sessions = sessionObject ? sessionObject.sessionIDs : null;
|
||||
|
@ -333,18 +343,18 @@ function listSessionsWithDBKey (dbkey, callback)
|
|||
});
|
||||
},
|
||||
function(callback)
|
||||
{
|
||||
{
|
||||
//collect all sessionIDs in an arrary
|
||||
var sessionIDs = [];
|
||||
for (var i in sessions)
|
||||
{
|
||||
sessionIDs.push(i);
|
||||
}
|
||||
|
||||
|
||||
//foreach trough the sessions and get the sessioninfos
|
||||
async.forEach(sessionIDs, function(sessionID, callback)
|
||||
{
|
||||
exports.getSessionInfo(sessionID, function(err, sessionInfo)
|
||||
that.getSessionInfo(sessionID, function(err, sessionInfo)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
sessions[sessionID] = sessionInfo;
|
||||
|
@ -360,7 +370,6 @@ function listSessionsWithDBKey (dbkey, callback)
|
|||
}
|
||||
|
||||
//checks if a number is an int
|
||||
function is_int(value)
|
||||
{
|
||||
return (parseFloat(value) == parseInt(value)) && !isNaN(value)
|
||||
function is_int(value) {
|
||||
return (parseFloat(value) == parseInt(value, 10)) && !isNaN(value);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue