From 30a041646c685c6f13d0469689f88c3016c3629c Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Fri, 4 Dec 2020 09:33:13 +0530 Subject: [PATCH] feat(guest-access): Allow Guest to view, edit allowed forms, making way remove web forms --- .../doctype/navbar_settings/navbar_settings.py | 2 +- frappe/core/doctype/role/role.json | 16 ++++++++-------- frappe/core/doctype/role/role.py | 2 +- .../doctype/user_permission/user_permission.py | 4 ++-- frappe/desk/form/load.py | 4 ++-- frappe/desk/form/meta.py | 16 ++++++++++------ frappe/desk/listview.py | 2 +- frappe/desk/reportview.py | 2 +- frappe/public/js/frappe/chat.js | 14 -------------- frappe/public/js/frappe/desk.js | 7 +------ frappe/public/js/frappe/form/footer/footer.js | 2 +- frappe/public/js/frappe/form/form.js | 14 ++++++++------ frappe/public/js/frappe/form/toolbar.js | 3 +++ frappe/public/js/frappe/list/base_list.js | 2 +- frappe/public/js/frappe/list/list_filter.js | 1 + frappe/public/js/frappe/model/user_settings.js | 3 +++ frappe/public/js/frappe/request.js | 5 +++-- frappe/public/js/frappe/router.js | 1 + frappe/public/js/frappe/router_history.js | 5 ++++- .../js/frappe/ui/notifications/notifications.js | 3 +-- .../public/js/frappe/ui/toolbar/awesome_bar.js | 2 ++ frappe/public/js/frappe/ui/toolbar/navbar.html | 6 +++--- frappe/public/js/frappe/ui/toolbar/toolbar.js | 11 +++++++---- frappe/sessions.py | 2 +- frappe/www/app.py | 4 ++-- 25 files changed, 68 insertions(+), 65 deletions(-) diff --git a/frappe/core/doctype/navbar_settings/navbar_settings.py b/frappe/core/doctype/navbar_settings/navbar_settings.py index f7c437bf00..db510981a4 100644 --- a/frappe/core/doctype/navbar_settings/navbar_settings.py +++ b/frappe/core/doctype/navbar_settings/navbar_settings.py @@ -23,7 +23,7 @@ class NavbarSettings(Document): if not frappe.flags.in_patch and (len(before_save_items) > len(after_save_items)): frappe.throw(_("Please hide the standard navbar items instead of deleting them")) -@frappe.whitelist() +@frappe.whitelist(allow_guest=True) def get_app_logo(): app_logo = frappe.db.get_single_value('Navbar Settings', 'app_logo') if not app_logo: diff --git a/frappe/core/doctype/role/role.json b/frappe/core/doctype/role/role.json index 1e2366c041..e47dc7194b 100644 --- a/frappe/core/doctype/role/role.json +++ b/frappe/core/doctype/role/role.json @@ -16,7 +16,7 @@ "two_factor_auth", "navigation_settings_section", "search_bar", - "notification", + "notifications", "chat", "list_settings_section", "list_sidebar", @@ -84,12 +84,6 @@ "fieldtype": "Check", "label": "Search Bar" }, - { - "default": "1", - "fieldname": "notification", - "fieldtype": "Check", - "label": "Notification" - }, { "default": "1", "fieldname": "chat", @@ -141,13 +135,19 @@ "fieldname": "view_switcher", "fieldtype": "Check", "label": "View Switcher" + }, + { + "default": "1", + "fieldname": "notifications", + "fieldtype": "Check", + "label": "Notifications" } ], "icon": "fa fa-bookmark", "idx": 1, "index_web_pages_for_search": 1, "links": [], - "modified": "2020-11-11 17:29:13.149522", + "modified": "2020-12-03 14:08:38.181035", "modified_by": "Administrator", "module": "Core", "name": "Role", diff --git a/frappe/core/doctype/role/role.py b/frappe/core/doctype/role/role.py index f9fbd9cbe6..bac68e30ab 100644 --- a/frappe/core/doctype/role/role.py +++ b/frappe/core/doctype/role/role.py @@ -6,7 +6,7 @@ import frappe from frappe.model.document import Document -desk_properties = ("search_bar", "notification", "chat", "list_sidebar", +desk_properties = ("search_bar", "notifications", "chat", "list_sidebar", "bulk_actions", "view_switcher", "form_sidebar", "timeline", "dashboard") class Role(Document): diff --git a/frappe/core/doctype/user_permission/user_permission.py b/frappe/core/doctype/user_permission/user_permission.py index ba14583c2f..de14651d50 100644 --- a/frappe/core/doctype/user_permission/user_permission.py +++ b/frappe/core/doctype/user_permission/user_permission.py @@ -55,7 +55,7 @@ class UserPermission(Document): ref_link = frappe.get_desk_link(self.doctype, overlap_exists[0].name) frappe.throw(_("{0} has already assigned default value for {1}.").format(ref_link, self.allow)) -@frappe.whitelist() +@frappe.whitelist(allow_guest=True) def get_user_permissions(user=None): '''Get all users permissions for the user as a dict of doctype''' # if this is called from client-side, @@ -66,7 +66,7 @@ def get_user_permissions(user=None): if not user: user = frappe.session.user - if not user or user == "Administrator": + if not user or user in ("Administrator", "Guest"): return {} cached_user_permissions = frappe.cache().hget("user_permissions", user) diff --git a/frappe/desk/form/load.py b/frappe/desk/form/load.py index 2d9223edf8..1f5c437330 100644 --- a/frappe/desk/form/load.py +++ b/frappe/desk/form/load.py @@ -13,7 +13,7 @@ from frappe.desk.form.document_follow import is_document_followed from frappe import _ from six.moves.urllib.parse import quote -@frappe.whitelist() +@frappe.whitelist(allow_guest=True) def getdoc(doctype, name, user=None): """ Loads a doclist for a given document. This method is called directly from the client. @@ -52,7 +52,7 @@ def getdoc(doctype, name, user=None): frappe.response.docs.append(doc) -@frappe.whitelist() +@frappe.whitelist(allow_guest=True) def getdoctype(doctype, with_parent=False, cached_timestamp=None): """load doctype""" diff --git a/frappe/desk/form/meta.py b/frappe/desk/form/meta.py index c28a40657f..d5428b1da2 100644 --- a/frappe/desk/form/meta.py +++ b/frappe/desk/form/meta.py @@ -202,13 +202,17 @@ class FormMeta(Meta): self.load_kanban_column_fields() def load_kanban_column_fields(self): - values = frappe.get_list( - 'Kanban Board', fields=['field_name'], - filters={'reference_doctype': self.name}) + try: + values = frappe.get_list( + 'Kanban Board', fields=['field_name'], + filters={'reference_doctype': self.name}) - fields = [x['field_name'] for x in values] - fields = list(set(fields)) - self.set("__kanban_column_fields", fields, as_value=True) + fields = [x['field_name'] for x in values] + fields = list(set(fields)) + self.set("__kanban_column_fields", fields, as_value=True) + except frappe.PermissionError: + # no access to kanban board + pass def get_code_files_via_hooks(hook, name): code_files = [] diff --git a/frappe/desk/listview.py b/frappe/desk/listview.py index 1d10a13930..91dc0f3ba9 100644 --- a/frappe/desk/listview.py +++ b/frappe/desk/listview.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import frappe -@frappe.whitelist() +@frappe.whitelist(allow_guest=True) def get_list_settings(doctype): try: return frappe.get_cached_doc("List View Settings", doctype) diff --git a/frappe/desk/reportview.py b/frappe/desk/reportview.py index 9f5a5d84c8..6cd1d24626 100644 --- a/frappe/desk/reportview.py +++ b/frappe/desk/reportview.py @@ -14,7 +14,7 @@ from frappe.core.doctype.access_log.access_log import make_access_log from frappe.utils import cstr, format_duration -@frappe.whitelist() +@frappe.whitelist(allow_guest=True) @frappe.read_only() def get(): args = get_form_params() diff --git a/frappe/public/js/frappe/chat.js b/frappe/public/js/frappe/chat.js index e17a7ebb4d..61fa89deab 100644 --- a/frappe/public/js/frappe/chat.js +++ b/frappe/public/js/frappe/chat.js @@ -2670,20 +2670,6 @@ frappe.chat.render = (render = true, force = false) => // With the assumption, that there's only one navbar. const $placeholder = $('.navbar .frappe-chat-dropdown') - // Render if frappe-chat-toggle doesn't exist. - if ( frappe.utils.is_empty($placeholder.has('.frappe-chat-toggle')) ) { - const $template = $(` - -
- -
-
- `) - - $placeholder.addClass('dropdown hidden') - $placeholder.html($template) - } - if ( render ) { $placeholder.removeClass('hidden') } else { diff --git a/frappe/public/js/frappe/desk.js b/frappe/public/js/frappe/desk.js index 5a6ea54a3c..c1bbe78781 100644 --- a/frappe/public/js/frappe/desk.js +++ b/frappe/public/js/frappe/desk.js @@ -160,8 +160,6 @@ frappe.Application = Class.extend({ }, 600000); // check every 10 minutes } } - - this.fetch_tags(); }, set_route() { @@ -294,6 +292,7 @@ frappe.Application = Class.extend({ set_globals: function() { frappe.session.user = frappe.boot.user.name; + frappe.session.logged_in_user = frappe.boot.user.name; frappe.session.user_email = frappe.boot.user.email; frappe.session.user_fullname = frappe.user_info().fullname; @@ -599,10 +598,6 @@ frappe.Application = Class.extend({ frappe.show_alert(message); }); }, - - fetch_tags() { - frappe.tags.utils.fetch_tags(); - } }); frappe.get_module = function(m, default_module) { diff --git a/frappe/public/js/frappe/form/footer/footer.js b/frappe/public/js/frappe/form/footer/footer.js index 827eb861dc..074646c67b 100644 --- a/frappe/public/js/frappe/form/footer/footer.js +++ b/frappe/public/js/frappe/form/footer/footer.js @@ -48,7 +48,7 @@ frappe.ui.form.Footer = Class.extend({ }); }, get_names_for_mentions() { - let names_for_mentions = Object.keys(frappe.boot.user_info) + let names_for_mentions = Object.keys(frappe.boot.user_info || []) .filter(user => { return !["Administrator", "Guest"].includes(user) && frappe.boot.user_info[user].allowed_in_mentions; diff --git a/frappe/public/js/frappe/form/form.js b/frappe/public/js/frappe/form/form.js index 77be2f2816..b819b6ad97 100644 --- a/frappe/public/js/frappe/form/form.js +++ b/frappe/public/js/frappe/form/form.js @@ -107,7 +107,7 @@ frappe.ui.form.Form = class FrappeForm { this.script_manager.setup(); this.watch_model_updates(); - if(!this.meta.hide_toolbar) { + if(!this.meta.hide_toolbar && frappe.boot.desk_settings.timeline) { this.footer = new frappe.ui.form.Footer({ frm: this, parent: $('
').appendTo(this.page.main.parent()) @@ -446,11 +446,13 @@ frappe.ui.form.Form = class FrappeForm { this.layout.doc = this.doc; this.layout.attach_doc_and_docfields(); - this.sidebar = new frappe.ui.form.Sidebar({ - frm: this, - page: this.page - }); - this.sidebar.make(); + if (frappe.boot.desk_settings.form_sidebar) { + this.sidebar = new frappe.ui.form.Sidebar({ + frm: this, + page: this.page + }); + this.sidebar.make(); + } // clear layout message this.layout.show_message(); diff --git a/frappe/public/js/frappe/form/toolbar.js b/frappe/public/js/frappe/form/toolbar.js index 28cc9bb28b..236e4b3fba 100644 --- a/frappe/public/js/frappe/form/toolbar.js +++ b/frappe/public/js/frappe/form/toolbar.js @@ -198,6 +198,9 @@ frappe.ui.form.Toolbar = Class.extend({ make_menu: function() { this.page.clear_icons(); this.page.clear_menu(); + + if (frappe.session.user === 'Guest') return; + var me = this; var p = this.frm.perm[0]; var docstatus = cint(this.frm.doc.docstatus); diff --git a/frappe/public/js/frappe/list/base_list.js b/frappe/public/js/frappe/list/base_list.js index c67de6afc9..b9a352bd06 100644 --- a/frappe/public/js/frappe/list/base_list.js +++ b/frappe/public/js/frappe/list/base_list.js @@ -236,7 +236,7 @@ frappe.views.BaseList = class BaseList { } setup_side_bar() { - if (this.hide_sidebar) return; + if (this.hide_sidebar || !frappe.boot.desk_settings.list_sidebar) return; this.list_sidebar = new frappe.views.ListSidebar({ doctype: this.doctype, stats: this.stats, diff --git a/frappe/public/js/frappe/list/list_filter.js b/frappe/public/js/frappe/list/list_filter.js index fbbf5e583f..c02755d50c 100644 --- a/frappe/public/js/frappe/list/list_filter.js +++ b/frappe/public/js/frappe/list/list_filter.js @@ -167,6 +167,7 @@ export default class ListFilter { } get_list_filters() { + if (frappe.session.user === 'Guest') return Promise.resolve(); return frappe.db .get_list('List Filter', { fields: ['name', 'filter_name', 'for_user', 'filters'], diff --git a/frappe/public/js/frappe/model/user_settings.js b/frappe/public/js/frappe/model/user_settings.js index 30bd98008d..4d11429ce4 100644 --- a/frappe/public/js/frappe/model/user_settings.js +++ b/frappe/public/js/frappe/model/user_settings.js @@ -6,6 +6,8 @@ $.extend(frappe.model.user_settings, { .then(r => JSON.parse(r.message || '{}')); }, save: function(doctype, key, value) { + if (frappe.session.user === 'Guest') return Promise.resolve(); + const old_user_settings = frappe.model.user_settings[doctype] || {}; const new_user_settings = $.extend(true, {}, old_user_settings); // deep copy @@ -31,6 +33,7 @@ $.extend(frappe.model.user_settings, { return this.update(doctype, user_settings); }, update: function(doctype, user_settings) { + if (frappe.session.user === 'Guest') return Promise.resolve(); return frappe.call({ method: 'frappe.model.utils.user_settings.save', args: { diff --git a/frappe/public/js/frappe/request.js b/frappe/public/js/frappe/request.js index a49b916f6e..93bec14237 100644 --- a/frappe/public/js/frappe/request.js +++ b/frappe/public/js/frappe/request.js @@ -127,7 +127,7 @@ frappe.request.call = function(opts) { message: __('The resource you are looking for is not available')}); }, 403: function(xhr) { - if (frappe.session.user === 'Guest') { + if (frappe.session.logged_in_user !== 'Guest') { // session expired frappe.app.handle_session_expired(); } @@ -322,7 +322,8 @@ frappe.request.cleanup = function(opts, r) { if(r) { // session expired? - Guest has no business here! - if (r.session_expired || frappe.session.user === "Guest") { + if (r.session_expired || + (frappe.session.user === 'Guest' && frappe.session.logged_in_user !== "Guest")) { frappe.app.handle_session_expired(); return; } diff --git a/frappe/public/js/frappe/router.js b/frappe/public/js/frappe/router.js index d3fe28dd10..445478b200 100644 --- a/frappe/public/js/frappe/router.js +++ b/frappe/public/js/frappe/router.js @@ -20,6 +20,7 @@ $(window).on('hashchange', function() { let sub_path = frappe.router.get_sub_path(window.location.hash); window.location.hash = ''; frappe.router.push_state(sub_path); + return false; } }); diff --git a/frappe/public/js/frappe/router_history.js b/frappe/public/js/frappe/router_history.js index 61fc4d6b13..41feaf2728 100644 --- a/frappe/public/js/frappe/router_history.js +++ b/frappe/public/js/frappe/router_history.js @@ -3,14 +3,17 @@ frappe.route_history_queue = []; const routes_to_skip = ['Form', 'social', 'setup-wizard', 'recorder']; const save_routes = frappe.utils.debounce(() => { + if (frappe.session.user === 'Guest') return; const routes = frappe.route_history_queue; frappe.route_history_queue = []; + frappe.xcall('frappe.deferred_insert.deferred_insert', { 'doctype': 'Route History', 'records': routes }).catch(() => { frappe.route_history_queue.concat(routes); - }); + }); + }, 10000); frappe.route.on('change', () => { diff --git a/frappe/public/js/frappe/ui/notifications/notifications.js b/frappe/public/js/frappe/ui/notifications/notifications.js index afdb40118a..998ddbedc9 100644 --- a/frappe/public/js/frappe/ui/notifications/notifications.js +++ b/frappe/public/js/frappe/ui/notifications/notifications.js @@ -12,8 +12,7 @@ frappe.ui.Notifications = class Notifications { } make() { - this.dropdown = $('.navbar').find('.dropdown-notifications'); - this.dropdown.removeClass("hidden") + this.dropdown = $('.navbar').find('.dropdown-notifications').removeClass('hidden'); this.dropdown_list = this.dropdown.find('.notifications-list'); this.header_items = this.dropdown_list.find('.header-items'); this.header_actions = this.dropdown_list.find('.header-actions'); diff --git a/frappe/public/js/frappe/ui/toolbar/awesome_bar.js b/frappe/public/js/frappe/ui/toolbar/awesome_bar.js index 577b3d3f14..f9ec4c789d 100644 --- a/frappe/public/js/frappe/ui/toolbar/awesome_bar.js +++ b/frappe/public/js/frappe/ui/toolbar/awesome_bar.js @@ -7,6 +7,7 @@ frappe.search.AwesomeBar = Class.extend({ setup: function(element) { var me = this; + $('.search-bar').removeClass('hidden'); var $input = $(element); var input = $input.get(0); @@ -122,6 +123,7 @@ frappe.search.AwesomeBar = Class.extend({ $input.blur(); }); frappe.search.utils.setup_recent(); + frappe.tags.utils.fetch_tags(); }, add_help: function() { diff --git a/frappe/public/js/frappe/ui/toolbar/navbar.html b/frappe/public/js/frappe/ui/toolbar/navbar.html index 5ddb5ffc83..2a48165d81 100644 --- a/frappe/public/js/frappe/ui/toolbar/navbar.html +++ b/frappe/public/js/frappe/ui/toolbar/navbar.html @@ -6,7 +6,7 @@