No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 
 
 

153 líneas
4.5 KiB

  1. # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
  2. # MIT License. See license.txt
  3. from __future__ import unicode_literals
  4. import json
  5. import frappe
  6. import frappe.handler
  7. import frappe.client
  8. from frappe.utils.response import build_response
  9. from frappe import _
  10. from urlparse import urlparse
  11. from urllib import urlencode
  12. def handle():
  13. """
  14. Handler for `/api` methods
  15. ### Examples:
  16. `/api/method/{methodname}` will call a whitelisted method
  17. `/api/resource/{doctype}` will query a table
  18. examples:
  19. - `?fields=["name", "owner"]`
  20. - `?filters=[["Task", "name", "like", "%005"]]`
  21. - `?limit_start=0`
  22. - `?limit_page_length=20`
  23. `/api/resource/{doctype}/{name}` will point to a resource
  24. `GET` will return doclist
  25. `POST` will insert
  26. `PUT` will update
  27. `DELETE` will delete
  28. `/api/resource/{doctype}/{name}?run_method={method}` will run a whitelisted controller method
  29. """
  30. validate_oauth()
  31. parts = frappe.request.path[1:].split("/",3)
  32. call = doctype = name = None
  33. if len(parts) > 1:
  34. call = parts[1]
  35. if len(parts) > 2:
  36. doctype = parts[2]
  37. if len(parts) > 3:
  38. name = parts[3]
  39. if call=="method":
  40. frappe.local.form_dict.cmd = doctype
  41. return frappe.handler.handle()
  42. elif call=="resource":
  43. if "run_method" in frappe.local.form_dict:
  44. method = frappe.local.form_dict.pop("run_method")
  45. doc = frappe.get_doc(doctype, name)
  46. doc.is_whitelisted(method)
  47. if frappe.local.request.method=="GET":
  48. if not doc.has_permission("read"):
  49. frappe.throw(_("Not permitted"), frappe.PermissionError)
  50. frappe.local.response.update({"data": doc.run_method(method, **frappe.local.form_dict)})
  51. if frappe.local.request.method=="POST":
  52. if not doc.has_permission("write"):
  53. frappe.throw(_("Not permitted"), frappe.PermissionError)
  54. frappe.local.response.update({"data": doc.run_method(method, **frappe.local.form_dict)})
  55. frappe.db.commit()
  56. else:
  57. if name:
  58. if frappe.local.request.method=="GET":
  59. doc = frappe.get_doc(doctype, name)
  60. if not doc.has_permission("read"):
  61. raise frappe.PermissionError
  62. frappe.local.response.update({"data": doc})
  63. if frappe.local.request.method=="PUT":
  64. data = json.loads(frappe.local.form_dict.data)
  65. doc = frappe.get_doc(doctype, name)
  66. if "flags" in data:
  67. del data["flags"]
  68. # Not checking permissions here because it's checked in doc.save
  69. doc.update(data)
  70. frappe.local.response.update({
  71. "data": doc.save().as_dict()
  72. })
  73. frappe.db.commit()
  74. if frappe.local.request.method=="DELETE":
  75. # Not checking permissions here because it's checked in delete_doc
  76. frappe.delete_doc(doctype, name)
  77. frappe.local.response.http_status_code = 202
  78. frappe.local.response.message = "ok"
  79. frappe.db.commit()
  80. elif doctype:
  81. if frappe.local.request.method=="GET":
  82. if frappe.local.form_dict.get('fields'):
  83. frappe.local.form_dict['fields'] = json.loads(frappe.local.form_dict['fields'])
  84. frappe.local.form_dict.setdefault('limit_page_length', 20)
  85. frappe.local.response.update({
  86. "data": frappe.call(frappe.client.get_list,
  87. doctype, **frappe.local.form_dict)})
  88. if frappe.local.request.method=="POST":
  89. data = json.loads(frappe.local.form_dict.data)
  90. data.update({
  91. "doctype": doctype
  92. })
  93. frappe.local.response.update({
  94. "data": frappe.get_doc(data).insert().as_dict()
  95. })
  96. frappe.db.commit()
  97. else:
  98. raise frappe.DoesNotExistError
  99. else:
  100. raise frappe.DoesNotExistError
  101. return build_response("json")
  102. def validate_oauth():
  103. from frappe.oauth import get_url_delimiter
  104. form_dict = frappe.local.form_dict
  105. authorization_header = frappe.get_request_header("Authorization").split(" ") if frappe.get_request_header("Authorization") else None
  106. if authorization_header and authorization_header[0].lower() == "bearer":
  107. from frappe.integrations.oauth2 import get_oauth_server
  108. token = authorization_header[1]
  109. r = frappe.request
  110. parsed_url = urlparse(r.url)
  111. access_token = { "access_token": token}
  112. uri = parsed_url.scheme + "://" + parsed_url.netloc + parsed_url.path + "?" + urlencode(access_token)
  113. http_method = r.method
  114. body = r.get_data()
  115. headers = r.headers
  116. required_scopes = frappe.db.get_value("OAuth Bearer Token", token, "scopes").split(get_url_delimiter())
  117. valid, oauthlib_request = get_oauth_server().verify_request(uri, http_method, body, headers, required_scopes)
  118. if valid:
  119. frappe.set_user(frappe.db.get_value("OAuth Bearer Token", token, "user"))
  120. frappe.local.form_dict = form_dict