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.
 
 
 
 
 
 

123 line
3.9 KiB

  1. from __future__ import unicode_literals
  2. import frappe, json
  3. from frappe.oauth import OAuthWebRequestValidator, WebApplicationServer
  4. from oauthlib.oauth2 import FatalClientError, OAuth2Error
  5. from urllib import quote, urlencode
  6. from urlparse import urlparse
  7. from frappe.integrations.doctype.oauth_provider_settings.oauth_provider_settings import get_oauth_settings
  8. #Variables required across requests
  9. oauth_validator = OAuthWebRequestValidator()
  10. oauth_server = WebApplicationServer(oauth_validator)
  11. credentials = None
  12. def get_urlparams_from_kwargs(param_kwargs):
  13. arguments = param_kwargs
  14. if arguments.get("data"):
  15. arguments.pop("data")
  16. if arguments.get("cmd"):
  17. arguments.pop("cmd")
  18. return urlencode(arguments)
  19. @frappe.whitelist()
  20. def approve(*args, **kwargs):
  21. r = frappe.request
  22. uri = r.url
  23. http_method = r.method
  24. body = r.get_data()
  25. headers = r.headers
  26. try:
  27. scopes, credentials = oauth_server.validate_authorization_request(uri, http_method, body, headers)
  28. headers, body, status = oauth_server.create_authorization_response(uri=credentials['redirect_uri'], \
  29. body=body, headers=headers, scopes=scopes, credentials=credentials)
  30. uri = headers.get('Location', None)
  31. frappe.local.response["type"] = "redirect"
  32. frappe.local.response["location"] = uri
  33. except FatalClientError as e:
  34. return e
  35. except OAuth2Error as e:
  36. return e
  37. @frappe.whitelist(allow_guest=True)
  38. def authorize(*args, **kwargs):
  39. #Fetch provider URL from settings
  40. oauth_settings = get_oauth_settings()
  41. params = get_urlparams_from_kwargs(kwargs)
  42. request_url = urlparse(frappe.request.url)
  43. success_url = request_url.scheme + "://" + request_url.netloc + "/api/method/frappe.integration_broker.oauth2.approve?" + params
  44. failure_url = frappe.form_dict["redirect_uri"] + "?error=access_denied"
  45. if frappe.session['user']=='Guest':
  46. #Force login, redirect to preauth again.
  47. frappe.local.response["type"] = "redirect"
  48. frappe.local.response["location"] = "/login?redirect-to=/api/method/frappe.integration_broker.oauth2.authorize?" + quote(params)
  49. elif frappe.session['user']!='Guest':
  50. try:
  51. r = frappe.request
  52. uri = r.url
  53. http_method = r.method
  54. body = r.get_data()
  55. headers = r.headers
  56. scopes, credentials = oauth_server.validate_authorization_request(uri, http_method, body, headers)
  57. skip_auth = frappe.db.get_value("OAuth Client", credentials['client_id'], "skip_authorization")
  58. unrevoked_tokens = frappe.get_all("OAuth Bearer Token", filters={"status":"Active"})
  59. if skip_auth or (oauth_settings["skip_authorization"] == "Auto" and len(unrevoked_tokens)):
  60. frappe.local.response["type"] = "redirect"
  61. frappe.local.response["location"] = success_url
  62. else:
  63. #Show Allow/Deny screen.
  64. response_html_params = frappe._dict({
  65. "client_id": frappe.db.get_value("OAuth Client", kwargs['client_id'], "app_name"),
  66. "success_url": success_url,
  67. "failure_url": failure_url,
  68. "details": scopes
  69. })
  70. resp_html = frappe.render_template("templates/includes/oauth_confirmation.html", response_html_params)
  71. frappe.respond_as_web_page("Confirm Access", resp_html)
  72. except FatalClientError as e:
  73. return e
  74. except OAuth2Error as e:
  75. return e
  76. @frappe.whitelist(allow_guest=True)
  77. def get_token(*args, **kwargs):
  78. r = frappe.request
  79. uri = r.url
  80. http_method = r.method
  81. body = r.form
  82. headers = r.headers
  83. try:
  84. headers, body, status = oauth_server.create_token_response(uri, http_method, body, headers, credentials)
  85. frappe.local.response = frappe._dict(json.loads(body))
  86. except FatalClientError as e:
  87. return e
  88. @frappe.whitelist(allow_guest=True)
  89. def revoke_token(*args, **kwargs):
  90. r = frappe.request
  91. uri = r.url
  92. http_method = r.method
  93. body = r.form
  94. headers = r.headers
  95. headers, body, status = oauth_server.create_revocation_response(uri, headers=headers, body=body, http_method=http_method)
  96. frappe.local.response['http_status_code'] = status
  97. if status == 200:
  98. return "success"
  99. else:
  100. return "bad request"