You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

application.py 4.5 kB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. # Copyright 2019 Huawei Technologies Co., Ltd
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. # ============================================================================
  15. """Web application module."""
  16. import os
  17. from importlib import import_module
  18. from werkzeug.datastructures import Headers
  19. from werkzeug.exceptions import HTTPException
  20. from flask import Flask
  21. from flask import request
  22. from flask import Response
  23. from flask_cors import CORS
  24. from mindinsight.conf import settings
  25. from mindinsight.utils.hook import HookUtils
  26. from mindinsight.datavisual.common.log import logger
  27. from mindinsight.datavisual.common.exceptions import RequestMethodNotAllowed
  28. from mindinsight.datavisual.common import error_handler
  29. from mindinsight.datavisual.utils.tools import find_app_package
  30. from mindinsight.datavisual.utils.tools import get_img_mimetype
  31. from mindinsight.utils.exceptions import MindInsightException
  32. def get_security_headers():
  33. """Get security headers."""
  34. domain_white_list = []
  35. for hook in HookUtils.instance().hooks():
  36. domain_white_list += hook.register_secure_domains()
  37. content_security_policy = {
  38. 'img-src': ["'self'", 'data:'],
  39. 'style-src': ["'self'", "'unsafe-inline'"],
  40. 'frame-src': ["'self'"] + domain_white_list,
  41. 'frame-ancestors': ["'self'"] + domain_white_list,
  42. 'default-src': ["'self'"],
  43. 'script-src': ["'self'", "'unsafe-eval'"]
  44. }
  45. headers = {
  46. 'X-Frame-Options': 'SAMEORIGIN',
  47. 'X-XSS-Protection': '1; mode=block',
  48. 'X-Content-Type-Options': 'nosniff',
  49. 'Access-Control-Allow-Methods': ', '.join(settings.SUPPORT_REQUEST_METHODS),
  50. 'Content-Security-Policy': '; '.join([
  51. f"{k} {' '.join(v)}" for k, v in content_security_policy.items()
  52. ]),
  53. 'X-Download-Options': 'noopen',
  54. 'Cache-Control': 'no-store',
  55. 'Pragma': 'no-cache'
  56. }
  57. return list(headers.items())
  58. SECURITY_HEADERS = get_security_headers()
  59. class CustomResponse(Response):
  60. """Define custom response."""
  61. def __init__(self, response=None, **kwargs):
  62. headers = kwargs.get("headers")
  63. security_headers = list(SECURITY_HEADERS)
  64. if isinstance(response, bytes):
  65. mimetype = get_img_mimetype(response)
  66. security_headers.append(('Content-Type', mimetype))
  67. if headers is None:
  68. headers = Headers(security_headers)
  69. else:
  70. for header in security_headers:
  71. headers.add(*header)
  72. kwargs['headers'] = headers
  73. super(CustomResponse, self).__init__(response, **kwargs)
  74. def _init_app_module(app):
  75. """
  76. Init app module.
  77. Args:
  78. app (Flask): An instance of Flask.
  79. """
  80. packages = find_app_package()
  81. for package in packages:
  82. try:
  83. app_module = import_module(package)
  84. app_module.init_module(app)
  85. except AttributeError:
  86. logger.debug('[%s].init_module not exists.', package)
  87. def before_request():
  88. """A function to run before each request."""
  89. if request.method not in settings.SUPPORT_REQUEST_METHODS:
  90. raise RequestMethodNotAllowed()
  91. def create_app():
  92. """Set flask APP config, and start the data manager."""
  93. static_url_path = settings.URL_PATH_PREFIX + "/static"
  94. static_folder_path = os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir, 'ui', 'dist', 'static'))
  95. app = Flask(__name__, static_url_path=static_url_path, static_folder=static_folder_path)
  96. app.config['JSON_SORT_KEYS'] = False
  97. if settings.ENABLE_CORS:
  98. CORS(app, supports_credentials=True)
  99. app.before_request(before_request)
  100. app.register_error_handler(HTTPException, error_handler.handle_http_exception_error)
  101. app.register_error_handler(MindInsightException, error_handler.handle_mindinsight_error)
  102. app.register_error_handler(Exception, error_handler.handle_unknown_error)
  103. app.response_class = CustomResponse
  104. _init_app_module(app)
  105. return app
  106. APP = create_app()