diff --git a/frappe/__init__.py b/frappe/__init__.py
index c540652c8c..1be882ab35 100644
--- a/frappe/__init__.py
+++ b/frappe/__init__.py
@@ -23,7 +23,7 @@ if sys.version[0] == '2':
reload(sys)
sys.setdefaultencoding("utf-8")
-__version__ = '11.1.4'
+__version__ = '11.1.5'
__title__ = "Frappe Framework"
local = Local()
@@ -501,6 +501,7 @@ def read_only():
retval = fn(*args, **get_newargs(fn, kwargs))
if local and hasattr(local, 'master_db'):
+ local.db.close()
local.db = local.master_db
return retval
diff --git a/frappe/core/doctype/user_permission/test_user_permission.py b/frappe/core/doctype/user_permission/test_user_permission.py
index 157fa44ae2..b83d103013 100644
--- a/frappe/core/doctype/user_permission/test_user_permission.py
+++ b/frappe/core/doctype/user_permission/test_user_permission.py
@@ -2,9 +2,84 @@
# Copyright (c) 2017, Frappe Technologies and Contributors
# See license.txt
from __future__ import unicode_literals
+from frappe.core.doctype.user_permission.user_permission import add_user_permissions
-#import frappe
+import frappe
import unittest
class TestUserPermission(unittest.TestCase):
- pass
+ def test_apply_to_all(self):
+ ''' Create User permission for User having access to all applicable Doctypes'''
+ user = get_user()
+ param = get_params(user, apply = 1)
+ created = add_user_permissions(param)
+ self.assertEquals(created, 1)
+
+ def test_for_applicable_on_update_from_apply_to_all(self):
+ ''' Update User Permission from all to some applicable Doctypes'''
+ user = get_user()
+ param = get_params(user, applicable = ["Chat Room", "Chat Message"])
+ create = add_user_permissions(param)
+ frappe.db.commit()
+
+ removed_apply_to_all = frappe.db.exists("User Permission", get_exists_param(user))
+ created_applicable_first = frappe.db.exists("User Permission", get_exists_param(user, applicable = "Chat Room"))
+ created_applicable_second = frappe.db.exists("User Permission", get_exists_param(user, applicable = "Chat Message"))
+
+ self.assertIsNone(removed_apply_to_all)
+ self.assertIsNotNone(created_applicable_first)
+ self.assertIsNotNone(created_applicable_second)
+ self.assertEquals(create, 1)
+
+ def test_for_apply_to_all_on_update_from_applicable(self):
+ ''' Update User Permission from some to all applicable Doctypes'''
+ user = get_user()
+ param = get_params(user, apply = 1)
+ created = add_user_permissions(param)
+ created_apply_to_all = frappe.db.exists("User Permission", get_exists_param(user))
+ removed_applicable_first = frappe.db.exists("User Permission", get_exists_param(user, applicable = "Chat Room"))
+ removed_applicable_second = frappe.db.exists("User Permission", get_exists_param(user, applicable = "Chat Message"))
+
+
+ self.assertIsNotNone(created_apply_to_all)
+ self.assertIsNone(removed_applicable_first)
+ self.assertIsNone(removed_applicable_second)
+ self.assertEquals(created, 1)
+
+def get_user():
+ if frappe.db.exists('User', 'test_bulk_creation_update@example.com'):
+ return frappe.get_doc('User', 'test_bulk_creation_update@example.com')
+ else:
+ user = frappe.new_doc('User')
+ user.email = 'test_bulk_creation_update@example.com'
+ user.first_name = 'Test_Bulk_Creation'
+ user.add_roles("System Manager")
+ return user
+
+def get_params(user, apply = None , applicable = None):
+ ''' Return param to insert '''
+ param = {
+ "user": user.name,
+ "doctype":"User",
+ "docname":user.name
+ }
+ if apply:
+ param.update({"apply_to_all_doctypes": 1})
+ param.update({"applicable_doctypes": []})
+ if applicable:
+ param.update({"apply_to_all_doctypes": 0})
+ param.update({"applicable_doctypes": applicable})
+ return param
+
+def get_exists_param(user, applicable = None):
+ ''' param to check existing Document '''
+ param = {
+ "user": user.name,
+ "allow": "User",
+ "for_value": user.name,
+ }
+ if applicable:
+ param.update({"applicable_for": applicable})
+ else:
+ param.update({"apply_to_all_doctypes": 1})
+ return param
diff --git a/frappe/core/doctype/user_permission/user_permission.py b/frappe/core/doctype/user_permission/user_permission.py
index 43dff47745..4dd152b54e 100644
--- a/frappe/core/doctype/user_permission/user_permission.py
+++ b/frappe/core/doctype/user_permission/user_permission.py
@@ -42,6 +42,9 @@ def get_user_permissions(user=None):
if not user:
user = frappe.session.user
+ if user == "Administrator":
+ return {}
+
cached_user_permissions = frappe.cache().hget("user_permissions", user)
if cached_user_permissions is not None:
@@ -112,12 +115,100 @@ def get_permitted_documents(doctype):
return [d.get('doc') for d in get_user_permissions().get(doctype, []) \
if d.get('doc')]
+@frappe.whitelist()
+def check_applicable_doc_perm(user, doctype, docname):
+ frappe.only_for('System Manager')
+ applicable = []
+ doc_exists = frappe.get_all('User Permission',
+ fields=['name'],
+ filters={"user": user,
+ "allow": doctype,
+ "for_value": docname,
+ "apply_to_all_doctypes":1,
+ }, limit=1)
+ if doc_exists:
+ applicable = get_linked_doctypes(doctype).keys()
+ else:
+ data = frappe.get_all('User Permission',
+ fields=['applicable_for'],
+ filters={"user": user,
+ "allow": doctype,
+ "for_value":docname,
+ })
+ for d in data:
+ applicable.append(d.applicable_for)
+ return applicable
+
+
@frappe.whitelist()
def clear_user_permissions(user, for_doctype):
frappe.only_for('System Manager')
-
total = frappe.db.count('User Permission', filters = dict(user=user, allow=for_doctype))
if total:
frappe.db.sql('DELETE FROM `tabUser Permission` WHERE user=%s AND allow=%s', (user, for_doctype))
frappe.clear_cache()
return total
+
+@frappe.whitelist()
+def add_user_permissions(data):
+ ''' Add and update the user permissions '''
+ frappe.only_for('System Manager')
+ if isinstance(data, frappe.string_types):
+ data = json.loads(data)
+ data = frappe._dict(data)
+
+ d = check_applicable_doc_perm(data.user, data.doctype, data.docname)
+ exists = frappe.db.exists("User Permission", {"user": data.user, "allow": data.doctype, "for_value": data.docname, "apply_to_all_doctypes": 1})
+ if data.apply_to_all_doctypes == 1 and not exists:
+ remove_applicable(d, data.user, data.doctype, data.docname)
+ insert_user_perm(data.user, data.doctype, data.docname, apply_to_all = 1)
+ return 1
+ else:
+ remove_apply_to_all(data.user, data.doctype, data.docname)
+ update_applicable(d, data.applicable_doctypes, data.user, data.doctype, data.docname)
+ for applicable in data.applicable_doctypes :
+ if applicable not in d:
+ insert_user_perm(data.user, data.doctype, data.docname, applicable = applicable)
+ elif exists:
+ insert_user_perm(data.user, data.doctype, data.docname, applicable = applicable)
+ return 1
+ return 0
+
+def insert_user_perm(user, doctype, docname, apply_to_all=None, applicable=None):
+ user_perm = frappe.new_doc("User Permission")
+ user_perm.user = user
+ user_perm.allow = doctype
+ user_perm.for_value = docname
+ if applicable:
+ user_perm.applicable_for = applicable
+ user_perm.apply_to_all_doctypes = 0
+ else:
+ user_perm.apply_to_all_doctypes = 1
+ user_perm.insert()
+
+def remove_applicable(d, user, doctype, docname):
+ for applicable_for in d:
+ frappe.db.sql("""DELETE FROM `tabUser Permission`
+ WHERE `user`=%s
+ AND `applicable_for`=%s
+ AND `allow`=%s
+ AND `for_value`=%s
+ """, (user, applicable_for, doctype, docname))
+
+def remove_apply_to_all(user, doctype, docname):
+ frappe.db.sql("""DELETE from `tabUser Permission`
+ WHERE `user`=%s
+ AND `apply_to_all_doctypes`=1
+ AND `allow`=%s
+ AND `for_value`=%s
+ """,(user, doctype, docname))
+
+def update_applicable(already_applied, to_apply, user, doctype, docname):
+ for applied in already_applied:
+ if applied not in to_apply:
+ frappe.db.sql("""DELETE FROM `tabUser Permission`
+ WHERE `user`=%s
+ AND `applicable_for`=%s
+ AND `allow`=%s
+ AND `for_value`=%s
+ """,(user, applied, doctype, docname))
\ No newline at end of file
diff --git a/frappe/core/doctype/user_permission/user_permission_list.js b/frappe/core/doctype/user_permission/user_permission_list.js
index 39a4648334..00d829b2a0 100644
--- a/frappe/core/doctype/user_permission/user_permission_list.js
+++ b/frappe/core/doctype/user_permission/user_permission_list.js
@@ -1,22 +1,123 @@
frappe.listview_settings['User Permission'] = {
+
onload: function(list_view) {
- list_view.page.add_menu_item(__("Clear User Permissions"), () => {
+ var me = this;
+ list_view.page.add_inner_button( __("Add / Update"), function() {
+ let dialog =new frappe.ui.Dialog({
+ title : __('Add User Permissions'),
+ fields: [
+ {
+ fieldname: 'user',
+ label: __('For User'),
+ fieldtype: 'Link',
+ options: 'User',
+ reqd: 1,
+ onchange: function() {
+ dialog.fields_dict.doctype.set_input(undefined);
+ dialog.fields_dict.docname.set_input(undefined);
+ dialog.set_df_property("docname", "hidden", 1);
+ dialog.set_df_property("apply_to_all_doctypes", "hidden", 1);
+ dialog.set_df_property("applicable_doctypes", "hidden", 1);
+ }
+ },
+ {
+ fieldname: 'doctype',
+ label: __('Document Type'),
+ fieldtype: 'Link',
+ options: 'DocType',
+ reqd: 1,
+ onchange: function() {
+ me.on_doctype_change(dialog);
+ }
+ },
+ {
+ fieldname: 'docname',
+ label: __('Document Name'),
+ fieldtype: 'Dynamic Link',
+ options: 'doctype',
+ hidden: 1,
+ onchange: function() {
+ let field = dialog.fields_dict["docname"];
+ if(field.value != field.last_value) {
+ if(dialog.fields_dict.doctype.value && dialog.fields_dict.docname.value && dialog.fields_dict.user.value){
+ me.get_applicable_doctype(dialog).then(applicable => {
+ me.get_multi_select_options(dialog, applicable).then(options => {
+ me.applicable_options = options;
+ me.on_docname_change(dialog, options, applicable);
+ if(options.length > 5){
+ dialog.fields_dict.applicable_doctypes.setup_select_all();
+ }
+ });
+ });
+ }
+ }
+ }
+ },
+ {
+ fieldname: 'apply_to_all_doctypes',
+ label: __('Apply to all Documents Types'),
+ fieldtype: 'Check',
+ checked: 1,
+ hidden: 1,
+ onchange: function() {
+ if(dialog.fields_dict.doctype.value && dialog.fields_dict.docname.value && dialog.fields_dict.user.value){
+ me.on_apply_to_all_doctypes_change(dialog, me.applicable_options);
+ if(me.applicable_options.length > 5){
+ dialog.fields_dict.applicable_doctypes.setup_select_all();
+ }
+ }
+ }
+ },
+ {
+ label: __("Applicable Document Types"),
+ fieldname: "applicable_doctypes",
+ fieldtype: "MultiCheck",
+ options: [],
+ columns: 2,
+ hidden: 1
+ },
+ ],
+ primary_action: (data) => {
+ data = me.validate(dialog, data);
+ frappe.call({
+ async: false,
+ method: "frappe.core.doctype.user_permission.user_permission.add_user_permissions",
+ args: {
+ data : data
+ },
+ callback: function(r) {
+ if(r.message === 1) {
+ frappe.show_alert({message:__("User Permissions created sucessfully"), indicator:'blue'});
+ } else {
+ frappe.show_alert({message:__("Nothing to update"), indicator:'red'});
+
+ }
+ }
+ });
+ dialog.hide();
+ list_view.refresh();
+ },
+ primary_action_label: __('Submit')
+ });
+ dialog.show();
+ });
+ list_view.page.add_inner_button( __("Bulk Delete"), function() {
const dialog = new frappe.ui.Dialog({
title: __('Clear User Permissions'),
fields: [
{
- 'fieldname': 'user',
- 'label': __('For User'),
- 'fieldtype': 'Link',
- 'options': 'User',
- 'reqd': 1
+ fieldname: 'user',
+ label: __('For User'),
+ fieldtype: 'Link',
+ options: 'User',
+ reqd: 1
},
{
- 'fieldname': 'for_doctype',
- 'label': __('For Document Type'),
- 'fieldtype': 'Link',
- 'options': 'DocType',
- 'reqd': 1
+ fieldname: 'for_doctype',
+ label: __('For Document Type'),
+ fieldtype: 'Link',
+ options: 'DocType',
+ reqd: 1
},
],
primary_action: (data) => {
@@ -31,6 +132,8 @@ frappe.listview_settings['User Permission'] = {
let message = '';
if (data === 0) {
message = __('No records deleted');
+ } else if(data === 1) {
+ message = __('{0} record deleted', [data]);
} else {
message = __('{0} records deleted', [data]);
}
@@ -43,10 +146,95 @@ frappe.listview_settings['User Permission'] = {
});
},
- primary_action_label: __('Clear')
+ primary_action_label: __('Delete')
});
dialog.show();
});
+ },
+
+ validate: function(dialog, data) {
+ if(dialog.fields_dict.applicable_doctypes.get_unchecked_options().length == 0) {
+ data.apply_to_all_doctypes = 1;
+ data.applicable_doctypes = [];
+ return data;
+ }
+ if(data.apply_to_all_doctypes == 0 && !("applicable_doctypes" in data)) {
+ frappe.throw("Please select applicable Doctypes");
+ }
+ return data;
+ },
+
+ get_applicable_doctype: function(dialog) {
+ return new Promise(resolve => {
+ frappe.call({
+ method: 'frappe.core.doctype.user_permission.user_permission.check_applicable_doc_perm',
+ async: false,
+ args:{
+ user: dialog.fields_dict.user.value,
+ doctype: dialog.fields_dict.doctype.value,
+ docname: dialog.fields_dict.docname.value
+ }
+ }).then(r => {
+ resolve(r.message);
+ });
+ });
+ },
+
+ get_multi_select_options: function(dialog, applicable){
+ return new Promise(resolve => {
+ frappe.call({
+ method: 'frappe.desk.form.linked_with.get_linked_doctypes',
+ async: false,
+ args:{
+ user: dialog.fields_dict.user.value,
+ doctype: dialog.fields_dict.doctype.value,
+ docname: dialog.fields_dict.docname.value
+ }
+ }).then(r => {
+ var options = [];
+ for(var d in r.message){
+ var checked = ($.inArray(d, applicable) != -1) ? 1 : 0;
+ options.push({ "label":d, "value": d , "checked": checked});
+ }
+ resolve(options);
+ });
+ });
+ },
+
+ on_doctype_change: function(dialog) {
+ dialog.set_df_property("docname", "hidden", 0);
+ dialog.set_df_property("docname", "reqd", 1);
+ dialog.set_df_property("apply_to_all_doctypes", "hidden", 0);
+ dialog.set_value("apply_to_all_doctypes","checked",1);
+ },
+
+ on_docname_change: function(dialog, options, applicable) {
+ if(applicable.length != 0 ) {
+ dialog.set_primary_action("Update");
+ dialog.set_title("Update User Permissions");
+ dialog.set_df_property("applicable_doctypes", "options", options);
+ if(dialog.fields_dict.applicable_doctypes.get_checked_options().length == options.length) {
+ dialog.set_df_property("applicable_doctypes", "hidden", 1);
+ } else {
+ dialog.set_df_property("applicable_doctypes", "hidden", 0);
+ dialog.set_df_property("apply_to_all_doctypes", "checked", 0);
+ }
+ } else {
+ dialog.set_primary_action("Submit");
+ dialog.set_title("Add User Permissions");
+ dialog.set_df_property("applicable_doctypes", "options", options);
+ dialog.set_df_property("applicable_doctypes", "hidden", 1);
+ }
+ },
+
+ on_apply_to_all_doctypes_change: function(dialog, options) {
+ if(dialog.fields_dict.apply_to_all_doctypes.get_value() == 0) {
+ dialog.set_df_property("applicable_doctypes", "hidden", 0);
+ dialog.set_df_property("applicable_doctypes", "options", options);
+ } else {
+ dialog.set_df_property("applicable_doctypes", "options", options);
+ dialog.set_df_property("applicable_doctypes", "hidden", 1);
+ }
}
-};
+};
\ No newline at end of file
diff --git a/frappe/desk/notifications.py b/frappe/desk/notifications.py
index 59c783c524..eb56c458ce 100644
--- a/frappe/desk/notifications.py
+++ b/frappe/desk/notifications.py
@@ -249,6 +249,11 @@ def get_open_count(doctype, name, items=[]):
:param transactions: List of transactions (json/dict)
:param filters: optional filters (json/list)'''
+ if frappe.flags.in_migrate or frappe.flags.in_install:
+ return {
+ 'count': []
+ }
+
frappe.has_permission(doc=frappe.get_doc(doctype, name), throw=True)
meta = frappe.get_meta(doctype)
diff --git a/frappe/email/doctype/email_group_member/email_group_member.py b/frappe/email/doctype/email_group_member/email_group_member.py
index d0968425d0..23b279e755 100644
--- a/frappe/email/doctype/email_group_member/email_group_member.py
+++ b/frappe/email/doctype/email_group_member/email_group_member.py
@@ -7,7 +7,13 @@ import frappe
from frappe.model.document import Document
class EmailGroupMember(Document):
- pass
+ def after_delete(self):
+ email_group = frappe.get_doc('Email Group', self.email_group)
+ email_group.update_total_subscribers()
+
+ def after_insert(self):
+ email_group = frappe.get_doc('Email Group', self.email_group)
+ email_group.update_total_subscribers()
def after_doctype_insert():
- frappe.db.add_unique("Email Group Member", ("email_group", "email"))
\ No newline at end of file
+ frappe.db.add_unique("Email Group Member", ("email_group", "email"))
diff --git a/frappe/email/doctype/newsletter/newsletter.py b/frappe/email/doctype/newsletter/newsletter.py
index d69fae1f1d..9344ae1b3e 100755
--- a/frappe/email/doctype/newsletter/newsletter.py
+++ b/frappe/email/doctype/newsletter/newsletter.py
@@ -137,7 +137,7 @@ def unsubscribe(email, name):
return
primary_action = frappe.utils.get_url() + "/api/method/frappe.email.doctype.newsletter.newsletter.confirmed_unsubscribe"+\
- "?" + get_signed_params({"email": email, "name":name})
+ "?" + get_signed_params({"email": email, "name":name.encode('utf-8')})
return_confirmation_page(email, name, primary_action)
diff --git a/frappe/email/doctype/notification/notification.py b/frappe/email/doctype/notification/notification.py
index a3f43f716d..acddf36777 100644
--- a/frappe/email/doctype/notification/notification.py
+++ b/frappe/email/doctype/notification/notification.py
@@ -212,8 +212,15 @@ def get_context(context):
please enable Allow Print For {0} in Print Settings""".format(status)),
title=_("Error in Notification"))
else:
- return [{"print_format_attachment":1, "doctype":doc.doctype, "name": doc.name,
- "print_format":self.print_format, "print_letterhead": print_settings.with_letterhead}]
+ return [{
+ "print_format_attachment": 1,
+ "doctype": doc.doctype,
+ "name": doc.name,
+ "print_format": self.print_format,
+ "print_letterhead": print_settings.with_letterhead,
+ "lang": frappe.db.get_value('Print Format', self.print_format, 'default_print_language')
+ if self.print_format else 'en'
+ }]
def get_template(self):
diff --git a/frappe/email/queue.py b/frappe/email/queue.py
index 0ed4044586..e62e7ca674 100755
--- a/frappe/email/queue.py
+++ b/frappe/email/queue.py
@@ -175,7 +175,8 @@ def get_email_queue(recipients, sender, subject, **kwargs):
if att.get('fid'):
_attachments.append(att)
elif att.get("print_format_attachment") == 1:
- att['lang'] = frappe.local.lang
+ if not att.get('lang', None):
+ att['lang'] = frappe.local.lang
att['print_letterhead'] = kwargs.get('print_letterhead')
_attachments.append(att)
e.attachments = json.dumps(_attachments)
diff --git a/frappe/model/create_new.py b/frappe/model/create_new.py
index c6bcc42f06..b48f279a5e 100644
--- a/frappe/model/create_new.py
+++ b/frappe/model/create_new.py
@@ -12,6 +12,7 @@ import frappe.defaults
from frappe.model.db_schema import type_map
import copy
from frappe.core.doctype.user_permission.user_permission import get_user_permissions
+from frappe.permissions import get_allowed_docs_for_doctype
def get_new_doc(doctype, parent_doc = None, parentfield = None, as_dict=False):
if doctype not in frappe.local.new_doc_templates:
@@ -53,36 +54,39 @@ def set_user_and_static_default_values(doc):
for df in doc.meta.get("fields"):
if df.fieldtype in type_map:
- user_default_value = get_user_default_value(df, defaults, user_permissions)
+ # user permissions for link options
+ doctype_user_permissions = user_permissions.get(df.options, [])
+ # Allowed records for the reference doctype (link field)
+ allowed_records = get_allowed_docs_for_doctype(doctype_user_permissions, df.parent)
+
+ user_default_value = get_user_default_value(df, defaults, doctype_user_permissions, allowed_records)
if user_default_value is not None:
doc.set(df.fieldname, user_default_value)
else:
if df.fieldname != doc.meta.title_field:
- static_default_value = get_static_default_value(df, user_permissions)
+ static_default_value = get_static_default_value(df, doctype_user_permissions, allowed_records)
if static_default_value is not None:
doc.set(df.fieldname, static_default_value)
-def get_user_default_value(df, defaults, user_permissions):
+def get_user_default_value(df, defaults, doctype_user_permissions, allowed_records):
# don't set defaults for "User" link field using User Permissions!
if df.fieldtype == "Link" and df.options != "User":
# 1 - look in user permissions only for document_type==Setup
# We don't want to include permissions of transactions to be used for defaults.
- if (frappe.get_meta(df.options).document_type=="Setup"
- and user_permissions_exist(df, user_permissions)
- and len(user_permissions.get(df.options))==1):
- return user_permissions.get(df.options)[0].get("doc")
+ if frappe.get_meta(df.options).document_type=="Setup" and len(allowed_records)==1:
+ return allowed_records[0]
# 2 - Look in user defaults
user_default = defaults.get(df.fieldname)
- is_allowed_user_default = user_default and (not user_permissions_exist(df, user_permissions)
- or (user_default in user_permissions.get(df.options, [])))
+ is_allowed_user_default = user_default and (not user_permissions_exist(df, doctype_user_permissions)
+ or user_default in allowed_records)
# is this user default also allowed as per user permissions?
if is_allowed_user_default:
return user_default
-def get_static_default_value(df, user_permissions):
+def get_static_default_value(df, doctype_user_permissions, allowed_records):
# 3 - look in default of docfield
if df.get("default"):
if df.default == "__user":
@@ -93,8 +97,8 @@ def get_static_default_value(df, user_permissions):
elif not df.default.startswith(":"):
# a simple default value
- is_allowed_default_value = (not user_permissions_exist(df, user_permissions)
- or (df.default in user_permissions.get(df.options, [])))
+ is_allowed_default_value = (not user_permissions_exist(df, doctype_user_permissions)
+ or (df.default in allowed_records))
if df.fieldtype!="Link" or df.options=="User" or is_allowed_default_value:
return df.default
@@ -126,10 +130,10 @@ def set_dynamic_default_values(doc, parent_doc, parentfield):
if parentfield:
doc["parentfield"] = parentfield
-def user_permissions_exist(df, user_permissions):
+def user_permissions_exist(df, doctype_user_permissions):
return (df.fieldtype=="Link"
and not getattr(df, "ignore_user_permissions", False)
- and df.options in (user_permissions or []))
+ and doctype_user_permissions)
def get_default_based_on_another_field(df, user_permissions, parent_doc):
# default value based on another document
@@ -139,7 +143,7 @@ def get_default_based_on_another_field(df, user_permissions, parent_doc):
ref_fieldname = ref_doctype.lower().replace(" ", "_")
reference_name = parent_doc.get(ref_fieldname) if parent_doc else frappe.db.get_default(ref_fieldname)
default_value = frappe.db.get_value(ref_doctype, reference_name, df.fieldname)
- is_allowed_default_value = (not user_permissions_exist(df, user_permissions) or
+ is_allowed_default_value = (not user_permissions_exist(df, user_permissions.get(df.options)) or
(default_value in get_allowed_docs_for_doctype(user_permissions[df.options], df.parent)))
# is this allowed as per user permissions
diff --git a/frappe/model/document.py b/frappe/model/document.py
index 6fdbf633d2..b2b68b2f62 100644
--- a/frappe/model/document.py
+++ b/frappe/model/document.py
@@ -166,10 +166,10 @@ class Document(BaseDocument):
self.latest = frappe.get_doc(self.doctype, self.name)
return self.latest
- def check_permission(self, permtype='read', permlabel=None):
+ def check_permission(self, permtype='read', permlevel=None):
"""Raise `frappe.PermissionError` if not permitted"""
if not self.has_permission(permtype):
- self.raise_no_permission_to(permlabel or permtype)
+ self.raise_no_permission_to(permlevel or permtype)
def has_permission(self, permtype="read", verbose=False):
"""Call `frappe.has_permission` if `self.flags.ignore_permissions`
@@ -989,7 +989,7 @@ class Document(BaseDocument):
frappe.db.commit()
def db_get(self, fieldname):
- '''get database vale for this fieldname'''
+ '''get database value for this fieldname'''
return frappe.db.get_value(self.doctype, self.name, fieldname)
def check_no_back_links_exist(self):
diff --git a/frappe/oauth.py b/frappe/oauth.py
index 0359e75214..4dc50366be 100644
--- a/frappe/oauth.py
+++ b/frappe/oauth.py
@@ -5,7 +5,7 @@ import pytz
from frappe import _
from frappe.auth import LoginManager
from oauthlib.oauth2.rfc6749.tokens import BearerToken
-from oauthlib.oauth2.rfc6749.grant_types import AuthorizationCodeGrant, ImplicitGrant, ResourceOwnerPasswordCredentialsGrant, ClientCredentialsGrant, RefreshTokenGrant, OpenIDConnectAuthCode
+from oauthlib.oauth2.rfc6749.grant_types import AuthorizationCodeGrant, ImplicitGrant, ResourceOwnerPasswordCredentialsGrant, ClientCredentialsGrant, RefreshTokenGrant
from oauthlib.oauth2 import RequestValidator
from oauthlib.oauth2.rfc6749.endpoints.authorization import AuthorizationEndpoint
from oauthlib.oauth2.rfc6749.endpoints.token import TokenEndpoint
@@ -40,19 +40,12 @@ class WebApplicationServer(AuthorizationEndpoint, TokenEndpoint, ResourceEndpoin
implicit_grant = ImplicitGrant(request_validator)
auth_grant = AuthorizationCodeGrant(request_validator)
refresh_grant = RefreshTokenGrant(request_validator)
- openid_connect_auth = OpenIDConnectAuthCode(request_validator)
resource_owner_password_credentials_grant = ResourceOwnerPasswordCredentialsGrant(request_validator)
bearer = BearerToken(request_validator, token_generator,
token_expires_in, refresh_token_generator)
AuthorizationEndpoint.__init__(self, default_response_type='code',
response_types={
'code': auth_grant,
- 'code+token': openid_connect_auth,
- 'code+id_token': openid_connect_auth,
- 'code+token+id_token': openid_connect_auth,
- 'code token': openid_connect_auth,
- 'code id_token': openid_connect_auth,
- 'code token id_token': openid_connect_auth,
'token': implicit_grant
},
default_token_type=bearer)
diff --git a/frappe/permissions.py b/frappe/permissions.py
index 7553cb5dc5..46924331f4 100644
--- a/frappe/permissions.py
+++ b/frappe/permissions.py
@@ -24,8 +24,10 @@ def print_has_permission_check_logs(func):
def inner(*args, **kwargs):
frappe.flags['has_permission_check_logs'] = []
result = func(*args, **kwargs)
+ self_perm_check = True if not kwargs.get('user') else kwargs.get('user') == frappe.session.user
# print only if access denied
- if not result:
+ # and if user is checking his own permission
+ if not result and self_perm_check:
msgprint(('
').join(frappe.flags['has_permission_check_logs']))
frappe.flags.pop('has_permission_check_logs', None)
return result
diff --git a/frappe/public/js/frappe/dom.js b/frappe/public/js/frappe/dom.js
index d91d7e38b0..a13b8754fd 100644
--- a/frappe/public/js/frappe/dom.js
+++ b/frappe/public/js/frappe/dom.js
@@ -220,6 +220,16 @@ frappe.dom = {
};
reader.readAsDataURL(file_obj);
});
+ },
+ pixel_to_inches(pixels) {
+ const div = $('