tokens.py 2.4 KB

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