mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-13 06:34:39 -04:00
Added private permission and clean up codes, solved potential race condition in realtime.js
This commit is contained in:
parent
473212676a
commit
49c7dded45
6 changed files with 297 additions and 199 deletions
204
lib/realtime.js
204
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue