正在显示
8 个修改的文件
包含
772 行增加
和
462 行删除
| 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 | ... | ... |
app/modules/auth/client_create.py
0 → 100644
| 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 | + } | ... | ... |
app/modules/auth/client_query.py
0 → 100644
| 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 | ... | ... |
app/modules/auth/user_create.py
0 → 100644
| 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) | ... | ... |
请
注册
或
登录
后发表评论