auth.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. from __future__ import absolute_import
  2. try:
  3. from urllib.parse import urlparse, parse_qsl, urlencode
  4. except ImportError:
  5. from urlparse import urlparse, parse_qsl
  6. from urllib import urlencode
  7. import re
  8. import tornado.web
  9. import tornado.auth
  10. from tornado import httpclient
  11. import json
  12. from .. import settings
  13. from ..views import BaseHandler
  14. class LoginHandler(BaseHandler, tornado.auth.GoogleOAuth2Mixin):
  15. @tornado.web.asynchronous
  16. def get(self):
  17. callback_uri = None
  18. if settings.URL_PREFIX:
  19. qs = dict(parse_qsl(urlparse(self.request.uri).query))
  20. next = qs.get('next', '/')
  21. callback_uri = self.absolute_url('/login')
  22. callback_uri += '?' + urlencode(dict(next=next))
  23. if self.get_argument('code', False):
  24. self.get_authenticated_user(
  25. redirect_uri=self.settings[self._OAUTH_SETTINGS_KEY]['redirect_uri'],
  26. code=self.get_argument('code'),
  27. callback=self._on_auth,
  28. )
  29. else:
  30. self.authorize_redirect(
  31. redirect_uri=self.settings[self._OAUTH_SETTINGS_KEY]['redirect_uri'],
  32. client_id=self.settings[self._OAUTH_SETTINGS_KEY]['key'],
  33. scope=['profile', 'email'],
  34. response_type='code',
  35. extra_params={'approval_prompt': 'auto'}
  36. )
  37. def _on_auth(self, user):
  38. if not user:
  39. raise tornado.web.HTTPError(500, 'Google auth failed')
  40. access_token = user['access_token']
  41. response = httpclient.HTTPClient().fetch('https://www.googleapis.com/plus/v1/people/me', headers={'Authorization': 'Bearer %s' % access_token})
  42. email = json.loads(response.body.decode('utf-8'))['emails'][0]['value']
  43. if not re.match(self.application.auth, email):
  44. raise tornado.web.HTTPError(
  45. 404,
  46. "Access denied to '{email}'. "
  47. "Please use another account or ask your admin to "
  48. "add your email to flower --auth".format(**user))
  49. self.set_secure_cookie("user", str(email))
  50. next = self.get_argument('next', '/')
  51. if settings.URL_PREFIX:
  52. next = self.absolute_url(next)
  53. self.redirect(next)
  54. class LogoutHandler(BaseHandler):
  55. def get(self):
  56. self.clear_cookie('user')
  57. self.render('404.html', message='Successfully logged out!')