Merge branch 'staging' into develop

This commit is contained in:
Sagar Vora 2019-01-22 15:43:40 +05:30
commit 47c0d10631
17 changed files with 176 additions and 38 deletions

View file

@ -17,7 +17,7 @@ from faker import Faker
from .exceptions import *
from .utils.jinja import (get_jenv, get_template, render_template, get_email_from_template, get_jloader)
__version__ = '10.1.69'
__version__ = '10.1.70'
__title__ = "Frappe Framework"
local = Local()

View file

@ -56,10 +56,10 @@ def get_user_permissions(user=None):
if not out.get(perm.allow):
out[perm.allow] = []
out[perm.allow].append({
out[perm.allow].append(frappe._dict({
'doc': doc_name,
'applicable_for': perm.get('applicable_for')
})
}))
try:
for perm in frappe.get_all('User Permission',
@ -74,6 +74,7 @@ def get_user_permissions(user=None):
for doc in decendants:
add_doc_to_perm(perm, doc)
out = frappe._dict(out)
frappe.cache().hset("user_permissions", user, out)
except frappe.db.SQLError:
if frappe.db.is_table_missing():
@ -94,7 +95,7 @@ def get_applicable_for_doctype_list(doctype, txt, searchfield, start, page_len,
linked_doctypes = get_linked_doctypes(doctype, True).keys()
linked_doctypes = list(linked_doctypes)
linked_doctypes += [doctype]
if txt:
linked_doctypes = [d for d in linked_doctypes if txt in d.lower()]
@ -109,3 +110,13 @@ def get_applicable_for_doctype_list(doctype, txt, searchfield, start, page_len,
def get_permitted_documents(doctype):
return [d.get('doc') for d in get_user_permissions().get(doctype, []) \
if d.get('doc')]
@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

View file

@ -0,0 +1,52 @@
frappe.listview_settings['User Permission'] = {
onload: function(list_view) {
list_view.page.add_menu_item(__("Clear User Permissions"), () => {
const dialog = new frappe.ui.Dialog({
title: __('Clear User Permissions'),
fields: [
{
'fieldname': 'user',
'label': __('For User'),
'fieldtype': 'Link',
'options': 'User',
'reqd': 1
},
{
'fieldname': 'for_doctype',
'label': __('For Document Type'),
'fieldtype': 'Link',
'options': 'DocType',
'reqd': 1
},
],
primary_action: (data) => {
// mandatory not filled
if (!data) return;
frappe.confirm(__('Are you sure?'), () => {
frappe
.xcall('frappe.core.doctype.user_permission.user_permission.clear_user_permissions', data)
.then(data => {
dialog.hide();
let message = '';
if (data === 0) {
message = __('No records deleted');
} else {
message = __('{0} records deleted', [data]);
}
frappe.show_alert({
message,
indicator: 'green'
});
list_view.refresh();
});
});
},
primary_action_label: __('Clear')
});
dialog.show();
});
}
};

View file

@ -92,7 +92,6 @@ def get_permission_query_conditions(user):
}
def has_permission(doc, user):
frappe.log_error(doc.owner)
if doc.event_type=="Public" or doc.owner==user:
return True

View file

@ -559,24 +559,55 @@
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"fieldname": "retry",
"fieldtype": "Int",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Retry",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-envelope",
"idx": 1,
"image_view": 0,
"in_create": 1,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-11-09 15:34:07.229657",
"modified_by": "Administrator",
"module": "Email",
"name": "Email Queue",
"owner": "Administrator",
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-envelope",
"idx": 1,
"image_view": 0,
"in_create": 1,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2019-01-11 09:05:04.175368",
"modified_by": "Administrator",
"module": "Email",
"name": "Email Queue",
"owner": "Administrator",
"permissions": [
{
"amend": 0,

View file

@ -382,7 +382,7 @@ def send_one(email, smtpserver=None, auto_commit=True, now=False, from_test=Fals
email = frappe.db.sql('''select
name, status, communication, message, sender, reference_doctype,
reference_name, unsubscribe_param, unsubscribe_method, expose_recipients,
show_as_cc, add_unsubscribe_link, attachments
show_as_cc, add_unsubscribe_link, attachments, retry
from
`tabEmail Queue`
where
@ -464,12 +464,16 @@ def send_one(email, smtpserver=None, auto_commit=True, now=False, from_test=Fals
except Exception as e:
frappe.db.rollback()
if any("Sent" == s.status for s in recipients_list):
frappe.db.sql("""update `tabEmail Queue` set status='Partially Errored', error=%s where name=%s""",
(text_type(e), email.name), auto_commit=auto_commit)
if email.retry < 3:
frappe.db.sql("""update `tabEmail Queue` set status='Not Sent', modified=%s, retry=retry+1 where name=%s""",
(now_datetime(), email.name), auto_commit=auto_commit)
else:
frappe.db.sql("""update `tabEmail Queue` set status='Error', error=%s
where name=%s""", (text_type(e), email.name), auto_commit=auto_commit)
if any("Sent" == s.status for s in recipients_list):
frappe.db.sql("""update `tabEmail Queue` set status='Partially Errored', error=%s where name=%s""",
(text_type(e), email.name), auto_commit=auto_commit)
else:
frappe.db.sql("""update `tabEmail Queue` set status='Error', error=%s
where name=%s""", (text_type(e), email.name), auto_commit=auto_commit)
if email.communication:
frappe.get_doc('Communication', email.communication).set_delivery_status(commit=auto_commit)

View file

@ -12,7 +12,7 @@ source_link = "https://github.com/frappe/frappe"
app_license = "MIT"
develop_version = '12.x.x-develop'
staging_version = '11.0.3-beta.49'
staging_version = '11.0.3-beta.50'
app_email = "info@frappe.io"

View file

@ -133,13 +133,14 @@ def user_permissions_exist(df, user_permissions):
def get_default_based_on_another_field(df, user_permissions, parent_doc):
# default value based on another document
from frappe.permissions import get_allowed_docs_for_doctype
ref_doctype = df.default[1:]
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
(default_value in user_permissions.get(df.options).get('docs', [])))
(default_value in get_allowed_docs_for_doctype(user_permissions[df.options], df.parent)))
# is this allowed as per user permissions
if is_allowed_default_value:

View file

@ -4,7 +4,7 @@ frappe.provide('frappe.utils');
*/
const EventEmitterMixin = {
init() {
this.jq = jQuery(this);
this.jq = jQuery({});
},
trigger(evt, data) {

View file

@ -45,7 +45,9 @@ frappe.ui.form.ControlData = frappe.ui.form.ControlInput.extend({
if (val) {
this.set_description(__('{0} already exists. Select another name', [val.name]));
}
});
},
this.doc.parenttype
);
this.last_check = null;
}, 1000);
this.last_check = timeout;

View file

@ -697,8 +697,8 @@ export default class Grid {
data.push([__("Do not edit headers which are preset in the template")]);
data.push(["------"]);
$.each(frappe.get_meta(me.df.options).fields, function(i, df) {
// don't include the hidden field in the template
if(frappe.model.is_value_type(df.fieldtype) && !df.hidden) {
// don't include the read-only field in the template
if(frappe.model.is_value_type(df.fieldtype) && !df.read_only) {
data[1].push(df.label);
data[2].push(df.fieldname);
let description = (df.description || "") + ' ';

View file

@ -611,7 +611,7 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
args: {
doctype: this.doctype,
filters: this.get_filters_for_args(),
fields: [`count(${frappe.model.get_full_column_name('name', this.doctype)}) as total_count`]
fields: [`count(distinct ${frappe.model.get_full_column_name('name', this.doctype)}) as total_count`],
}
}).then(r => {
this.total_count = r.message.values[0][0] || current_count;

View file

@ -153,6 +153,7 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup {
this.$wrapper.modal("show");
this.primary_action_fulfilled = false;
this.is_visible = true;
return this;
}
hide() {
this.$wrapper.modal("hide");

View file

@ -639,6 +639,10 @@ frappe.views.CommunicationComposer = Class.extend({
+ this.real_name + ",</p><!-- salutation-ends --><br>" + (this.message || "");
}
if(this.message && signature && this.message.includes(signature)) {
signature = "";
}
let reply = (this.message || "") + (signature ? ("<br>" + signature) : "");
let content = '';

View file

@ -14,6 +14,7 @@ from frappe.permissions import (add_user_permission, remove_user_permission,
get_valid_perms)
from frappe.core.page.permission_manager.permission_manager import update, reset
from frappe.test_runner import make_test_records_for_doctype
from frappe.core.doctype.user_permission.user_permission import clear_user_permissions
test_dependencies = ['Blogger', 'Blog Post', "User", "Contact", "Salutation"]
@ -427,4 +428,35 @@ class TestPermissions(unittest.TestCase):
self.assertTrue(doc.has_permission("delete"))
# delete the created doc
frappe.delete_doc('Blog Post', '-test-blog-post-title')
frappe.delete_doc('Blog Post', '-test-blog-post-title')
def test_clear_user_permissions(self):
current_user = frappe.session.user
frappe.set_user('Administrator')
clear_user_permissions_for_doctype('Blog Category', 'test2@example.com')
clear_user_permissions_for_doctype('Blog Post', 'test2@example.com')
add_user_permission('Blog Post', '-test-blog-post-1', 'test2@example.com')
add_user_permission('Blog Post', '-test-blog-post-2', 'test2@example.com')
add_user_permission("Blog Category", '_Test Blog Category 1', 'test2@example.com')
deleted_user_permission_count = clear_user_permissions('test2@example.com', 'Blog Post')
self.assertEqual(deleted_user_permission_count, 2)
blog_post_user_permission_count = frappe.db.count('User Permission', filters={
'user': 'test2@example.com',
'allow': 'Blog Post'
})
self.assertEqual(blog_post_user_permission_count, 0)
blog_category_user_permission_count = frappe.db.count('User Permission', filters={
'user': 'test2@example.com',
'allow': 'Blog Category'
})
self.assertEqual(blog_category_user_permission_count, 1)
# reset the user
frappe.set_user(current_user)

View file

@ -106,7 +106,7 @@ def print_by_server(doctype, name, print_format=None, doc=None, no_letterhead=0)
print_settings = frappe.get_doc("Print Settings")
try:
import cups
except ModuleNotFoundError:
except ImportError:
frappe.throw("You need to install pycups to use this feature!")
return
try:

View file

@ -35,6 +35,7 @@ pyasn1
zxcvbn-python
unittest-xml-reporting
oauthlib==2.1.0
requests-oauthlib==1.1.0
pdfkit
PyJWT
PyPDF2