tokens.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. # -*- coding: utf-8 -*-
  2. """
  3. flaskbb.utils.tokens
  4. ~~~~~~~~~~~~~~~~~~~~
  5. A module that helps to create and verify various tokens that
  6. are used by FlaskBB.
  7. :copyright: (c) 2014 by the FlaskBB Team.
  8. :license: BSD, see LICENSE for more details.
  9. """
  10. import logging
  11. from flask import current_app
  12. from itsdangerous import (TimedJSONWebSignatureSerializer, SignatureExpired,
  13. BadSignature)
  14. from flaskbb.user.models import User
  15. logger = logging.getLogger(__name__)
  16. def make_token(user, operation, expire=3600):
  17. """Generates a JSON Web Signature (JWS).
  18. See `RFC 7515 <https://tools.ietf.org/html/rfc7515>` if you want to know
  19. more about JWS.
  20. :param user: The user object for whom the token should be generated.
  21. :param operation: The function of the token. For example, you might want
  22. to generate two different tokens. One for a
  23. password reset link, which you hypothetically want
  24. to name 'reset' and the second one, for the generation
  25. of a token for a E-Mail confirmation link, which you
  26. name 'email'.
  27. :param expire: The time, in seconds, after which the token should be
  28. invalid. Defaults to 3600.
  29. """
  30. s = TimedJSONWebSignatureSerializer(
  31. current_app.config['SECRET_KEY'], expire
  32. )
  33. data = {"id": user.id, "op": operation}
  34. return s.dumps(data)
  35. def get_token_status(token, operation, return_data=False):
  36. """Returns the expired status, invalid status, the user and optionally
  37. the content of the JSON Web Signature token.
  38. :param token: A valid JSON Web Signature token.
  39. :param operation: The function of the token.
  40. :param return_data: If set to ``True``, it will also return the content
  41. of the token.
  42. """
  43. s = TimedJSONWebSignatureSerializer(current_app.config['SECRET_KEY'])
  44. user, data = None, None
  45. expired, invalid = False, False
  46. try:
  47. data = s.loads(token)
  48. except SignatureExpired:
  49. expired = True
  50. except (BadSignature, TypeError, ValueError):
  51. invalid = True
  52. if data is not None:
  53. # check if the operation matches the one from the token
  54. if operation == data.get("op", None):
  55. user = User.query.filter_by(id=data.get('id')).first()
  56. else:
  57. invalid = True
  58. if return_data:
  59. return expired, invalid, user, data
  60. return expired, invalid, user