You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

255 lines
6.4 KiB

  1. # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
  2. # MIT License. See license.txt
  3. from __future__ import unicode_literals
  4. from werkzeug.wrappers import Response
  5. import frappe
  6. import frappe.utils
  7. import frappe.sessions
  8. from frappe.utils import cint
  9. from frappe import _, is_whitelisted
  10. from frappe.utils.response import build_response
  11. from frappe.utils.csvutils import build_csv_response
  12. from frappe.core.doctype.server_script.server_script_utils import run_server_script_api
  13. ALLOWED_MIMETYPES = ('image/png', 'image/jpeg', 'application/pdf', 'application/msword',
  14. 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  15. 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  16. 'application/vnd.oasis.opendocument.text', 'application/vnd.oasis.opendocument.spreadsheet')
  17. def handle():
  18. """handle request"""
  19. cmd = frappe.local.form_dict.cmd
  20. data = None
  21. if cmd!='login':
  22. data = execute_cmd(cmd)
  23. # data can be an empty string or list which are valid responses
  24. if data is not None:
  25. if isinstance(data, Response):
  26. # method returns a response object, pass it on
  27. return data
  28. # add the response to `message` label
  29. frappe.response['message'] = data
  30. return build_response("json")
  31. def execute_cmd(cmd, from_async=False):
  32. """execute a request as python module"""
  33. for hook in frappe.get_hooks("override_whitelisted_methods", {}).get(cmd, []):
  34. # override using the first hook
  35. cmd = hook
  36. break
  37. # via server script
  38. if run_server_script_api(cmd):
  39. return None
  40. try:
  41. method = get_attr(cmd)
  42. except Exception as e:
  43. frappe.throw(_('Invalid Method'))
  44. if from_async:
  45. method = method.queue
  46. if method != run_doc_method:
  47. is_whitelisted(method)
  48. is_valid_http_method(method)
  49. return frappe.call(method, **frappe.form_dict)
  50. def is_valid_http_method(method):
  51. http_method = frappe.local.request.method
  52. if http_method not in frappe.allowed_http_methods_for_whitelisted_func[method]:
  53. throw_permission_error()
  54. def throw_permission_error():
  55. frappe.throw(_("Not permitted"), frappe.PermissionError)
  56. @frappe.whitelist(allow_guest=True)
  57. def version():
  58. return frappe.__version__
  59. @frappe.whitelist(allow_guest=True)
  60. def logout():
  61. frappe.local.login_manager.logout()
  62. frappe.db.commit()
  63. @frappe.whitelist(allow_guest=True)
  64. def web_logout():
  65. frappe.local.login_manager.logout()
  66. frappe.db.commit()
  67. frappe.respond_as_web_page(_("Logged Out"), _("You have been successfully logged out"),
  68. indicator_color='green')
  69. @frappe.whitelist()
  70. def uploadfile():
  71. ret = None
  72. try:
  73. if frappe.form_dict.get('from_form'):
  74. try:
  75. ret = frappe.get_doc({
  76. "doctype": "File",
  77. "attached_to_name": frappe.form_dict.docname,
  78. "attached_to_doctype": frappe.form_dict.doctype,
  79. "attached_to_field": frappe.form_dict.docfield,
  80. "file_url": frappe.form_dict.file_url,
  81. "file_name": frappe.form_dict.filename,
  82. "is_private": frappe.utils.cint(frappe.form_dict.is_private),
  83. "content": frappe.form_dict.filedata,
  84. "decode": True
  85. })
  86. ret.save()
  87. except frappe.DuplicateEntryError:
  88. # ignore pass
  89. ret = None
  90. frappe.db.rollback()
  91. else:
  92. if frappe.form_dict.get('method'):
  93. method = frappe.get_attr(frappe.form_dict.method)
  94. is_whitelisted(method)
  95. ret = method()
  96. except Exception:
  97. frappe.errprint(frappe.utils.get_traceback())
  98. frappe.response['http_status_code'] = 500
  99. ret = None
  100. return ret
  101. @frappe.whitelist(allow_guest=True)
  102. def upload_file():
  103. user = None
  104. if frappe.session.user == 'Guest':
  105. if frappe.get_system_settings('allow_guests_to_upload_files'):
  106. ignore_permissions = True
  107. else:
  108. return
  109. else:
  110. user = frappe.get_doc("User", frappe.session.user)
  111. ignore_permissions = False
  112. files = frappe.request.files
  113. is_private = frappe.form_dict.is_private
  114. doctype = frappe.form_dict.doctype
  115. docname = frappe.form_dict.docname
  116. fieldname = frappe.form_dict.fieldname
  117. file_url = frappe.form_dict.file_url
  118. folder = frappe.form_dict.folder or 'Home'
  119. method = frappe.form_dict.method
  120. content = None
  121. filename = None
  122. if 'file' in files:
  123. file = files['file']
  124. content = file.stream.read()
  125. filename = file.filename
  126. frappe.local.uploaded_file = content
  127. frappe.local.uploaded_filename = filename
  128. if frappe.session.user == 'Guest' or (user and not user.has_desk_access()):
  129. import mimetypes
  130. filetype = mimetypes.guess_type(filename)[0]
  131. if filetype not in ALLOWED_MIMETYPES:
  132. frappe.throw(_("You can only upload JPG, PNG, PDF, or Microsoft documents."))
  133. if method:
  134. method = frappe.get_attr(method)
  135. is_whitelisted(method)
  136. return method()
  137. else:
  138. ret = frappe.get_doc({
  139. "doctype": "File",
  140. "attached_to_doctype": doctype,
  141. "attached_to_name": docname,
  142. "attached_to_field": fieldname,
  143. "folder": folder,
  144. "file_name": filename,
  145. "file_url": file_url,
  146. "is_private": cint(is_private),
  147. "content": content
  148. })
  149. ret.save(ignore_permissions=ignore_permissions)
  150. return ret
  151. def get_attr(cmd):
  152. """get method object from cmd"""
  153. if '.' in cmd:
  154. method = frappe.get_attr(cmd)
  155. else:
  156. method = globals()[cmd]
  157. frappe.log("method:" + cmd)
  158. return method
  159. @frappe.whitelist(allow_guest=True)
  160. def ping():
  161. return "pong"
  162. def run_doc_method(method, docs=None, dt=None, dn=None, arg=None, args=None):
  163. """run a whitelisted controller method"""
  164. import json
  165. import inspect
  166. if not args:
  167. args = arg or ""
  168. if dt: # not called from a doctype (from a page)
  169. if not dn:
  170. dn = dt # single
  171. doc = frappe.get_doc(dt, dn)
  172. else:
  173. doc = frappe.get_doc(json.loads(docs))
  174. doc._original_modified = doc.modified
  175. doc.check_if_latest()
  176. if not doc or not doc.has_permission("read"):
  177. throw_permission_error()
  178. try:
  179. args = json.loads(args)
  180. except ValueError:
  181. args = args
  182. method_obj = getattr(doc, method)
  183. fn = getattr(method_obj, '__func__', method_obj)
  184. is_whitelisted(fn)
  185. is_valid_http_method(fn)
  186. fnargs = inspect.getfullargspec(method_obj).args
  187. if not fnargs or (len(fnargs)==1 and fnargs[0]=="self"):
  188. response = doc.run_method(method)
  189. elif "args" in fnargs or not isinstance(args, dict):
  190. response = doc.run_method(method, args)
  191. else:
  192. response = doc.run_method(method, **args)
  193. frappe.response.docs.append(doc)
  194. if not response:
  195. return
  196. # build output as csv
  197. if cint(frappe.form_dict.get('as_csv')):
  198. build_csv_response(response, doc.doctype.replace(' ', ''))
  199. return
  200. frappe.response['message'] = response
  201. # for backwards compatibility
  202. runserverobj = run_doc_method