session.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. # GNU MediaGoblin -- federated, autonomous media hosting
  2. # Copyright (C) 2013 MediaGoblin contributors. See AUTHORS.
  3. #
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU Affero General Public License as published by
  6. # the Free Software Foundation, either version 3 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU Affero General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU Affero General Public License
  15. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. import itsdangerous
  17. import logging
  18. from mediagoblin.tools import crypto
  19. _log = logging.getLogger(__name__)
  20. MAX_AGE = 30 * 24 * 60 * 60
  21. class Session(dict):
  22. def __init__(self, *args, **kwargs):
  23. self.send_new_cookie = False
  24. dict.__init__(self, *args, **kwargs)
  25. def save(self):
  26. self.send_new_cookie = True
  27. def is_updated(self):
  28. return self.send_new_cookie
  29. def delete(self):
  30. self.clear()
  31. self.save()
  32. class SessionManager(object):
  33. def __init__(self, cookie_name='MGSession', namespace=None):
  34. if namespace is None:
  35. namespace = cookie_name
  36. self.signer = crypto.get_timed_signer_url(namespace)
  37. self.cookie_name = cookie_name
  38. def load_session_from_cookie(self, request):
  39. cookie = request.cookies.get(self.cookie_name)
  40. if not cookie:
  41. return Session()
  42. ### FIXME: Future cookie-blacklisting code
  43. # m = BadCookie.query.filter_by(cookie = cookie)
  44. # if m:
  45. # _log.warn("Bad cookie received: %s", m.reason)
  46. # raise BadRequest()
  47. try:
  48. return Session(self.signer.loads(cookie))
  49. except itsdangerous.BadData:
  50. return Session()
  51. def save_session_to_cookie(self, session, request, response):
  52. if not session.is_updated():
  53. return
  54. elif not session:
  55. response.delete_cookie(self.cookie_name)
  56. else:
  57. if session.get('stay_logged_in', False):
  58. max_age = MAX_AGE
  59. else:
  60. max_age = None
  61. response.set_cookie(self.cookie_name, self.signer.dumps(session),
  62. max_age=max_age, httponly=True)