wraps.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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).filter(App.id == site.app_id).first()
  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('Authorization header is missing.')
  34. if ' ' not in auth_header:
  35. raise Unauthorized('Invalid Authorization header format. Expected \'Bearer <api-key>\' format.')
  36. auth_scheme, auth_token = auth_header.split(None, 1)
  37. auth_scheme = auth_scheme.lower()
  38. if auth_scheme != 'bearer':
  39. raise Unauthorized('Invalid Authorization header format. Expected \'Bearer <api-key>\' format.')
  40. site = db.session.query(Site).filter(
  41. Site.code == auth_token,
  42. Site.status == 'normal'
  43. ).first()
  44. if not site:
  45. raise NotFound()
  46. return site
  47. def create_or_update_end_user_for_session(app_model):
  48. """
  49. Create or update session terminal based on session ID.
  50. """
  51. if 'session_id' not in session:
  52. session['session_id'] = generate_session_id()
  53. session_id = session.get('session_id')
  54. end_user = db.session.query(EndUser) \
  55. .filter(
  56. EndUser.session_id == session_id,
  57. EndUser.type == 'browser'
  58. ).first()
  59. if end_user is None:
  60. end_user = EndUser(
  61. tenant_id=app_model.tenant_id,
  62. app_id=app_model.id,
  63. type='browser',
  64. is_anonymous=True,
  65. session_id=session_id
  66. )
  67. db.session.add(end_user)
  68. db.session.commit()
  69. return end_user
  70. def generate_session_id():
  71. """
  72. Generate a unique session ID.
  73. """
  74. count = 1
  75. session_id = ''
  76. while count != 0:
  77. session_id = str(uuid.uuid4())
  78. count = db.session.query(EndUser) \
  79. .filter(EndUser.session_id == session_id).count()
  80. return session_id
  81. class WebApiResource(Resource):
  82. method_decorators = [validate_token]