提交 978f7fa2a3737508c283610453f1d682becb358a

作者 nheweijun
2 个父辈 f54eb3c0 dac245db
  1 +from datetime import datetime
1 from logging import error 2 from logging import error
2 from flasgger import swag_from 3 from flasgger import swag_from
3 from app.util import BlueprintApi 4 from app.util import BlueprintApi
@@ -6,7 +7,7 @@ from .models import * @@ -6,7 +7,7 @@ from .models import *
6 from .oauth2 import authorization, generate_user_info, require_oauth 7 from .oauth2 import authorization, generate_user_info, require_oauth
7 from authlib.oauth2 import OAuth2Error 8 from authlib.oauth2 import OAuth2Error
8 from authlib.integrations.flask_oauth2 import current_token 9 from authlib.integrations.flask_oauth2 import current_token
9 -from . import user_create, client_create, client_query, user_query, user_update, user_delete 10 +from . import user_create, client_create, client_query, user_query, user_update, user_delete, auth_log_query
10 import configure 11 import configure
11 from app.decorators.auth_decorator import auth_decorator 12 from app.decorators.auth_decorator import auth_decorator
12 import time 13 import time
@@ -15,7 +16,8 @@ from app.util.component.StructurePrint import StructurePrint @@ -15,7 +16,8 @@ from app.util.component.StructurePrint import StructurePrint
15 import traceback 16 import traceback
16 # from oauthlib import oauth2 17 # from oauthlib import oauth2
17 import requests 18 import requests
18 -from app.modules.auth.models import OAuth2Token, User, db 19 +from app.modules.auth.models import OAuth2Token, User, db, OAuthLog
  20 +from app.util.enum.AuthEnum import AuthEnum, OriginEnum, OperateEnum
19 21
20 22
21 def current_user(): 23 def current_user():
@@ -35,6 +37,16 @@ def split_by_crlf(s): @@ -35,6 +37,16 @@ def split_by_crlf(s):
35 return [v for v in s.splitlines() if v] 37 return [v for v in s.splitlines() if v]
36 38
37 39
  40 +def getRedirectUrl(request): # 获取重定向地址
  41 + # 获取头部信息
  42 + X_Forwarded_Proto = request.headers.get("X-Forwarded-Proto") # 协议
  43 + X_Forwarded_Host = request.headers.get("X-Forwarded-Host") # host
  44 + if not X_Forwarded_Proto == None and not X_Forwarded_Host == None:
  45 + return X_Forwarded_Proto+"://"+X_Forwarded_Host
  46 + else:
  47 + return request.host_url.rstrip("/")
  48 +
  49 +
38 class DataManager(BlueprintApi): 50 class DataManager(BlueprintApi):
39 bp = Blueprint("Auth", __name__, url_prefix="/auth") 51 bp = Blueprint("Auth", __name__, url_prefix="/auth")
40 52
@@ -45,7 +57,7 @@ class DataManager(BlueprintApi): @@ -45,7 +57,7 @@ class DataManager(BlueprintApi):
45 request2 = authorization.create_oauth2_request(request) 57 request2 = authorization.create_oauth2_request(request)
46 grant2 = authorization.get_authorization_grant(request=request2) 58 grant2 = authorization.get_authorization_grant(request=request2)
47 redirect_uri = grant2.validate_authorization_request() 59 redirect_uri = grant2.validate_authorization_request()
48 - session["redirect_uri"] = redirect_uri 60 + session["redirect_uri"] = redirect_uri # 记录跳转重定向地址
49 if request.method == "GET": 61 if request.method == "GET":
50 # 没有登录,跳转到登录界面 62 # 没有登录,跳转到登录界面
51 try: 63 try:
@@ -71,8 +83,11 @@ class DataManager(BlueprintApi): @@ -71,8 +83,11 @@ class DataManager(BlueprintApi):
71 crypt_pwd = request.form.get("password") 83 crypt_pwd = request.form.get("password")
72 # password = SM3.encode(crypt_pwd) 84 # password = SM3.encode(crypt_pwd)
73 password = SM3.encode(AESHelper.decode(crypt_pwd)) 85 password = SM3.encode(AESHelper.decode(crypt_pwd))
  86 +
  87 + # 仅支持dmap平台保留用户登录
  88 + origin_type = OriginEnum.Dmap.name.lower()
74 user = User.query.filter_by( 89 user = User.query.filter_by(
75 - username=username, password=password).first() 90 + username=username, password=password, origin=origin_type).first()
76 if not user: 91 if not user:
77 error = "账号或密码不正确" 92 error = "账号或密码不正确"
78 flash(error) 93 flash(error)
@@ -83,6 +98,17 @@ class DataManager(BlueprintApi): @@ -83,6 +98,17 @@ class DataManager(BlueprintApi):
83 if user: 98 if user:
84 session["id"] = user.id 99 session["id"] = user.id
85 grant_user = user 100 grant_user = user
  101 +
  102 + # 日志
  103 + log = OAuthLog(user_id=user.id, username=user.username,
  104 + auth_type=AuthEnum.Other.name.lower(),
  105 + message="认证成功", create_time=datetime.now(),
  106 + operate_type=OperateEnum.Login,
  107 + displayname=user.displayname, ip=request.remote_addr
  108 + )
  109 + db.session.add(log)
  110 + db.session.commit()
  111 +
86 return authorization.create_authorization_response(request=request, grant_user=grant_user) 112 return authorization.create_authorization_response(request=request, grant_user=grant_user)
87 113
88 # try: 114 # try:
@@ -116,16 +142,34 @@ class DataManager(BlueprintApi): @@ -116,16 +142,34 @@ class DataManager(BlueprintApi):
116 def logout(): 142 def logout():
117 try: 143 try:
118 request2 = authorization.create_oauth2_request(request) 144 request2 = authorization.create_oauth2_request(request)
119 - grant1 = authorization.get_authorization_grant(request=request2) 145 + grant1 = authorization.get_authorization_grant(
  146 + request=request2)
120 redirect_uri = grant1.validate_authorization_request() 147 redirect_uri = grant1.validate_authorization_request()
121 access_token = request.args.get("accesstoken") 148 access_token = request.args.get("accesstoken")
122 - accesstoken = OAuth2Token.query.filter_by(  
123 - access_token=access_token).first()  
124 - accesstoken.revoked = True  
125 - db.session.commit()  
126 - remove_user() 149 +
  150 + if not access_token == None:
  151 + accesstoken = OAuth2Token.query.filter_by(
  152 + access_token=access_token).one_or_none()
  153 + if not accesstoken == None:
  154 + accesstoken.revoked = True
  155 + db.session.commit()
  156 + if current_user() != None:
  157 + remove_user()
  158 +
  159 + user = User.query.get(accesstoken.user_id)
  160 + # 日志
  161 + if user != None:
  162 + log = OAuthLog(user_id=user.id, username=user.username,
  163 + auth_type=AuthEnum.Other.name.lower(),
  164 + message="注销成功", create_time=datetime.now(),
  165 + operate_type=OperateEnum.Logout, token=access_token,
  166 + displayname=user.displayname, ip=request.remote_addr
  167 + )
  168 + db.session.add(log)
  169 + db.session.commit()
  170 +
127 except OAuth2Error as error: 171 except OAuth2Error as error:
128 - return jsonify(dict(error.get_body())) 172 + StructurePrint().print(error.__str__()+":" + traceback.format_exc(), "error")
129 return redirect(redirect_uri) 173 return redirect(redirect_uri)
130 174
131 """接口""" 175 """接口"""
@@ -207,15 +251,15 @@ class DataManager(BlueprintApi): @@ -207,15 +251,15 @@ class DataManager(BlueprintApi):
207 except Exception as e: 251 except Exception as e:
208 StructurePrint().print(e.__str__()+":" + traceback.format_exc(), "error") 252 StructurePrint().print(e.__str__()+":" + traceback.format_exc(), "error")
209 253
210 - @staticmethod  
211 - @bp.route("/translate", methods=["GET"])  
212 - def translate():  
213 - password = ['esri@123', 'admin', 'DMap@123', 'passwd']  
214 - result = {}  
215 - for p in password:  
216 - new_pwd = SM3.encode(p)  
217 - result[p] = new_pwd  
218 - return result 254 + # @staticmethod
  255 + # @bp.route("/translate", methods=["GET"])
  256 + # def translate():
  257 + # password = ['esri@123', 'admin', 'DMap@123', 'passwd','dci112..']
  258 + # result = {}
  259 + # for p in password:
  260 + # new_pwd = SM3.encode(p)
  261 + # result[p] = new_pwd
  262 + # return result
219 263
220 ''' 264 '''
221 三方登录:OA 265 三方登录:OA
@@ -226,8 +270,9 @@ class DataManager(BlueprintApi): @@ -226,8 +270,9 @@ class DataManager(BlueprintApi):
226 client = oauth2.WebApplicationClient( 270 client = oauth2.WebApplicationClient(
227 configure.OA["client_id"]) 271 configure.OA["client_id"])
228 state = client.state_generator() 272 state = client.state_generator()
  273 + StructurePrint().print(request.headers, "info")
229 auth_uri = client.prepare_request_uri( 274 auth_uri = client.prepare_request_uri(
230 - configure.OA["authorization_endpoint"], configure.OA["redirect_uri"], configure.OA["scope"], state) 275 + configure.OA["authorization_endpoint"], getRedirectUrl(request) + configure.OA["redirect_uri"], configure.OA["scope"], state)
231 session["oauth_state"] = state 276 session["oauth_state"] = state
232 return redirect(auth_uri) 277 return redirect(auth_uri)
233 278
@@ -237,78 +282,111 @@ class DataManager(BlueprintApi): @@ -237,78 +282,111 @@ class DataManager(BlueprintApi):
237 @staticmethod 282 @staticmethod
238 @bp.route("/oa/callback", methods=["GET"]) 283 @bp.route("/oa/callback", methods=["GET"])
239 def oa_callback(): 284 def oa_callback():
  285 + try:
  286 + auth_default_redirect_uri = configure.auth_default_redirect_uri
  287 + client = oauth2.WebApplicationClient(
  288 + configure.OA["client_id"])
  289 +
  290 + # 获取code
  291 + code = client.parse_request_uri_response(
  292 + request.url, session["oauth_state"]).get("code")
  293 +
  294 + if code == None:
  295 + return "登录失败"
  296 +
  297 + # 获取token
  298 + body = client.prepare_request_body(
  299 + code, redirect_uri=getRedirectUrl(request) + configure.OA["redirect_uri"], client_secret=configure.OA["client_secret"])
  300 +
  301 + r = requests.post(configure.OA["token_endpoint"], body, headers={
  302 + "Content-Type": "application/x-www-form-urlencoded"})
  303 +
  304 + tokeninfo = r.json()
  305 + access_token = tokeninfo.get("access_token")
  306 + id_token = tokeninfo.get("id_token")
  307 +
  308 + origin_type = "dci_oa" # 三方登录标识
  309 + if access_token:
  310 + # 获取用户信息
  311 + userinfo_url = configure.OA["userinfo_endpoint"]
  312 + user_request = requests.get(userinfo_url, headers={
  313 + "Authorization": "Bearer %s" % access_token})
  314 + userinfo = user_request.json()
  315 + user_name = userinfo.get("user_name")
  316 + display_name = userinfo.get("displayname")
  317 + display_name = display_name.split(
  318 + )[-1] if display_name != None else user_name
  319 +
  320 + # 默认关联dmap用户
  321 + try:
  322 + user = User.query.filter_by(
  323 + username=user_name, origin=origin_type).first()
  324 + except error as e:
  325 + user = None
  326 +
  327 + # 用户不存在,创建用户
240 328
241 - client = oauth2.WebApplicationClient(  
242 - configure.OA["client_id"])  
243 -  
244 - # 获取code  
245 - code = client.parse_request_uri_response(  
246 - request.url, session["oauth_state"]).get("code")  
247 -  
248 - if code == None:  
249 - return "登录失败"  
250 -  
251 - # 获取token  
252 - body = client.prepare_request_body(  
253 - code, redirect_uri=configure.OA["redirect_uri"], client_secret=configure.OA["client_secret"])  
254 -  
255 - r = requests.post(configure.OA["token_endpoint"], body, headers={  
256 - "Content-Type": "application/x-www-form-urlencoded"})  
257 -  
258 - tokeninfo = r.json()  
259 - access_token = tokeninfo.get("access_token")  
260 -  
261 - if access_token:  
262 - # 获取用户信息  
263 - userinfo_url = configure.OA["userinfo_endpoint"]  
264 - user_request = requests.get(userinfo_url, headers={  
265 - "Authorization": "Bearer %s" % access_token})  
266 - userinfo = user_request.json()  
267 - user_name = userinfo.get("user_name")  
268 - display_name = userinfo.get("displayname")  
269 -  
270 - # 默认关联dmap用户  
271 - try:  
272 - user = User.query.filter_by(  
273 - username=user_name).first()  
274 - except error as e:  
275 - user = None 329 + if not user:
  330 + user = User(username=user_name, password=SM3.encode('DMap@123'), role='dataman',
  331 + phone='', company='', position='', email='', displayname=display_name,
  332 + origin=origin_type,
  333 + create_time=time.strftime(
  334 + "%Y-%m-%d %H:%M:%S", time.localtime()),
  335 + update_time=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
  336 + db.session.add(user)
  337 + db.session.commit()
  338 +
  339 + session["id"] = user.id
  340 +
  341 + # dmap token授权
  342 + # 存入数据库
  343 + token = OAuth2Token(
  344 + client_id=configure.OA["client_id"],
  345 + token_type=tokeninfo.get("token_type"),
  346 + access_token=access_token,
  347 + scope=tokeninfo.get("scope"),
  348 + expires_in=tokeninfo.get("expires_in"),
  349 + user_id=user.id
  350 + )
  351 +
  352 + db.session.add(token)
  353 + db.session.commit()
276 354
277 - # 用户不存在,创建用户  
278 - if not user:  
279 - user = User(username=user_name, password=SM3.encode('DMap@123'), role='dataman',  
280 - phone='', company='', position='', email='',  
281 - create_time=time.strftime(  
282 - "%Y-%m-%d %H:%M:%S", time.localtime()),  
283 - update_time=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))  
284 - db.session.add(user) 355 + redirect_uri = session["redirect_uri"] if "redirect_uri" in session else auth_default_redirect_uri
  356 +
  357 + #session["id_token"] = id_token
  358 + response = make_response(redirect(redirect_uri))
  359 + response.set_cookie('accessToken', access_token,
  360 + max_age=configure.expiretime)
  361 + response.set_cookie('id_token', id_token,
  362 + max_age=configure.expiretime)
  363 +
  364 + log = OAuthLog(user_id=user.id, username=user_name,
  365 + auth_type=AuthEnum.Other.name.lower(),
  366 + message="三方认证成功", create_time=datetime.now(),
  367 + operate_type=OperateEnum.Login, token=access_token,
  368 + displayname=display_name, ip=request.remote_addr)
  369 + db.session.add(log)
285 db.session.commit() 370 db.session.commit()
286 371
287 - # dmap token授权  
288 - session["id"] = user.id 372 + return response
  373 + else:
  374 + raise Exception("缺少access_token")
289 375
290 - # 存入数据库  
291 - token = OAuth2Token(  
292 - client_id=configure.OA["client_id"],  
293 - token_type=tokeninfo.get("token_type"),  
294 - access_token=access_token,  
295 - scope=tokeninfo.get("scope"),  
296 - expires_in=tokeninfo.get("expires_in"),  
297 - user_id=user.id  
298 - )  
299 - db.session.add(token)  
300 - db.session.commit()  
301 - redirect_uri = ""  
302 - try:  
303 - redirect_uri = session["redirect_uri"]  
304 - if not redirect_uri:  
305 - redirect_uri = '/'  
306 - except:  
307 - redirect_uri = "/"  
308 -  
309 - response = make_response(redirect(redirect_uri))  
310 - response.set_cookie('accessToken', access_token, max_age=604_800)  
311 -  
312 - return response  
313 - else:  
314 - return redirect('/') 376 + except Exception as e:
  377 + StructurePrint().print(e.__str__()+":" + traceback.format_exc(), "error")
  378 + pop_list = ["id", "redirect_uri"]
  379 + for p in pop_list:
  380 + if p in session:
  381 + session.pop(p)
  382 + return redirect(auth_default_redirect_uri)
  383 +
  384 + @staticmethod
  385 + @bp.route("/logs", methods=["GET"])
  386 + @swag_from(auth_log_query.Api.api_doc)
  387 + @auth_decorator(configure.UserPermission)
  388 + def authLog():
  389 + '''
  390 + 登录日志
  391 + '''
  392 + return auth_log_query.Api().result
  1 +# coding=utf-8
  2 +# author: qianyingz
  3 +# createtime: 2022/03/09
  4 +# email: qianyingz@chinadci.com
  5 +from tokenize import String
  6 +from numpy import number
  7 +from sqlalchemy import or_
  8 +from .models import *
  9 +from app.util.component.ApiTemplate import ApiTemplate
  10 +import json
  11 +
  12 +
  13 +class Api(ApiTemplate):
  14 + api_name = "登录日志"
  15 +
  16 + def para_check(self):
  17 + pass
  18 +
  19 + def process(self):
  20 + # 返回结果
  21 + res = {}
  22 + res["result"] = False
  23 + try:
  24 + # 业务逻辑
  25 + page_index = int(self.para.get("page_index", "0"))
  26 + page_size = int(self.para.get("page_size", "1000"))
  27 + # name = self.para.get("name")
  28 + order_by = self.para.get("order_by")
  29 + filter_param = self.para.get("filter_param", "")
  30 + filter_param_json = {} if filter_param == "" else json.loads(
  31 + filter_param)
  32 + kw = filter_param_json["kw"] if "kw" in filter_param_json else None
  33 + type = filter_param_json["type"] if "type" in filter_param_json else None
  34 +
  35 + log_query = OAuthLog.query
  36 +
  37 + if kw != None:
  38 + if isinstance(kw, str):
  39 + filter_username_query = log_query.filter(OAuthLog.username.like(
  40 + "%" + kw + "%"))
  41 + filter_display_query = log_query.filter(
  42 + OAuthLog.displayname.like("%" + kw + "%"))
  43 + log_query = filter_username_query.union(
  44 + filter_display_query)
  45 +
  46 + if type != None:
  47 + if isinstance(type, (str,int)):
  48 + log_query = log_query.filter(OAuthLog.operate_type == type)
  49 + elif isinstance(type, list):
  50 + log_query = log_query.filter(OAuthLog.operate_type.in_(type))
  51 +
  52 + log_query = log_query.order_by(OAuthLog.create_time.desc())
  53 +
  54 + count = log_query.count()
  55 + logs = log_query.limit(page_size).offset(
  56 + page_index*page_size).all()
  57 +
  58 + res["data"] = {"count": count,
  59 + "list": list(map(lambda t:
  60 + {"id": t.id, "username": t.username, "ip": t.ip,
  61 + "message": t.message, "create_time": t.create_time.strftime("%Y-%m-%d %H:%M:%S"),
  62 + "operate_type": t.operate_type,
  63 + "auth_type": t.auth_type,
  64 + "displayname": t.displayname}, logs))}
  65 +
  66 + # # 获取集合
  67 + # userLinq = User.query.order_by(User.id.desc())
  68 + # if name:
  69 + # userLinq = userLinq.filter(
  70 + # User.username.like("%" + name + "%"))
  71 + # tmp_count = userLinq.count()
  72 + # tmp_list = userLinq.limit(page_size).offset(
  73 + # page_index * page_size).all()
  74 + # res["data"] = {
  75 + # "count": tmp_count,
  76 + # "list": list(map(lambda t:
  77 + # {"guid": t.id, "username": t.username,
  78 + # "role": t.role, "display_name": t.display_name,
  79 + # "status": t.status},
  80 + # tmp_list))}
  81 +
  82 + res["result"] = True
  83 +
  84 + except Exception as e:
  85 + raise e
  86 + return res
  87 +
  88 + api_doc = {
  89 + "tags": ["登录日志"],
  90 + "parameters": [
  91 + {"name": "page_index",
  92 + "in": "query",
  93 + "type": "int",
  94 + "description": "当前页",
  95 + "default": 0},
  96 + {"name": "page_size",
  97 + "in": "query",
  98 + "type": "int",
  99 + "description": "条数",
  100 + "default": 1000},
  101 + {"name": "order_by",
  102 + "in": "query",
  103 + "type": "string",
  104 + "description": "排序"},
  105 + {"name": "filter_param",
  106 + "in": "query",
  107 + "type": "json",
  108 + "description": "过滤"}
  109 + ],
  110 + "responses": {
  111 + 200: {
  112 + "schema": {
  113 + "properties": {
  114 + }
  115 + }
  116 + }
  117 + }
  118 + }
1 -from flask_sqlalchemy import sqlalchemy  
2 -from sqlalchemy import Column, Integer, Text, Time, ForeignKey 1 +from sqlalchemy import Column, Integer, Text, Time, ForeignKey, DateTime
3 from app.models import db 2 from app.models import db
4 from authlib.integrations.sqla_oauth2 import ( 3 from authlib.integrations.sqla_oauth2 import (
5 OAuth2ClientMixin, 4 OAuth2ClientMixin,
@@ -7,6 +6,7 @@ from authlib.integrations.sqla_oauth2 import ( @@ -7,6 +6,7 @@ from authlib.integrations.sqla_oauth2 import (
7 OAuth2AuthorizationCodeMixin 6 OAuth2AuthorizationCodeMixin
8 ) 7 )
9 from sqlalchemy.orm import relationship 8 from sqlalchemy.orm import relationship
  9 +from app.util.enum.AuthEnum import OriginEnum,UserStatusEnum
10 10
11 11
12 class User (db.Model): 12 class User (db.Model):
@@ -16,17 +16,18 @@ class User (db.Model): @@ -16,17 +16,18 @@ class User (db.Model):
16 __tablename__ = "dmap_user" 16 __tablename__ = "dmap_user"
17 id = Column(Integer, primary_key=True) 17 id = Column(Integer, primary_key=True)
18 username = Column(Text) 18 username = Column(Text)
19 -  
20 password = Column(Text) 19 password = Column(Text)
21 company = Column(Text) 20 company = Column(Text)
22 position = Column(Text) 21 position = Column(Text)
23 phone = Column(Text) 22 phone = Column(Text)
24 email = Column(Text) 23 email = Column(Text)
25 - create_time = Column(Time)  
26 - update_time = Column(Time) 24 + create_time = Column(DateTime)
  25 + update_time = Column(DateTime)
27 role = Column(Text) 26 role = Column(Text)
28 - #display_name = Column(Text, nullable=True) # 昵称  
29 - #origin = Column(Text, default="dmap") # 用户来源,默认dmap平台用户 27 + displayname = Column(Text, nullable=True) # 昵称
  28 + # 用户来源,默认dmap平台用户
  29 + origin = Column(Text, default=OriginEnum.Dmap.name.lower())
  30 + status = Column(Integer, default=UserStatusEnum.Active) # 1:激活,2:冻结,0:注销
30 31
31 def __str__(self): 32 def __str__(self):
32 return self.username 33 return self.username
@@ -68,3 +69,26 @@ class OAuth2Token(db.Model, OAuth2TokenMixin): @@ -68,3 +69,26 @@ class OAuth2Token(db.Model, OAuth2TokenMixin):
68 Integer, ForeignKey('dmap_user.id', ondelete='CASCADE')) 69 Integer, ForeignKey('dmap_user.id', ondelete='CASCADE'))
69 # name = Column(Text) 70 # name = Column(Text)
70 user = relationship('User') 71 user = relationship('User')
  72 +
  73 +
  74 +'''
  75 +认证日志
  76 +'''
  77 +
  78 +# 认证日志
  79 +
  80 +
  81 +class OAuthLog(db.Model):
  82 + __tablename__ = "dmap_oauth_log"
  83 +
  84 + id = Column(Integer, primary_key=True)
  85 + user_id = Column(Text, nullable=False)
  86 + username = Column(Text) # 用户输入账号
  87 + displayname=Column(Text) # 昵称
  88 + ip = Column(Text)
  89 + # 登录方式:password,三方登录
  90 + auth_type = Column(Text)
  91 + message = Column(Text) # 登录返回提示
  92 + create_time = Column(DateTime) # 记录创建时间
  93 + operate_type = Column(Integer, nullable=False) # 操作类型,登录,注销
  94 + token = Column(Text)
@@ -51,7 +51,7 @@ def exists_nonce(nonce, req): @@ -51,7 +51,7 @@ def exists_nonce(nonce, req):
51 51
52 52
53 def generate_user_info(user, scope): 53 def generate_user_info(user, scope):
54 - return UserInfo(sub=str(user.id), name=user.username, role=user.role, company=user.company) 54 + return UserInfo(sub=str(user.id), name=user.username, role=user.role, company=user.company, display_name=user.displayname, status=user.status)
55 55
56 56
57 def create_authorization_code(client, grant_user, request): 57 def create_authorization_code(client, grant_user, request):
@@ -27,18 +27,19 @@ class Api(ApiTemplate): @@ -27,18 +27,19 @@ class Api(ApiTemplate):
27 res["result"] = False 27 res["result"] = False
28 try: 28 try:
29 # 业务逻辑 29 # 业务逻辑
30 - username = AESHelper.decode( self.para.get("username", '')) 30 + username = AESHelper.decode(self.para.get("username", ''))
31 password = SM3.encode(AESHelper.decode(self.para.get("pwd", ''))) 31 password = SM3.encode(AESHelper.decode(self.para.get("pwd", '')))
32 role = AESHelper.decode(self.para.get("role", '')) 32 role = AESHelper.decode(self.para.get("role", ''))
33 company = AESHelper.decode(self.para.get("company", '')) 33 company = AESHelper.decode(self.para.get("company", ''))
34 position = AESHelper.decode(self.para.get("position", '')) 34 position = AESHelper.decode(self.para.get("position", ''))
35 email = AESHelper.decode(self.para.get("email", '')) 35 email = AESHelper.decode(self.para.get("email", ''))
36 phone = AESHelper.decode(self.para.get("phone", '')) 36 phone = AESHelper.decode(self.para.get("phone", ''))
  37 + displayname = username
37 # 是否重名 38 # 是否重名
38 if(User.query.filter_by(username=username).one_or_none()): 39 if(User.query.filter_by(username=username).one_or_none()):
39 res["msg"] = "username 已存在" 40 res["msg"] = "username 已存在"
40 else: 41 else:
41 - user = User(username=username, password=password, role=role, 42 + user = User(username=username, displayname=displayname, password=password, role=role,
42 phone=phone, company=company, position=position, email=email, 43 phone=phone, company=company, position=position, email=email,
43 create_time=time.strftime( 44 create_time=time.strftime(
44 "%Y-%m-%d %H:%M:%S", time.localtime()), 45 "%Y-%m-%d %H:%M:%S", time.localtime()),
@@ -20,7 +20,6 @@ class Api(ApiTemplate): @@ -20,7 +20,6 @@ class Api(ApiTemplate):
20 res["result"] = False 20 res["result"] = False
21 try: 21 try:
22 # 业务逻辑 22 # 业务逻辑
23 - pass  
24 page_index = int(self.para.get("page_index", "0")) 23 page_index = int(self.para.get("page_index", "0"))
25 page_size = int(self.para.get("page_size", "1000")) 24 page_size = int(self.para.get("page_size", "1000"))
26 name = self.para.get("name") 25 name = self.para.get("name")
@@ -31,7 +30,8 @@ class Api(ApiTemplate): @@ -31,7 +30,8 @@ class Api(ApiTemplate):
31 res["data"] = {"guid": tmp_user.id, "username": tmp_user.username, 30 res["data"] = {"guid": tmp_user.id, "username": tmp_user.username,
32 "role": tmp_user.role, "company": tmp_user.company, 31 "role": tmp_user.role, "company": tmp_user.company,
33 "position": tmp_user.position, "email": tmp_user.email, 32 "position": tmp_user.position, "email": tmp_user.email,
34 - "phone": tmp_user.phone} 33 + "phone": tmp_user.phone, "display_name": tmp_user.displayname,
  34 + "status": tmp_user.status}
35 else: 35 else:
36 # 获取集合 36 # 获取集合
37 userLinq = User.query.order_by(User.id.desc()) 37 userLinq = User.query.order_by(User.id.desc())
@@ -45,7 +45,8 @@ class Api(ApiTemplate): @@ -45,7 +45,8 @@ class Api(ApiTemplate):
45 "count": tmp_count, 45 "count": tmp_count,
46 "list": list(map(lambda t: 46 "list": list(map(lambda t:
47 {"guid": t.id, "username": t.username, 47 {"guid": t.id, "username": t.username,
48 - "role": t.role}, 48 + "role": t.role, "display_name": t.displayname,
  49 + "status": t.status},
49 tmp_list))} 50 tmp_list))}
50 res["result"] = True 51 res["result"] = True
51 52
@@ -55,7 +55,7 @@ class Api(ApiTemplate): @@ -55,7 +55,7 @@ class Api(ApiTemplate):
55 {"name": "database_guid", 55 {"name": "database_guid",
56 "in": "formData", 56 "in": "formData",
57 "type": "string", 57 "type": "string",
58 - "description": "数据库guid", "": "true"}, 58 + "description": "数据库guid", "required": "true"},
59 59
60 ], 60 ],
61 "responses":{ 61 "responses":{
@@ -238,4 +238,28 @@ button { @@ -238,4 +238,28 @@ button {
238 -webkit-box-sizing: border-box; 238 -webkit-box-sizing: border-box;
239 -moz-box-sizing: border-box; 239 -moz-box-sizing: border-box;
240 box-sizing: border-box; 240 box-sizing: border-box;
  241 +}
  242 +
  243 +.other-mod {
  244 + margin-top: 35px;
  245 +}
  246 +
  247 +.other-mod .other-tit {
  248 + color: #999;
  249 + display: inline-block;
  250 + margin-right: 20px;
  251 +}
  252 +
  253 +.other-mod .other-link {
  254 + text-align: right;
  255 + margin-left: 20px;
  256 + float: right;
  257 +}
  258 +
  259 +.other-mod .other-link a {
  260 + color: #545454;
  261 +}
  262 +
  263 +.other-mod .other-link:hover a {
  264 + color: #3081c3;
241 } 265 }
@@ -76,8 +76,13 @@ @@ -76,8 +76,13 @@
76 立即登录 76 立即登录
77 </button> 77 </button>
78 </div> 78 </div>
79 - <div>——或者——</div>  
80 - <a href="/auth/oa"> 城信所统一用户认证 </a> 79 +
  80 + <div class="form-group other-mod">
  81 + <div class="other-tit"><span>其他登录方式</span></div>
  82 + <div class="other-link">
  83 + <a href="/auth/oa">城信所统一用户认证</a>
  84 + </div>
  85 + </div>
81 </form> 86 </form>
82 </div> 87 </div>
83 <div class="clear"></div> 88 <div class="clear"></div>
  1 +from enum import Enum,IntEnum
  2 +
  3 +'''
  4 +认证方式
  5 +'''
  6 +
  7 +
  8 +class AuthEnum(IntEnum):
  9 + Password = 1 # 账号密码登录,包括三方的账号密码登录
  10 + Other = 3 # 三方登录
  11 +
  12 +
  13 +'''
  14 +用户来源
  15 +'''
  16 +
  17 +
  18 +class OriginEnum(IntEnum):
  19 + Dmap = 1
  20 +
  21 +
  22 +'''用户状态'''
  23 +
  24 +
  25 +class UserStatusEnum(IntEnum):
  26 + Cancellation = 0, # 注销
  27 + Active = 1, # 活跃
  28 + Freeze = 2 # 冻结
  29 +
  30 +
  31 +class OperateEnum(IntEnum):
  32 + Login = 1, # 登录
  33 + Logout = 2 # 注销
@@ -27,13 +27,17 @@ ServicePermission = ['admin', 'dataman', 'publisher'] @@ -27,13 +27,17 @@ ServicePermission = ['admin', 'dataman', 'publisher']
27 27
28 log_level = logging.INFO 28 log_level = logging.INFO
29 29
  30 +expiretime = 604_800 # 7天
30 31
31 OA = { 32 OA = {
32 "client_id": "dmap", 33 "client_id": "dmap",
33 "client_secret": "secret", 34 "client_secret": "secret",
34 "scope": "openid profile", 35 "scope": "openid profile",
35 - "redirect_uri": "http://localhost:8841/auth/oa/callback", 36 + "redirect_uri": "/auth/oa/callback",
36 "authorization_endpoint": "https://login.chinadci.com/netsso/connect/authorize", 37 "authorization_endpoint": "https://login.chinadci.com/netsso/connect/authorize",
37 "token_endpoint": "https://login.chinadci.com/netsso/connect/token", 38 "token_endpoint": "https://login.chinadci.com/netsso/connect/token",
38 - "userinfo_endpoint": "https://login.chinadci.com/netsso/connect/userinfo" 39 + "userinfo_endpoint": "https://login.chinadci.com/netsso/connect/userinfo",
  40 + "end_session_endpoint": "https://login.chinadci.com/netsso/connect/endsession"
39 } 41 }
  42 +
  43 +auth_default_redirect_uri="http://localhost:9999"
@@ -77,4 +77,8 @@ result=AESHelper.decode(encryption) @@ -77,4 +77,8 @@ result=AESHelper.decode(encryption)
77 77
78 [验证码基础知识](https://baike.baidu.com/item/%E9%AA%8C%E8%AF%81%E7%A0%81/31701) 78 [验证码基础知识](https://baike.baidu.com/item/%E9%AA%8C%E8%AF%81%E7%A0%81/31701)
79 [使用python图像处理标准库](https://www.liaoxuefeng.com/wiki/1016959663602400/1017785454949568) 79 [使用python图像处理标准库](https://www.liaoxuefeng.com/wiki/1016959663602400/1017785454949568)
80 -[pillow](https://pillow.readthedocs.io/en/stable/index.html)  
  80 +[pillow](https://pillow.readthedocs.io/en/stable/index.html)
  81 +
  82 +
  83 +## 5 使用编译文件的方法
  84 +cmd下运行./compile.py
注册登录 后发表评论