|
- # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
- # MIT License. See license.txt
-
- from __future__ import unicode_literals
- import frappe
- from frappe import _
- import frappe.utils
- import frappe.sessions
- import frappe.desk.form.run_method
- from frappe.utils.response import build_response
- from frappe.api import validate_auth
- from frappe.utils import cint
- from frappe.core.doctype.server_script.server_script_utils import run_server_script_api
- from werkzeug.wrappers import Response
- from six import string_types
-
- ALLOWED_MIMETYPES = ('image/png', 'image/jpeg', 'application/pdf', 'application/msword',
- 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
- 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
- 'application/vnd.oasis.opendocument.text', 'application/vnd.oasis.opendocument.spreadsheet')
-
-
- def handle():
- """handle request"""
- validate_auth()
- cmd = frappe.local.form_dict.cmd
- data = None
-
- if cmd!='login':
- data = execute_cmd(cmd)
-
- # data can be an empty string or list which are valid responses
- if data is not None:
- if isinstance(data, Response):
- # method returns a response object, pass it on
- return data
-
- # add the response to `message` label
- frappe.response['message'] = data
-
- return build_response("json")
-
- def execute_cmd(cmd, from_async=False):
- """execute a request as python module"""
- for hook in frappe.get_hooks("override_whitelisted_methods", {}).get(cmd, []):
- # override using the first hook
- cmd = hook
- break
-
- # via server script
- if run_server_script_api(cmd):
- return None
-
- try:
- method = get_attr(cmd)
- except Exception as e:
- if frappe.local.conf.developer_mode:
- raise e
- else:
- frappe.respond_as_web_page(title='Invalid Method', html='Method not found',
- indicator_color='red', http_status_code=404)
- return
-
- if from_async:
- method = method.queue
-
- is_whitelisted(method)
- is_valid_http_method(method)
-
- return frappe.call(method, **frappe.form_dict)
-
- def is_valid_http_method(method):
- http_method = frappe.local.request.method
-
- if http_method not in frappe.allowed_http_methods_for_whitelisted_func[method]:
- frappe.throw(_("Not permitted"), frappe.PermissionError)
-
- def is_whitelisted(method):
- # check if whitelisted
- if frappe.session['user'] == 'Guest':
- if (method not in frappe.guest_methods):
- frappe.throw(_("Not permitted"), frappe.PermissionError)
-
- if method not in frappe.xss_safe_methods:
- # strictly sanitize form_dict
- # escapes html characters like <> except for predefined tags like a, b, ul etc.
- for key, value in frappe.form_dict.items():
- if isinstance(value, string_types):
- frappe.form_dict[key] = frappe.utils.sanitize_html(value)
-
- else:
- if not method in frappe.whitelisted:
- frappe.throw(_("Not permitted"), frappe.PermissionError)
-
- @frappe.whitelist(allow_guest=True)
- def version():
- return frappe.__version__
-
- @frappe.whitelist()
- def runserverobj(method, docs=None, dt=None, dn=None, arg=None, args=None):
- frappe.desk.form.run_method.runserverobj(method, docs=docs, dt=dt, dn=dn, arg=arg, args=args)
-
- @frappe.whitelist(allow_guest=True)
- def logout():
- frappe.local.login_manager.logout()
- frappe.db.commit()
-
- @frappe.whitelist(allow_guest=True)
- def web_logout():
- frappe.local.login_manager.logout()
- frappe.db.commit()
- frappe.respond_as_web_page(_("Logged Out"), _("You have been successfully logged out"),
- indicator_color='green')
-
- @frappe.whitelist(allow_guest=True)
- def run_custom_method(doctype, name, custom_method):
- """cmd=run_custom_method&doctype={doctype}&name={name}&custom_method={custom_method}"""
- doc = frappe.get_doc(doctype, name)
- if getattr(doc, custom_method, frappe._dict()).is_whitelisted:
- frappe.call(getattr(doc, custom_method), **frappe.local.form_dict)
- else:
- frappe.throw(_("Not permitted"), frappe.PermissionError)
-
- @frappe.whitelist()
- def uploadfile():
- ret = None
-
- try:
- if frappe.form_dict.get('from_form'):
- try:
- ret = frappe.get_doc({
- "doctype": "File",
- "attached_to_name": frappe.form_dict.docname,
- "attached_to_doctype": frappe.form_dict.doctype,
- "attached_to_field": frappe.form_dict.docfield,
- "file_url": frappe.form_dict.file_url,
- "file_name": frappe.form_dict.filename,
- "is_private": frappe.utils.cint(frappe.form_dict.is_private),
- "content": frappe.form_dict.filedata,
- "decode": True
- })
- ret.save()
- except frappe.DuplicateEntryError:
- # ignore pass
- ret = None
- frappe.db.rollback()
- else:
- if frappe.form_dict.get('method'):
- method = frappe.get_attr(frappe.form_dict.method)
- is_whitelisted(method)
- ret = method()
- except Exception:
- frappe.errprint(frappe.utils.get_traceback())
- frappe.response['http_status_code'] = 500
- ret = None
-
- return ret
-
- @frappe.whitelist(allow_guest=True)
- def upload_file():
- user = None
- if frappe.session.user == 'Guest':
- if frappe.get_system_settings('allow_guests_to_upload_files'):
- ignore_permissions = True
- else:
- return
- else:
- user = frappe.get_doc("User", frappe.session.user)
- ignore_permissions = False
-
- files = frappe.request.files
- is_private = frappe.form_dict.is_private
- doctype = frappe.form_dict.doctype
- docname = frappe.form_dict.docname
- fieldname = frappe.form_dict.fieldname
- file_url = frappe.form_dict.file_url
- folder = frappe.form_dict.folder or 'Home'
- method = frappe.form_dict.method
- content = None
- filename = None
-
- if 'file' in files:
- file = files['file']
- content = file.stream.read()
- filename = file.filename
-
- frappe.local.uploaded_file = content
- frappe.local.uploaded_filename = filename
-
- if frappe.session.user == 'Guest' or (user and not user.has_desk_access()):
- import mimetypes
- filetype = mimetypes.guess_type(filename)[0]
- if filetype not in ALLOWED_MIMETYPES:
- frappe.throw(_("You can only upload JPG, PNG, PDF, or Microsoft documents."))
-
- if method:
- method = frappe.get_attr(method)
- is_whitelisted(method)
- return method()
- else:
- ret = frappe.get_doc({
- "doctype": "File",
- "attached_to_doctype": doctype,
- "attached_to_name": docname,
- "attached_to_field": fieldname,
- "folder": folder,
- "file_name": filename,
- "file_url": file_url,
- "is_private": cint(is_private),
- "content": content
- })
- ret.save(ignore_permissions=ignore_permissions)
- return ret
-
-
- def get_attr(cmd):
- """get method object from cmd"""
- if '.' in cmd:
- method = frappe.get_attr(cmd)
- else:
- method = globals()[cmd]
- frappe.log("method:" + cmd)
- return method
-
- @frappe.whitelist(allow_guest = True)
- def ping():
- return "pong"
|