提交 963ce9d5a912f040b5e2d00346ada94f8f88cfad

作者 nheweijun
2 个父辈 4588c76b e49c1cc3
1   -from enum import auto
2 1 from logging import error
3   -from unittest import result
4 2 from flasgger import swag_from
5 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 5 from .models import *
9 6 from .oauth2 import authorization, generate_user_info, require_oauth
10 7 from authlib.oauth2 import OAuth2Error
... ... @@ -16,6 +13,9 @@ import time
16 13 from app.models import SM3, AESHelper
17 14 from app.util.component.StructurePrint import StructurePrint
18 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 21 def current_user():
... ... @@ -42,6 +42,10 @@ class DataManager(BlueprintApi):
42 42 @bp.route("/authorize", methods=("GET", "POST"))
43 43 def authorize():
44 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 49 if request.method == "GET":
46 50 # 没有登录,跳转到登录界面
47 51 try:
... ... @@ -212,3 +216,99 @@ class DataManager(BlueprintApi):
212 216 new_pwd = SM3.encode(p)
213 217 result[p] = new_pwd
214 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 16 __tablename__ = "dmap_user"
17 17 id = Column(Integer, primary_key=True)
18 18 username = Column(Text)
  19 +
19 20 password = Column(Text)
20 21 company = Column(Text)
21 22 position = Column(Text)
... ... @@ -24,6 +25,8 @@ class User (db.Model):
24 25 create_time = Column(Time)
25 26 update_time = Column(Time)
26 27 role = Column(Text)
  28 + #display_name = Column(Text, nullable=True) # 昵称
  29 + #origin = Column(Text, default="dmap") # 用户来源,默认dmap平台用户
27 30
28 31 def __str__(self):
29 32 return self.username
... ...
... ... @@ -55,7 +55,7 @@ class Api(ApiTemplate):
55 55 {"name": "database_guid",
56 56 "in": "formData",
57 57 "type": "string",
58   - "description": "数据库guid", "required": "true"},
  58 + "description": "数据库guid", "": "true"},
59 59
60 60 ],
61 61 "responses":{
... ...
... ... @@ -76,6 +76,8 @@
76 76 立即登录
77 77 </button>
78 78 </div>
  79 + <div>——或者——</div>
  80 + <a href="/auth/oa"> 城信所统一用户认证 </a>
79 81 </form>
80 82 </div>
81 83 <div class="clear"></div>
... ...
... ... @@ -5,12 +5,11 @@ deploy_ip_host = "172.26.40.105:8840"
5 5 # 系统数据库
6 6 SQLALCHEMY_DATABASE_URI = "postgresql://postgres:chinadci@172.26.60.101:5432/dmap_manager"
7 7
8   -
9 8 # 指定精华表所在位置(必须为空间库),设置为None则存放在各自的实体库中
10 9 VACUATE_DB_URI = None
11 10 #VACUATE_DB_URI = SQLALCHEMY_DATABASE_URI
12 11
13   -#DMap引擎
  12 +# DMap引擎
14 13 dmap_engine = "http://172.26.60.101:8820"
15 14
16 15 # 固定配置不需要修改
... ... @@ -27,3 +26,14 @@ PublishPermission = ['admin', 'dataman', 'publisher']
27 26 ServicePermission = ['admin', 'dataman', 'publisher']
28 27
29 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 6 os.environ['AUTHLIB_INSECURE_TRANSPORT'] = '1'
7 7 app: Flask = create_app()
8 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)
\ No newline at end of file
... ...
注册登录 后发表评论