Merge pull request #12008 from gavindsouza/server-script-fixes

fix: Server scripts enhancements
This commit is contained in:
mergify[bot] 2020-12-03 11:32:21 +00:00 committed by GitHub
commit c394488f79
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 6 deletions

View file

@ -4,6 +4,8 @@
from __future__ import unicode_literals
import ast
import frappe
from frappe.model.document import Document
from frappe.utils.safe_exec import safe_exec
@ -11,9 +13,9 @@ from frappe import _
class ServerScript(Document):
@staticmethod
def validate():
def validate(self):
frappe.only_for('Script Manager', True)
ast.parse(self.script)
@staticmethod
def on_update():

View file

@ -45,6 +45,15 @@ frappe.response['message'] = 'hello'
allow_guest = 1,
script = '''
frappe.flags = 'hello'
'''
),
dict(
name='test_invalid_namespace_method',
script_type = 'DocType Event',
doctype_event = 'Before Insert',
reference_doctype = 'Note',
script = '''
frappe.method_that_doesnt_exist("do some magic")
'''
)
]
@ -85,3 +94,8 @@ class TestServerScript(unittest.TestCase):
def test_api_return(self):
self.assertEqual(frappe.get_doc('Server Script', 'test_return_value').execute_method(), 'hello')
def test_attribute_error(self):
"""Raise AttributeError if method not found in Namespace"""
note = frappe.get_doc({"doctype": "Note", "title": "Test Note: Server Script"})
self.assertRaises(AttributeError, note.insert)

View file

@ -13,7 +13,19 @@ from frappe.www.printview import get_visible_columns
import frappe.exceptions
import frappe.integrations.utils
class ServerScriptNotEnabled(frappe.PermissionError): pass
class ServerScriptNotEnabled(frappe.PermissionError):
pass
class NamespaceDict(frappe._dict):
"""Raise AttributeError if function not found in namespace"""
def __getattr__(self, key):
ret = self.get(key)
if (not ret and key.startswith("__")) or (key not in self):
def default_function(*args, **kwargs):
raise AttributeError(f"module has no attribute '{key}'")
return default_function
return ret
def safe_exec(script, _globals=None, _locals=None):
# script reports must be enabled via site_config.json
@ -46,13 +58,13 @@ def get_safe_globals():
user = getattr(frappe.local, "session", None) and frappe.local.session.user or "Guest"
out = frappe._dict(
out = NamespaceDict(
# make available limited methods of frappe
json=json,
dict=dict,
log=frappe.log,
_dict=frappe._dict,
frappe=frappe._dict(
frappe=NamespaceDict(
flags=frappe._dict(),
format=frappe.format_value,
format_value=frappe.format_value,
@ -112,7 +124,7 @@ def get_safe_globals():
out.get_visible_columns = get_visible_columns
out.frappe.date_format = date_format
out.frappe.time_format = time_format
out.frappe.db = frappe._dict(
out.frappe.db = NamespaceDict(
get_list = frappe.get_list,
get_all = frappe.get_all,
get_value = frappe.db.get_value,