lesscode-flask 0.0.84__tar.gz → 0.0.85__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 (58) hide show
  1. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/PKG-INFO +1 -1
  2. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/__init__.py +1 -1
  3. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/app.py +4 -3
  4. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/log/access_log_handler.py +1 -10
  5. lesscode-flask-0.0.85/lesscode_flask/model/user.py +218 -0
  6. lesscode-flask-0.0.85/lesscode_flask/service/authentication_service.py +106 -0
  7. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/setup/__init__.py +1 -19
  8. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/utils/thread/thread_utils.py +7 -4
  9. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask.egg-info/PKG-INFO +1 -1
  10. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask.egg-info/SOURCES.txt +0 -4
  11. lesscode-flask-0.0.84/lesscode_flask/model/auth_client.py +0 -42
  12. lesscode-flask-0.0.84/lesscode_flask/model/auth_permission.py +0 -25
  13. lesscode-flask-0.0.84/lesscode_flask/model/user.py +0 -136
  14. lesscode-flask-0.0.84/lesscode_flask/service/auth_client_service.py +0 -7
  15. lesscode-flask-0.0.84/lesscode_flask/service/auth_permission_service.py +0 -7
  16. lesscode-flask-0.0.84/lesscode_flask/service/authentication_service.py +0 -97
  17. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/README.md +0 -0
  18. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/db/__init__.py +0 -0
  19. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/db/datasource.py +0 -0
  20. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/db/executor.py +0 -0
  21. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/export_data/__init__.py +0 -0
  22. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/export_data/data_download_handler.py +0 -0
  23. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/model/access_log.py +0 -0
  24. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/model/base_model.py +0 -0
  25. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/model/parameterized_query.py +0 -0
  26. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/model/response_result.py +0 -0
  27. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/service/access_log_service.py +0 -0
  28. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/service/base_service.py +0 -0
  29. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/setting/__init__.py +0 -0
  30. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/utils/__init__.py +0 -0
  31. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/utils/decorator/__init__.py +0 -0
  32. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/utils/decorator/cache.py +0 -0
  33. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/utils/decorator/swagger.py +0 -0
  34. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/utils/file/file_exporter.py +0 -0
  35. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/utils/helpers.py +0 -0
  36. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/utils/json/NotSortJSONProvider.py +0 -0
  37. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/utils/oss/__init__.py +0 -0
  38. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/utils/oss/ks3_oss.py +0 -0
  39. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/utils/redis/redis_helper.py +0 -0
  40. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/utils/request/request.py +0 -0
  41. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/utils/swagger/swagger_template.py +0 -0
  42. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/utils/swagger/swagger_util.py +0 -0
  43. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask/wsgi.py +0 -0
  44. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask.egg-info/dependency_links.txt +0 -0
  45. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask.egg-info/requires.txt +0 -0
  46. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/lesscode_flask.egg-info/top_level.txt +0 -0
  47. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/redash/query_runner/__init__.py +0 -0
  48. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/redash/query_runner/clickhouse.py +0 -0
  49. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/redash/query_runner/elasticsearch.py +0 -0
  50. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/redash/query_runner/kingbase.py +0 -0
  51. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/redash/query_runner/mysql.py +0 -0
  52. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/redash/query_runner/pg.py +0 -0
  53. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/redash/settings/__init__.py +0 -0
  54. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/redash/settings/helpers.py +0 -0
  55. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/redash/utils/__init__.py +0 -0
  56. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/redash/utils/requests_session.py +0 -0
  57. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/setup.cfg +0 -0
  58. {lesscode-flask-0.0.84 → lesscode-flask-0.0.85}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lesscode-flask
3
- Version: 0.0.84
3
+ Version: 0.0.85
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.0.84'
1
+ __version__ = '0.0.85'
2
2
 
3
3
  import functools
4
4
  import logging
@@ -63,18 +63,19 @@ class Lesscoder(Flask):
63
63
  # 获取URL 对应的id 与访问权限
64
64
  id, access = RedisHelper(app_config.get("REDIS_OAUTH_KEY", "redis")).sync_hmget(f"upms:url_info:{url}",
65
65
  ["id", "access"])
66
+ current_user = flask_login.current_user
66
67
  if not id:
67
68
  # 如果没有进行注册的url 默认需要登录权限
68
69
  access = app_config.get("AUTH_DEFAULT_ACCESS", "0")
69
70
  # '访问权限2:需要权限 1:需要登录 0:游客',
70
71
  if str(access) == "1": # 需要登录
71
- if flask_login.current_user.is_anonymous_user:
72
+ if current_user.is_anonymous_user:
72
73
  # abort(403, "需要登录")
73
74
  ResponseResult.fail("请登录后访问", status_code="403")
74
75
  elif str(access) == "2": # 需要权限
75
- if flask_login.current_user.is_anonymous_user:
76
+ if current_user.is_anonymous_user:
76
77
  ResponseResult.fail("请登录后访问", status_code="403")
77
- if not flask_login.current_user.has_permission(id):
78
+ if not current_user.has_permission(id):
78
79
  ResponseResult.fail("请获取授权后访问", status_code="403")
79
80
  return super(Lesscoder, self).preprocess_request()
80
81
 
@@ -6,7 +6,6 @@ from logging import Handler
6
6
  from flask import request, copy_current_request_context
7
7
 
8
8
  from lesscode_flask.model.access_log import AccessLog
9
- from lesscode_flask.model.user import AnonymousUser, ApiUser
10
9
  from lesscode_flask.service.access_log_service import AccessLogService
11
10
  from lesscode_flask.utils.helpers import app_config
12
11
  from lesscode_flask.utils.redis.redis_helper import RedisHelper
@@ -55,16 +54,8 @@ class AccessLogHandler(Handler):
55
54
  flask_login = import_module("flask_login")
56
55
  except ImportError as e:
57
56
  raise Exception(f"flask_login is not exist,run:pip install Flask-Login==0.6.3")
58
- '请求类型0:用户请求,1:API用户,2:匿名用户',
59
- if isinstance(flask_login.current_user, AnonymousUser):
60
- type = 2
61
- elif isinstance(flask_login.current_user, ApiUser):
62
- type = 1
63
- else:
64
- type = 0
65
-
66
57
  access_log = AccessLog(request_id=request_id, display_name=flask_login.current_user.display_name,
67
- obj_id=flask_login.current_user.id, type=type,
58
+ obj_id=flask_login.current_user.id, type=flask_login.current_user.type,
68
59
  resource_id=resource_id,
69
60
  resource_label=resource_label, url=url, referrer=referrer, client_ip=client_ip,
70
61
  user_agent=user_agent_string, start_time=start_time, end_time=end_time,
@@ -0,0 +1,218 @@
1
+ from functools import reduce
2
+ from importlib import import_module
3
+ import json
4
+ from urllib.parse import unquote
5
+
6
+ from lesscode_flask.utils.helpers import app_config
7
+ from lesscode_flask.utils.redis.redis_helper import RedisHelper
8
+
9
+ try:
10
+ flask_login = import_module("flask_login")
11
+ except ImportError as e:
12
+ raise Exception(f"flask_login is not exist,run:pip install Flask-Login==0.6.3")
13
+
14
+
15
+ class PermissionsCheckMixin:
16
+ def has_permission(self, permission):
17
+ return self.has_permissions((permission,))
18
+
19
+ def has_permissions(self, permissions):
20
+ has_permissions = reduce(
21
+ lambda a, b: a and b,
22
+ [permission in self.permissions for permission in permissions],
23
+ True,
24
+ )
25
+
26
+ return has_permissions
27
+
28
+
29
+ class User(flask_login.UserMixin, PermissionsCheckMixin):
30
+ """
31
+ 在线用户对象类
32
+ """
33
+
34
+ def __init__(self, id="AnonymousUserId", username="AnonymousUser", display_name="匿名用户", phone_no: str = None,
35
+ email: str = None,
36
+ type: int = 0, account_status: str = None, permissions=[], permissions_url=[], client_id: str = None):
37
+ # '账号id',
38
+ self.id = id
39
+ # 用户名
40
+ self.username = username
41
+ # '显示名',
42
+ self.display_name = display_name
43
+ # 手机号,
44
+ self.phone_no = phone_no
45
+ # 邮箱
46
+ self.email = email
47
+ # 用户类型 0:匿名用户,1:普通用户,2:API用户,3:客户端用户
48
+ self.type = type
49
+ # # 组织机构id',
50
+ # self.org_id = org_id
51
+ # '1正常(激活);2未激活(管理员新增,首次登录需要改密码); 3锁定(登录错误次数超限,锁定时长可配置); 4休眠(长期未登录(字段,时长可配置),定时) 5禁用-账号失效;
52
+ self.account_status = account_status
53
+ # 当前用户登录成功的客户端id'
54
+ self.client_id = client_id
55
+ # 权限集合(symbol)
56
+ self.permissions = permissions
57
+ # 权限集合(url)
58
+ self.permissions_url = permissions_url
59
+ # # 角色集合
60
+ # self.roleIds = roleIds
61
+
62
+ #
63
+ def is_anonymous_user(self):
64
+ """
65
+ 判断是否是匿名用户
66
+ :return:
67
+ """
68
+ return self.type == 0
69
+
70
+ def is_user(self):
71
+ """
72
+ 判断是否是普通用户
73
+ :return:
74
+ """
75
+ return self.type == 1
76
+
77
+ def is_api_user(self):
78
+ """
79
+ 判断是否是API用户
80
+ :return:
81
+ """
82
+ return self.type == 2
83
+
84
+ def is_client_user(self):
85
+ """
86
+ 判断是否是客户端用户
87
+ :return:
88
+ """
89
+ return self.type == 3
90
+
91
+ def __str__(self):
92
+ return (f"User(id={self.id},username={self.username},phone_no={self.phone_no},"
93
+ f"display_name={self.display_name},email={self.email},type={self.type},"
94
+ f"account_status={self.account_status},permissions={self.permissions},client_id={self.client_id})")
95
+
96
+ def __repr__(self):
97
+ return (f"User(id={self.id},username={self.username},phone_no={self.phone_no},"
98
+ f"display_name={self.display_name},email={self.email},type={self.type},"
99
+ f"account_status={self.account_status},permissions={self.permissions},client_id={self.client_id})")
100
+
101
+ def to_dict(self):
102
+ return {
103
+ "id": self.id,
104
+ "username": self.username,
105
+ "display_name": self.display_name,
106
+ "phone_no": self.phone_no,
107
+ "email": self.email if self.email else "",
108
+ "type": self.type if self.type else "",
109
+ "account_status": self.account_status,
110
+ "permissions": json.dumps(self.permissions)
111
+ }
112
+
113
+ @staticmethod
114
+ def to_user(user_data):
115
+ if not isinstance(user_data, dict):
116
+ user_data = user_data.__dict__
117
+ return User(id=user_data.get("id"), username=user_data.get("username", ""),
118
+ display_name=user_data.get("display_name", ""), phone_no=user_data.get("phone_no", ""),
119
+ email=user_data.get("email", ""), type=user_data.get("type", 0),
120
+ account_status=user_data.get("account_status", 1), permissions=user_data.get("permissions", []),
121
+ client_id=user_data.get("client_id", ""))
122
+
123
+ @staticmethod
124
+ def get_user(request):
125
+ # 使用token访问的用户
126
+ if app_config.get("GATEWAY_USER_ENABLE"):
127
+ user_json = request.headers.get("User", "")
128
+ if user_json:
129
+ return User.get_gateway_user(user_json)
130
+ # 使用token访问的用户
131
+ authorization = request.headers.get("Authorization", "")
132
+ if "Bearer " in authorization:
133
+ token = request.headers.get("Authorization", "").replace("Bearer ", "")
134
+ if token:
135
+ return User.get_token_user(token)
136
+ apikey = request.headers.get("app_key")
137
+ if apikey:
138
+ # 使用AK访问的接口用户
139
+ return User.get_api_user(apikey)
140
+ # 无任何用户信息返回 匿名用户
141
+ return User()
142
+
143
+ @staticmethod
144
+ def get_gateway_user(user_json):
145
+ """
146
+ 网关传输信息中获取用户信息
147
+ :param apikey:
148
+ :return:
149
+ """
150
+ if user_json:
151
+ user_dict = json.loads(user_json)
152
+ if user_dict and isinstance(user_dict, dict):
153
+ if type(user_dict["roleIds"]) == str:
154
+ user_dict["roleIds"] = json.loads(user_dict["roleIds"])
155
+ user = User(
156
+ id=user_dict["id"],
157
+ username=user_dict["username"],
158
+ display_name=unquote(user_dict["display_name"]),
159
+ phone_no=user_dict["phone_no"],
160
+ permissions=user_dict.get("permissions", []),
161
+ roleIds=user_dict["roleIds"],
162
+ client_id=user_dict["client_id"]
163
+ )
164
+ return user
165
+ return User()
166
+
167
+ @staticmethod
168
+ def get_token_user(token):
169
+ """
170
+ 根据token获取用户信息。
171
+
172
+ 该函数通过Redis缓存来获取用户信息。如果在缓存中找到了对应的用户数据,
173
+ 则会创建一个User对象并返回;如果没有找到,则返回一个AnonymousUser对象。
174
+
175
+ 参数:
176
+ - token (str): 用户的令牌。
177
+
178
+ 返回:
179
+ - User: 如果找到了用户信息,则返回一个User对象。
180
+ - AnonymousUser: 如果没有找到用户信息,则返回一个AnonymousUser对象。
181
+ """
182
+ # 生成用户缓存键
183
+ user_cache_key = f"oauth2:user:{token}"
184
+
185
+ # 从Redis中获取用户数据
186
+ user_dict = RedisHelper(app_config.get("REDIS_OAUTH_KEY", "redis")).sync_hgetall(user_cache_key)
187
+
188
+ # 检查是否获取到了用户数据
189
+ if user_dict:
190
+ # 创建并返回User对象
191
+ user = User(
192
+ id=user_dict.get("id"),
193
+ username=user_dict.get("username"),
194
+ display_name=user_dict.get("display_name"),
195
+ phone_no=user_dict.get("phone_no"),
196
+ email=user_dict.get("email"),
197
+ permissions=json.loads(user_dict.get("permissions")) if user_dict.get(
198
+ "permissions") is not None else [],
199
+ client_id=user_dict.get("client_id")
200
+ )
201
+ return user
202
+ return User()
203
+
204
+ @staticmethod
205
+ def get_api_user(apikey):
206
+ """
207
+ 使用API key 获取用户信息
208
+ :param apikey:
209
+ :return:
210
+ """
211
+ cache_key = f"oauth2:user:{apikey}"
212
+ # 优先从缓存中获取
213
+ user_dict = RedisHelper(app_config.get("REDIS_OAUTH_KEY", "redis")).sync_hgetall(cache_key)
214
+ if user_dict:
215
+ user = User.to_user(user_dict)
216
+ return user
217
+ return User()
218
+
@@ -0,0 +1,106 @@
1
+ import json
2
+ from urllib.parse import unquote
3
+
4
+
5
+ from lesscode_flask.model.user import User
6
+ from lesscode_flask.utils.helpers import app_config
7
+ from lesscode_flask.utils.redis.redis_helper import RedisHelper
8
+
9
+
10
+ class LoadUser():
11
+
12
+ @staticmethod
13
+ def get_user(request):
14
+ # 使用token访问的用户
15
+ if app_config.get("GATEWAY_USER_ENABLE"):
16
+ user_json = request.headers.get("User", "")
17
+ if user_json:
18
+ return LoadUser.get_gateway_user(user_json)
19
+ # 使用token访问的用户
20
+ authorization = request.headers.get("Authorization", "")
21
+ if "Bearer " in authorization:
22
+ token = request.headers.get("Authorization", "").replace("Bearer ", "")
23
+ if token:
24
+ return LoadUser.get_token_user(token)
25
+ apikey = request.headers.get("app_key")
26
+ if apikey:
27
+ # 使用AK访问的接口用户
28
+ return LoadUser.get_api_user(apikey)
29
+ # 无任何用户信息返回 匿名用户
30
+ return User()
31
+
32
+ @staticmethod
33
+ def get_gateway_user(user_json):
34
+ """
35
+ 网关传输信息中获取用户信息
36
+ :param apikey:
37
+ :return:
38
+ """
39
+ if user_json:
40
+ user_dict = json.loads(user_json)
41
+ if user_dict and isinstance(user_dict, dict):
42
+ if type(user_dict["roleIds"]) == str:
43
+ user_dict["roleIds"] = json.loads(user_dict["roleIds"])
44
+ user = User(
45
+ id=user_dict["id"],
46
+ username=user_dict["username"],
47
+ display_name=unquote(user_dict["display_name"]),
48
+ phone_no=user_dict["phone_no"],
49
+ permissions=user_dict.get("permissions", []),
50
+ roleIds=user_dict["roleIds"],
51
+ client_id=user_dict["client_id"]
52
+ )
53
+ return user
54
+ return User()
55
+
56
+ @staticmethod
57
+ def get_token_user(token):
58
+ """
59
+ 根据token获取用户信息。
60
+
61
+ 该函数通过Redis缓存来获取用户信息。如果在缓存中找到了对应的用户数据,
62
+ 则会创建一个User对象并返回;如果没有找到,则返回一个AnonymousUser对象。
63
+
64
+ 参数:
65
+ - token (str): 用户的令牌。
66
+
67
+ 返回:
68
+ - User: 如果找到了用户信息,则返回一个User对象。
69
+ - AnonymousUser: 如果没有找到用户信息,则返回一个AnonymousUser对象。
70
+ """
71
+ # 生成用户缓存键
72
+ user_cache_key = f"oauth2:user:{token}"
73
+
74
+ # 从Redis中获取用户数据
75
+ user_dict = RedisHelper(app_config.get("REDIS_OAUTH_KEY", "redis")).sync_hgetall(user_cache_key)
76
+
77
+ # 检查是否获取到了用户数据
78
+ if user_dict:
79
+ # 创建并返回User对象
80
+ user = User(
81
+ id=user_dict.get("id"),
82
+ username=user_dict.get("username"),
83
+ display_name=user_dict.get("display_name"),
84
+ phone_no=user_dict.get("phone_no"),
85
+ email=user_dict.get("email"),
86
+ permissions=json.loads(user_dict.get("permissions")) if user_dict.get(
87
+ "permissions") is not None else [],
88
+ client_id=user_dict.get("client_id")
89
+ )
90
+ return user
91
+ return User()
92
+
93
+ @staticmethod
94
+ def get_api_user(apikey):
95
+ """
96
+ 使用API key 获取用户信息
97
+ :param apikey:
98
+ :return:
99
+ """
100
+ cache_key = f"oauth2:user:{apikey}"
101
+ # 优先从缓存中获取
102
+ user_dict = RedisHelper(app_config.get("REDIS_OAUTH_KEY", "redis")).sync_hgetall(cache_key)
103
+ if user_dict:
104
+ user = User.to_user(user_dict)
105
+ return user
106
+ return User()
@@ -10,8 +10,6 @@ from lesscode_flask import download_func_dict
10
10
  from lesscode_flask.db import db
11
11
  from lesscode_flask.export_data.data_download_handler import convert_page, format_to_table_download, upload_result_url
12
12
  from lesscode_flask.log.access_log_handler import AccessLogHandler
13
- from lesscode_flask.model.user import AnonymousUser
14
- from lesscode_flask.service.authentication_service import get_token_user, get_api_user, get_gateway_user
15
13
  from lesscode_flask.utils.swagger.swagger_template import split_doc
16
14
  from lesscode_flask.utils.swagger.swagger_util import generate_openapi_spec, replace_symbol, get_params_type, \
17
15
  get_sample_data
@@ -138,23 +136,7 @@ def setup_login_manager(app):
138
136
 
139
137
  @login_manager.request_loader
140
138
  def request_loader(request):
141
- # 使用token访问的用户
142
- if app.config.get("GATEWAY_USER_ENABLE"):
143
- user_json = request.headers.get("User", "")
144
- if user_json:
145
- return get_gateway_user(user_json)
146
- # 使用token访问的用户
147
- authorization = request.headers.get("Authorization", "")
148
- if "Bearer " in authorization:
149
- token = request.headers.get("Authorization", "").replace("Bearer ", "")
150
- if token:
151
- return get_token_user(token)
152
- apikey = request.headers.get("app_key")
153
- if apikey:
154
- # 使用AK访问的接口用户
155
- return get_api_user(apikey)
156
- # 无任何用户信息返回 匿名用户
157
- return AnonymousUser()
139
+ return LoadUser.get_user(request)
158
140
 
159
141
 
160
142
  def setup_swagger(app):
@@ -4,7 +4,7 @@ from typing import List
4
4
  from flask import copy_current_request_context
5
5
 
6
6
 
7
- class MyThread:
7
+ class FlaskThread:
8
8
  def __init__(self, target, args=None, kwargs=None):
9
9
  self.target = target
10
10
  self.args = args or []
@@ -36,7 +36,7 @@ def wrapper(_func, _args, _kwargs, _result: list = None, _lock=None, _is_throw_e
36
36
  return _thread_func
37
37
 
38
38
 
39
- def run_in_thread(func_list: List[MyThread], is_throw_error=False, is_lock=True):
39
+ def run_in_thread(func_list: List[FlaskThread], is_throw_error=False, is_lock=True):
40
40
  results = []
41
41
  threads = []
42
42
  result_locks = []
@@ -63,12 +63,15 @@ def run_in_thread(func_list: List[MyThread], is_throw_error=False, is_lock=True)
63
63
 
64
64
  final_results = []
65
65
  for result, lock in zip(results, result_locks):
66
- with lock:
66
+ if is_lock:
67
+ with lock:
68
+ final_results.append(result[0])
69
+ else:
67
70
  final_results.append(result[0])
68
71
  return final_results
69
72
 
70
73
 
71
- def run_in_background(func_list: List[MyThread], is_throw_error=False, is_lock=False):
74
+ def run_in_background(func_list: List[FlaskThread], is_throw_error=False, is_lock=False):
72
75
  thread = threading.Thread(target=wrapper(_func=run_in_thread,
73
76
  _args=[],
74
77
  _kwargs=dict(func_list=func_list, is_throw_error=is_throw_error,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lesscode-flask
3
- Version: 0.0.84
3
+ Version: 0.0.85
4
4
  Summary: lesscode-flask 是基于flask的web开发脚手架项目,该项目初衷为简化开发过程,让研发人员更加关注业务。
5
5
  Home-page: https://lesscode-flask
6
6
  Author: Chao.yy
@@ -15,15 +15,11 @@ lesscode_flask/export_data/__init__.py
15
15
  lesscode_flask/export_data/data_download_handler.py
16
16
  lesscode_flask/log/access_log_handler.py
17
17
  lesscode_flask/model/access_log.py
18
- lesscode_flask/model/auth_client.py
19
- lesscode_flask/model/auth_permission.py
20
18
  lesscode_flask/model/base_model.py
21
19
  lesscode_flask/model/parameterized_query.py
22
20
  lesscode_flask/model/response_result.py
23
21
  lesscode_flask/model/user.py
24
22
  lesscode_flask/service/access_log_service.py
25
- lesscode_flask/service/auth_client_service.py
26
- lesscode_flask/service/auth_permission_service.py
27
23
  lesscode_flask/service/authentication_service.py
28
24
  lesscode_flask/service/base_service.py
29
25
  lesscode_flask/setting/__init__.py
@@ -1,42 +0,0 @@
1
- # # coding: utf-8
2
- # from lesscode_flask.model.base_model import BaseModel, JSONEncodedDict, DatetimeEncodedString
3
- # from lesscode_flask.utils.helpers import generate_uuid
4
- # from sqlalchemy import Column, DateTime, Integer, JSON, text, Text, String, Float, BigInteger
5
- #
6
- #
7
- # class AuthClient(BaseModel):
8
- # __tablename__ = 'lc_auth_client'
9
- # __table_args__ = {'comment': '客户端信息表'}
10
- # __bind_key__ = 'auth_db'
11
- #
12
- # id = Column(String(36), primary_key=True, comment='主键', insert_default=generate_uuid)
13
- # client_name = Column(String(255), comment='系统名称')
14
- # app_key = Column(String(64), nullable=False, unique=True, comment='用于唯一标识每一个客户端')
15
- # secret_key = Column(String(256), comment='用于指定客户端(client)的访问密匙')
16
- # scope = Column(String(256), comment='指定客户端申请的权限范围,可选值包括read,write,trust')
17
- # authorized_grant_types = Column(String(256),
18
- # comment='指定客户端支持的grant_type,可选值包括authorization_code,password,refresh_token,implicit,client_credentials, 若支持多个grant_type用逗号(,)分隔')
19
- # redirect_uris = Column(String(256), comment='客户端的重定向uri,可为空, 当grant_type为authorization_code或implicit时')
20
- # logout_redirect_uri = Column(String(255), comment='客户端登出重定向uri')
21
- # access_token_validity = Column(Integer,
22
- # comment='设定客户端的access_token的有效时间值(单位:秒),可选, 若不设定值则使用默认的有效时间值(60 * 60 * 12, 12小时)')
23
- # refresh_token_validity = Column(Integer,
24
- # comment='设定客户端的refresh_token的有效时间值(单位:秒),可选, 若不设定值则使用默认的有效时间值(60 * 60 * 24 * 30, 30天)')
25
- # autoapprove = Column(String(256), comment='设置用户是否自动approval操作, 默认值为 false, 可选值包括 true,false, read,write')
26
- # response_types = Column(String(255))
27
- # serial_index = Column(Float(11, True), comment='排序字段')
28
- # client_id_issued_at = Column(BigInteger)
29
- # client_secret_expires_at = Column(BigInteger)
30
- # token_expires_in = Column(Integer, default=3600)
31
- # description = Column(String(255), comment='描述')
32
- # is_enable = Column(Integer, nullable=False, default=1, comment='1:可用,0:禁用')
33
- # is_deleted = Column(Integer, nullable=False, default=0, comment='1:删除,0:未删除')
34
- # create_user_id = Column(String(36), nullable=False, comment='创建人id')
35
- # create_user_name = Column(String(36), nullable=False, comment='创建人用户名')
36
- # modify_user_id = Column(String(36), comment='修改人id')
37
- # modify_user_name = Column(String(36), comment='修改人用户名')
38
- # create_time = Column(DatetimeEncodedString(), server_default=text("CURRENT_TIMESTAMP"), comment='创建时间')
39
- # modify_time = Column(DatetimeEncodedString(), comment='修改时间')
40
- # service_export = Column(String(255), comment='服务出口,例如:https://chanyeos.com')
41
- # is_only_one = Column(Integer, default=1, comment='1:互踢,0:不互踢')
42
- # metadata_ = Column('metadata', JSONEncodedDict())
@@ -1,25 +0,0 @@
1
- # # coding: utf-8
2
- # from lesscode_flask.model.base_model import BaseModel
3
- # from lesscode_flask.utils.helpers import generate_uuid
4
- # from sqlalchemy import Column, DateTime, Integer, JSON, text, Text, String, Float, BigInteger
5
- #
6
- #
7
- # class AuthPermission(BaseModel):
8
- # __tablename__ = 'lc_auth_permissions'
9
- # __table_args__ = {'comment': '权限表(用户、角色、应用-资源关系表)'}
10
- # __bind_key__ = 'auth_db'
11
- #
12
- # id = Column(String(36), primary_key=True, insert_default=generate_uuid)
13
- # user_id = Column(String(36), comment='用户id')
14
- # role_id = Column(String(36), comment='角色id')
15
- # client_id = Column(String(36), comment='客户端id')
16
- # type = Column(Integer, comment='0:角色资源,1:客户端资源,2:用户资源')
17
- # resource_id = Column(String(36), comment='资源id')
18
- # expires_at = Column(Integer, comment='资源失效时间')
19
- # validator = Column(JSON, comment='验证数据')
20
- # create_user_id = Column(String(36), nullable=False, comment='创建人id')
21
- # create_user_name = Column(String(36), nullable=False, comment='创建人用户名')
22
- # modify_user_id = Column(String(36), comment='修改人id')
23
- # modify_user_name = Column(String(36), comment='修改人用户名')
24
- # create_time = Column(DateTime, server_default=text("CURRENT_TIMESTAMP"), comment='创建时间')
25
- # modify_time = Column(DateTime, comment='修改时间')
@@ -1,136 +0,0 @@
1
- from functools import reduce
2
- from importlib import import_module
3
- import json
4
-
5
- # from flask_login import AnonymousUserMixin, UserMixin
6
- try:
7
- flask_login = import_module("flask_login")
8
- except ImportError as e:
9
- raise Exception(f"flask_login is not exist,run:pip install Flask-Login==0.6.3")
10
-
11
-
12
- class PermissionsCheckMixin:
13
- def has_permission(self, permission):
14
- return self.has_permissions((permission,))
15
-
16
- def has_permissions(self, permissions):
17
- has_permissions = reduce(
18
- lambda a, b: a and b,
19
- [permission in self.permissions for permission in permissions],
20
- True,
21
- )
22
-
23
- return has_permissions
24
-
25
-
26
- class User(flask_login.UserMixin, PermissionsCheckMixin):
27
- """
28
- 在线用户对象类
29
- """
30
-
31
- def __init__(self, id, username: str = None, display_name: str = None, phone_no: str = None, email: str = None,
32
- type: int = 0, account_status: str = None, permissions=[], client_id: str = None):
33
- # '账号id',
34
- self.id = id
35
- # 用户名
36
- self.username = username
37
- # '显示名',
38
- self.display_name = display_name
39
- # 手机号,
40
- self.phone_no = phone_no
41
- # 邮箱
42
- self.email = email
43
- # 用户类型 0:匿名用户,1:普通用户,2:API用户,3:客户端用户
44
- self.type = type
45
- # # 组织机构id',
46
- # self.org_id = org_id
47
- # '1正常(激活);2未激活(管理员新增,首次登录需要改密码); 3锁定(登录错误次数超限,锁定时长可配置); 4休眠(长期未登录(字段,时长可配置),定时) 5禁用-账号失效;
48
- self.account_status = account_status
49
- # 当前用户登录成功的客户端id'
50
- self.client_id = client_id
51
- # 权限集合
52
- self.permissions = permissions
53
- # # 角色集合
54
- # self.roleIds = roleIds
55
-
56
- #
57
- #
58
- # @staticmethod
59
- # def is_api_user():
60
- # return False
61
- #
62
- # @staticmethod
63
- # def is_anonymous_user():
64
- # return False
65
-
66
- def __str__(self):
67
- return (f"User(id={self.id},username={self.username},phone_no={self.phone_no},"
68
- f"display_name={self.display_name},email={self.email},type={self.type},"
69
- f"account_status={self.account_status},permissions={self.permissions},client_id={self.client_id})")
70
-
71
- def __repr__(self):
72
- return (f"User(id={self.id},username={self.username},phone_no={self.phone_no},"
73
- f"display_name={self.display_name},email={self.email},type={self.type},"
74
- f"account_status={self.account_status},permissions={self.permissions},client_id={self.client_id})")
75
-
76
- def to_dict(self):
77
- return {
78
- "id": self.id,
79
- "username": self.username,
80
- "display_name": self.display_name,
81
- "phone_no": self.phone_no,
82
- "email": self.email if self.email else "",
83
- "type": self.type if self.type else "",
84
- "account_status": self.account_status,
85
- "permissions": json.dumps(self.permissions)
86
- }
87
- @staticmethod
88
- def to_user(user_data):
89
- if not isinstance(user_data, dict):
90
- user_data = user_data.__dict__
91
- return User(id=user_data.get("id"), username=user_data.get("username",""), display_name=user_data.get("display_name",""),phone_no=user_data.get("phone_no",""),email=user_data.get("email",""),type=user_data.get("type",0),account_status=user_data.get("account_status",1),permissions=user_data.get("permissions",[]),client_id=user_data.get("client_id",""))
92
-
93
- class AnonymousUser(User):
94
- """
95
- 匿名用户
96
- """
97
-
98
- def __init__(self, permissions=None):
99
- super(AnonymousUser, self).__init__("AnonymousUserId", "AnonymousUser", "匿名用户", "-", "-", None, 1,
100
- permissions)
101
- #
102
- # @staticmethod
103
- # def is_api_user():
104
- # return False
105
- #
106
- # @staticmethod
107
- # def is_anonymous_user():
108
- # return True
109
-
110
-
111
- class ApiUser(User):
112
- def __init__(self, id, username: str = None, display_name: str = None,
113
- permissions=None):
114
- super(ApiUser, self).__init__(id, username, display_name, "-", "-", None, 1, permissions)
115
-
116
- @staticmethod
117
- def is_api_user():
118
- return True
119
-
120
- @staticmethod
121
- def to_obj(_user):
122
- user = ApiUser(_user.get("id"))
123
- for key, value in _user.items():
124
- if isinstance(key, bytes):
125
- key = key.decode('utf-8')
126
- if isinstance(value, bytes):
127
- value = value.decode('utf-8')
128
- if key == "permissions":
129
- user.permissions = value.split(",")
130
- elif key == "org_id":
131
- user.org_id = value if value else None
132
- elif key == "account_status":
133
- user.account_status = int(value)
134
- else:
135
- setattr(user, key, value)
136
- return user
@@ -1,7 +0,0 @@
1
- # from lesscode_flask.model.auth_client import AuthClient
2
- # from lesscode_flask.service.base_service import BaseService
3
- #
4
- #
5
- # class AuthClientService(BaseService):
6
- # def __init__(self):
7
- # super().__init__(AuthClient)
@@ -1,7 +0,0 @@
1
- # from lesscode_flask.model.auth_permission import AuthPermission
2
- # from lesscode_flask.service.base_service import BaseService
3
- #
4
- #
5
- # class AuthPermissionService(BaseService):
6
- # def __init__(self):
7
- # super().__init__(AuthPermission)
@@ -1,97 +0,0 @@
1
- import json
2
- from urllib.parse import unquote
3
-
4
- # from lesscode_flask.model.auth_client import AuthClient
5
- # from lesscode_flask.model.auth_permission import AuthPermission
6
- from lesscode_flask.model.user import ApiUser, User, AnonymousUser
7
- # from lesscode_flask.service.auth_client_service import AuthClientService
8
- # from lesscode_flask.service.auth_permission_service import AuthPermissionService
9
- from lesscode_flask.utils.helpers import app_config
10
- from lesscode_flask.utils.redis.redis_helper import RedisHelper
11
-
12
-
13
- def get_gateway_user(user_json):
14
- """
15
- 网关传输信息中获取用户信息
16
- :param apikey:
17
- :return:
18
- """
19
- if user_json:
20
- user_dict = json.loads(user_json)
21
- if user_dict and isinstance(user_dict, dict):
22
- if type(user_dict["roleIds"]) == str:
23
- user_dict["roleIds"] = json.loads(user_dict["roleIds"])
24
- user = User(
25
- id=user_dict["id"],
26
- username=user_dict["username"],
27
- display_name=unquote(user_dict["display_name"]),
28
- phone_no=user_dict["phone_no"],
29
- permissions=user_dict.get("permissions",[]),
30
- roleIds=user_dict["roleIds"],
31
- client_id=user_dict["client_id"]
32
- )
33
- return user
34
- return AnonymousUser()
35
-
36
-
37
- def get_token_user(token):
38
- """
39
- 根据token获取用户信息。
40
-
41
- 该函数通过Redis缓存来获取用户信息。如果在缓存中找到了对应的用户数据,
42
- 则会创建一个User对象并返回;如果没有找到,则返回一个AnonymousUser对象。
43
-
44
- 参数:
45
- - token (str): 用户的令牌。
46
-
47
- 返回:
48
- - User: 如果找到了用户信息,则返回一个User对象。
49
- - AnonymousUser: 如果没有找到用户信息,则返回一个AnonymousUser对象。
50
- """
51
- # 生成用户缓存键
52
- user_cache_key = f"oauth2:user:{token}"
53
-
54
- # 从Redis中获取用户数据
55
- user_dict = RedisHelper(app_config.get("REDIS_OAUTH_KEY", "redis")).sync_hgetall(user_cache_key)
56
-
57
- # 检查是否获取到了用户数据
58
- if user_dict:
59
- # 创建并返回User对象
60
- user = User(
61
- id=user_dict.get("id"),
62
- username=user_dict.get("username"),
63
- display_name=user_dict.get("display_name"),
64
- phone_no=user_dict.get("phone_no"),
65
- email=user_dict.get("email"),
66
- permissions=json.loads(user_dict.get("permissions")) if user_dict.get("permissions") is not None else [],
67
- client_id=user_dict.get("client_id")
68
- )
69
- return user
70
- # 如果没有获取到用户数据,返回AnonymousUser对象
71
- return AnonymousUser()
72
-
73
-
74
- def get_api_user(apikey):
75
- """
76
- 使用API key 获取用户信息
77
- :param apikey:
78
- :return:
79
- """
80
- cache_key = f"oauth2:apikey_user_info:{apikey}"
81
- # 优先从缓存中获取
82
- user_dict = RedisHelper(app_config.get("REDIS_OAUTH_KEY", "redis")).sync_hgetall(cache_key)
83
- if user_dict:
84
- user = ApiUser.to_obj(user_dict)
85
- return user
86
- # else:
87
- # # 库里查询
88
- # authClient = AuthClientService().get_one([AuthClient.client_id == apikey])
89
- # if authClient:
90
- # authPermission = AuthPermissionService().get_items([AuthPermission.client_id == authClient.id])
91
- # permissions = [permission.resource_id for permission in authPermission]
92
- # user = ApiUser(authClient.id, authClient.client_id, authClient.client_name, permissions)
93
- # RedisHelper(app_config.get("REDIS_OAUTH_KEY", "redis")).sync_hset(cache_key,
94
- # mapping=user.to_dict(),
95
- # time=authClient.token_expires_in)
96
- # return user
97
- return AnonymousUser()