__init__.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. from __future__ import absolute_import
  2. import re
  3. import inspect
  4. import traceback
  5. try:
  6. from urllib.parse import urljoin
  7. except ImportError:
  8. from urlparse import urljoin
  9. from base64 import b64decode
  10. import tornado
  11. from .. import settings
  12. from ..utils import template, bugreport
  13. class BaseHandler(tornado.web.RequestHandler):
  14. def prepare(self):
  15. self.application.state.resume()
  16. def render(self, *args, **kwargs):
  17. functions = inspect.getmembers(template, inspect.isfunction)
  18. assert not set(map(lambda x: x[0], functions)) & set(kwargs.keys())
  19. kwargs.update(functions)
  20. kwargs.update(absolute_url=self.absolute_url)
  21. kwargs.update(url_prefix=settings.URL_PREFIX)
  22. super(BaseHandler, self).render(*args, **kwargs)
  23. def write_error(self, status_code, **kwargs):
  24. if status_code == 404:
  25. message = None
  26. if 'exc_info' in kwargs and\
  27. kwargs['exc_info'][0] == tornado.web.HTTPError:
  28. message = kwargs['exc_info'][1].log_message
  29. self.render('404.html', message=message)
  30. elif status_code == 500:
  31. error_trace = ""
  32. for line in traceback.format_exception(*kwargs['exc_info']):
  33. error_trace += line
  34. self.render('error.html',
  35. status_code=status_code,
  36. error_trace=error_trace,
  37. bugreport=bugreport())
  38. elif status_code == 401:
  39. self.set_status(status_code)
  40. self.set_header('WWW-Authenticate', 'Basic realm="flower"')
  41. self.finish('Access denied')
  42. else:
  43. message = None
  44. if 'exc_info' in kwargs and\
  45. kwargs['exc_info'][0] == tornado.web.HTTPError:
  46. message = kwargs['exc_info'][1].log_message
  47. self.set_header('Content-Type', 'text/plain')
  48. self.write(message)
  49. self.set_status(status_code)
  50. def get_current_user(self):
  51. # Basic Auth
  52. basic_auth = self.application.basic_auth
  53. if basic_auth:
  54. auth_header = self.request.headers.get("Authorization", "")
  55. try:
  56. basic, credentials = auth_header.split()
  57. credentials = b64decode(credentials.encode()).decode()
  58. if basic != 'Basic' or credentials not in basic_auth:
  59. raise tornado.web.HTTPError(401)
  60. except ValueError:
  61. raise tornado.web.HTTPError(401)
  62. # Google OpenID
  63. if not self.application.auth:
  64. return True
  65. user = self.get_secure_cookie('user')
  66. if user:
  67. if not isinstance(user, str):
  68. user = user.decode()
  69. if re.search(self.application.auth, user):
  70. return user
  71. return None
  72. def absolute_url(self, url):
  73. if settings.URL_PREFIX:
  74. base = "{0}://{1}/{2}/".format(self.request.protocol,
  75. self.request.host,
  76. settings.URL_PREFIX)
  77. else:
  78. base = '/'
  79. aurl = urljoin(base, url[1:] if url.startswith('/') else url)
  80. aurl = aurl[:-1] if aurl.endswith('/') else aurl
  81. return aurl
  82. def get_argument(self, name, default=[], strip=True, type=None):
  83. arg = super(BaseHandler, self).get_argument(name, default, strip)
  84. if type is not None:
  85. try:
  86. arg = type(arg)
  87. except (ValueError, TypeError):
  88. if arg is None and default is None:
  89. return arg
  90. raise tornado.web.HTTPError(
  91. 400,
  92. "Invalid argument '%s' of type '%s'" % (
  93. arg, type.__name__))
  94. return arg