From 49c7dded4539044d8053dba8d3fe24b97056c0d2 Mon Sep 17 00:00:00 2001 From: Wu Cheng-Han Date: Sun, 17 Jan 2016 09:51:27 -0600 Subject: Added private permission and clean up codes, solved potential race condition in realtime.js --- lib/realtime.js | 204 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 124 insertions(+), 80 deletions(-) (limited to 'lib/realtime.js') diff --git a/lib/realtime.js b/lib/realtime.js index 484ef12e..d0db6072 100644 --- a/lib/realtime.js +++ b/lib/realtime.js @@ -90,46 +90,10 @@ var updater = setInterval(function () { if (note.server.isDirty) { if (config.debug) logger.info("updater found dirty note: " + key); - Note.findNote(note.id, function (err, _note) { - if (err || !_note) return callback(err, null); - //mongo update - if (note.lastchangeuser && _note.lastchangeuser != note.lastchangeuser) { - var lastchangeuser = note.lastchangeuser; - var lastchangeuserprofile = null; - User.findUser(lastchangeuser, function (err, user) { - if (err) return callback(err, null); - if (user && user.profile) { - var profile = JSON.parse(user.profile); - if (profile) { - lastchangeuserprofile = { - name: profile.displayName || profile.username, - photo: User.parsePhotoByProfile(profile) - } - note.lastchangeuser = lastchangeuser; - note.lastchangeuserprofile = lastchangeuserprofile; - Note.updateLastChangeUser(_note, lastchangeuser, function (err, result) { - if (err) return callback(err, null); - }); - } - } - }); - } else { - note.lastchangeuser = null; - note.lastchangeuserprofile = null; - Note.updateLastChangeUser(_note, null, function (err, result) { - if (err) return callback(err, null); - }); - } - //postgres update - var body = note.server.document; - var title = Note.getNoteTitle(body); - title = LZString.compressToBase64(title); - body = LZString.compressToBase64(body); - db.saveToDB(key, title, body, function (err, result) { + updaterUpdateMongo(note, function(err, result) { + if (err) return callback(err, null); + updaterUpdatePostgres(note, function(err, result) { if (err) return callback(err, null); - note.server.isDirty = false; - note.updatetime = Date.now(); - emitCheck(note); callback(null, null); }); }); @@ -140,6 +104,56 @@ var updater = setInterval(function () { if (err) return logger.error('updater error', err); }); }, 1000); +function updaterUpdateMongo(note, callback) { + Note.findNote(note.id, function (err, _note) { + if (err || !_note) return callback(err, null); + if (note.lastchangeuser) { + if (_note.lastchangeuser != note.lastchangeuser) { + var lastchangeuser = note.lastchangeuser; + var lastchangeuserprofile = null; + User.findUser(lastchangeuser, function (err, user) { + if (err) return callback(err, null); + if (user && user.profile) { + var profile = JSON.parse(user.profile); + if (profile) { + lastchangeuserprofile = { + name: profile.displayName || profile.username, + photo: User.parsePhotoByProfile(profile) + } + _note.lastchangeuser = lastchangeuser; + note.lastchangeuserprofile = lastchangeuserprofile; + Note.updateLastChangeUser(_note, lastchangeuser, function (err, result) { + if (err) return callback(err, null); + callback(null, null); + }); + } + } + }); + } + } else { + _note.lastchangeuser = null; + note.lastchangeuserprofile = null; + Note.updateLastChangeUser(_note, null, function (err, result) { + if (err) return callback(err, null); + callback(null, null); + }); + } + }); +} +function updaterUpdatePostgres(note, callback) { + //postgres update + var body = note.server.document; + var title = Note.getNoteTitle(body); + title = LZString.compressToBase64(title); + body = LZString.compressToBase64(body); + db.saveToDB(note.id, title, body, function (err, result) { + if (err) return callback(err, null); + note.server.isDirty = false; + note.updatetime = Date.now(); + emitCheck(note); + callback(null, null); + }); +} //clean when user not in any rooms or user not in connected list var cleaner = setInterval(function () { async.each(Object.keys(users), function (key, callback) { @@ -310,6 +324,19 @@ var disconnectSocketQueue = []; function finishConnection(socket, note, user) { if (!socket || !note || !user) return; + //check view permission + if (note.permission == 'private') { + if (socket.request.user && socket.request.user.logged_in && socket.request.user._id == note.owner) { + //na + } else { + socket.emit('info', { + code: 403 + }); + clearSocketQueue(connectionSocketQueue, socket); + isConnectionBusy = false; + return socket.disconnect(true); + } + } note.users[socket.id] = user; note.socks.push(socket); note.server.addClient(socket); @@ -363,13 +390,9 @@ function startConnection(socket) { var owner = data.rows[0].owner; var ownerprofile = null; - var permission = "freely"; - if (owner && owner != "null") { - permission = "editable"; - } //find or new note - Note.findOrNewNote(notename, permission, function (err, note) { + Note.findOrNewNote(notename, owner, function (err, note) { if (err) { responseError(res, "404", "Not Found", "oops."); clearSocketQueue(connectionSocketQueue, socket); @@ -399,41 +422,52 @@ function startConnection(socket) { updatetime: moment(updatetime).valueOf(), server: server }; - - if (lastchangeuser) { - //find last change user profile if lastchangeuser exists - User.findUser(lastchangeuser, function (err, user) { - if (!err && user && user.profile) { - var profile = JSON.parse(user.profile); - if (profile) { - lastchangeuserprofile = { - name: profile.displayName || profile.username, - photo: User.parsePhotoByProfile(profile) + + async.parallel([ + function getlastchangeuser(callback) { + if (lastchangeuser) { + //find last change user profile if lastchangeuser exists + User.findUser(lastchangeuser, function (err, user) { + if (!err && user && user.profile) { + var profile = JSON.parse(user.profile); + if (profile) { + lastchangeuserprofile = { + name: profile.displayName || profile.username, + photo: User.parsePhotoByProfile(profile) + } + notes[notename].lastchangeuserprofile = lastchangeuserprofile; + } } - notes[notename].lastchangeuserprofile = lastchangeuserprofile; - } + callback(null, null); + }); + } else { + callback(null, null); } - }); - } - - if (owner && owner != "null") { - //find owner profile if owner exists - User.findUser(owner, function (err, user) { - if (!err && user && user.profile) { - var profile = JSON.parse(user.profile); - if (profile) { - ownerprofile = { - name: profile.displayName || profile.username, - photo: User.parsePhotoByProfile(profile) + }, + function getowner(callback) { + if (owner && owner != "null") { + //find owner profile if owner exists + User.findUser(owner, function (err, user) { + if (!err && user && user.profile) { + var profile = JSON.parse(user.profile); + if (profile) { + ownerprofile = { + name: profile.displayName || profile.username, + photo: User.parsePhotoByProfile(profile) + } + notes[notename].ownerprofile = ownerprofile; + } } - notes[notename].ownerprofile = ownerprofile; - } + callback(null, null); + }); + } else { + callback(null, null); } - finishConnection(socket, notes[notename], users[socket.id]); - }); - } else { + } + ], function(err, results){ + if (err) return; finishConnection(socket, notes[notename], users[socket.id]); - } + }); }); }); } else { @@ -545,14 +579,14 @@ function ifMayEdit(socket, callback) { if (!socket.request.user || !socket.request.user.logged_in) mayEdit = false; break; - case "locked": + case "locked": case "private": //only owner can change if (note.owner != socket.request.user._id) mayEdit = false; break; } //if user may edit and this note have owner (not anonymous usage) - if (mayEdit && note.owner && note.owner != "null") { + if (socket.origin == 'operation' && mayEdit && note.owner && note.owner != "null") { //save for the last change user id if (socket.request.user && socket.request.user.logged_in) { note.lastchangeuser = socket.request.user._id; @@ -652,12 +686,22 @@ function connection(socket) { permission: permission }; realtime.io.to(note.id).emit('permission', out); - /* for (var i = 0, l = note.socks.length; i < l; i++) { var sock = note.socks[i]; - sock.emit('permission', out); - }; - */ + if (typeof sock !== 'undefined' && sock) { + //check view permission + if (permission == 'private') { + if (sock.request.user && sock.request.user.logged_in && sock.request.user._id == note.owner) { + //na + } else { + sock.emit('info', { + code: 403 + }); + return sock.disconnect(true); + } + } + } + } }); }); } -- cgit v1.2.3