PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/node/db/SessionManager.js

https://github.com/nguyennamtien/etherpad-lite
JavaScript | 397 lines | 282 code | 33 blank | 82 comment | 41 complexity | f41775b46666c3ef4290f2a28c7bf015 MD5 | raw file
  1. /**
  2. * The Session Manager provides functions to manage session in the database
  3. */
  4. /*
  5. * 2011 Peter 'Pita' Martischka (Primary Technology Ltd)
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS-IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. */
  19. var db = require("./DB").db;
  20. var async = require("async");
  21. var groupMangager = require("./GroupManager");
  22. var authorMangager = require("./AuthorManager");
  23. exports.doesSessionExist = function(sessionID, callback)
  24. {
  25. //check if the database entry of this session exists
  26. db.get("session:" + sessionID, function (err, session)
  27. {
  28. callback(err, session != null);
  29. });
  30. }
  31. /**
  32. * Creates a new session between an author and a group
  33. */
  34. exports.createSession = function(groupID, authorID, validUntil, callback)
  35. {
  36. var sessionID;
  37. async.series([
  38. //check if group exists
  39. function(callback)
  40. {
  41. groupMangager.doesGroupExist(groupID, function(err, exists)
  42. {
  43. //error
  44. if(err)
  45. {
  46. callback(err);
  47. }
  48. //group does not exist
  49. else if(exists == false)
  50. {
  51. callback({stop: "groupID does not exist"});
  52. }
  53. //everything is fine, continue
  54. else
  55. {
  56. callback();
  57. }
  58. });
  59. },
  60. //check if author exists
  61. function(callback)
  62. {
  63. authorMangager.doesAuthorExists(authorID, function(err, exists)
  64. {
  65. //error
  66. if(err)
  67. {
  68. callback(err);
  69. }
  70. //author does not exist
  71. else if(exists == false)
  72. {
  73. callback({stop: "authorID does not exist"});
  74. }
  75. //everything is fine, continue
  76. else
  77. {
  78. callback();
  79. }
  80. });
  81. },
  82. //check validUntil and create the session db entry
  83. function(callback)
  84. {
  85. //check if rev is a number
  86. if(typeof validUntil != "number")
  87. {
  88. //try to parse the number
  89. if(!isNaN(parseInt(validUntil)))
  90. {
  91. validUntil = parseInt(validUntil);
  92. }
  93. else
  94. {
  95. callback({stop: "validUntil is not a number"});
  96. return;
  97. }
  98. }
  99. //ensure this is not a negativ number
  100. if(validUntil < 0)
  101. {
  102. callback({stop: "validUntil is a negativ number"});
  103. return;
  104. }
  105. //ensure this is not a float value
  106. if(!is_int(validUntil))
  107. {
  108. callback({stop: "validUntil is a float value"});
  109. return;
  110. }
  111. //check if validUntil is in the future
  112. if(Math.floor(new Date().getTime()/1000) > validUntil)
  113. {
  114. callback({stop: "validUntil is in the past"});
  115. return;
  116. }
  117. //generate sessionID
  118. sessionID = "s." + randomString(16);
  119. //set the session into the database
  120. db.set("session:" + sessionID, {"groupID": groupID, "authorID": authorID, "validUntil": validUntil});
  121. callback();
  122. },
  123. //set the group2sessions entry
  124. function(callback)
  125. {
  126. //get the entry
  127. db.get("group2sessions:" + groupID, function(err, group2sessions)
  128. {
  129. //did a error happen?
  130. if(err)
  131. {
  132. callback(err);
  133. return;
  134. }
  135. //the entry doesn't exist so far, let's create it
  136. if(group2sessions == null)
  137. {
  138. group2sessions = {sessionIDs : {}};
  139. }
  140. //add the entry for this session
  141. group2sessions.sessionIDs[sessionID] = 1;
  142. //save the new element back
  143. db.set("group2sessions:" + groupID, group2sessions);
  144. callback();
  145. });
  146. },
  147. //set the author2sessions entry
  148. function(callback)
  149. {
  150. //get the entry
  151. db.get("author2sessions:" + authorID, function(err, author2sessions)
  152. {
  153. //did a error happen?
  154. if(err)
  155. {
  156. callback(err);
  157. return;
  158. }
  159. //the entry doesn't exist so far, let's create it
  160. if(author2sessions == null)
  161. {
  162. author2sessions = {sessionIDs : {}};
  163. }
  164. //add the entry for this session
  165. author2sessions.sessionIDs[sessionID] = 1;
  166. //save the new element back
  167. db.set("author2sessions:" + authorID, author2sessions);
  168. callback();
  169. });
  170. }
  171. ], function(err)
  172. {
  173. //return error and sessionID
  174. callback(err, {sessionID: sessionID});
  175. })
  176. }
  177. exports.getSessionInfo = function(sessionID, callback)
  178. {
  179. //check if the database entry of this session exists
  180. db.get("session:" + sessionID, function (err, session)
  181. {
  182. //error
  183. if(err)
  184. {
  185. callback(err);
  186. }
  187. //session does not exists
  188. else if(session == null)
  189. {
  190. callback({stop: "sessionID does not exist"})
  191. }
  192. //everything is fine, return the sessioninfos
  193. else
  194. {
  195. callback(null, session);
  196. }
  197. });
  198. }
  199. /**
  200. * Deletes a session
  201. */
  202. exports.deleteSession = function(sessionID, callback)
  203. {
  204. var authorID, groupID;
  205. var group2sessions, author2sessions;
  206. async.series([
  207. function(callback)
  208. {
  209. //get the session entry
  210. db.get("session:" + sessionID, function (err, session)
  211. {
  212. //error
  213. if(err)
  214. {
  215. callback(err);
  216. }
  217. //session does not exists
  218. else if(session == null)
  219. {
  220. callback({stop: "sessionID does not exist"})
  221. }
  222. //everything is fine, return the sessioninfos
  223. else
  224. {
  225. authorID = session.authorID;
  226. groupID = session.groupID;
  227. callback();
  228. }
  229. });
  230. },
  231. //get the group2sessions entry
  232. function(callback)
  233. {
  234. db.get("group2sessions:" + groupID, function (err, _group2sessions)
  235. {
  236. group2sessions = _group2sessions;
  237. callback(err);
  238. });
  239. },
  240. //get the author2sessions entry
  241. function(callback)
  242. {
  243. db.get("author2sessions:" + authorID, function (err, _author2sessions)
  244. {
  245. author2sessions = _author2sessions;
  246. callback(err);
  247. });
  248. },
  249. //remove the values from the database
  250. function(callback)
  251. {
  252. //remove the session
  253. db.remove("session:" + sessionID);
  254. //remove session from group2sessions
  255. delete group2sessions.sessionIDs[sessionID];
  256. db.set("group2sessions:" + groupID, group2sessions);
  257. //remove session from author2sessions
  258. delete author2sessions.sessionIDs[sessionID];
  259. db.set("author2sessions:" + authorID, author2sessions);
  260. callback();
  261. }
  262. ], function(err)
  263. {
  264. callback(err);
  265. })
  266. }
  267. exports.listSessionsOfGroup = function(groupID, callback)
  268. {
  269. groupMangager.doesGroupExist(groupID, function(err, exists)
  270. {
  271. //error
  272. if(err)
  273. {
  274. callback(err);
  275. }
  276. //group does not exist
  277. else if(exists == false)
  278. {
  279. callback({stop: "groupID does not exist"});
  280. }
  281. //everything is fine, continue
  282. else
  283. {
  284. listSessionsWithDBKey("group2sessions:" + groupID, callback);
  285. }
  286. });
  287. }
  288. exports.listSessionsOfAuthor = function(authorID, callback)
  289. {
  290. authorMangager.doesAuthorExists(authorID, function(err, exists)
  291. {
  292. //error
  293. if(err)
  294. {
  295. callback(err);
  296. }
  297. //group does not exist
  298. else if(exists == false)
  299. {
  300. callback({stop: "authorID does not exist"});
  301. }
  302. //everything is fine, continue
  303. else
  304. {
  305. listSessionsWithDBKey("author2sessions:" + authorID, callback);
  306. }
  307. });
  308. }
  309. //this function is basicly the code listSessionsOfAuthor and listSessionsOfGroup has in common
  310. function listSessionsWithDBKey (dbkey, callback)
  311. {
  312. var sessions;
  313. async.series([
  314. function(callback)
  315. {
  316. //get the group2sessions entry
  317. db.get(dbkey, function(err, sessionObject)
  318. {
  319. sessions = sessionObject ? sessionObject.sessionIDs : null;
  320. callback(err);
  321. });
  322. },
  323. function(callback)
  324. {
  325. //collect all sessionIDs in an arrary
  326. var sessionIDs = [];
  327. for (var i in sessions)
  328. {
  329. sessionIDs.push(i);
  330. }
  331. //foreach trough the sessions and get the sessioninfos
  332. async.forEach(sessionIDs, function(sessionID, callback)
  333. {
  334. exports.getSessionInfo(sessionID, function(err, sessionInfo)
  335. {
  336. sessions[sessionID] = sessionInfo;
  337. callback(err);
  338. });
  339. }, callback);
  340. }
  341. ], function(err)
  342. {
  343. callback(err, sessions);
  344. });
  345. }
  346. /**
  347. * Generates a random String with the given length. Is needed to generate the SessionIDs
  348. */
  349. function randomString(len)
  350. {
  351. var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  352. var randomstring = '';
  353. for (var i = 0; i < len; i++)
  354. {
  355. var rnum = Math.floor(Math.random() * chars.length);
  356. randomstring += chars.substring(rnum, rnum + 1);
  357. }
  358. return randomstring;
  359. }
  360. //checks if a number is an int
  361. function is_int(value)
  362. {
  363. return (parseFloat(value) == parseInt(value)) && !isNaN(value)
  364. }