Advertisement
Guest User

Untitled

a guest
Jan 17th, 2018
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.86 KB | None | 0 0
  1. """Backend of API Explorer
  2.  
  3. Serves as a proxy between client side code and API server
  4. """
  5.  
  6. from api_explorer_oauth_client import APIExplorerOAuthClient
  7.  
  8. import cgi
  9. import json
  10. import logging
  11. import sys
  12.  
  13. import flask
  14. import oauth
  15. import werkzeug.debug
  16.  
  17. import api_explorer_oauth_client
  18. import js_version
  19. try:
  20. import secrets
  21. except ImportError:
  22. # If the secrets aren't present, we can't run the server.
  23. logging.critical("Can't find secrets.py.\nCopy secrets.example.py" +
  24. " to secrets.py, enter the necessary values, and try again.")
  25. sys.exit(1)
  26.  
  27. app = flask.Flask(__name__)
  28. app.config.from_object('explorer.settings')
  29.  
  30. if app.debug:
  31. app.wsgi_app = werkzeug.debug.DebuggedApplication(app.wsgi_app,
  32. evalex=True)
  33.  
  34. # Keep around an instance of the client. It's reusable because all the
  35. # stateful stuff is passed around as parameters.
  36. OAuthClient = api_explorer_oauth_client.APIExplorerOAuthClient(
  37. secrets.server_url, secrets.consumer_key, secrets.consumer_secret)
  38.  
  39.  
  40. @app.route("/")
  41. def index():
  42. return flask.render_template("index.html",
  43. prod=(not app.debug),
  44. js_version=js_version.SHASUM,
  45. is_logged_in=is_logged_in())
  46.  
  47.  
  48. @app.route("/group/<path:group>")
  49. def group_url(group):
  50. if not flask.request.is_xhr:
  51. return index()
  52. else:
  53. return "Invalid request", 400
  54.  
  55.  
  56. @app.route("/api/v1/<path:method>")
  57. def api_proxy(method):
  58. # Relies on X-Requested-With header
  59. # http://flask.pocoo.org/docs/api/#flask.Request.is_xhr
  60. url_template = "api/v1/{0}"
  61. if flask.request.is_xhr:
  62.  
  63. resource = OAuthClient.access_api_resource(
  64. url_template.format(method), access_token(),
  65. query_params=flask.request.args.items(),
  66. method=flask.request.method)
  67.  
  68. response_text = resource.text
  69. if "text/html" in resource.headers["Content-Type"]:
  70. # per this stackoverflow thread
  71. # http://stackoverflow.com/questions/1061697/whats-the-easiest-way-to-escape-html-in-python
  72. response_text = cgi.escape(response_text).encode("ascii",
  73. "xmlcharrefreplace")
  74.  
  75. # Include the original headers with response body.
  76. # The client side will know what to do with these.
  77. # There is a limit of 498 bytes per header, which will not be changed
  78. # https://code.google.com/p/googleappengine/issues/detail?id=407
  79. response = flask.make_response(json.dumps({
  80. "headers": dict(resource.headers),
  81. "response": response_text}))
  82.  
  83. response.headers["X-Original-Status"] = resource.status_code
  84. response.headers["Content-Type"] = resource.headers["Content-Type"]
  85.  
  86. return response
  87. else:
  88. return index()
  89.  
  90.  
  91. # Begin the process of getting a request token from Khan.
  92. @app.route("/oauth_get_request_token")
  93. def oauth_get_request_token():
  94. request_token_url = OAuthClient.url_for_request_token(
  95. flask.url_for("oauth_callback",
  96. continuation=flask.request.args.get("continue"),
  97. _external=True))
  98.  
  99. logging.debug("Redirecting to request token URL: \n{0}".format(
  100. request_token_url))
  101. return flask.redirect(request_token_url)
  102.  
  103.  
  104. # The OAuth approval flow finishes here.
  105. # Query string version would have been preferable though it causes oauth
  106. # signature errors.
  107. @app.route("/oauth_callback")
  108. @app.route("/oauth_callback/<path:continuation>")
  109. def oauth_callback(continuation=None):
  110. oauth_token = flask.request.args.get("oauth_token", "")
  111. oauth_secret = flask.request.args.get("oauth_token_secret", "")
  112. oauth_verifier = flask.request.args.get("oauth_verifier", "")
  113.  
  114. request_token = oauth.OAuthToken(oauth_token, oauth_secret)
  115. request_token.set_verifier(oauth_verifier)
  116.  
  117. flask.session["request_token_string"] = request_token.to_string()
  118.  
  119. # We do this before we redirect so that there's no "limbo" state where the
  120. # user has a request token but no access token.
  121. access_token = OAuthClient.fetch_access_token(request_token)
  122. flask.session["oauth_token_string"] = access_token.to_string()
  123.  
  124. # We're done authenticating, and the credentials are now stored in the
  125. # session. We can redirect back home.
  126. if continuation:
  127. return flask.redirect(continuation)
  128. else:
  129. return flask.redirect(flask.url_for("index"))
  130.  
  131.  
  132. def access_token():
  133. token_string = flask.session.get("oauth_token_string")
  134.  
  135. # Sanity check.
  136. if not token_string:
  137. clear_session()
  138. return None
  139.  
  140. return oauth.OAuthToken.from_string(token_string)
  141.  
  142.  
  143. def is_logged_in():
  144. return ("request_token_string" in flask.session and
  145. "oauth_token_string" in flask.session)
  146.  
  147.  
  148. def clear_session():
  149. flask.session.pop("request_token_string", None)
  150. flask.session.pop("oauth_token_string", None)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement