2
0
mirror of https://github.com/frappe/frappe.git synced 2024-06-13 04:42:20 +00:00

refactor: better permission checking on sockets

- no more "can subscribe X"
- add a new util function on socket `has_permission`

Basic usage:

```js
socket.has_permission(doctype, [name]).then(() => { // do something });
```
This commit is contained in:
Ankush Menat 2024-04-06 19:44:46 +05:30
parent 4778090024
commit 2a56869c99
2 changed files with 36 additions and 91 deletions

View File

@ -114,21 +114,9 @@ def emit_via_redis(event, message, room):
@frappe.whitelist(allow_guest=True)
def can_subscribe_doc(doctype: str, docname: str) -> bool:
from frappe.exceptions import PermissionError
if not frappe.has_permission(doctype=doctype, doc=docname, ptype="read"):
raise PermissionError()
return True
@frappe.whitelist(allow_guest=True)
def can_subscribe_doctype(doctype: str) -> bool:
from frappe.exceptions import PermissionError
if not frappe.has_permission(doctype=doctype, ptype="read"):
raise PermissionError()
def has_permission(doctype: str, name: str) -> bool:
if not frappe.has_permission(doctype=doctype, doc=name, ptype="read"):
raise frappe.PermissionError
return True

View File

@ -12,13 +12,27 @@ function frappe_handlers(socket) {
socket.join(SITE_ROOM);
}
socket.has_permission = (doctype, name) => {
return new Promise((resolve) => {
frappe_request("/api/method/frappe.realtime.has_permission", socket)
.type("form")
.query({
doctype,
name,
})
.end(function (err, res) {
if (res?.status == 200) {
resolve();
} else if (res.status != 403) {
log("Something went wrong", err, res);
}
});
});
};
socket.on("doctype_subscribe", function (doctype) {
can_subscribe_doctype({
socket,
doctype,
callback: () => {
socket.join(doctype_room(doctype));
},
socket.has_permission(doctype).then(() => {
socket.join(doctype_room(doctype));
});
});
@ -42,14 +56,8 @@ function frappe_handlers(socket) {
});
socket.on("doc_subscribe", function (doctype, docname) {
can_subscribe_doc({
socket,
doctype,
docname,
callback: () => {
let room = doc_room(doctype, docname);
socket.join(room);
},
socket.has_permission(doctype, docname).then(() => {
socket.join(doc_room(doctype, docname));
});
});
@ -59,23 +67,18 @@ function frappe_handlers(socket) {
});
socket.on("doc_open", function (doctype, docname) {
can_subscribe_doc({
socket,
doctype,
docname,
callback: () => {
let room = open_doc_room(doctype, docname);
socket.join(room);
if (!socket.subscribed_documents) socket.subscribed_documents = [];
socket.subscribed_documents.push([doctype, docname]);
socket.has_permission(doctype, docname).then(() => {
let room = open_doc_room(doctype, docname);
socket.join(room);
if (!socket.subscribed_documents) socket.subscribed_documents = [];
socket.subscribed_documents.push([doctype, docname]);
// show who is currently viewing the form
notify_subscribed_doc_users({
socket: socket,
doctype: doctype,
docname: docname,
});
},
// show who is currently viewing the form
notify_subscribed_doc_users({
socket: socket,
doctype: doctype,
docname: docname,
});
});
});
@ -110,28 +113,6 @@ function notify_disconnected_documents(socket) {
}
}
function can_subscribe_doctype(args) {
if (!args) return;
if (!args.doctype) return;
frappe_request("/api/method/frappe.realtime.can_subscribe_doctype", args.socket)
.type("form")
.query({
doctype: args.doctype,
})
.end(function (err, res) {
if (!res || res.status == 403 || err) {
if (err) {
log(err);
}
return false;
} else if (res.status == 200) {
args.callback && args.callback(err, res);
return true;
}
log("ERROR (can_subscribe_doctype): ", err, res);
});
}
function notify_subscribed_doc_users(args) {
if (!(args && args.doctype && args.docname)) {
return;
@ -160,30 +141,6 @@ function notify_subscribed_doc_users(args) {
});
}
function can_subscribe_doc(args) {
if (!args) return;
if (!args.doctype || !args.docname) return;
frappe_request("/api/method/frappe.realtime.can_subscribe_doc", args.socket)
.type("form")
.query({
doctype: args.doctype,
docname: args.docname,
})
.end(function (err, res) {
if (!res) {
log("No response for doc_subscribe");
} else if (res.status == 403) {
return;
} else if (err) {
log(err);
} else if (res.status == 200) {
args.callback(err, res);
} else {
log("Something went wrong", err, res);
}
});
}
const doc_room = (doctype, docname) => "doc:" + doctype + "/" + docname;
const open_doc_room = (doctype, docname) => "open_doc:" + doctype + "/" + docname;
const user_room = (user) => "user:" + user;