fix: Check Reference Doctype perms & control indicator change

- Don’t change indicator on filter change if user can’t write to board. They can’t save filters
- Invoke `update_order` on Kanban board init() only if user has `write` access to reference doctype (non-deliberate invocation)
- All deliberate invocations of `update_order` via UI actions are blocked/hidden without `write` access
- Remove elements with no access instead of hiding to avoid inspect element hacks
- Card Actions: Block card dragging if no `write` access to reference doctype
- Card Actions: Block card adding  if no `create` access to reference doctype
This commit is contained in:
marination 2022-11-25 12:09:36 +05:30
parent 0981f593ff
commit d6bdd636dc
3 changed files with 23 additions and 3 deletions

View file

@ -302,6 +302,7 @@ def has_permission(doctype, docname, perm_type="read"):
# perm_type can be one of read, write, create, submit, cancel, report
return {"has_permission": frappe.has_permission(doctype, perm_type.lower(), docname)}
@frappe.whitelist()
def get_doc_permissions(doctype, docname):
"""Returns an evaluated document permissions dict like `{"read":1, "write":1}`
@ -312,6 +313,7 @@ def get_doc_permissions(doctype, docname):
doc = frappe.get_doc(doctype, docname)
return {"permissions": frappe.permissions.get_doc_permissions(doc)}
@frappe.whitelist()
def get_password(doctype, name, fieldname):
"""Return a password type property. Only applicable for System Managers

View file

@ -326,7 +326,12 @@ frappe.provide("frappe.views");
store.watch((state, getters) => {
return state.empty_state;
}, show_empty_state);
store.dispatch("update_order");
if (frappe.model.can_write(store.state.doctype)) {
// Check for reference doctype access before initiating
// non-deliberate action
store.dispatch("update_order");
}
}
function prepare() {
@ -377,7 +382,7 @@ frappe.provide("frappe.views");
function bind_add_column() {
if (!self.board_perms.write) {
// If no write access, editing board (by adding column) should be blocked
self.$kanban_board.find(".add-new-column").hide();
self.$kanban_board.find(".add-new-column").remove();
return;
}
@ -576,6 +581,9 @@ frappe.provide("frappe.views");
}
function setup_sortable() {
// Block card dragging/record editing without 'write' access
if (!frappe.model.can_write(store.state.doctype)) return;
Sortable.create(self.$kanban_cards.get(0), {
group: "cards",
animation: 150,
@ -609,6 +617,14 @@ frappe.provide("frappe.views");
var $wrapper = self.$kanban_column;
var $btn_add = $wrapper.find(".add-card");
var $new_card_area = $wrapper.find(".new-card-area");
if (!frappe.model.can_create(store.state.doctype)) {
// Block record/card creation without 'create' access
$btn_add.remove();
$new_card_area.remove();
return;
}
var $textarea = $new_card_area.find("textarea");
//Add card button
@ -652,7 +668,7 @@ frappe.provide("frappe.views");
function bind_options() {
if (!board_perms.write) {
// If no write access, column options should be hidden
self.$kanban_column.find(".column-options").hide();
self.$kanban_column.find(".column-options").remove();
return;
}

View file

@ -151,6 +151,8 @@ frappe.views.KanbanView = class KanbanView extends frappe.views.ListView {
render_list() {}
on_filter_change() {
if (!this.board_perms.write) return; // avoid misleading ux
if (JSON.stringify(this.board.filters_array) !== JSON.stringify(this.filter_area.get())) {
this.page.set_indicator(__("Not Saved"), "orange");
} else {