serializer.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. # -*- coding: utf -*-
  2. """
  3. flaskbb.tokens.serializer
  4. ~~~~~~~~~~~~~~~~~~~~~~~~~
  5. :copyright: (c) 2018 the FlaskBB Team.
  6. :license: BSD, see LICENSE for more details
  7. """
  8. from datetime import timedelta
  9. from itsdangerous import (BadData, BadSignature, SignatureExpired,
  10. TimedJSONWebSignatureSerializer)
  11. from ..core import tokens
  12. class FlaskBBTokenSerializer(tokens.TokenSerializer):
  13. """
  14. Default token serializer for FlaskBB. Generates JWTs
  15. that are time sensitive. By default they will expire after
  16. 1 hour.
  17. It creates tokens from flaskbb.core.tokens.Token instances
  18. and creates instances of that class when loading tokens.
  19. When loading a token, if an error occurs related to the
  20. token itself, a flaskbb.core.tokens.TokenError will be
  21. raised. Exceptions not caused by parsing the token
  22. are simply propagated.
  23. :str secret_key: The secret key used to sign the tokens
  24. :timedelta expiry: Expiration of tokens
  25. """
  26. def __init__(self, secret_key, expiry=timedelta(hours=1)):
  27. self._serializer = TimedJSONWebSignatureSerializer(
  28. secret_key, int(expiry.total_seconds())
  29. )
  30. def dumps(self, token):
  31. """
  32. Transforms an instance of flaskbb.core.tokens.Token into
  33. a text serialized JWT.
  34. :flaskbb.core.tokens.Token token: Token to transformed into a JWT
  35. :returns str: A fully serialized token
  36. """
  37. return self._serializer.dumps(
  38. {
  39. 'id': token.user_id,
  40. 'op': token.operation,
  41. }
  42. )
  43. def loads(self, raw_token):
  44. """
  45. Transforms a JWT into a flaskbb.core.tokens.Token.
  46. If a token is invalid due to it being malformed,
  47. tampered with or expired, a flaskbb.core.tokens.TokenError
  48. is raised. Errors not related to token parsing are
  49. simply propagated.
  50. :str raw_token: JWT to be parsed
  51. :returns flaskbb.core.tokens.Token: Parsed token
  52. """
  53. try:
  54. parsed = self._serializer.loads(raw_token)
  55. except SignatureExpired:
  56. raise tokens.TokenError.expired()
  57. except BadSignature: # pragma: no branch
  58. raise tokens.TokenError.invalid()
  59. # ideally we never end up here as BadSignature should
  60. # catch everything else, however since this is the root
  61. # exception for itsdangerous we'll catch it down and
  62. # and re-raise our own
  63. except BadData: # pragma: no cover
  64. raise tokens.TokenError.bad()
  65. else:
  66. return tokens.Token(user_id=parsed['id'], operation=parsed['op'])