lesscode-flask 0.2.38__tar.gz → 0.2.39__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/PKG-INFO +1 -1
  2. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/__init__.py +37 -12
  3. lesscode-flask-0.2.39/lesscode_flask/utils/limit/req/rate_limiter_handler.py +88 -0
  4. lesscode-flask-0.2.39/lesscode_flask/utils/limit/req_count/count_limiter_handler.py +84 -0
  5. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask.egg-info/PKG-INFO +1 -1
  6. lesscode-flask-0.2.38/lesscode_flask/utils/limit/req/rate_limiter_handler.py +0 -58
  7. lesscode-flask-0.2.38/lesscode_flask/utils/limit/req_count/count_limiter_handler.py +0 -57
  8. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/README.md +0 -0
  9. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/app.py +0 -0
  10. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/db/__init__.py +0 -0
  11. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/db/datasource.py +0 -0
  12. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/db/executor.py +0 -0
  13. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/export_data/__init__.py +0 -0
  14. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/export_data/data_download_handler.py +0 -0
  15. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/log/access_log_handler.py +0 -0
  16. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/model/access_log.py +0 -0
  17. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/model/base_model.py +0 -0
  18. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/model/parameterized_query.py +0 -0
  19. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/model/resource_param_template.py +0 -0
  20. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/model/response_result.py +0 -0
  21. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/model/user.py +0 -0
  22. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/model/user_limit_policy.py +0 -0
  23. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/service/access_log_service.py +0 -0
  24. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/service/base_service.py +0 -0
  25. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/service/resource_param_template_service.py +0 -0
  26. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/setting/__init__.py +0 -0
  27. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/setup/__init__.py +0 -0
  28. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/signals.py +0 -0
  29. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/static/swagger.py +0 -0
  30. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/decorator/__init__.py +0 -0
  31. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/decorator/cache.py +0 -0
  32. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/decorator/sql_injection.py +0 -0
  33. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/decorator/swagger.py +0 -0
  34. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/dify_utils.py +0 -0
  35. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/file/file_exporter.py +0 -0
  36. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/file/file_utils.py +0 -0
  37. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/fs_util.py +0 -0
  38. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/helpers.py +0 -0
  39. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/json/NotSortJSONProvider.py +0 -0
  40. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/limit/__init__.py +0 -0
  41. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/limit/consecutive/consecutive_limiter_handler.py +0 -0
  42. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/limit/consecutive/redis_consecutive_limiter.py +0 -0
  43. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/limit/limit_util.py +0 -0
  44. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/limit/req/redis_rate_limiter.py +0 -0
  45. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/limit/req_count/redis_count_limiter.py +0 -0
  46. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/oss/__init__.py +0 -0
  47. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/oss/aliyun_oss.py +0 -0
  48. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/oss/ks3_oss.py +0 -0
  49. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/oss/minio_oss.py +0 -0
  50. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/redis/redis_helper.py +0 -0
  51. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/request/request.py +0 -0
  52. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/swagger/swagger_template.py +0 -0
  53. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/swagger/swagger_util.py +0 -0
  54. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/task/__init__.py +0 -0
  55. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/task/task_helper.py +0 -0
  56. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/utils/thread/thread_utils.py +0 -0
  57. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask/wsgi.py +0 -0
  58. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask.egg-info/SOURCES.txt +0 -0
  59. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask.egg-info/dependency_links.txt +0 -0
  60. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask.egg-info/requires.txt +0 -0
  61. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/lesscode_flask.egg-info/top_level.txt +0 -0
  62. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/redash/query_runner/__init__.py +0 -0
  63. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/redash/query_runner/clickhouse.py +0 -0
  64. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/redash/query_runner/elasticsearch.py +0 -0
  65. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/redash/query_runner/kingbase.py +0 -0
  66. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/redash/query_runner/mysql.py +0 -0
  67. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/redash/query_runner/pg.py +0 -0
  68. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/redash/settings/__init__.py +0 -0
  69. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/redash/settings/helpers.py +0 -0
  70. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/redash/utils/__init__.py +0 -0
  71. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/redash/utils/requests_session.py +0 -0
  72. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/setup.cfg +0 -0
  73. {lesscode-flask-0.2.38 → lesscode-flask-0.2.39}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lesscode-flask
3
- Version: 0.2.38
3
+ Version: 0.2.39
4
4
  Summary: lesscode-flask 是基于flask的web开发脚手架项目,该项目初衷为简化开发过程,让研发人员更加关注业务。
5
5
  Home-page: https://lesscode-flask
6
6
  Author: Chao.yy
@@ -1,4 +1,4 @@
1
- __version__ = '0.2.38'
1
+ __version__ = "0.2.39"
2
2
 
3
3
  import functools
4
4
  import logging
@@ -17,8 +17,16 @@ class SQ_Blueprint(Blueprint):
17
17
  kwargs["import_name"] = __name__
18
18
  super().__init__(name=name, url_prefix=url_prefix, **kwargs)
19
19
 
20
- def decorator_handler(self, title: str, url: str = None, cache_enalbe: bool = False, cache_ex: int = 3600 * 10,
21
- content_type: str = "json", methods=['POST'], export_enable: bool = False):
20
+ def decorator_handler(
21
+ self,
22
+ title: str,
23
+ url: str = None,
24
+ cache_enalbe: bool = False,
25
+ cache_ex: int = 3600 * 10,
26
+ content_type: str = "json",
27
+ methods=["POST"],
28
+ export_enable: bool = False,
29
+ ):
22
30
  options = {"methods": methods}
23
31
 
24
32
  def decorator(func):
@@ -41,9 +49,7 @@ class SQ_Blueprint(Blueprint):
41
49
  # 如果没有开启缓存,或者缓存未命中,则执行原始函数
42
50
  data = func(*args, **kwargs)
43
51
  if isinstance(data, dict) and export_enable:
44
- data.update({
45
- "download_key": download_key
46
- })
52
+ data.update({"download_key": download_key})
47
53
  return data
48
54
 
49
55
  wrapper._title = title
@@ -54,12 +60,31 @@ class SQ_Blueprint(Blueprint):
54
60
 
55
61
  return decorator
56
62
 
57
- def post_route(self, title: str, url: str = None, cache_enalbe: bool = False, cache_ex: int = 3600 * 10,
58
- content_type: str = "json", methods=['POST'], export_enable: bool = False):
59
- decorator = self.decorator_handler(title, url, cache_enalbe, cache_ex, content_type, methods, export_enable)
63
+ def post_route(
64
+ self,
65
+ title: str,
66
+ url: str = None,
67
+ cache_enalbe: bool = False,
68
+ cache_ex: int = 3600 * 10,
69
+ content_type: str = "json",
70
+ methods=["POST"],
71
+ export_enable: bool = False,
72
+ ):
73
+ decorator = self.decorator_handler(
74
+ title, url, cache_enalbe, cache_ex, content_type, methods, export_enable
75
+ )
60
76
  return decorator
61
77
 
62
- def get_route(self, title: str, url: str = None, cache_enalbe: bool = False, cache_ex: int = 3600 * 10,
63
- content_type: str = "json", methods=['GET']):
64
- decorator = self.decorator_handler(title, url, cache_enalbe, cache_ex, content_type, methods)
78
+ def get_route(
79
+ self,
80
+ title: str,
81
+ url: str = None,
82
+ cache_enalbe: bool = False,
83
+ cache_ex: int = 3600 * 10,
84
+ content_type: str = "json",
85
+ methods=["GET"],
86
+ ):
87
+ decorator = self.decorator_handler(
88
+ title, url, cache_enalbe, cache_ex, content_type, methods
89
+ )
65
90
  return decorator
@@ -0,0 +1,88 @@
1
+ import time
2
+ import logging
3
+
4
+ import requests
5
+ from flask import current_app, request
6
+
7
+ from lesscode_flask.model.response_result import ResponseResult
8
+ from lesscode_flask.model.user import flask_login
9
+ from lesscode_flask.utils.fs_util import fs_webhook
10
+ from lesscode_flask.utils.redis.redis_helper import RedisHelper
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+
15
+ class RateLimitHandler:
16
+ """
17
+ 限流后的处理函数实现
18
+ """
19
+
20
+ def __init__(self, req, delay: float, excess: float):
21
+ """
22
+ 初始化
23
+ :param req:
24
+ :param delay: 延迟时间
25
+ :param excess: 超出数量
26
+ """
27
+ self.req = req
28
+ self.delay = delay
29
+ self.excess = excess
30
+
31
+ def response_handler(self):
32
+ # 如果配置了飞书 webhook URL,则发送告警通知
33
+ # 收集用户相关信息
34
+ current_user = flask_login.current_user
35
+ fs_oam_service_url = current_app.config.get("FS_OAM_SERVICE_URL")
36
+ token = request.headers.get("Authorization", "").replace("Bearer ", "")
37
+ lock_account_url = (
38
+ f"{fs_oam_service_url}/icp/authUser/lock_account?id={current_user.id}"
39
+ )
40
+ logout_url = f"{fs_oam_service_url}/icp/oauth/logout_token?token={token}"
41
+
42
+ # 发送 GET 请求到 lock_account_url
43
+ try:
44
+ lock_response = requests.get(lock_account_url, timeout=30)
45
+ logger.info(
46
+ "Lock account request sent, status: %s", lock_response.status_code
47
+ )
48
+ except requests.RequestException as e:
49
+ logger.error("Failed to send lock account request: %s", str(e))
50
+
51
+ # 发送 GET 请求到 logout_url
52
+ try:
53
+ logout_response = requests.get(logout_url, timeout=30)
54
+ logger.info("Logout request sent, status: %s", logout_response.status_code)
55
+ except requests.RequestException as e:
56
+ logger.error("Failed to send logout request: %s", str(e))
57
+
58
+ limit_fs_webhook_url = current_app.config.get("LIMIT_FS_WEBHOOK_URL")
59
+ # 如果配置了飞书 webhook URL,则发送告警通知
60
+ if limit_fs_webhook_url:
61
+ content = []
62
+ current_user = flask_login.current_user
63
+ # 收集用户相关信息
64
+ content.append(
65
+ {"tag": "text", "text": f"用户名称:{current_user.display_name}\n"}
66
+ )
67
+ phone_no = (
68
+ current_user.phone_no if current_user.phone_no is not None else "-"
69
+ )
70
+ content.append({"tag": "text", "text": f"手机号:{phone_no}\n"})
71
+ content.append({"tag": "text", "text": f"用户IP:{request.remote_addr}\n"})
72
+ content.append({"tag": "text", "text": f"资源地址:{request.path}\n"})
73
+ token = request.headers.get("Authorization", "").replace("Bearer ", "")
74
+ if token:
75
+ FS_OAM_SERVICE_URL = current_app.config.get("FS_OAM_SERVICE_URL")
76
+ content.append({"tag": "text", "text": "运维处理:"})
77
+ # lock_account_url = f"{FS_OAM_SERVICE_URL}/icp/authUser/lock_account?id={current_user.id}"
78
+ # url = f"{FS_OAM_SERVICE_URL}/icp/oauth/logout_token?token={token}"
79
+ # content.append({"tag": "a","text": "强制下线","href": f"{url}"})
80
+ # content.append({"tag": "a", "text": " 禁止登录 ", "href": f"{lock_account_url}"})
81
+ ban_ip_url = f"{FS_OAM_SERVICE_URL}/icp/accessLog/ban_ip?ip={request.remote_addr}"
82
+ content.append({"tag": "a", "text": "封禁IP ", "href": f"{ban_ip_url}"})
83
+
84
+ # 发送飞书 webhook 告警
85
+ fs_webhook(limit_fs_webhook_url, "触发频率限流告警", content)
86
+ return ResponseResult.fail(
87
+ status_code="403", http_code="403", message="请求过于频繁,请稍后再试!"
88
+ )
@@ -0,0 +1,84 @@
1
+ import logging
2
+ import requests
3
+
4
+ from flask import current_app, request
5
+
6
+ from lesscode_flask.model.response_result import ResponseResult
7
+ from lesscode_flask.model.user import flask_login
8
+ from lesscode_flask.utils.fs_util import fs_webhook
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ class CountLimitHandler:
14
+ """
15
+ 限流后的处理函数实现
16
+ """
17
+
18
+ def __init__(self, req, remaining):
19
+ self.req = req
20
+ self.remaining = remaining
21
+
22
+ def response_handler(self):
23
+ """
24
+ 处理请求频率超限的响应
25
+
26
+ 该函数用于当用户请求过于频繁触发限流时,返回相应的错误响应。
27
+ 同时会发送告警信息到飞书 webhook,记录相关用户和请求信息。
28
+
29
+ Returns:
30
+ ResponseResult: 包含403状态码和错误信息的响应结果
31
+ """
32
+ # 收集用户相关信息
33
+ current_user = flask_login.current_user
34
+ fs_oam_service_url = current_app.config.get("FS_OAM_SERVICE_URL")
35
+ token = request.headers.get("Authorization", "").replace("Bearer ", "")
36
+ lock_account_url = (
37
+ f"{fs_oam_service_url}/icp/authUser/lock_account?id={current_user.id}"
38
+ )
39
+ logout_url = f"{fs_oam_service_url}/icp/oauth/logout_token?token={token}"
40
+
41
+ # 发送 GET 请求到 lock_account_url
42
+ try:
43
+ lock_response = requests.get(lock_account_url, timeout=30)
44
+ logger.info(
45
+ "Lock account request sent, status: %s", lock_response.status_code
46
+ )
47
+ except requests.RequestException as e:
48
+ logger.error("Failed to send lock account request: %s", str(e))
49
+
50
+ # 发送 GET 请求到 logout_url
51
+ try:
52
+ logout_response = requests.get(logout_url, timeout=30)
53
+ logger.info("Logout request sent, status: %s", logout_response.status_code)
54
+ except requests.RequestException as e:
55
+ logger.error("Failed to send logout request: %s", str(e))
56
+ limit_fs_webhook_url = current_app.config.get("LIMIT_FS_WEBHOOK_URL")
57
+ # 如果配置了飞书 webhook URL,则发送告警通知
58
+ if limit_fs_webhook_url:
59
+ content = []
60
+ # 收集用户相关信息
61
+ content.append(
62
+ {"tag": "text", "text": f"用户名称:{current_user.display_name}\n"}
63
+ )
64
+ phone_no = (
65
+ current_user.phone_no if current_user.phone_no is not None else "-"
66
+ )
67
+ content.append({"tag": "text", "text": f"手机号:{phone_no}\n"})
68
+ content.append({"tag": "text", "text": f"用户IP:{request.remote_addr}\n"})
69
+ content.append({"tag": "text", "text": f"资源地址:{request.path}\n"})
70
+
71
+ if token:
72
+
73
+ content.append({"tag": "text", "text": "运维处理:"})
74
+ # content.append({"tag": "a", "text": "强制下线", "href": f"{url}"})
75
+ # content.append({"tag": "a", "text": " 禁止登录 ",
76
+ # "href": f"{lock_account_url}"})
77
+ ban_ip_url = f"{fs_oam_service_url}/icp/accessLog/ban_ip?ip={request.remote_addr}"
78
+ content.append({"tag": "a", "text": "封禁IP ", "href": f"{ban_ip_url}"})
79
+ # 发送飞书 webhook 告警
80
+ fs_webhook(limit_fs_webhook_url, "触发总量限流告警", content)
81
+
82
+ return ResponseResult.fail(
83
+ status_code="403", http_code="403", message="请求过于频繁,请稍后再试!"
84
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lesscode-flask
3
- Version: 0.2.38
3
+ Version: 0.2.39
4
4
  Summary: lesscode-flask 是基于flask的web开发脚手架项目,该项目初衷为简化开发过程,让研发人员更加关注业务。
5
5
  Home-page: https://lesscode-flask
6
6
  Author: Chao.yy
@@ -1,58 +0,0 @@
1
- import time
2
- import logging
3
-
4
- from flask import current_app, request
5
-
6
- from lesscode_flask.model.response_result import ResponseResult
7
- from lesscode_flask.model.user import flask_login
8
- from lesscode_flask.utils.fs_util import fs_webhook
9
- from lesscode_flask.utils.redis.redis_helper import RedisHelper
10
-
11
- logger = logging.getLogger(__name__)
12
-
13
-
14
- class RateLimitHandler:
15
- """
16
- 限流后的处理函数实现
17
- """
18
- def __init__(self, req, delay: float, excess: float):
19
- """
20
- 初始化
21
- :param req:
22
- :param delay: 延迟时间
23
- :param excess: 超出数量
24
- """
25
- self.req = req
26
- self.delay = delay
27
- self.excess = excess
28
-
29
-
30
- def response_handler(self):
31
- # 如果配置了飞书 webhook URL,则发送告警通知
32
- limit_fs_webhook_url = current_app.config.get("LIMIT_FS_WEBHOOK_URL")
33
- # 如果配置了飞书 webhook URL,则发送告警通知
34
- if limit_fs_webhook_url:
35
- content = []
36
- current_user = flask_login.current_user
37
- # 收集用户相关信息
38
- content.append({"tag": "text","text": f"用户名称:{current_user.display_name}\n"})
39
- phone_no = current_user.phone_no if current_user.phone_no is not None else "-"
40
- content.append({"tag": "text","text": f"手机号:{phone_no}\n"})
41
- content.append({"tag": "text","text": f"用户IP:{request.remote_addr}\n"})
42
- content.append({"tag": "text","text": f"资源地址:{request.path}\n"})
43
- token = request.headers.get("Authorization", "").replace("Bearer ", "")
44
- if token:
45
- FS_OAM_SERVICE_URL = current_app.config.get("FS_OAM_SERVICE_URL")
46
- content.append({"tag": "text","text": f"运维处理:\n"})
47
- lock_account_url = f"{FS_OAM_SERVICE_URL}/icp/authUser/lock_account?id={current_user.id}"
48
- url = f"{FS_OAM_SERVICE_URL}/icp/oauth/logout_token?token={token}"
49
- content.append({"tag": "a","text": "强制下线","href": f"{url}"})
50
- content.append({"tag": "a", "text": " 禁止登录 ", "href": f"{lock_account_url}"})
51
- ban_ip_url = f"{FS_OAM_SERVICE_URL}/icp/accessLog/ban_ip?ip={request.remote_addr}"
52
- content.append({"tag": "a", "text": "封禁IP ", "href": f"{ban_ip_url}"})
53
-
54
- # 发送飞书 webhook 告警
55
- fs_webhook(limit_fs_webhook_url, "触发频率限流告警", content)
56
- return ResponseResult.fail(status_code="403", http_code="403", message="请求过于频繁,请稍后再试!")
57
-
58
-
@@ -1,57 +0,0 @@
1
- import logging
2
-
3
- from flask import current_app, request
4
-
5
- from lesscode_flask.model.response_result import ResponseResult
6
- from lesscode_flask.model.user import flask_login
7
- from lesscode_flask.utils.fs_util import fs_webhook
8
-
9
- logger = logging.getLogger(__name__)
10
-
11
-
12
- class CountLimitHandler:
13
- """
14
- 限流后的处理函数实现
15
- """
16
-
17
- def __init__(self, req, remaining):
18
- self.req = req
19
- self.remaining = remaining
20
-
21
-
22
- def response_handler(self):
23
- """
24
- 处理请求频率超限的响应
25
-
26
- 该函数用于当用户请求过于频繁触发限流时,返回相应的错误响应。
27
- 同时会发送告警信息到飞书 webhook,记录相关用户和请求信息。
28
-
29
- Returns:
30
- ResponseResult: 包含403状态码和错误信息的响应结果
31
- """
32
- limit_fs_webhook_url = current_app.config.get("LIMIT_FS_WEBHOOK_URL")
33
- # 如果配置了飞书 webhook URL,则发送告警通知
34
- if limit_fs_webhook_url:
35
- content = []
36
- current_user = flask_login.current_user
37
- # 收集用户相关信息
38
- current_user = flask_login.current_user
39
- # 收集用户相关信息
40
- content.append({"tag": "text","text": f"用户名称:{current_user.display_name}\n"})
41
- phone_no = current_user.phone_no if current_user.phone_no is not None else "-"
42
- content.append({"tag": "text","text": f"手机号:{phone_no}\n"})
43
- content.append({"tag": "text","text": f"用户IP:{request.remote_addr}\n"})
44
- content.append({"tag": "text","text": f"资源地址:{request.path}\n"})
45
- token = request.headers.get("Authorization", "").replace("Bearer ", "")
46
- if token:
47
- FS_OAM_SERVICE_URL = current_app.config.get("FS_OAM_SERVICE_URL")
48
- content.append({"tag": "text", "text": f"运维处理:\n"})
49
- lock_account_url = f"{FS_OAM_SERVICE_URL}/icp/authUser/lock_account?id={current_user.id}"
50
- url = f"{FS_OAM_SERVICE_URL}/icp/oauth/logout_token?token={token}"
51
- content.append({"tag": "a", "text": "强制下线", "href": f"{url}"})
52
- content.append({"tag": "a", "text": " 禁止登录 ", "href": f"{lock_account_url}"})
53
- ban_ip_url = f"{FS_OAM_SERVICE_URL}/icp/accessLog/ban_ip?ip={request.remote_addr}"
54
- content.append({"tag": "a", "text": "封禁IP ", "href": f"{ban_ip_url}"})
55
- # 发送飞书 webhook 告警
56
- fs_webhook(limit_fs_webhook_url, "触发总量限流告警", content)
57
- return ResponseResult.fail(status_code="403", http_code="403", message="请求过于频繁,请稍后再试!")