提交 963ce9d5a912f040b5e2d00346ada94f8f88cfad

作者 nheweijun
2 个父辈 4588c76b e49c1cc3
1 -from enum import auto  
2 from logging import error 1 from logging import error
3 -from unittest import result  
4 from flasgger import swag_from 2 from flasgger import swag_from
5 from app.util import BlueprintApi 3 from app.util import BlueprintApi
6 -from app.util import BlueprintApi  
7 -from flask import Blueprint, render_template, redirect, request, session, jsonify, flash 4 +from flask import Blueprint, render_template, redirect, request, session, jsonify, flash, make_response
8 from .models import * 5 from .models import *
9 from .oauth2 import authorization, generate_user_info, require_oauth 6 from .oauth2 import authorization, generate_user_info, require_oauth
10 from authlib.oauth2 import OAuth2Error 7 from authlib.oauth2 import OAuth2Error
@@ -16,6 +13,9 @@ import time @@ -16,6 +13,9 @@ import time
16 from app.models import SM3, AESHelper 13 from app.models import SM3, AESHelper
17 from app.util.component.StructurePrint import StructurePrint 14 from app.util.component.StructurePrint import StructurePrint
18 import traceback 15 import traceback
  16 +from oauthlib import oauth2
  17 +import requests
  18 +from app.modules.auth.models import OAuth2Token, User, db
19 19
20 20
21 def current_user(): 21 def current_user():
@@ -42,6 +42,10 @@ class DataManager(BlueprintApi): @@ -42,6 +42,10 @@ class DataManager(BlueprintApi):
42 @bp.route("/authorize", methods=("GET", "POST")) 42 @bp.route("/authorize", methods=("GET", "POST"))
43 def authorize(): 43 def authorize():
44 user = current_user() 44 user = current_user()
  45 + request2 = authorization.create_oauth2_request(request)
  46 + grant2 = authorization.get_authorization_grant(request=request2)
  47 + redirect_uri = grant2.validate_authorization_request()
  48 + session["redirect_uri"] = redirect_uri
45 if request.method == "GET": 49 if request.method == "GET":
46 # 没有登录,跳转到登录界面 50 # 没有登录,跳转到登录界面
47 try: 51 try:
@@ -212,3 +216,99 @@ class DataManager(BlueprintApi): @@ -212,3 +216,99 @@ class DataManager(BlueprintApi):
212 new_pwd = SM3.encode(p) 216 new_pwd = SM3.encode(p)
213 result[p] = new_pwd 217 result[p] = new_pwd
214 return result 218 return result
  219 +
  220 + '''
  221 + 三方登录:OA
  222 + '''
  223 + @staticmethod
  224 + @bp.route("/oa", methods=["GET"])
  225 + def oa_authorization():
  226 + client = oauth2.WebApplicationClient(
  227 + configure.OA["client_id"])
  228 + state = client.state_generator()
  229 + auth_uri = client.prepare_request_uri(
  230 + configure.OA["authorization_endpoint"], configure.OA["redirect_uri"], configure.OA["scope"], state)
  231 + session["oauth_state"] = state
  232 + return redirect(auth_uri)
  233 +
  234 + '''
  235 + oa三方登录回调
  236 + '''
  237 + @staticmethod
  238 + @bp.route("/oa/callback", methods=["GET"])
  239 + def oa_callback():
  240 +
  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
  276 +
  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)
  285 + db.session.commit()
  286 +
  287 + # dmap token授权
  288 + session["id"] = user.id
  289 +
  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('/')
@@ -16,6 +16,7 @@ class User (db.Model): @@ -16,6 +16,7 @@ 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 +
19 password = Column(Text) 20 password = Column(Text)
20 company = Column(Text) 21 company = Column(Text)
21 position = Column(Text) 22 position = Column(Text)
@@ -24,6 +25,8 @@ class User (db.Model): @@ -24,6 +25,8 @@ class User (db.Model):
24 create_time = Column(Time) 25 create_time = Column(Time)
25 update_time = Column(Time) 26 update_time = Column(Time)
26 role = Column(Text) 27 role = Column(Text)
  28 + #display_name = Column(Text, nullable=True) # 昵称
  29 + #origin = Column(Text, default="dmap") # 用户来源,默认dmap平台用户
27 30
28 def __str__(self): 31 def __str__(self):
29 return self.username 32 return self.username
@@ -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", "required": "true"}, 58 + "description": "数据库guid", "": "true"},
59 59
60 ], 60 ],
61 "responses":{ 61 "responses":{
@@ -76,6 +76,8 @@ @@ -76,6 +76,8 @@
76 立即登录 76 立即登录
77 </button> 77 </button>
78 </div> 78 </div>
  79 + <div>——或者——</div>
  80 + <a href="/auth/oa"> 城信所统一用户认证 </a>
79 </form> 81 </form>
80 </div> 82 </div>
81 <div class="clear"></div> 83 <div class="clear"></div>
@@ -5,12 +5,11 @@ deploy_ip_host = "172.26.40.105:8840" @@ -5,12 +5,11 @@ deploy_ip_host = "172.26.40.105:8840"
5 # 系统数据库 5 # 系统数据库
6 SQLALCHEMY_DATABASE_URI = "postgresql://postgres:chinadci@172.26.60.101:5432/dmap_manager" 6 SQLALCHEMY_DATABASE_URI = "postgresql://postgres:chinadci@172.26.60.101:5432/dmap_manager"
7 7
8 -  
9 # 指定精华表所在位置(必须为空间库),设置为None则存放在各自的实体库中 8 # 指定精华表所在位置(必须为空间库),设置为None则存放在各自的实体库中
10 VACUATE_DB_URI = None 9 VACUATE_DB_URI = None
11 #VACUATE_DB_URI = SQLALCHEMY_DATABASE_URI 10 #VACUATE_DB_URI = SQLALCHEMY_DATABASE_URI
12 11
13 -#DMap引擎 12 +# DMap引擎
14 dmap_engine = "http://172.26.60.101:8820" 13 dmap_engine = "http://172.26.60.101:8820"
15 14
16 # 固定配置不需要修改 15 # 固定配置不需要修改
@@ -27,3 +26,14 @@ PublishPermission = ['admin', 'dataman', 'publisher'] @@ -27,3 +26,14 @@ PublishPermission = ['admin', 'dataman', 'publisher']
27 ServicePermission = ['admin', 'dataman', 'publisher'] 26 ServicePermission = ['admin', 'dataman', 'publisher']
28 27
29 log_level = logging.INFO 28 log_level = logging.INFO
  29 +
  30 +
  31 +OA = {
  32 + "client_id": "dmap",
  33 + "client_secret": "secret",
  34 + "scope": "openid profile",
  35 + "redirect_uri": "http://localhost:8841/auth/oa/callback",
  36 + "authorization_endpoint": "https://login.chinadci.com/netsso/connect/authorize",
  37 + "token_endpoint": "https://login.chinadci.com/netsso/connect/token",
  38 + "userinfo_endpoint": "https://login.chinadci.com/netsso/connect/userinfo"
  39 +}
@@ -6,4 +6,4 @@ import os @@ -6,4 +6,4 @@ import os
6 os.environ['AUTHLIB_INSECURE_TRANSPORT'] = '1' 6 os.environ['AUTHLIB_INSECURE_TRANSPORT'] = '1'
7 app: Flask = create_app() 7 app: Flask = create_app()
8 if __name__ == '__main__': 8 if __name__ == '__main__':
9 - app.run(host="0.0.0.0", port="8841", threaded=True, debug=True) 9 + app.run(host="0.0.0.0", port="8841", threaded=True, debug=True)
注册登录 后发表评论