提交 a3228acb082e602f8bf8ea9c6a6ca74257d1dfbd

作者 qianyingz
1 个父辈 924fa172

新增接口:注册用户、注册client、获取client列表;解决跨域注销问题

1   -import decimal
2   -
3   -from flask import Flask as _Flask
4   -from flask.json import JSONEncoder as _JSONEncoder
5   -from flask_cors import CORS
6   -import time
7   -
8   -from sqlalchemy.sql.expression import true
9   -import configure
10   -from app.util import BlueprintApi
11   -from app.util import find_class
12   -from app.models import db, Table, InsertingLayerName, Database, DES, Task
13   -from app.modules.auth.oauth2 import config_oauth, myCodeIDToken
14   -from flasgger import Swagger
15   -# from rtree import index
16   -import logging
17   -from sqlalchemy.orm import Session
18   -import multiprocessing
19   -from app.util.component.EntryData import EntryData
20   -from app.util.component.EntryDataVacuate import EntryDataVacuate
21   -import json
22   -import threading
23   -import traceback
24   -from sqlalchemy import distinct
25   -import uuid
26   -from osgeo.ogr import DataSource
27   -import datetime
28   -from sqlalchemy import or_
29   -from app.util.component.StructuredPrint import StructurePrint
30   -from app.util.component.PGUtil import PGUtil
31   -import os
32   -
33   -
34   -class JSONEncoder(_JSONEncoder):
35   - """
36   - 因为decimal不能序列化,增加Flask对decimal类的解析
37   - """
38   -
39   - def default(self, o):
40   - if isinstance(o, decimal.Decimal):
41   - return float(o)
42   - super(JSONEncoder, self).default(o)
43   -
44   -
45   -class Flask(_Flask):
46   - json_encoder = JSONEncoder
47   -
48   -
49   -GLOBAL_DIC = {}
50   -
51   -
52   -def create_app():
53   - """
54   - flask应用创建函数
55   - :return:app,flask实例
56   - """
57   -
58   - # app基本设置
59   - app = Flask(__name__)
60   - app.config['SQLALCHEMY_DATABASE_URI'] = configure.SQLALCHEMY_DATABASE_URI
61   - app.config['echo'] = True
62   - app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
63   - app.config['JSON_AS_ASCII'] = False
64   - app.config['SECRET_KEY'] = configure.SECRET_KEY
65   - app.config['OAUTH2_JWT_ENABLED'] = True
66   -
67   - app.config['OAUTH2_JWT_ISS'] = 'http://localhost:5000'
68   - app.config['OAUTH2_JWT_KEY'] = 'secret-key'
69   - app.config['OAUTH2_JWT_ALG'] = 'HS256'
70   - # app.config['SQLALCHEMY_ECHO'] = True
71   -
72   - # allows cookies and credentials to be submitted across domains
73   - app.config['CORS_SUPPORTS_CREDENTIALS'] = true
74   -
75   - # 跨域设置
76   - CORS(app)
77   -
78   - # swagger设置
79   - swagger_config = Swagger.DEFAULT_CONFIG
80   - swagger_config.update(configure.swagger_configure)
81   - Swagger(app, config=swagger_config)
82   -
83   - # 创建数据库
84   - db.init_app(app)
85   - db.create_all(app=app)
86   -
87   - # 日志
88   - logging.basicConfig(level=logging.INFO)
89   - log_file = os.path.join(os.path.dirname(os.path.dirname(
90   - os.path.realpath(__file__))), "logs", "log.txt")
91   - handler = logging.FileHandler(
92   - log_file, encoding='UTF-8') # 设置日志字符集和存储路径名字
93   - logging_format = logging.Formatter(
94   - '[%(levelname)s] %(asctime)s %(message)s')
95   - handler.setFormatter(logging_format)
96   - app.logger.addHandler(handler)
97   -
98   - # 配置使用鉴权组件,不写无法认证授权
99   - config_oauth(app)
100   -
101   - # 注册blueprint,查找BlueprintApi的子类
102   - for scan in configure.scan_module:
103   - for api in find_class(scan, BlueprintApi):
104   - app.register_blueprint(api.bp)
105   -
106   - # 入库监测线程
107   -
108   - @app.before_first_request
109   - def data_entry_process():
110   - StructurePrint.print("start listen")
111   - process = threading.Thread(target=data_entry_center)
112   - process.start()
113   -
114   - # 不检测https
115   - os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
116   -
117   - # 上下文全局变量字典
118   - global GLOBAL_DIC
119   -
120   - return app
121   -
122   -
123   -def data_entry_center():
124   - running_dict = {}
125   - sys_session: Session = PGUtil.get_db_session(
126   - configure.SQLALCHEMY_DATABASE_URI)
127   -
128   - while True:
129   -
130   - try:
131   - time.sleep(3)
132   -
133   - # 已经结束的进程 从监测中删除
134   - remove_process = []
135   -
136   - # structured_print(running_dict.__len__().__str__())
137   -
138   - for process, layer_names in running_dict.items():
139   - if not process.is_alive():
140   - for l in layer_names:
141   - inserted = sys_session.query(
142   - InsertingLayerName).filter_by(name=l).one_or_none()
143   - if inserted:
144   - sys_session.delete(inserted)
145   - sys_session.commit()
146   - remove_process.append(process)
147   - for process in remove_process:
148   - running_dict.pop(process)
149   -
150   - # StructurePrint.print("listening...")
151   -
152   - # 入库进程少于阈值,开启入库进程
153   -
154   - inter_size = sys_session.query(
155   - distinct(InsertingLayerName.task_guid)).count()
156   -
157   - if inter_size < configure.entry_data_thread:
158   - # 锁表啊
159   - ready_task: Task = sys_session.query(Task).filter_by(state=0, task_type=1).order_by(
160   - Task.create_time).with_lockmode("update").limit(1).one_or_none()
161   - if ready_task:
162   -
163   - try:
164   - parameter = json.loads(ready_task.parameter)
165   - StructurePrint.print("检测到入库任务")
166   - ready_task.state = 2
167   - ready_task.process = "入库中"
168   - sys_session.commit()
169   -
170   - metas: list = json.loads(
171   - parameter.get("meta").__str__())
172   - parameter["meta"] = metas
173   -
174   - database = sys_session.query(Database).filter_by(
175   - guid=ready_task.database_guid).one_or_none()
176   - pg_ds: DataSource = PGUtil.open_pg_data_source(
177   - 1, DES.decode(database.sqlalchemy_uri))
178   -
179   - this_task_layer = []
180   - for meta in metas:
181   - overwrite = parameter.get("overwrite", "no")
182   -
183   - for layer_name_origin, layer_name in meta.get("layer").items():
184   - origin_name = layer_name
185   - no = 1
186   -
187   - while (overwrite.__eq__("no") and pg_ds.GetLayerByName(layer_name)) or sys_session.query(InsertingLayerName).filter_by(name=layer_name).one_or_none():
188   - layer_name = origin_name + "_{}".format(no)
189   - no += 1
190   -
191   - # 添加到正在入库的列表中
192   - iln = InsertingLayerName(guid=uuid.uuid1().__str__(),
193   - task_guid=ready_task.guid,
194   - name=layer_name)
195   -
196   - sys_session.add(iln)
197   - sys_session.commit()
198   - this_task_layer.append(layer_name)
199   - # 修改表名
200   - meta["layer"][layer_name_origin] = layer_name
201   -
202   - pg_ds.Destroy()
203   - entry_data_process = multiprocessing.Process(
204   - target=EntryDataVacuate().entry, args=(parameter,))
205   - entry_data_process.start()
206   - running_dict[entry_data_process] = this_task_layer
207   - except Exception as e:
208   - sys_session.query(Task).filter_by(guid=ready_task.guid).update(
209   - {"state": -1, "process": "入库失败"})
210   - sys_session.commit()
211   - StructurePrint.print(e.__str__(), "error")
212   - else:
213   - # 解表啊
214   - sys_session.commit()
215   - except Exception as e:
216   - sys_session.commit()
  1 +import decimal
  2 +
  3 +from flask import Flask as _Flask
  4 +from flask.json import JSONEncoder as _JSONEncoder
  5 +from flask_cors import CORS
  6 +import time
  7 +
  8 +from sqlalchemy.sql.expression import true
  9 +import configure
  10 +from app.util import BlueprintApi
  11 +from app.util import find_class
  12 +from app.models import db, Table, InsertingLayerName, Database, DES, Task
  13 +from app.modules.auth.oauth2 import config_oauth, myCodeIDToken
  14 +from flasgger import Swagger
  15 +# from rtree import index
  16 +import logging
  17 +from sqlalchemy.orm import Session
  18 +import multiprocessing
  19 +from app.util.component.EntryData import EntryData
  20 +from app.util.component.EntryDataVacuate import EntryDataVacuate
  21 +import json
  22 +import threading
  23 +import traceback
  24 +from sqlalchemy import distinct
  25 +import uuid
  26 +from osgeo.ogr import DataSource
  27 +import datetime
  28 +from sqlalchemy import or_
  29 +from app.util.component.StructuredPrint import StructurePrint
  30 +from app.util.component.PGUtil import PGUtil
  31 +import os
  32 +
  33 +
  34 +class JSONEncoder(_JSONEncoder):
  35 + """
  36 + 因为decimal不能序列化,增加Flask对decimal类的解析
  37 + """
  38 +
  39 + def default(self, o):
  40 + if isinstance(o, decimal.Decimal):
  41 + return float(o)
  42 + super(JSONEncoder, self).default(o)
  43 +
  44 +
  45 +class Flask(_Flask):
  46 + json_encoder = JSONEncoder
  47 +
  48 +
  49 +GLOBAL_DIC = {}
  50 +
  51 +
  52 +def create_app():
  53 + """
  54 + flask应用创建函数
  55 + :return:app,flask实例
  56 + """
  57 +
  58 + # app基本设置
  59 + app = Flask(__name__)
  60 + app.config['SQLALCHEMY_DATABASE_URI'] = configure.SQLALCHEMY_DATABASE_URI
  61 + app.config['echo'] = True
  62 + app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
  63 + app.config['JSON_AS_ASCII'] = False
  64 + app.config['SECRET_KEY'] = configure.SECRET_KEY
  65 + app.config['OAUTH2_JWT_ENABLED'] = True
  66 +
  67 + app.config['OAUTH2_JWT_ISS'] = 'http://localhost:5000'
  68 + app.config['OAUTH2_JWT_KEY'] = 'secret-key'
  69 + app.config['OAUTH2_JWT_ALG'] = 'HS256'
  70 + # app.config['SQLALCHEMY_ECHO'] = True
  71 +
  72 + # allows cookies and credentials to be submitted across domains
  73 + app.config['CORS_SUPPORTS_CREDENTIALS'] = true
  74 + app.config['CORS_ORIGINS ']="*"
  75 +
  76 + # 跨域设置
  77 + CORS(app)
  78 +
  79 + # swagger设置
  80 + swagger_config = Swagger.DEFAULT_CONFIG
  81 + swagger_config.update(configure.swagger_configure)
  82 + Swagger(app, config=swagger_config)
  83 +
  84 + # 创建数据库
  85 + db.init_app(app)
  86 + db.create_all(app=app)
  87 +
  88 + # 日志
  89 + logging.basicConfig(level=logging.INFO)
  90 + log_file = os.path.join(os.path.dirname(os.path.dirname(
  91 + os.path.realpath(__file__))), "logs", "log.txt")
  92 + handler = logging.FileHandler(
  93 + log_file, encoding='UTF-8') # 设置日志字符集和存储路径名字
  94 + logging_format = logging.Formatter(
  95 + '[%(levelname)s] %(asctime)s %(message)s')
  96 + handler.setFormatter(logging_format)
  97 + app.logger.addHandler(handler)
  98 +
  99 + # 配置使用鉴权组件,不写无法认证授权
  100 + config_oauth(app)
  101 +
  102 + # 注册blueprint,查找BlueprintApi的子类
  103 + for scan in configure.scan_module:
  104 + for api in find_class(scan, BlueprintApi):
  105 + app.register_blueprint(api.bp)
  106 +
  107 + # 入库监测线程
  108 +
  109 + @app.before_first_request
  110 + def data_entry_process():
  111 + StructurePrint.print("start listen")
  112 + process = threading.Thread(target=data_entry_center)
  113 + process.start()
  114 +
  115 + # 不检测https
  116 + os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
  117 +
  118 + # 上下文全局变量字典
  119 + global GLOBAL_DIC
  120 +
  121 + return app
  122 +
  123 +
  124 +def data_entry_center():
  125 + running_dict = {}
  126 + sys_session: Session = PGUtil.get_db_session(
  127 + configure.SQLALCHEMY_DATABASE_URI)
  128 +
  129 + while True:
  130 +
  131 + try:
  132 + time.sleep(3)
  133 +
  134 + # 已经结束的进程 从监测中删除
  135 + remove_process = []
  136 +
  137 + # structured_print(running_dict.__len__().__str__())
  138 +
  139 + for process, layer_names in running_dict.items():
  140 + if not process.is_alive():
  141 + for l in layer_names:
  142 + inserted = sys_session.query(
  143 + InsertingLayerName).filter_by(name=l).one_or_none()
  144 + if inserted:
  145 + sys_session.delete(inserted)
  146 + sys_session.commit()
  147 + remove_process.append(process)
  148 + for process in remove_process:
  149 + running_dict.pop(process)
  150 +
  151 + # StructurePrint.print("listening...")
  152 +
  153 + # 入库进程少于阈值,开启入库进程
  154 +
  155 + inter_size = sys_session.query(
  156 + distinct(InsertingLayerName.task_guid)).count()
  157 +
  158 + if inter_size < configure.entry_data_thread:
  159 + # 锁表啊
  160 + ready_task: Task = sys_session.query(Task).filter_by(state=0, task_type=1).order_by(
  161 + Task.create_time).with_lockmode("update").limit(1).one_or_none()
  162 + if ready_task:
  163 +
  164 + try:
  165 + parameter = json.loads(ready_task.parameter)
  166 + StructurePrint.print("检测到入库任务")
  167 + ready_task.state = 2
  168 + ready_task.process = "入库中"
  169 + sys_session.commit()
  170 +
  171 + metas: list = json.loads(
  172 + parameter.get("meta").__str__())
  173 + parameter["meta"] = metas
  174 +
  175 + database = sys_session.query(Database).filter_by(
  176 + guid=ready_task.database_guid).one_or_none()
  177 + pg_ds: DataSource = PGUtil.open_pg_data_source(
  178 + 1, DES.decode(database.sqlalchemy_uri))
  179 +
  180 + this_task_layer = []
  181 + for meta in metas:
  182 + overwrite = parameter.get("overwrite", "no")
  183 +
  184 + for layer_name_origin, layer_name in meta.get("layer").items():
  185 + origin_name = layer_name
  186 + no = 1
  187 +
  188 + while (overwrite.__eq__("no") and pg_ds.GetLayerByName(layer_name)) or sys_session.query(InsertingLayerName).filter_by(name=layer_name).one_or_none():
  189 + layer_name = origin_name + "_{}".format(no)
  190 + no += 1
  191 +
  192 + # 添加到正在入库的列表中
  193 + iln = InsertingLayerName(guid=uuid.uuid1().__str__(),
  194 + task_guid=ready_task.guid,
  195 + name=layer_name)
  196 +
  197 + sys_session.add(iln)
  198 + sys_session.commit()
  199 + this_task_layer.append(layer_name)
  200 + # 修改表名
  201 + meta["layer"][layer_name_origin] = layer_name
  202 +
  203 + pg_ds.Destroy()
  204 + entry_data_process = multiprocessing.Process(
  205 + target=EntryDataVacuate().entry, args=(parameter,))
  206 + entry_data_process.start()
  207 + running_dict[entry_data_process] = this_task_layer
  208 + except Exception as e:
  209 + sys_session.query(Task).filter_by(guid=ready_task.guid).update(
  210 + {"state": -1, "process": "入库失败"})
  211 + sys_session.commit()
  212 + StructurePrint.print(e.__str__(), "error")
  213 + else:
  214 + # 解表啊
  215 + sys_session.commit()
  216 + except Exception as e:
  217 + sys_session.commit()
217 218 StructurePrint.print(e.__str__(), "error")
\ No newline at end of file
... ...
1   -from enum import auto
2   -from logging import error
3   -
4   -from sqlalchemy.sql.expression import false, true
5   -from app.util import BlueprintApi
6   -from app.util import BlueprintApi
7   -from flask import Blueprint, render_template, redirect, url_for, request, session, jsonify
8   -from flask_sqlalchemy import sqlalchemy
9   -from sqlalchemy import and_
10   -from .models import *
11   -from werkzeug.security import gen_salt
12   -import time
13   -from .oauth2 import authorization, myCodeIDToken, require_oauth, generate_user_info
14   -from authlib.oauth2 import OAuth2Error
15   -from authlib.integrations.flask_oauth2 import current_token
16   -from authlib.oidc.core import CodeIDToken
17   -
18   -
19   -def current_user():
20   - if 'id' in session:
21   - uid = session['id']
22   - return User.query.get(uid)
23   - return None
24   -
25   -
26   -def remove_user():
27   - user = current_user()
28   - if user:
29   - session.pop('id')
30   -
31   -
32   -def split_by_crlf(s):
33   - return [v for v in s.splitlines() if v]
34   -
35   -
36   -class DataManager(BlueprintApi):
37   - bp = Blueprint("Auth", __name__, url_prefix="/auth")
38   -
39   - # @staticmethod
40   - # @bp.route('/test', methods=('GET', 'POST'))
41   - # def Test():
42   - # res = {}
43   - # try:
44   - # res['user'] = User.query.all()
45   - # except Exception as e:
46   - # raise e
47   - # return res
48   -
49   - # @staticmethod
50   - # @bp.route('/login', methods=('GET', 'POST'))
51   - # def Login():
52   - # if request.method == 'POST':
53   - # username = request.form['username']
54   - # password = request.form['password']
55   - # user = User.query.filter_by(username=username).first()
56   - # if not user:
57   - # user = User(username=username,
58   - # password=password, role='admin')
59   - # db.session.add(user)
60   - # db.session.commit()
61   - # session['id'] = user.id
62   - # return redirect('/auth/authorize')
63   - # user = current_user()
64   - # if user:
65   - # clients = OAuth2Client.query.filter_by(user_id=user.id).all()
66   - # else:
67   - # clients = []
68   - # return render_template('auth/authorize.html', user=user, clients=clients)
69   -
70   - # @staticmethod
71   - # @bp.route('/create_client', methods=('GET', 'POST'))
72   - # def create_client():
73   - # user = current_user()
74   - # if not user:
75   - # return redirect('/auth/login')
76   - # if request.method == 'GET':
77   - # return render_template('auth/create_client.html')
78   - # form = request.form
79   - # client_id = gen_salt(24)
80   - # client = OAuth2Client(client_id=client_id, user_id=user.id)
81   - # # Mixin doesn't set the issue_at date
82   - # client.client_id_issued_at = int(time.time())
83   - # if client.token_endpoint_auth_method == 'none':
84   - # client.client_secret = ''
85   - # else:
86   - # client.client_secret = gen_salt(48)
87   - # client_metadata = {
88   - # "client_name": form["client_name"],
89   - # "client_uri": form["client_uri"],
90   - # "grant_types": split_by_crlf(form["grant_type"]),
91   - # "redirect_uris": split_by_crlf(form["redirect_uri"]),
92   - # "response_types": split_by_crlf(form["response_type"]),
93   - # "scope": form["scope"],
94   - # "token_endpoint_auth_method": form["token_endpoint_auth_method"]
95   - # }
96   - # client.set_client_metadata(client_metadata)
97   - # db.session.add(client)
98   - # db.session.commit()
99   - # return redirect('/auth/login')
100   -
101   - @staticmethod
102   - @bp.route('/authorize', methods=('GET', 'POST'))
103   - def authorize():
104   - user = current_user()
105   - if request.method == 'GET':
106   - # 没有登录,跳转到登录界面
107   - try:
108   - grant = authorization.validate_consent_request(end_user=user)
109   - except OAuth2Error as error:
110   - return jsonify(dict(error.get_body()))
111   - if not user:
112   - return render_template('auth/authorize.html', user=user, grant=grant)
113   - # return render_template('auth/login1.html', user=user, grant=grant)
114   - if not user and 'username' in request.form:
115   - username = request.form.get('username')
116   - password = request.form.get('password')
117   - user = User.query.filter_by(
118   - username=username, password=password).first()
119   - if User:
120   - session['id'] = user.id
121   - grant_user = user
122   - # if request.form['confirm']:
123   - # grant_user = user
124   - # else:
125   - # grant_user = None
126   - return authorization.create_authorization_response(grant_user=grant_user)
127   -
128   - @staticmethod
129   - @bp.route('/token', methods=['POST'])
130   - def issue_token():
131   - return authorization.create_token_response()
132   -
133   - @staticmethod
134   - @bp.route('/userinfo')
135   - @require_oauth('profile')
136   - def api_me():
137   - try:
138   - return jsonify(generate_user_info(current_token.user, current_token.scope))
139   - except error as e:
140   - return jsonify(dict(e.get_body()))
141   -
142   - @staticmethod
143   - @bp.route('/logout', methods=('GET', 'POST'))
144   - @require_oauth('profile')
145   - def logout():
146   - if current_token:
147   - remove_user()
148   - accesstoken = OAuth2Token.query.filter_by(
149   - access_token=current_token.access_token).first()
150   - try:
151   - accesstoken.revoked = True
152   - db.session.commit()
153   - except error as e:
154   - return jsonify(dict(e.get_body()))
155   - else:
156   - return jsonify({'result': False, 'message': 'access_token is null'})
157   -
158   - return jsonify({'result': True, 'message': 'logout success'})
  1 +from enum import auto
  2 +from logging import error
  3 +from flasgger import swag_from
  4 +from app.util import BlueprintApi
  5 +from app.util import BlueprintApi
  6 +from flask import Blueprint, render_template, redirect, request, session, jsonify
  7 +from sqlalchemy import and_
  8 +from .models import *
  9 +from .oauth2 import authorization, require_oauth, generate_user_info
  10 +from authlib.oauth2 import OAuth2Error
  11 +from authlib.integrations.flask_oauth2 import current_token
  12 +from . import user_create, client_create, client_query
  13 +
  14 +
  15 +def current_user():
  16 + if "id" in session:
  17 + uid = session["id"]
  18 + return User.query.get(uid)
  19 + return None
  20 +
  21 +
  22 +def remove_user():
  23 + user = current_user()
  24 + if user:
  25 + session.pop("id")
  26 +
  27 +
  28 +def split_by_crlf(s):
  29 + return [v for v in s.splitlines() if v]
  30 +
  31 +
  32 +class DataManager(BlueprintApi):
  33 + bp = Blueprint("Auth", __name__, url_prefix="/auth")
  34 +
  35 + # @staticmethod
  36 + # @bp.route("/test", methods=("GET", "POST"))
  37 + # def Test():
  38 + # res = {}
  39 + # try:
  40 + # res["user"] = User.query.all()
  41 + # except Exception as e:
  42 + # raise e
  43 + # return res
  44 +
  45 + # @staticmethod
  46 + # @bp.route("/login", methods=("GET", "POST"))
  47 + # def Login():
  48 + # if request.method == "POST":
  49 + # username = request.form["username"]
  50 + # password = request.form["password"]
  51 + # user = User.query.filter_by(username=username).first()
  52 + # if not user:
  53 + # user = User(username=username,
  54 + # password=password, role="admin")
  55 + # db.session.add(user)
  56 + # db.session.commit()
  57 + # session["id"] = user.id
  58 + # return redirect("/auth/authorize")
  59 + # user = current_user()
  60 + # if user:
  61 + # clients = OAuth2Client.query.filter_by(user_id=user.id).all()
  62 + # else:
  63 + # clients = []
  64 + # return render_template("auth/authorize.html", user=user, clients=clients)
  65 +
  66 + # @staticmethod
  67 + # @bp.route("/create_client", methods=("GET", "POST"))
  68 + # def create_client():
  69 + # user = current_user()
  70 + # if not user:
  71 + # return redirect("/auth/login")
  72 + # if request.method == "GET":
  73 + # return render_template("auth/create_client.html")
  74 + # form = request.form
  75 + # client_id = gen_salt(24)
  76 + # client = OAuth2Client(client_id=client_id, user_id=user.id)
  77 + # # Mixin doesn"t set the issue_at date
  78 + # client.client_id_issued_at = int(time.time())
  79 + # if client.token_endpoint_auth_method == "none":
  80 + # client.client_secret = ""
  81 + # else:
  82 + # client.client_secret = gen_salt(48)
  83 + # client_metadata = {
  84 + # "client_name": form["client_name"],
  85 + # "client_uri": form["client_uri"],
  86 + # "grant_types": split_by_crlf(form["grant_type"]),
  87 + # "redirect_uris": split_by_crlf(form["redirect_uri"]),
  88 + # "response_types": split_by_crlf(form["response_type"]),
  89 + # "scope": form["scope"],
  90 + # "token_endpoint_auth_method": form["token_endpoint_auth_method"]
  91 + # }
  92 + # client.set_client_metadata(client_metadata)
  93 + # db.session.add(client)
  94 + # db.session.commit()
  95 + # return redirect("/auth/login")
  96 +
  97 + @staticmethod
  98 + @bp.route("/authorize", methods=("GET", "POST"))
  99 + def authorize():
  100 + user = current_user()
  101 + if request.method == "GET":
  102 + # 没有登录,跳转到登录界面
  103 + try:
  104 + grant = authorization.validate_consent_request(end_user=user)
  105 + except OAuth2Error as error:
  106 + return jsonify(dict(error.get_body()))
  107 + if not user:
  108 + return render_template("auth/authorize.html", user=user, grant=grant)
  109 + # return render_template("auth/login1.html", user=user, grant=grant)
  110 + if not user and "username" in request.form:
  111 + username = request.form.get("username")
  112 + password = request.form.get("password")
  113 + user = User.query.filter_by(
  114 + username=username, password=password).first()
  115 + if User:
  116 + session["id"] = user.id
  117 + grant_user = user
  118 + # if request.form["confirm"]:
  119 + # grant_user = user
  120 + # else:
  121 + # grant_user = None
  122 + return authorization.create_authorization_response(grant_user=grant_user)
  123 +
  124 + @staticmethod
  125 + @bp.route("/token", methods=["POST"])
  126 + def issue_token():
  127 + return authorization.create_token_response()
  128 +
  129 + @staticmethod
  130 + @bp.route("/userinfo")
  131 + @require_oauth("profile")
  132 + def api_me():
  133 + try:
  134 + return jsonify(generate_user_info(current_token.user, current_token.scope))
  135 + except error as e:
  136 + return jsonify(dict(e.get_body()))
  137 +
  138 + @staticmethod
  139 + @bp.route("/logout", methods=["GET"])
  140 + # @require_oauth("profile")
  141 + def logout():
  142 + url=''
  143 + try:
  144 + user = current_user()
  145 + grant = authorization.validate_consent_request(end_user=user)
  146 + access_token = request.args.get("accesstoken")
  147 + accesstoken = OAuth2Token.query.filter_by(
  148 + access_token=access_token).first()
  149 + accesstoken.revoked = True
  150 + db.session.commit()
  151 + remove_user()
  152 + if accesstoken:
  153 + url =grant.client.client_uri
  154 + except OAuth2Error as error:
  155 + return jsonify(dict(error.get_body()))
  156 + return redirect(url)
  157 + # if current_token:
  158 + # remove_user()
  159 + # # accesstoken = OAuth2Token.query.filter_by(
  160 + # # access_token=current_token.access_token).first()
  161 + # try:
  162 + # # accesstoken.revoked = True
  163 + # # db.session.commit()
  164 + # except error as e:
  165 + # return jsonify(dict(e.get_body()))
  166 + # else:
  167 + # return jsonify({"result": False, "message": "access_token is null"})
  168 +
  169 + # return jsonify({"result": True, "message": "logout success"})
  170 +
  171 + """接口"""
  172 + @staticmethod
  173 + @bp.route("/user_create", methods=["POST"])
  174 + @swag_from(user_create.Api.api_doc)
  175 + def user_create():
  176 + """
  177 + 创建用户
  178 + """
  179 + return user_create.Api().result
  180 +
  181 + @staticmethod
  182 + @bp.route("/client_create", methods=["POST"])
  183 + @swag_from(client_create.Api.api_doc)
  184 + def client_create():
  185 + """
  186 + 创建client
  187 + """
  188 + return client_create.Api().result
  189 +
  190 + @staticmethod
  191 + @bp.route("/client", methods=["GET"])
  192 + @swag_from(client_query.Api.api_doc)
  193 + def client_query():
  194 + """
  195 + 获取client列表
  196 + """
  197 + return client_query.Api().result
... ...
  1 +# coding=utf-8
  2 +#author: qianyingz
  3 +#createtime: 2021/8/13
  4 +#email: qianyingz@chinadci.com
  5 +
  6 +from re import split
  7 +from .models import *
  8 +from app.util.component.ApiTemplate import ApiTemplate
  9 +from werkzeug.security import gen_salt
  10 +import time
  11 +import string
  12 +
  13 +
  14 +class Api(ApiTemplate):
  15 + api_name = "注册客户端"
  16 +
  17 + def para_check(self):
  18 + if not self.para.get("name"):
  19 + raise Exception("name is null")
  20 + if not self.para.get("uri"):
  21 + raise Exception("uri is null")
  22 + if not self.para.get("redirect_uris"):
  23 + raise Exception("redirect_uris is null")
  24 + # if not self.para.get('username'):
  25 + # raise Exception("username is null")
  26 + # if not self.para.get("scope"):
  27 + # raise Exception("scope is null")
  28 + # if not self.para.get("grant_type"):
  29 + # raise Exception("grant_type is null")
  30 + # if not self.para.get("response_type"):
  31 + # raise Exception("response_type is null")
  32 +
  33 + def process(self):
  34 +
  35 + # 返回结果
  36 + res = {}
  37 + res["result"] = False
  38 + try:
  39 + # 默认值
  40 + scope = "openid profile"
  41 + grant_type = ["authorization_code"]
  42 + response_type = ["code"]
  43 + auth_method = "client_secret_basic"
  44 + # 业务逻辑
  45 + username = self.para.get("username")
  46 + client_id = gen_salt(24)
  47 + name = self.para.get("name")
  48 + uri = self.para.get("uri")
  49 + redirect_uris = self.para.get("redirect_uris").split(",")
  50 +
  51 + if not username:
  52 + username = 'admin'
  53 + user = User.query.filter_by(username=username).first()
  54 + if not User:
  55 + res["msg"] = "username 指定用户不存在"
  56 + res["data"] = {}
  57 + res["result"] = False
  58 + else:
  59 + client = OAuth2Client(client_id=client_id, user_id=user.id)
  60 + # Mixin doesn"t set the issue_at date
  61 + client.client_id_issued_at = int(time.time())
  62 + if client.token_endpoint_auth_method == "none":
  63 + client.client_secret = ""
  64 + else:
  65 + client.client_secret = gen_salt(48)
  66 + client_metadata = {
  67 + "client_name": name,
  68 + "client_uri": uri,
  69 + "grant_types": grant_type,
  70 + "redirect_uris": redirect_uris,
  71 + "response_types": response_type,
  72 + "scope": scope,
  73 + "token_endpoint_auth_method": auth_method
  74 + }
  75 + client.set_client_metadata(client_metadata)
  76 + db.session.add(client)
  77 + db.session.commit()
  78 + res["msg"] = "创建client成功"
  79 + res["data"] = {"client_secret": client.client_secret,
  80 + "client_id": client.client_id}
  81 + res["result"] = True
  82 + except Exception as e:
  83 + db.session.rollback()
  84 + raise e
  85 + return res
  86 +
  87 + api_doc = {
  88 +
  89 + "tags": ["认证接口"],
  90 + "parameters": [
  91 + {"name": "name",
  92 + "in": "formData",
  93 + "type": "string",
  94 + "description": "客户端名称",
  95 + "required": "true"},
  96 + {"name": "uri",
  97 + "in": "formData",
  98 + "type": "string",
  99 + "description": "客户端地址,多个地址用,连接",
  100 + "required": "true"},
  101 + {"name": "redirect_uris",
  102 + "in": "formData",
  103 + "type": "string",
  104 + "description": "重定向地址",
  105 + "required": "true"},
  106 + {"name": "username",
  107 + "in": "formData",
  108 + "type": "string",
  109 + "description": "注册client账号,默认使用admin"
  110 + },
  111 + # {"name": "scope",
  112 + # "in": "formData",
  113 + # "type": "string",
  114 + # "description": "范围"},
  115 + # {"name": "grant_type",
  116 + # "in": "formData",
  117 + # "type": "string",
  118 + # "description": "授权类型: authorization_code"},
  119 + # {"name": "response_type",
  120 + # "in": "formData",
  121 + # "type": "string",
  122 + # "description": "授权类型: code"}
  123 + ],
  124 + "responses": {
  125 + 200: {
  126 + "schema": {
  127 + "properties": {
  128 + }
  129 + }
  130 + }
  131 + }
  132 + }
... ...
  1 +# coding=utf-8
  2 +#author: qianyingz
  3 +#createtime: 2021/8/13
  4 +#email: qianyingz@chinadci.com
  5 +
  6 +from .models import *
  7 +from app.util.component.ApiTemplate import ApiTemplate
  8 +from werkzeug.security import gen_salt
  9 +
  10 +class Api(ApiTemplate):
  11 + api_name = "获取client列表"
  12 +
  13 + def para_check(self):
  14 + pass
  15 +
  16 + def process(self):
  17 + # 返回结果
  18 + res = {}
  19 + res["result"] = False
  20 + res["data"] = []
  21 + try:
  22 + # 默认值
  23 + name = self.para.get("name")
  24 + if name:
  25 + clients = OAuth2Client.query.filter_by(client_name=name).all()
  26 + else:
  27 + clients = OAuth2Client.query.all()
  28 + for client in clients:
  29 + res["data"].append(
  30 + {'client_id': client.client_id,
  31 + 'client_secret': client.client_secret,
  32 + 'client_id_issued_at': client.client_id_issued_at,
  33 + 'client_secret_expires_at': client.client_secret_expires_at,
  34 + 'client_metadata': client.client_metadata,
  35 + 'id': client.id,
  36 + 'user_id': client.user_id
  37 + })
  38 + res["msg"] = "获取clients集合成功"
  39 + res["result"] = True
  40 + except Exception as e:
  41 + db.session.rollback()
  42 + raise e
  43 + return res
  44 +
  45 + api_doc = {
  46 +
  47 + "tags": ["认证接口"],
  48 + "parameters": [
  49 + {"name": "name",
  50 + "in": "formData",
  51 + "type": "string",
  52 + "description": "客户端名称"}
  53 + ],
  54 + "responses": {
  55 + 200: {
  56 + "schema": {
  57 + "properties": {
  58 + }
  59 + }
  60 + }
  61 + }
  62 + }
... ...
1   -from flask_sqlalchemy import sqlalchemy
2   -from sqlalchemy import Column, Integer, Text, Time, ForeignKey
3   -from app.models import db
4   -from authlib.integrations.sqla_oauth2 import (
5   - OAuth2ClientMixin,
6   - OAuth2TokenMixin,
7   - OAuth2AuthorizationCodeMixin
8   -)
9   -from sqlalchemy.orm import relationship
10   -
11   -
12   -class User (db.Model):
13   - '''
14   - 用户信息表
15   - '''
16   - __tablename__ = "dmdms_user"
17   - id = Column(Integer, primary_key=True)
18   - username = Column(Text)
19   - password = Column(Text)
20   - company = Column(Text)
21   - position = Column(Text)
22   - phone = Column(Text)
23   - email = Column(Text)
24   - create_time = Column(Time)
25   - update_time = Column(Time)
26   - role = Column(Text)
27   -
28   - def __str__(self):
29   - return self.username
30   -
31   - def get_user_id(self):
32   - return self.id
33   -
34   -
35   -class OAuth2Client(db.Model, OAuth2ClientMixin):
36   - __tablename__ = 'oauth2_client'
37   -
38   - id = Column(Integer, primary_key=True)
39   - user_id = Column(
40   - Integer, ForeignKey('dmdms_user.id', ondelete='CASCADE'))
41   - user = relationship('User')
42   -
43   -
44   -class OAuth2AuthorizationCode(db.Model, OAuth2AuthorizationCodeMixin):
45   - __tablename__ = 'oauth2_code'
46   -
47   - id = Column(Integer, primary_key=True)
48   - user_id = Column(
49   - Integer, ForeignKey('dmdms_user.id', ondelete='CASCADE'))
50   - user = relationship('User')
51   -
52   -
53   -class OAuth2Token(db.Model, OAuth2TokenMixin):
54   - __tablename__ = 'oauth2_token'
55   -
56   - id = Column(Integer, primary_key=True)
57   - user_id = Column(
58   - Integer, ForeignKey('dmdms_user.id', ondelete='CASCADE'))
59   - # name = Column(Text)
  1 +from flask_sqlalchemy import sqlalchemy
  2 +from sqlalchemy import Column, Integer, Text, Time, ForeignKey
  3 +from app.models import db
  4 +from authlib.integrations.sqla_oauth2 import (
  5 + OAuth2ClientMixin,
  6 + OAuth2TokenMixin,
  7 + OAuth2AuthorizationCodeMixin
  8 +)
  9 +from sqlalchemy.orm import relationship
  10 +
  11 +
  12 +class User (db.Model):
  13 + '''
  14 + 用户信息表
  15 + '''
  16 + __tablename__ = "dmdms_user"
  17 + id = Column(Integer, primary_key=True)
  18 + username = Column(Text)
  19 + password = Column(Text)
  20 + company = Column(Text)
  21 + position = Column(Text)
  22 + phone = Column(Text)
  23 + email = Column(Text)
  24 + create_time = Column(Time)
  25 + update_time = Column(Time)
  26 + role = Column(Text)
  27 +
  28 + def __str__(self):
  29 + return self.username
  30 +
  31 + def get_user_id(self):
  32 + return self.id
  33 +
  34 +
  35 +class OAuth2Client(db.Model, OAuth2ClientMixin):
  36 + __tablename__ = 'dmdms_oauth2_client'
  37 +
  38 + id = Column(Integer, primary_key=True)
  39 + user_id = Column(
  40 + Integer, ForeignKey('dmdms_user.id', ondelete='CASCADE'))
  41 + user = relationship('User')
  42 +
  43 +
  44 +class OAuth2AuthorizationCode(db.Model, OAuth2AuthorizationCodeMixin):
  45 + __tablename__ = 'dmdms_oauth2_code'
  46 +
  47 + id = Column(Integer, primary_key=True)
  48 + user_id = Column(
  49 + Integer, ForeignKey('dmdms_user.id', ondelete='CASCADE'))
  50 + user = relationship('User')
  51 +
  52 +
  53 +class OAuth2Token(db.Model, OAuth2TokenMixin):
  54 + __tablename__ = 'dmdms_oauth2_token'
  55 +
  56 + id = Column(Integer, primary_key=True)
  57 + user_id = Column(
  58 + Integer, ForeignKey('dmdms_user.id', ondelete='CASCADE'))
  59 + # name = Column(Text)
60 60 user = relationship('User')
\ No newline at end of file
... ...
  1 +# coding=utf-8
  2 +#author: qianyingz
  3 +#createtime: 2021/8/13
  4 +#email: qianyingz@chinadci.com
  5 +
  6 +from .models import *
  7 +from app.util.component.ApiTemplate import ApiTemplate
  8 +
  9 +
  10 +class Api(ApiTemplate):
  11 + api_name = "创建用户"
  12 +
  13 + def para_check(self):
  14 + if not self.para.get("username"):
  15 + raise Exception("username is null")
  16 + if not self.para.get("password"):
  17 + raise Exception("password is null")
  18 + if not self.para.get("role"):
  19 + raise Exception("role is null")
  20 +
  21 + def process(self):
  22 +
  23 + # 返回结果
  24 + res = {}
  25 + res["result"] = False
  26 + try:
  27 + # 业务逻辑
  28 + username = self.para.get("username")
  29 + password = self.para.get("password")
  30 + role = self.para.get("role")
  31 + # 是否重名
  32 + if(len(User.query.filter_by(username=username).all()) > 0):
  33 + res["msg"] = "username 已存在"
  34 + else:
  35 + user = User(username=username, password=password, role=role)
  36 + db.session.add(user)
  37 + db.session.commit()
  38 + res["msg"] = "用户创建成功"
  39 + res["data"] = {user.id, user.username, user.role}
  40 + res["result"] = True
  41 + except Exception as e:
  42 + db.session.rollback()
  43 + raise e
  44 + return res
  45 +
  46 + api_doc = {
  47 +
  48 + "tags": ["认证接口"],
  49 + "parameters": [
  50 + {"name": "username",
  51 + "in": "formData",
  52 + "type": "string",
  53 + "description": "用户名",
  54 + "required": "true"},
  55 + {"name": "password",
  56 + "in": "formData",
  57 + "type": "string",
  58 + "description": "密码",
  59 + "required": "true"},
  60 + {"name": "role",
  61 + "in": "formData",
  62 + "type": "string",
  63 + "description": "角色",
  64 + "required": "true"}
  65 + ],
  66 + "responses": {
  67 + 200: {
  68 + "schema": {
  69 + "properties": {
  70 + }
  71 + }
  72 + }
  73 + }
  74 + }
... ...
1   -# coding=utf-8
2   -
3   -# 程序部署ip:host
4   -deploy_ip_host = "172.26.99.160:8840"
5   -# 系统数据库
6   -
7   -SQLALCHEMY_DATABASE_URI = "postgresql://postgres:postgres@172.26.40.254:5433/dmap_dms_test"
8   -# SQLALCHEMY_DATABASE_URI = "postgresql://postgres:chinadci@172.26.99.160:5432/dmap_dms_test"
9   -
10   -
11   -# 部署模式cluster,standalone
12   -deployment_mode = "cluster"
13   -# 部署模式味cluster时有用,master,slave
14   -application_name = "master"
15   -
16   -zookeeper = "172.26.99.168:2181"
17   -
18   -# 固定配置不需要修改
19   -swagger_configure = {"title": "DMapManager"}
20   -entry_data_thread = 3
21   -scan_module = ["app.modules"] # API所在的模块
22   -SECRET_KEY = b'_5#y2L"F4Q8z\n\xec]/'
  1 +# coding=utf-8
  2 +
  3 +# 程序部署ip:host
  4 +deploy_ip_host = "172.26.99.160:8840"
  5 +# 系统数据库
  6 +
  7 +SQLALCHEMY_DATABASE_URI = "postgresql://postgres:postgres@172.26.40.254:5433/dmap_dms_test1"
  8 +# SQLALCHEMY_DATABASE_URI = "postgresql://postgres:chinadci@172.26.99.160:5432/dmap_dms_test"
  9 +
  10 +
  11 +# 部署模式cluster,standalone
  12 +deployment_mode = "cluster"
  13 +# 部署模式味cluster时有用,master,slave
  14 +application_name = "master"
  15 +
  16 +zookeeper = "172.26.99.168:2181"
  17 +
  18 +# 固定配置不需要修改
  19 +swagger_configure = {"title": "DMapManager"}
  20 +entry_data_thread = 3
  21 +scan_module = ["app.modules"] # API所在的模块
  22 +SECRET_KEY = b'_5#y2L"F4Q8z\n\xec]/'
... ...
1   -# coding=utf-8
2   -from flask import Flask
3   -from app import create_app
4   -app: Flask = create_app()
5   -if __name__ == '__main__':
6   - app.run(host="0.0.0.0", port="8840", threaded=True, debug=True)
7   - # app.run(host="0.0.0.0", port="8840", threaded=True)
  1 +# coding=utf-8
  2 +from flask import Flask
  3 +from app import create_app
  4 +import os
  5 +os.environ
  6 +app: Flask = create_app()
  7 +if __name__ == '__main__':
  8 + app.run(host="0.0.0.0", port="8840", threaded=True, debug=True)
  9 + # app.run(host="0.0.0.0", port="8840", threaded=True)
... ...
注册登录 后发表评论