wraps.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. # -*- coding:utf-8 -*-
  2. import uuid
  3. from functools import wraps
  4. from flask import request, session
  5. from flask_restful import Resource
  6. from werkzeug.exceptions import NotFound, Unauthorized
  7. from extensions.ext_database import db
  8. from models.model import App, Site, EndUser
  9. def validate_token(view=None):
  10. def decorator(view):
  11. @wraps(view)
  12. def decorated(*args, **kwargs):
  13. site = validate_and_get_site()
  14. app_model = db.session.query(App).get(site.app_id)
  15. if not app_model:
  16. raise NotFound()
  17. if app_model.status != 'normal':
  18. raise NotFound()
  19. if not app_model.enable_site:
  20. raise NotFound()
  21. end_user = create_or_update_end_user_for_session(app_model)
  22. return view(app_model, end_user, *args, **kwargs)
  23. return decorated
  24. if view:
  25. return decorator(view)
  26. return decorator
  27. def validate_and_get_site():
  28. """
  29. Validate and get API token.
  30. """
  31. auth_header = request.headers.get('Authorization')
  32. if auth_header is None:
  33. raise Unauthorized()
  34. auth_scheme, auth_token = auth_header.split(None, 1)
  35. auth_scheme = auth_scheme.lower()
  36. if auth_scheme != 'bearer':
  37. raise Unauthorized()
  38. site = db.session.query(Site).filter(
  39. Site.code == auth_token,
  40. Site.status == 'normal'
  41. ).first()
  42. if not site:
  43. raise NotFound()
  44. return site
  45. def create_or_update_end_user_for_session(app_model):
  46. """
  47. Create or update session terminal based on session ID.
  48. """
  49. if 'session_id' not in session:
  50. session['session_id'] = generate_session_id()
  51. session_id = session.get('session_id')
  52. end_user = db.session.query(EndUser) \
  53. .filter(
  54. EndUser.session_id == session_id,
  55. EndUser.type == 'browser'
  56. ).first()
  57. if end_user is None:
  58. end_user = EndUser(
  59. tenant_id=app_model.tenant_id,
  60. app_id=app_model.id,
  61. type='browser',
  62. is_anonymous=True,
  63. session_id=session_id
  64. )
  65. db.session.add(end_user)
  66. db.session.commit()
  67. return end_user
  68. def generate_session_id():
  69. """
  70. Generate a unique session ID.
  71. """
  72. count = 1
  73. session_id = ''
  74. while count != 0:
  75. session_id = str(uuid.uuid4())
  76. count = db.session.query(EndUser) \
  77. .filter(EndUser.session_id == session_id).count()
  78. return session_id
  79. class WebApiResource(Resource):
  80. method_decorators = [validate_token]