2011-08-03 19:31:25 +01:00
|
|
|
/**
|
2013-02-13 01:33:22 +00:00
|
|
|
* The Session Manager provides functions to manage session in the database, it only provides session management for sessions created by the API
|
2011-08-03 19:31:25 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2011-08-11 15:26:41 +01:00
|
|
|
* 2011 Peter 'Pita' Martischka (Primary Technology Ltd)
|
2011-08-03 19:31:25 +01:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
2012-02-28 21:19:10 +01:00
|
|
|
|
2011-12-04 16:50:02 +01:00
|
|
|
var ERR = require("async-stacktrace");
|
2011-12-10 16:46:47 +01:00
|
|
|
var customError = require("../utils/customError");
|
2014-01-15 11:25:47 -08:00
|
|
|
var randomString = require("../utils/randomstring");
|
2011-08-09 16:45:49 +01:00
|
|
|
var db = require("./DB").db;
|
|
|
|
var async = require("async");
|
|
|
|
var groupMangager = require("./GroupManager");
|
|
|
|
var authorMangager = require("./AuthorManager");
|
2019-02-08 23:20:57 +01:00
|
|
|
|
2011-08-09 16:45:49 +01:00
|
|
|
exports.doesSessionExist = function(sessionID, callback)
|
|
|
|
{
|
|
|
|
//check if the database entry of this session exists
|
|
|
|
db.get("session:" + sessionID, function (err, session)
|
|
|
|
{
|
2011-12-04 16:50:02 +01:00
|
|
|
if(ERR(err, callback)) return;
|
|
|
|
callback(null, session != null);
|
2011-08-09 16:45:49 +01:00
|
|
|
});
|
|
|
|
}
|
2019-02-08 23:20:57 +01:00
|
|
|
|
2011-08-09 16:45:49 +01:00
|
|
|
/**
|
|
|
|
* Creates a new session between an author and a group
|
|
|
|
*/
|
|
|
|
exports.createSession = function(groupID, authorID, validUntil, callback)
|
|
|
|
{
|
|
|
|
var sessionID;
|
|
|
|
|
|
|
|
async.series([
|
2019-02-08 23:20:57 +01:00
|
|
|
// check if the group exists
|
2011-08-09 16:45:49 +01:00
|
|
|
function(callback)
|
|
|
|
{
|
|
|
|
groupMangager.doesGroupExist(groupID, function(err, exists)
|
|
|
|
{
|
2011-12-04 16:50:02 +01:00
|
|
|
if(ERR(err, callback)) return;
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// group does not exist
|
|
|
|
if (exists == false) {
|
|
|
|
callback(new customError("groupID does not exist", "apierror"));
|
|
|
|
} else {
|
|
|
|
// everything is fine, continue
|
2011-08-09 16:45:49 +01:00
|
|
|
callback();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// check if the author exists
|
2011-08-09 16:45:49 +01:00
|
|
|
function(callback)
|
|
|
|
{
|
|
|
|
authorMangager.doesAuthorExists(authorID, function(err, exists)
|
|
|
|
{
|
2011-12-04 16:50:02 +01:00
|
|
|
if(ERR(err, callback)) return;
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
if (exists == false) {
|
|
|
|
// author does not exist
|
|
|
|
callback(new customError("authorID does not exist", "apierror"));
|
|
|
|
} else {
|
|
|
|
// everything is fine, continue
|
2011-08-09 16:45:49 +01:00
|
|
|
callback();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// check validUntil and create the session db entry
|
2011-08-09 16:45:49 +01:00
|
|
|
function(callback)
|
|
|
|
{
|
2019-02-08 23:20:57 +01:00
|
|
|
// check if rev is a number
|
|
|
|
if (typeof validUntil != "number")
|
2011-08-09 16:45:49 +01:00
|
|
|
{
|
2019-02-08 23:20:57 +01:00
|
|
|
// try to parse the number
|
|
|
|
if (isNaN(parseInt(validUntil))) {
|
|
|
|
callback(new customError("validUntil is not a number", "apierror"));
|
2011-08-09 16:45:49 +01:00
|
|
|
return;
|
|
|
|
}
|
2018-08-29 02:08:05 +02:00
|
|
|
|
|
|
|
validUntil = parseInt(validUntil);
|
2011-08-09 16:45:49 +01:00
|
|
|
}
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// ensure this is not a negative number
|
|
|
|
if (validUntil < 0) {
|
|
|
|
callback(new customError("validUntil is a negativ number", "apierror"));
|
2011-08-09 16:45:49 +01:00
|
|
|
return;
|
|
|
|
}
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// ensure this is not a float value
|
|
|
|
if (!is_int(validUntil)) {
|
|
|
|
callback(new customError("validUntil is a float value", "apierror"));
|
2011-08-09 16:45:49 +01:00
|
|
|
return;
|
|
|
|
}
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// check if validUntil is in the future
|
|
|
|
if (Math.floor(Date.now()/1000) > validUntil) {
|
|
|
|
callback(new customError("validUntil is in the past", "apierror"));
|
2011-08-09 16:45:49 +01:00
|
|
|
return;
|
|
|
|
}
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// generate sessionID
|
2011-08-09 16:45:49 +01:00
|
|
|
sessionID = "s." + randomString(16);
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// set the session into the database
|
2011-08-09 16:45:49 +01:00
|
|
|
db.set("session:" + sessionID, {"groupID": groupID, "authorID": authorID, "validUntil": validUntil});
|
2019-02-08 23:20:57 +01:00
|
|
|
|
2011-08-09 16:45:49 +01:00
|
|
|
callback();
|
|
|
|
},
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// set the group2sessions entry
|
2011-08-09 16:45:49 +01:00
|
|
|
function(callback)
|
|
|
|
{
|
2019-02-08 23:20:57 +01:00
|
|
|
// get the entry
|
2011-08-09 16:45:49 +01:00
|
|
|
db.get("group2sessions:" + groupID, function(err, group2sessions)
|
|
|
|
{
|
2011-12-04 16:50:02 +01:00
|
|
|
if(ERR(err, callback)) return;
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
if (group2sessions == null || group2sessions.sessionIDs == null) {
|
|
|
|
// the entry doesn't exist so far, let's create it
|
2011-08-09 20:14:32 +01:00
|
|
|
group2sessions = {sessionIDs : {}};
|
2011-08-09 16:45:49 +01:00
|
|
|
}
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// add the entry for this session
|
2011-08-09 20:14:32 +01:00
|
|
|
group2sessions.sessionIDs[sessionID] = 1;
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// save the new element back
|
2011-08-09 20:14:32 +01:00
|
|
|
db.set("group2sessions:" + groupID, group2sessions);
|
2019-02-08 23:20:57 +01:00
|
|
|
|
2011-08-09 16:45:49 +01:00
|
|
|
callback();
|
|
|
|
});
|
|
|
|
},
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// set the author2sessions entry
|
2011-08-09 16:45:49 +01:00
|
|
|
function(callback)
|
|
|
|
{
|
2019-02-08 23:20:57 +01:00
|
|
|
// get the entry
|
2011-08-09 16:45:49 +01:00
|
|
|
db.get("author2sessions:" + authorID, function(err, author2sessions)
|
|
|
|
{
|
2011-12-04 16:50:02 +01:00
|
|
|
if(ERR(err, callback)) return;
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
if (author2sessions == null || author2sessions.sessionIDs == null) {
|
|
|
|
// the entry doesn't exist so far, let's create it
|
2011-08-09 20:14:32 +01:00
|
|
|
author2sessions = {sessionIDs : {}};
|
2011-08-09 16:45:49 +01:00
|
|
|
}
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// add the entry for this session
|
2011-08-09 20:14:32 +01:00
|
|
|
author2sessions.sessionIDs[sessionID] = 1;
|
2019-02-08 23:20:57 +01:00
|
|
|
|
2011-08-09 20:14:32 +01:00
|
|
|
//save the new element back
|
|
|
|
db.set("author2sessions:" + authorID, author2sessions);
|
2019-02-08 23:20:57 +01:00
|
|
|
|
2011-08-09 16:45:49 +01:00
|
|
|
callback();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
], function(err)
|
|
|
|
{
|
2011-12-04 16:50:02 +01:00
|
|
|
if(ERR(err, callback)) return;
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// return error and sessionID
|
2011-12-04 16:50:02 +01:00
|
|
|
callback(null, {sessionID: sessionID});
|
2011-08-09 16:45:49 +01:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
exports.getSessionInfo = function(sessionID, callback)
|
|
|
|
{
|
2019-02-08 23:20:57 +01:00
|
|
|
// check if the database entry of this session exists
|
2011-08-09 16:45:49 +01:00
|
|
|
db.get("session:" + sessionID, function (err, session)
|
|
|
|
{
|
2011-12-04 16:50:02 +01:00
|
|
|
if(ERR(err, callback)) return;
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
if (session == null) {
|
|
|
|
// session does not exist
|
|
|
|
callback(new customError("sessionID does not exist", "apierror"))
|
|
|
|
} else {
|
|
|
|
// everything is fine, return the sessioninfos
|
2011-08-09 16:45:49 +01:00
|
|
|
callback(null, session);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Deletes a session
|
|
|
|
*/
|
|
|
|
exports.deleteSession = function(sessionID, callback)
|
|
|
|
{
|
2011-08-10 14:04:28 +01:00
|
|
|
var authorID, groupID;
|
|
|
|
var group2sessions, author2sessions;
|
|
|
|
|
|
|
|
async.series([
|
|
|
|
function(callback)
|
|
|
|
{
|
2019-02-08 23:20:57 +01:00
|
|
|
// get the session entry
|
2011-08-10 14:04:28 +01:00
|
|
|
db.get("session:" + sessionID, function (err, session)
|
|
|
|
{
|
2011-12-04 16:50:02 +01:00
|
|
|
if(ERR(err, callback)) return;
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
if (session == null) {
|
|
|
|
// session does not exist
|
|
|
|
callback(new customError("sessionID does not exist", "apierror"))
|
|
|
|
} else {
|
|
|
|
// everything is fine, use the sessioninfos
|
2011-08-10 14:04:28 +01:00
|
|
|
authorID = session.authorID;
|
|
|
|
groupID = session.groupID;
|
2019-02-08 23:20:57 +01:00
|
|
|
|
2011-08-10 14:04:28 +01:00
|
|
|
callback();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// get the group2sessions entry
|
2011-08-10 14:04:28 +01:00
|
|
|
function(callback)
|
|
|
|
{
|
|
|
|
db.get("group2sessions:" + groupID, function (err, _group2sessions)
|
|
|
|
{
|
2011-12-04 16:50:02 +01:00
|
|
|
if(ERR(err, callback)) return;
|
2011-08-10 14:04:28 +01:00
|
|
|
group2sessions = _group2sessions;
|
2011-12-04 16:50:02 +01:00
|
|
|
callback();
|
2011-08-10 14:04:28 +01:00
|
|
|
});
|
|
|
|
},
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// get the author2sessions entry
|
2011-08-10 14:04:28 +01:00
|
|
|
function(callback)
|
|
|
|
{
|
|
|
|
db.get("author2sessions:" + authorID, function (err, _author2sessions)
|
|
|
|
{
|
2011-12-04 16:50:02 +01:00
|
|
|
if(ERR(err, callback)) return;
|
2011-08-10 14:04:28 +01:00
|
|
|
author2sessions = _author2sessions;
|
2011-12-04 16:50:02 +01:00
|
|
|
callback();
|
2011-08-10 14:04:28 +01:00
|
|
|
});
|
|
|
|
},
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// remove the values from the database
|
2011-08-10 14:04:28 +01:00
|
|
|
function(callback)
|
|
|
|
{
|
|
|
|
//remove the session
|
|
|
|
db.remove("session:" + sessionID);
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// remove session from group2sessions
|
2014-03-14 17:50:37 +01:00
|
|
|
if(group2sessions != null) { // Maybe the group was already deleted
|
|
|
|
delete group2sessions.sessionIDs[sessionID];
|
|
|
|
db.set("group2sessions:" + groupID, group2sessions);
|
|
|
|
}
|
|
|
|
|
2019-02-08 23:20:57 +01:00
|
|
|
// remove session from author2sessions
|
2014-03-14 17:50:37 +01:00
|
|
|
if(author2sessions != null) { // Maybe the author was already deleted
|
|
|
|
delete author2sessions.sessionIDs[sessionID];
|
|
|
|
db.set("author2sessions:" + authorID, author2sessions);
|
|
|
|
}
|
2019-02-08 23:20:57 +01:00
|
|
|
|
2011-08-10 14:04:28 +01:00
|
|
|
callback();
|
|
|
|
}
|
|
|
|
], function(err)
|
|
|
|
{
|
2011-12-04 16:50:02 +01:00
|
|
|
if(ERR(err, callback)) return;
|
|
|
|
callback();
|
2011-08-10 14:04:28 +01:00
|
|
|
})
|
2011-08-09 16:45:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
exports.listSessionsOfGroup = function(groupID, callback)
|
|
|
|
{
|
2011-08-09 20:14:32 +01:00
|
|
|
groupMangager.doesGroupExist(groupID, function(err, exists)
|
|
|
|
{
|
2011-12-04 16:50:02 +01:00
|
|
|
if(ERR(err, callback)) return;
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
if (exists == false) {
|
|
|
|
// group does not exist
|
|
|
|
callback(new customError("groupID does not exist", "apierror"));
|
|
|
|
} else {
|
|
|
|
// everything is fine, continue
|
2011-08-09 20:14:32 +01:00
|
|
|
listSessionsWithDBKey("group2sessions:" + groupID, callback);
|
|
|
|
}
|
|
|
|
});
|
2011-08-09 16:45:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
exports.listSessionsOfAuthor = function(authorID, callback)
|
2019-02-08 23:20:57 +01:00
|
|
|
{
|
2011-08-09 20:14:32 +01:00
|
|
|
authorMangager.doesAuthorExists(authorID, function(err, exists)
|
|
|
|
{
|
2011-12-04 16:50:02 +01:00
|
|
|
if(ERR(err, callback)) return;
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
if (exists == false) {
|
|
|
|
// group does not exist
|
|
|
|
callback(new customError("authorID does not exist", "apierror"));
|
|
|
|
} else {
|
|
|
|
// everything is fine, continue
|
2011-08-09 20:14:32 +01:00
|
|
|
listSessionsWithDBKey("author2sessions:" + authorID, callback);
|
|
|
|
}
|
|
|
|
});
|
2011-08-09 16:45:49 +01:00
|
|
|
}
|
|
|
|
|
2019-02-08 23:20:57 +01:00
|
|
|
// this function is basically the code listSessionsOfAuthor and listSessionsOfGroup has in common
|
2011-08-09 20:14:32 +01:00
|
|
|
function listSessionsWithDBKey (dbkey, callback)
|
2011-08-09 16:45:49 +01:00
|
|
|
{
|
2011-08-09 20:14:32 +01:00
|
|
|
var sessions;
|
2011-08-09 16:45:49 +01:00
|
|
|
|
2011-08-09 20:14:32 +01:00
|
|
|
async.series([
|
|
|
|
function(callback)
|
|
|
|
{
|
2019-02-08 23:20:57 +01:00
|
|
|
// get the group2sessions entry
|
2011-08-09 20:14:32 +01:00
|
|
|
db.get(dbkey, function(err, sessionObject)
|
|
|
|
{
|
2011-12-04 16:50:02 +01:00
|
|
|
if(ERR(err, callback)) return;
|
2011-08-09 20:14:32 +01:00
|
|
|
sessions = sessionObject ? sessionObject.sessionIDs : null;
|
2011-12-04 16:50:02 +01:00
|
|
|
callback();
|
2011-08-09 20:14:32 +01:00
|
|
|
});
|
|
|
|
},
|
2019-02-08 23:20:57 +01:00
|
|
|
|
2011-08-09 20:14:32 +01:00
|
|
|
function(callback)
|
2019-02-08 23:20:57 +01:00
|
|
|
{
|
|
|
|
// collect all sessionIDs in an arrary
|
2011-08-09 20:14:32 +01:00
|
|
|
var sessionIDs = [];
|
|
|
|
for (var i in sessions)
|
|
|
|
{
|
|
|
|
sessionIDs.push(i);
|
|
|
|
}
|
2019-02-08 23:20:57 +01:00
|
|
|
|
|
|
|
// iterate through the sessions and get the sessioninfos
|
2011-08-09 20:14:32 +01:00
|
|
|
async.forEach(sessionIDs, function(sessionID, callback)
|
|
|
|
{
|
|
|
|
exports.getSessionInfo(sessionID, function(err, sessionInfo)
|
|
|
|
{
|
2019-02-08 23:20:57 +01:00
|
|
|
if (err == "apierror: sessionID does not exist") {
|
2018-08-27 01:29:37 +02:00
|
|
|
console.warn(`Found bad session ${sessionID} in ${dbkey}`);
|
2019-02-08 23:20:57 +01:00
|
|
|
} else if(ERR(err, callback)) {
|
2013-03-29 10:09:39 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-08-09 20:14:32 +01:00
|
|
|
sessions[sessionID] = sessionInfo;
|
2011-12-04 16:50:02 +01:00
|
|
|
callback();
|
2011-08-09 20:14:32 +01:00
|
|
|
});
|
|
|
|
}, callback);
|
|
|
|
}
|
|
|
|
], function(err)
|
|
|
|
{
|
2011-12-04 16:50:02 +01:00
|
|
|
if(ERR(err, callback)) return;
|
|
|
|
callback(null, sessions);
|
2011-08-09 20:14:32 +01:00
|
|
|
});
|
2011-08-09 16:45:49 +01:00
|
|
|
}
|
|
|
|
|
2019-02-08 23:20:57 +01:00
|
|
|
// checks if a number is an int
|
2011-08-09 16:45:49 +01:00
|
|
|
function is_int(value)
|
2019-02-08 23:20:57 +01:00
|
|
|
{
|
|
|
|
return (parseFloat(value) == parseInt(value)) && !isNaN(value);
|
2011-08-09 16:45:49 +01:00
|
|
|
}
|