提交 f1f7116b2acda9b224204094c738ec39c5e01bef

作者 nheweijun
2 个父辈 6c8be461 c5800678

merge

DMapManager @ 8e446e18
1   -Subproject commit 8e446e18a7a81ea282d05f6026f4d41d5dae1378
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   -import configure
8   -from app.util import BlueprintApi
9   -from app.util import find_class
10   -from app.models import db, Table, InsertingLayerName, Database, DES, Task
11   -from app.modules.auth.oauth2 import config_oauth
12   -from flasgger import Swagger
13   -# from rtree import index
14   -import logging
15   -from sqlalchemy.orm import Session
16   -import multiprocessing
17   -from app.util.component.EntryData import EntryData
18   -from app.util.component.EntryDataVacuate import EntryDataVacuate
19   -import json
20   -import threading
21   -import traceback
22   -from sqlalchemy import distinct
23   -import uuid
24   -from osgeo.ogr import DataSource
25   -import datetime
26   -from sqlalchemy import or_
27   -from app.util.component.StructuredPrint import StructurePrint
28   -from app.util.component.PGUtil import PGUtil
29   -import os
30   -
31   -class JSONEncoder(_JSONEncoder):
32   - """
33   - 因为decimal不能序列化,增加Flask对decimal类的解析
34   - """
35   - def default(self, o):
36   - if isinstance(o, decimal.Decimal):
37   - return float(o)
38   - super(JSONEncoder, self).default(o)
39   -
40   -
41   -class Flask(_Flask):
42   - json_encoder = JSONEncoder
43   -
44   -
45   -GLOBAL_DIC={}
46   -def create_app():
47   - """
48   - flask应用创建函数
49   - :return:app,flask实例
50   - """
51   -
52   - # app基本设置
53   - app = Flask(__name__)
54   - app.config['SQLALCHEMY_DATABASE_URI'] = configure.SQLALCHEMY_DATABASE_URI
55   - app.config['echo'] = True
56   - app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
57   - app.config['JSON_AS_ASCII'] = False
58   - app.config['SECRET_KEY'] = configure.SECRET_KEY
59   - app.config['OAUTH2_JWT_ENABLED'] = True
60   -
61   - app.config['OAUTH2_JWT_ISS'] = 'http://localhost:5000'
62   - app.config['OAUTH2_JWT_KEY'] = 'secret-key'
63   - app.config['OAUTH2_JWT_ALG'] = 'HS256'
64   - # app.config['SQLALCHEMY_ECHO'] = True
65   -
66   - # 跨域设置
67   - CORS(app)
68   -
69   - # swagger设置
70   - swagger_config = Swagger.DEFAULT_CONFIG
71   - swagger_config.update(configure.swagger_configure)
72   - Swagger(app, config=swagger_config)
73   -
74   - # 创建数据库
75   - db.init_app(app)
76   - db.create_all(app=app)
77   -
78   - # 日志
79   - logging.basicConfig(level=logging.INFO)
80   - log_file = os.path.join(os.path.dirname(os.path.dirname(
81   - os.path.realpath(__file__))), "logs", "log.txt")
82   - handler = logging.FileHandler(
83   - log_file, encoding='UTF-8') # 设置日志字符集和存储路径名字
84   - logging_format = logging.Formatter(
85   - '[%(levelname)s] %(asctime)s %(message)s')
86   - handler.setFormatter(logging_format)
87   - app.logger.addHandler(handler)
88   -
89   - # 配置使用鉴权组件,不写无法认证授权
90   - config_oauth(app)
91   -
92   - # 注册blueprint,查找BlueprintApi的子类
93   - for scan in configure.scan_module:
94   - for api in find_class(scan, BlueprintApi):
95   - app.register_blueprint(api.bp)
96   -
97   - # 入库监测线程
98   -
99   - @app.before_first_request
100   - def data_entry_process():
101   - StructurePrint.print("start listen")
102   - process = threading.Thread(target=data_entry_center)
103   - process.start()
104   -
105   - # 不检测https
106   - os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
107   -
108   - # 上下文全局变量字典
109   - global GLOBAL_DIC
110   -
111   - return app
112   -
113   -
114   -def data_entry_center():
115   - running_dict = {}
116   - sys_session: Session = PGUtil.get_db_session(
117   - configure.SQLALCHEMY_DATABASE_URI)
118   -
119   - while True:
120   -
121   - try:
122   - time.sleep(3)
123   -
124   - # 已经结束的进程 从监测中删除
125   - remove_process = []
126   -
127   - # structured_print(running_dict.__len__().__str__())
128   -
129   - for process, layer_names in running_dict.items():
130   - if not process.is_alive():
131   - for l in layer_names:
132   - inserted = sys_session.query(
133   - InsertingLayerName).filter_by(name=l).one_or_none()
134   - if inserted:
135   - sys_session.delete(inserted)
136   - sys_session.commit()
137   - remove_process.append(process)
138   - for process in remove_process:
139   - running_dict.pop(process)
140   -
141   - # StructurePrint.print("listening...")
142   -
143   - # 入库进程少于阈值,开启入库进程
144   -
145   - inter_size = sys_session.query(
146   - distinct(InsertingLayerName.task_guid)).count()
147   -
148   - if inter_size < configure.entry_data_thread:
149   - # 锁表啊
150   - ready_task:Task = sys_session.query(Task).filter_by(state=0,task_type=1).order_by(Task.create_time).with_lockmode("update").limit(1).one_or_none()
151   - if ready_task:
152   -
153   - try:
154   - parameter = json.loads(ready_task.parameter)
155   - StructurePrint.print("检测到入库任务")
156   - ready_task.state = 2
157   - ready_task.process = "入库中"
158   - sys_session.commit()
159   -
160   - metas: list = json.loads(
161   - parameter.get("meta").__str__())
162   - parameter["meta"] = metas
163   -
164   - database = sys_session.query(Database).filter_by(
165   - guid=ready_task.database_guid).one_or_none()
166   - pg_ds: DataSource = PGUtil.open_pg_data_source(
167   - 1, DES.decode(database.sqlalchemy_uri))
168   -
169   - this_task_layer = []
170   - for meta in metas:
171   - overwrite = parameter.get("overwrite", "no")
172   -
173   - for layer_name_origin, layer_name in meta.get("layer").items():
174   - origin_name = layer_name
175   - no = 1
176   -
177   - while (overwrite.__eq__("no") and pg_ds.GetLayerByName(layer_name)) or sys_session.query(InsertingLayerName).filter_by(name=layer_name).one_or_none():
178   - layer_name = origin_name + "_{}".format(no)
179   - no += 1
180   -
181   - # 添加到正在入库的列表中
182   - iln = InsertingLayerName(guid=uuid.uuid1().__str__(),
183   - task_guid=ready_task.guid,
184   - name=layer_name)
185   -
186   - sys_session.add(iln)
187   - sys_session.commit()
188   - this_task_layer.append(layer_name)
189   - # 修改表名
190   - meta["layer"][layer_name_origin] = layer_name
191   -
192   - pg_ds.Destroy()
193   - entry_data_process = multiprocessing.Process(
194   - target=EntryDataVacuate().entry, args=(parameter,))
195   - entry_data_process.start()
196   - running_dict[entry_data_process] = this_task_layer
197   - except Exception as e:
198   - sys_session.query(Task).filter_by(guid=ready_task.guid).update(
199   - {"state": -1, "process": "入库失败"})
200   - sys_session.commit()
201   - StructurePrint.print(e.__str__(), "error")
202   - else:
203   - # 解表啊
204   - sys_session.commit()
205   - except Exception as e:
206   - sys_session.commit()
207   - StructurePrint.print(e.__str__(), "error")
  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()
  218 + StructurePrint.print(e.__str__(), "error")
\ No newline at end of file
... ...
1   -from app.util import BlueprintApi
2   -from app.util import BlueprintApi
3   -from flask import Blueprint, render_template, redirect, url_for, request, session, jsonify
4   -from flask_sqlalchemy import sqlalchemy
5   -from sqlalchemy import and_
6   -from .models import *
7   -from werkzeug.security import gen_salt
8   -import time
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   -
13   -
14   -def current_user():
15   - if 'id' in session:
16   - uid = session['id']
17   - return User.query.get(uid)
18   - return None
19   -
20   -
21   -def split_by_crlf(s):
22   - return [v for v in s.splitlines() if v]
23   -
24   -
25   -class DataManager(BlueprintApi):
26   - bp = Blueprint("Auth", __name__, url_prefix="/auth")
27   -
28   - # @staticmethod
29   - # @bp.route('/test', methods=('GET', 'POST'))
30   - # def Test():
31   - # res = {}
32   - # try:
33   - # res['user'] = User.query.all()
34   - # except Exception as e:
35   - # raise e
36   - # return res
37   -
38   - # @staticmethod
39   - # @bp.route('/login', methods=('GET', 'POST'))
40   - # def Login():
41   - # if request.method == 'POST':
42   - # username = request.form['username']
43   - # password = request.form['password']
44   - # user = User.query.filter_by(username=username).first()
45   - # if not user:
46   - # user = User(username=username,
47   - # password=password, role='admin')
48   - # db.session.add(user)
49   - # db.session.commit()
50   - # session['id'] = user.id
51   - # return redirect('/auth/authorize')
52   - # user = current_user()
53   - # if user:
54   - # clients = OAuth2Client.query.filter_by(user_id=user.id).all()
55   - # else:
56   - # clients = []
57   - # return render_template('auth/authorize.html', user=user, clients=clients)
58   -
59   - # @staticmethod
60   - # @bp.route('/create_client', methods=('GET', 'POST'))
61   - # def create_client():
62   - # user = current_user()
63   - # if not user:
64   - # return redirect('/auth/login')
65   - # if request.method == 'GET':
66   - # return render_template('auth/create_client.html')
67   - # form = request.form
68   - # client_id = gen_salt(24)
69   - # client = OAuth2Client(client_id=client_id, user_id=user.id)
70   - # # Mixin doesn't set the issue_at date
71   - # client.client_id_issued_at = int(time.time())
72   - # if client.token_endpoint_auth_method == 'none':
73   - # client.client_secret = ''
74   - # else:
75   - # client.client_secret = gen_salt(48)
76   - # client_metadata = {
77   - # "client_name": form["client_name"],
78   - # "client_uri": form["client_uri"],
79   - # "grant_types": split_by_crlf(form["grant_type"]),
80   - # "redirect_uris": split_by_crlf(form["redirect_uri"]),
81   - # "response_types": split_by_crlf(form["response_type"]),
82   - # "scope": form["scope"],
83   - # "token_endpoint_auth_method": form["token_endpoint_auth_method"]
84   - # }
85   - # client.set_client_metadata(client_metadata)
86   - # db.session.add(client)
87   - # db.session.commit()
88   - # return redirect('/auth/login')
89   -
90   - @staticmethod
91   - @bp.route('/authorize', methods=('GET', 'POST'))
92   - def authorize():
93   - user = current_user()
94   - if request.method == 'GET':
95   - try:
96   - grant = authorization.validate_consent_request(end_user=user)
97   - except OAuth2Error as error:
98   - return jsonify(dict(error.get_body()))
99   - return render_template('auth/authorize.html', user=user, grant=grant)
100   - # return render_template('auth/login1.html', user=user, grant=grant)
101   - if not user and 'username' in request.form:
102   - username = request.form.get('username')
103   - password = request.form.get('password')
104   - user = User.query.filter_by(
105   - username=username, password=password).first()
106   - grant_user = user
107   - # if request.form['confirm']:
108   - # grant_user = user
109   - # else:
110   - # grant_user = None
111   - return authorization.create_authorization_response(grant_user=grant_user)
112   -
113   - @staticmethod
114   - @bp.route('/token', methods=['POST'])
115   - def issue_token():
116   - return authorization.create_token_response()
117   -
118   - @staticmethod
119   - @bp.route('/userinfo')
120   - @require_oauth('profile')
121   - def api_me():
122   - return jsonify(generate_user_info(current_token.user, current_token.scope))
  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, user_query, user_update, user_delete
  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 + error = ""
  111 + if not user:
  112 + if not "username" in request.form or not request.form.get("username"):
  113 + error = "用户名不可为空"
  114 + elif not "password" in request.form or not request.form.get("password"):
  115 + error = "密码不可为空"
  116 + else:
  117 + username = request.form.get("username")
  118 + password = request.form.get("password")
  119 + user = User.query.filter_by(
  120 + username=username, password=password).first()
  121 + if not user:
  122 + error = "账号或密码不正确"
  123 +
  124 + if user:
  125 + session["id"] = user.id
  126 + grant_user = user
  127 + return authorization.create_authorization_response(grant_user=grant_user)
  128 +
  129 + try:
  130 + grant = authorization.validate_consent_request(end_user=user)
  131 + except OAuth2Error as error:
  132 + return jsonify(dict(error.get_body()))
  133 + return render_template("auth/authorize.html", user=user, grant=grant, error=error)
  134 +
  135 + # if request.form["confirm"]:
  136 + # grant_user = user
  137 + # else:
  138 + # grant_user = None
  139 +
  140 + @staticmethod
  141 + @bp.route("/token", methods=["POST"])
  142 + def issue_token():
  143 + return authorization.create_token_response()
  144 +
  145 + @staticmethod
  146 + @bp.route("/userinfo")
  147 + @require_oauth("profile")
  148 + def api_me():
  149 + try:
  150 + return jsonify(generate_user_info(current_token.user, current_token.scope))
  151 + except error as e:
  152 + return jsonify(dict(e.get_body()))
  153 +
  154 + @staticmethod
  155 + @bp.route("/logout", methods=["GET"])
  156 + # @require_oauth("profile")
  157 + def logout():
  158 + url = ''
  159 + try:
  160 + user = current_user()
  161 + grant = authorization.validate_consent_request(end_user=user)
  162 + access_token = request.args.get("accesstoken")
  163 + accesstoken = OAuth2Token.query.filter_by(
  164 + access_token=access_token).first()
  165 + accesstoken.revoked = True
  166 + db.session.commit()
  167 + remove_user()
  168 + if accesstoken:
  169 + url = grant.client.client_uri
  170 + except OAuth2Error as error:
  171 + return jsonify(dict(error.get_body()))
  172 + return redirect(url)
  173 + # if current_token:
  174 + # remove_user()
  175 + # # accesstoken = OAuth2Token.query.filter_by(
  176 + # # access_token=current_token.access_token).first()
  177 + # try:
  178 + # # accesstoken.revoked = True
  179 + # # db.session.commit()
  180 + # except error as e:
  181 + # return jsonify(dict(e.get_body()))
  182 + # else:
  183 + # return jsonify({"result": False, "message": "access_token is null"})
  184 +
  185 + # return jsonify({"result": True, "message": "logout success"})
  186 +
  187 + """接口"""
  188 + @staticmethod
  189 + @bp.route("/users", methods=["GET"])
  190 + @swag_from(user_query.Api.api_doc)
  191 + def user_query():
  192 + """
  193 + 获取用户列表
  194 + """
  195 + return user_query.Api().result
  196 +
  197 + @staticmethod
  198 + @bp.route("/users", methods=["POST"])
  199 + @swag_from(user_create.Api.api_doc)
  200 + def user_create():
  201 + """
  202 + 创建用户
  203 + """
  204 + return user_create.Api().result
  205 +
  206 + @staticmethod
  207 + @bp.route("/userEdit", methods=["POST"])
  208 + @swag_from(user_update.Api.api_doc)
  209 + def user_update():
  210 + """
  211 + 更新用户信息
  212 + """
  213 + return user_update.Api().result
  214 +
  215 + @staticmethod
  216 + @bp.route("/userDelete", methods=["POST"])
  217 + @swag_from(user_delete.Api.api_doc)
  218 + def user_delete():
  219 + """
  220 + 删除用户
  221 + """
  222 + return user_delete.Api().result
  223 +
  224 + @staticmethod
  225 + @bp.route("/client", methods=["POST"])
  226 + @swag_from(client_create.Api.api_doc)
  227 + def client_create():
  228 + """
  229 + 创建client
  230 + """
  231 + return client_create.Api().result
  232 +
  233 + @staticmethod
  234 + @bp.route("/client", methods=["GET"])
  235 + @swag_from(client_query.Api.api_doc)
  236 + def client_query():
  237 + """
  238 + 获取client列表
  239 + """
  240 + 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   - user = relationship('User')
  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 + user = relationship('User')
\ No newline at end of file
... ...
  1 +from os import access, remove
  2 +from time import time
1 3 from authlib.integrations.flask_oauth2 import (
2 4 AuthorizationServer, ResourceProtector)
3 5 from authlib.integrations.sqla_oauth2 import (
... ... @@ -13,11 +15,12 @@ from authlib.oidc.core.grants import (
13 15 OpenIDImplicitGrant as _OpenIDImplicitGrant,
14 16 OpenIDHybridGrant as _OpenIDHybridGrant,
15 17 )
16   -from authlib.oidc.core import UserInfo
  18 +from authlib.oidc.core import UserInfo, CodeIDToken, IDToken
  19 +from sqlalchemy.sql.sqltypes import DateTime
17 20 from werkzeug.security import gen_salt
18 21 from .models import db, User
19 22 from .models import OAuth2Client, OAuth2AuthorizationCode, OAuth2Token
20   -
  23 +from flask import g
21 24
22 25 DUMMY_JWT_CONFIG = {
23 26 'key': 'secret-key',
... ... @@ -26,6 +29,17 @@ DUMMY_JWT_CONFIG = {
26 29 'exp': 7200,
27 30 }
28 31
  32 +class myCodeIDToken(CodeIDToken):
  33 + def validate(self, now, leeway):
  34 + return super().validate(now=now, leeway=leeway)
  35 +
  36 + def validate_exp(self, now, leeway):
  37 + return super().validate_exp(now, leeway)
  38 +
  39 +
  40 +def validate_token(accesstoken):
  41 + return IDToken.validate(self=accesstoken)
  42 +
29 43
30 44 def exists_nonce(nonce, req):
31 45 exists = OAuth2AuthorizationCode.query.filter_by(
... ... @@ -119,11 +133,12 @@ def config_oauth(app):
119 133 app,
120 134 query_client=query_client,
121 135 save_token=save_token
  136 + # fetch_token=fetch_token
122 137 )
123 138
124 139 # support all openid grants
125 140 authorization.register_grant(AuthorizationCodeGrant, [
126   - OpenIDCode(require_nonce=True),
  141 + OpenIDCode(require_nonce=True)
127 142 ])
128 143 authorization.register_grant(ImplicitGrant)
129 144 authorization.register_grant(HybridGrant)
... ...
  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 +import time
  9 +
  10 +
  11 +class Api(ApiTemplate):
  12 + api_name = "创建用户"
  13 +
  14 + def para_check(self):
  15 + if not self.para.get("username"):
  16 + raise Exception("username is null")
  17 + if not self.para.get("pwd"):
  18 + raise Exception("pwd is null")
  19 + if not self.para.get("role"):
  20 + raise Exception("role is null")
  21 +
  22 + def process(self):
  23 +
  24 + # 返回结果
  25 + res = {}
  26 + res["result"] = False
  27 + try:
  28 + # 业务逻辑
  29 + username = self.para.get("username")
  30 + password = self.para.get("pwd")
  31 + role = self.para.get("role")
  32 + company = self.para.get("company", None)
  33 + position = self.para.get("position", None)
  34 + email = self.para.get("email", None)
  35 + phone = self.para.get("phone", None)
  36 + # 是否重名
  37 + if(User.query.filter_by(username=username).one_or_none()):
  38 + res["msg"] = "username 已存在"
  39 + else:
  40 + user = User(username=username, password=password, role=role,
  41 + phone=phone, company=company, position=position, email=email,
  42 + create_time=time.strftime(
  43 + "%Y-%m-%d %H:%M:%S", time.localtime()),
  44 + update_time=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
  45 + db.session.add(user)
  46 + db.session.commit()
  47 + res["msg"] = "用户创建成功"
  48 + res["data"] = {"id": user.id,
  49 + "username": user.username, "role": user.role}
  50 + res["result"] = True
  51 + except Exception as e:
  52 + db.session.rollback()
  53 + raise e
  54 + return res
  55 +
  56 + api_doc = {
  57 +
  58 + "tags": ["认证接口"],
  59 + "parameters": [
  60 + {"name": "username",
  61 + "in": "formData",
  62 + "type": "string",
  63 + "description": "用户名",
  64 + "required": "true"},
  65 + {"name": "pwd",
  66 + "in": "formData",
  67 + "type": "string",
  68 + "description": "密码",
  69 + "required": "true"},
  70 + {"name": "role",
  71 + "in": "formData",
  72 + "type": "string",
  73 + "description": "角色",
  74 + "required": "true"},
  75 + {"name": "company",
  76 + "in": "formData",
  77 + "type": "string",
  78 + "description": "单位",
  79 + "required": ""},
  80 + {"name": "email",
  81 + "in": "formData",
  82 + "type": "string",
  83 + "description": "邮件",
  84 + "required": ""},
  85 + {"name": "phone",
  86 + "in": "formData",
  87 + "type": "string",
  88 + "description": "电话",
  89 + "required": ""},
  90 + {"name": "position",
  91 + "in": "formData",
  92 + "type": "string",
  93 + "description": "职位",
  94 + "required": ""},
  95 + ],
  96 + "responses": {
  97 + 200: {
  98 + "schema": {
  99 + "properties": {
  100 + }
  101 + }
  102 + }
  103 + }
  104 + }
... ...
  1 +from app.util.component.ApiTemplate import ApiTemplate
  2 +import time
  3 +from .models import *
  4 +
  5 +
  6 +class Api(ApiTemplate):
  7 + api_name = "更新用户信息"
  8 +
  9 + def para_check(self):
  10 + if not self.para.get("guid"):
  11 + raise Exception("guid is null")
  12 + return super().para_check()
  13 +
  14 + def process(self):
  15 + res = {}
  16 + res["result"] = False
  17 + try:
  18 + user_guid = int(self.para.get("guid"))
  19 + userinfo = User.query.filter_by(id=user_guid).one_or_none()
  20 + if not userinfo:
  21 + res["msg"] = "用户不存在"
  22 + else:
  23 + db.session.delete(userinfo)
  24 + db.session.commit()
  25 + res["result"] = True
  26 + res["msg"] = "删除用户成功"
  27 + except Exception as e:
  28 + db.session.rollback()
  29 + raise e
  30 + return res
  31 +
  32 + api_doc = {
  33 + "tags": ["认证接口"],
  34 + "parameters": [
  35 + {"name": "guid",
  36 + "in": "formData",
  37 + "type": "string",
  38 + "description": "用户id",
  39 + "required": "true"}
  40 + ],
  41 + "responses": {
  42 + 200: {
  43 + "schema": {
  44 + "properties": {
  45 + }
  46 + }
  47 + }
  48 + }
  49 + }
... ...
  1 +# coding=utf-8
  2 +#author: qianyingz
  3 +#createtime: 2021/8/14
  4 +#email: qianyingz@chinadci.com
  5 +
  6 +from authlib.oidc.core.claims import UserInfo
  7 +from .models import *
  8 +from app.util.component.ApiTemplate import ApiTemplate
  9 +
  10 +
  11 +class Api(ApiTemplate):
  12 + api_name = "获取用户列表"
  13 +
  14 + def para_check(self):
  15 + pass
  16 +
  17 + def process(self):
  18 + # 返回结果
  19 + res = {}
  20 + res["result"] = False
  21 + try:
  22 + # 业务逻辑
  23 + pass
  24 + page_index = int(self.para.get("page_index", "0"))
  25 + page_size = int(self.para.get("page_size", "1000"))
  26 + name = self.para.get("name")
  27 + id = self.para.get('guid')
  28 +
  29 + if id:
  30 + tmp_user = User.query.filter_by(id=id).first()
  31 + res["data"] = {"guid": tmp_user.id, "username": tmp_user.username,
  32 + "role": tmp_user.role, "company": tmp_user.company,
  33 + "position": tmp_user.position, "email": tmp_user.email,
  34 + "phone": tmp_user.phone}
  35 + else:
  36 + # 获取集合
  37 + userLinq = User.query.order_by(User.id.desc())
  38 + if name:
  39 + userLinq = userLinq.filter(
  40 + User.username.like("%" + name + "%"))
  41 + tmp_count = userLinq.count()
  42 + tmp_list = userLinq.limit(page_size).offset(
  43 + page_index * page_size).all()
  44 + res["data"] = {
  45 + "count": tmp_count,
  46 + "list": list(map(lambda t:
  47 + {"guid": t.id, "username": t.username,
  48 + "role": t.role},
  49 + tmp_list))}
  50 + res["result"] = True
  51 +
  52 + except Exception as e:
  53 + raise e
  54 + return res
  55 +
  56 + api_doc = {
  57 +
  58 + "tags": ["认证接口"],
  59 + "parameters": [
  60 + {"name": "page_index",
  61 + "in": "query",
  62 + "type": "int",
  63 + "description": "当前页",
  64 + "default": 0},
  65 + {"name": "page_size",
  66 + "in": "query",
  67 + "type": "int",
  68 + "description": "条数",
  69 + "default": 1000},
  70 + {"name": "name",
  71 + "in": "query",
  72 + "type": "string",
  73 + "description": "名称关键字"},
  74 + {"name": "guid",
  75 + "in": "query",
  76 + "type": "string",
  77 + "description": "用户id,用于获取用户信息"}
  78 + ],
  79 + "responses": {
  80 + 200: {
  81 + "schema": {
  82 + "properties": {
  83 + }
  84 + }
  85 + }
  86 + }
  87 + }
... ...
  1 +from app.util.component.ApiTemplate import ApiTemplate
  2 +import time
  3 +from .models import *
  4 +
  5 +
  6 +class Api(ApiTemplate):
  7 + api_name = "更新用户信息"
  8 +
  9 + def para_check(self):
  10 + if not self.para.get("guid"):
  11 + raise Exception("guid is null")
  12 + return super().para_check()
  13 +
  14 + def process(self):
  15 + res = {}
  16 + res["result"] = False
  17 + try:
  18 + user_guid = int(self.para.get("guid"))
  19 + obj_value = {"company": "company", "email": "email",
  20 + "position": "position", "phone": "phone"}
  21 +
  22 + userinfo = User.query.filter_by(id=user_guid)
  23 + if not userinfo.one_or_none():
  24 + res["msg"] = "数据不存在"
  25 + else:
  26 + # 更新密码要求同时输入pwd/newPwd/reNewPwd
  27 + if self.para.__contains__("pwd") or self.para.__contains__("newPwd") or self.para.__contains__("reNewPwd"):
  28 + password = self.para.get("pwd")
  29 + new_password = self.para.get("newPwd")
  30 + re_new_password = self.para.get("reNewPwd")
  31 +
  32 + # validate pwd
  33 + if not password:
  34 + res["result"] = False
  35 + res["msg"] = "无原密码"
  36 + return res
  37 + if new_password != re_new_password:
  38 + res["result"] = False
  39 + res["msg"] = "两次输入密码不一致"
  40 + return res
  41 + if userinfo.first().password != password:
  42 + res["result"] = False
  43 + res["msg"] = "原密码输入错误"
  44 + return res
  45 +
  46 + # 更新密码
  47 + userinfo.update({"password": new_password})
  48 +
  49 + #更新用户基本信息
  50 + for key in obj_value:
  51 + if self.para.__contains__(obj_value[key]):
  52 + value = self.para.get(obj_value[key])
  53 + value = "" if value == "None" or value == "none" else value
  54 + userinfo.update({key: value})
  55 +
  56 + db.session.commit()
  57 + res["result"] = True
  58 + res["msg"] = "更新用户信息成功"
  59 + except Exception as e:
  60 + db.session.rollback()
  61 + raise e
  62 + return res
  63 +
  64 + api_doc = {
  65 + "tags": ["认证接口"],
  66 + "parameters": [
  67 + {"name": "guid",
  68 + "in": "formData",
  69 + "type": "string",
  70 + "description": "用户id",
  71 + "required": "true"},
  72 + {"name": "pwd",
  73 + "in": "formData",
  74 + "type": "string",
  75 + "description": "密码",
  76 + "required": ""},
  77 + {"name": "newPwd",
  78 + "in": "formData",
  79 + "type": "string",
  80 + "description": "密码",
  81 + "required": ""},
  82 + {"name": "reNewPwd",
  83 + "in": "formData",
  84 + "type": "string",
  85 + "description": "密码",
  86 + "required": ""},
  87 + {"name": "company",
  88 + "in": "formData",
  89 + "type": "string",
  90 + "description": "单位",
  91 + "required": ""},
  92 + {"name": "email",
  93 + "in": "formData",
  94 + "type": "string",
  95 + "description": "邮件",
  96 + "required": ""},
  97 + {"name": "phone",
  98 + "in": "formData",
  99 + "type": "string",
  100 + "description": "电话",
  101 + "required": ""},
  102 + {"name": "position",
  103 + "in": "formData",
  104 + "type": "string",
  105 + "description": "职位",
  106 + "required": ""},
  107 + ],
  108 + "responses": {
  109 + 200: {
  110 + "schema": {
  111 + "properties": {
  112 + }
  113 + }
  114 + }
  115 + }
  116 + }
... ...
1   -html,
2   -body {
3   - font-family: Microsoft YaHei Regular, Microsoft YaHei Regular-Regular;
4   -}
5   -
6   -html,
7   -body,
8   -p,
9   -input {
10   - margin: 0;
11   - padding: 0;
12   -}
13   -
14   -.login {
15   - background: url(../images/login_background.png) no-repeat;
16   - background-size: 100% 100%;
17   - width: 100%;
18   - height: 100%;
19   - position: relative;
20   -}
21   -
22   -.login-container {
23   - position: absolute;
24   - top: -50px;
25   - bottom: 0;
26   - left: 0;
27   - right: 0;
28   - margin: auto;
29   - width: 900px;
30   - height: 454px;
31   - background: #ffffff;
32   - border-radius: 4px;
33   - box-shadow: 2px 0 21px 0 rgba(38, 106, 184, 0.53);
34   -}
35   -
36   -.login-container-logo {
37   - margin: 0;
38   - background: url(../images/login_logo.png) no-repeat;
39   - width: 401px;
40   - height: 455px;
41   - overflow: hidden;
42   - float: left;
43   -}
44   -
45   -.login-container-header {
46   - font-size: 22px;
47   - font-weight: 700;
48   - text-align: left;
49   - color: #545454;
50   - letter-spacing: 1px;
51   - text-align: center;
52   - margin-bottom: 54px;
53   -}
54   -
55   -.login-container-form {
56   - margin-left: 401px;
57   - height: 100%;
58   - padding: 80px;
59   -}
60   -
61   -.login-container-form .form-group {
62   - width: 296px;
63   - margin: 0 auto;
64   - margin-top: 22px;
65   -}
66   -
67   -.login-container-form .has-feedback.feedback-left .form-control-feedback {
68   - left: 0;
69   - right: auto;
70   - width: 38px;
71   - height: 45px;
72   - line-height: 45px;
73   - z-index: 4;
74   - color: #dcdcdc;
75   - font-size: 16px;
76   -}
77   -
78   -.login-container-form .has-feedback.feedback-left .micons-pwd {
79   - font-size: 18px;
80   - line-height: 48px;
81   -}
82   -
83   -.login-container-form .has-feedback.feedback-left .form-control {
84   - padding-left: 38px;
85   - padding-right: 12px;
86   - border: 1px solid #ebebeb;
87   - border-radius: 4px;
88   - height: 45px;
89   - color: #999;
90   - font-size: 16px;
91   - letter-spacing: 1px;
92   -}
93   -
94   -.login-container-form .has-feedback.feedback-left .form-control:hover,
95   -.login-container-form .has-feedback.feedback-left .form-control:hover,
96   -.login-container-form .has-feedback.feedback-left .form-control:focus {
97   - border: 1px solid #3081c3;
98   - outline: unset;
99   - box-shadow: unset;
100   -}
101   -
102   -.login-container-form .overhidden {
103   - padding-left: 24px;
104   - font-size: 14px;
105   - color: #999999;
106   - vertical-align: bottom;
107   - line-height: 18px;
108   -}
109   -
110   -.login-container-form .overhidden:hover {
111   - color: #3081c3;
112   -}
113   -
114   -.login-container-form .ftdms-checkbox span::before {
115   - height: 15px;
116   - width: 15px;
117   - border-width: 1px;
118   - top: 2px;
119   -}
120   -
121   -#btn-login {
122   - background: #3081c3;
123   - height: 45px;
124   - font-size: 16px;
125   - font-weight: 400;
126   - color: #ffffff;
127   - letter-spacing: 1px;
128   -}
129   -
130   -#btn-login:hover {
131   - background: #2ba3f6;
132   -}
133   -
134   -.form-control:focus,
135   -.form-control:hover {
136   - box-shadow: unset;
137   - border: 1px solid #3081c3 !important;
138   -}
139   -
140   -.form-control {
141   - width: 100%;
142   -}
143   -
144   -.btn-info.btn-info:active {
145   - border: 1px solid;
146   -}
147   -
148   -.btn {
149   - padding: 8px 12px;
150   - border-radius: 2px;
151   - outline: none !important;
152   - -webkit-transition: 0.15s linear;
153   - transition: 0.15s linear;
154   -}
155   -
156   -button {
157   - display: block;
158   - width: 100%;
159   - margin-bottom: 0;
160   - line-height: 1.42857143;
161   - text-align: center;
162   - white-space: nowrap;
163   - touch-action: manipulation;
164   - cursor: pointer;
165   - user-select: none;
166   - font-family: inherit;
167   - overflow: visible;
168   - margin: 0;
169   - font: inherit;
170   - outline: none !important;
171   -}
172   -
173   -.ftdms-checkbox span::before,
174   -.ftdms-radio span::before {
175   - content: '';
176   - position: absolute;
177   - display: inline-block;
178   - height: 18px;
179   - width: 18px;
180   - left: 0.5px;
181   - top: 0px;
182   - border: 2px solid #ebebeb;
183   - -webkit-transition: all 0.1s;
184   - -o-transition: all 0.1s;
185   - transition: all 0.1s;
186   -}
187   -
188   -:after,
189   -:before {
190   - -webkit-box-sizing: border-box;
191   - -moz-box-sizing: border-box;
192   - box-sizing: border-box;
  1 +html,
  2 +body {
  3 + font-family: Microsoft YaHei Regular, Microsoft YaHei Regular-Regular;
  4 +}
  5 +
  6 +html,
  7 +body,
  8 +p,
  9 +input {
  10 + margin: 0;
  11 + padding: 0;
  12 +}
  13 +
  14 +.login {
  15 + background: url(../images/login_background.png) no-repeat;
  16 + background-size: 100% 100%;
  17 + width: 100%;
  18 + height: 100%;
  19 + position: relative;
  20 +}
  21 +
  22 +.login-container {
  23 + position: absolute;
  24 + top: -50px;
  25 + bottom: 0;
  26 + left: 0;
  27 + right: 0;
  28 + margin: auto;
  29 + width: 900px;
  30 + height: 454px;
  31 + background: #ffffff;
  32 + border-radius: 4px;
  33 + box-shadow: 2px 0 21px 0 rgba(38, 106, 184, 0.53);
  34 +}
  35 +
  36 +.login-container-logo {
  37 + margin: 0;
  38 + background: url(../images/login_logo.png) no-repeat;
  39 + width: 401px;
  40 + height: 455px;
  41 + overflow: hidden;
  42 + float: left;
  43 +}
  44 +
  45 +.login-container-header {
  46 + font-size: 22px;
  47 + font-weight: 700;
  48 + text-align: left;
  49 + color: #545454;
  50 + letter-spacing: 1px;
  51 + text-align: center;
  52 + margin-bottom: 54px;
  53 +}
  54 +
  55 +.login-container-header-small.login-container-header {
  56 + font-size: 22px;
  57 + font-weight: 700;
  58 + text-align: left;
  59 + color: #545454;
  60 + letter-spacing: 1px;
  61 + text-align: center;
  62 + margin-bottom: 22px;
  63 +}
  64 +
  65 +.login-container-form {
  66 + margin-left: 401px;
  67 + height: 100%;
  68 + padding: 80px;
  69 +}
  70 +
  71 +.login-container-form .form-tip {
  72 + margin-left: 21.5px;
  73 + color: red;
  74 + margin-bottom: 10px;
  75 + padding: 5px 6px;
  76 + width: 296px;
  77 + background: #ffebeb;
  78 + border: 1px solid #faccc6;
  79 + font-size: 11px;
  80 + border-radius: 4px;
  81 +}
  82 +
  83 +.login-container-form .form-tip {
  84 + height: 32px;
  85 +}
  86 +
  87 +.login-container-form .form-tip p {
  88 + margin: 0 0 0 5px;
  89 + line-height: 23px;
  90 +}
  91 +
  92 +.login-container-form .form-tip p,
  93 +.login-container-form .form-tip span {
  94 + display: block;
  95 + float: left;
  96 + height: 20px;
  97 +}
  98 +
  99 +.stop {
  100 + background: url(../images/stop.png) no-repeat;
  101 + width: 20px;
  102 + height: 20px;
  103 +}
  104 +
  105 +.login-container-form .form-group {
  106 + width: 296px;
  107 + margin: 0 auto;
  108 + margin-top: 22px;
  109 +}
  110 +
  111 +.login-container-form :first-child {
  112 + margin-top: 0px;
  113 +}
  114 +
  115 +.login-container-form .has-feedback.feedback-left .form-control-feedback {
  116 + left: 0;
  117 + right: auto;
  118 + width: 38px;
  119 + height: 45px;
  120 + line-height: 45px;
  121 + z-index: 4;
  122 + color: #dcdcdc;
  123 + font-size: 16px;
  124 +}
  125 +
  126 +.login-container-form .has-feedback.feedback-left .micons-pwd {
  127 + font-size: 18px;
  128 + line-height: 48px;
  129 +}
  130 +
  131 +.login-container-form .has-feedback.feedback-left .form-control {
  132 + padding-left: 38px;
  133 + padding-right: 12px;
  134 + border: 1px solid #ebebeb;
  135 + border-radius: 4px;
  136 + height: 45px;
  137 + color: #999;
  138 + font-size: 16px;
  139 + letter-spacing: 1px;
  140 +}
  141 +
  142 +.login-container-form .has-feedback.feedback-left .form-control:hover,
  143 +.login-container-form .has-feedback.feedback-left .form-control:hover,
  144 +.login-container-form .has-feedback.feedback-left .form-control:focus {
  145 + border: 1px solid #3081c3;
  146 + outline: unset;
  147 + box-shadow: unset;
  148 +}
  149 +
  150 +.login-container-form .overhidden {
  151 + padding-left: 24px;
  152 + font-size: 14px;
  153 + color: #999999;
  154 + vertical-align: bottom;
  155 + line-height: 18px;
  156 +}
  157 +
  158 +.login-container-form .overhidden:hover {
  159 + color: #3081c3;
  160 +}
  161 +
  162 +.login-container-form .ftdms-checkbox span::before {
  163 + height: 15px;
  164 + width: 15px;
  165 + border-width: 1px;
  166 + top: 2px;
  167 +}
  168 +
  169 +#btn-login {
  170 + background: #3081c3;
  171 + height: 45px;
  172 + font-size: 16px;
  173 + font-weight: 400;
  174 + color: #ffffff;
  175 + letter-spacing: 1px;
  176 +}
  177 +
  178 +#btn-login:hover {
  179 + background: #2ba3f6;
  180 +}
  181 +
  182 +.form-control:focus,
  183 +.form-control:hover {
  184 + box-shadow: unset;
  185 + border: 1px solid #3081c3 !important;
  186 +}
  187 +
  188 +.form-control {
  189 + width: 100%;
  190 +}
  191 +
  192 +.btn-info.btn-info:active {
  193 + border: 1px solid;
  194 +}
  195 +
  196 +.btn {
  197 + padding: 8px 12px;
  198 + border-radius: 2px;
  199 + outline: none !important;
  200 + -webkit-transition: 0.15s linear;
  201 + transition: 0.15s linear;
  202 +}
  203 +
  204 +button {
  205 + display: block;
  206 + width: 100%;
  207 + margin-bottom: 0;
  208 + line-height: 1.42857143;
  209 + text-align: center;
  210 + white-space: nowrap;
  211 + touch-action: manipulation;
  212 + cursor: pointer;
  213 + user-select: none;
  214 + font-family: inherit;
  215 + overflow: visible;
  216 + margin: 0;
  217 + font: inherit;
  218 + outline: none !important;
  219 +}
  220 +
  221 +.ftdms-checkbox span::before,
  222 +.ftdms-radio span::before {
  223 + content: '';
  224 + position: absolute;
  225 + display: inline-block;
  226 + height: 18px;
  227 + width: 18px;
  228 + left: 0.5px;
  229 + top: 0px;
  230 + border: 2px solid #ebebeb;
  231 + -webkit-transition: all 0.1s;
  232 + -o-transition: all 0.1s;
  233 + transition: all 0.1s;
  234 +}
  235 +
  236 +:after,
  237 +:before {
  238 + -webkit-box-sizing: border-box;
  239 + -moz-box-sizing: border-box;
  240 + box-sizing: border-box;
193 241 }
\ No newline at end of file
... ...

224.1 KB | 宽: | 高:

234.1 KB | 宽: | 高:

  • 两方对比
  • 交换覆盖
  • 透明覆盖
1   -if (typeof(dmap) == "undefined") var dmap = {};
2   -dmap.login = {
3   - init: function() {
4   - $('#btn-login').bind('click', function(e) {
5   - let username = $("#username").val();
6   - let password = $("#password").val();
7   -
8   - if (username.length <= 0 || password.length <= 0) {
9   - tips.notify("用户名或密码不能为空", "danger", 1e3);
10   - return false;
11   - }
12   -
13   - $.post("authorize", { username: username, password: password })
14   - });
15   - }
  1 +if (typeof(dmap) == "undefined") var dmap = {};
  2 +dmap.login = {
  3 + init: function() {
  4 + $('#btn-login').bind('click', function(e) {
  5 + let username = $("#username").val();
  6 + let password = $("#password").val();
  7 +
  8 + if (username.length <= 0 || password.length <= 0) {
  9 + tips.notify("用户名或密码不能为空", "danger", 1e3);
  10 + return false;
  11 + }
  12 +
  13 + $.post("authorize", { username: username, password: password }, function(data) {
  14 + if (!data.result) {
  15 + tips.notify("账号或密码错误", "danger", 1e3);
  16 + }
  17 + })
  18 + });
  19 + }
16 20 };
\ No newline at end of file
... ...
1   -<html>
2   - <head>
3   - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
4   - <title>DMap Server</title>
5   - <link
6   - rel="stylesheet"
7   - type="text/css"
8   - href="{{ url_for('static', filename = 'content/css/login.css') }}"
9   - />
10   - <link
11   - rel="stylesheet"
12   - type="text/css"
13   - href="{{ url_for('static', filename = 'content/css/font.css') }}"
14   - />
15   - <link
16   - rel="stylesheet"
17   - type="text/css"
18   - href="{{ url_for('static', filename = 'content/css/bootstrap.min.css') }}"
19   - />
20   - <script src="{{ url_for('static',filename='content/js/jquery.min.js') }}"></script>
21   - <script src="{{ url_for('static',filename='content/js/bootstrap-notify.min.js') }}"></script>
22   - <script src="{{ url_for('static',filename='content/js/tips.js') }}"></script>
23   - <script src="{{ url_for('static',filename='content/js/login.js') }}"></script>
24   - </head>
25   -</html>
26   -
27   -<div class="login">
28   - <div class="login-container">
29   - <p class="login-container-logo"></p>
30   - <div class="login-container-form">
31   - <p class="login-container-header">广州城市信息研究所有限公司</p>
32   - <form action="" method="post">
33   - <div class="form-group has-feedback feedback-left">
34   - <input
35   - type="text"
36   - placeholder="用户名"
37   - maxlength="20"
38   - autocomplete="off"
39   - class="form-control border-info"
40   - name="username"
41   - id="username"
42   - />
43   - <span class="micons-user form-control-feedback"></span>
44   - </div>
45   -
46   - <div class="form-group has-feedback feedback-left">
47   - <input
48   - type="password"
49   - placeholder="密码"
50   - maxlength="20"
51   - autocomplete="off"
52   - class="form-control border-info"
53   - id="password"
54   - name="password"
55   - />
56   - <span class="micons-pwd form-control-feedback"></span>
57   - </div>
58   -
59   - <div class="form-group">
60   - <button class="btn btn-block btn-info" type="submit" id="btn-login">
61   - 立即登录
62   - </button>
63   - </div>
64   - </form>
65   - </div>
66   - <div class="clear"></div>
67   - </div>
68   -</div>
69   -<script>
70   - $(function () {})
71   -</script>
  1 +<html>
  2 + <head>
  3 + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  4 + <title>DMap Server</title>
  5 + <link
  6 + rel="stylesheet"
  7 + type="text/css"
  8 + href="{{ url_for('static', filename = 'content/css/login.css') }}"
  9 + />
  10 + <link
  11 + rel="stylesheet"
  12 + type="text/css"
  13 + href="{{ url_for('static', filename = 'content/css/font.css') }}"
  14 + />
  15 + <link
  16 + rel="stylesheet"
  17 + type="text/css"
  18 + href="{{ url_for('static', filename = 'content/css/bootstrap.min.css') }}"
  19 + />
  20 + <script src="{{ url_for('static',filename='content/js/jquery.min.js') }}"></script>
  21 + <script src="{{ url_for('static',filename='content/js/bootstrap-notify.min.js') }}"></script>
  22 + <script src="{{ url_for('static',filename='content/js/tips.js') }}"></script>
  23 + <script src="{{ url_for('static',filename='content/js/login.js') }}"></script>
  24 + </head>
  25 +</html>
  26 +
  27 +<div class="login">
  28 + <div class="login-container">
  29 + <p class="login-container-logo"></p>
  30 + <div class="login-container-form">
  31 +
  32 + {%if error%}
  33 + <p class="login-container-header-small login-container-header">广州城市信息研究所有限公司</p>
  34 + <div class="form-tip">
  35 + <span class="stop"></span>
  36 + <p>{{error}}</p>
  37 + </div>
  38 + {% else %}
  39 + <p class="login-container-header">广州城市信息研究所有限公司</p>
  40 + {% endif %}
  41 +
  42 + <form action="" method="post">
  43 + <div class="form-group has-feedback feedback-left">
  44 + <input
  45 + type="text"
  46 + placeholder="用户名"
  47 + maxlength="20"
  48 + autocomplete="off"
  49 + class="form-control border-info"
  50 + name="username"
  51 + id="username"
  52 + />
  53 + <span class="micons-user form-control-feedback"></span>
  54 + </div>
  55 +
  56 + <div class="form-group has-feedback feedback-left">
  57 + <input
  58 + type="password"
  59 + placeholder="密码"
  60 + maxlength="20"
  61 + autocomplete="off"
  62 + class="form-control border-info"
  63 + id="password"
  64 + name="password"
  65 + />
  66 + <span class="micons-pwd form-control-feedback"></span>
  67 + </div>
  68 +
  69 + <div class="form-group">
  70 + <button class="btn btn-block btn-info" type="submit" id="btn-login">
  71 + 立即登录
  72 + </button>
  73 + </div>
  74 + </form>
  75 + </div>
  76 + <div class="clear"></div>
  77 + </div>
  78 +</div>
  79 +<script>
  80 + $(function () {})
  81 +</script>
... ...
... ... @@ -20,3 +20,4 @@ swagger_configure = {"title": "DMapManager"}
20 20 entry_data_thread = 3
21 21 scan_module = ["app.modules"] # API所在的模块
22 22 SECRET_KEY = b'_5#y2L"F4Q8z\n\xec]/'
  23 +
... ...
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)
\ No newline at end of file
  1 +# coding=utf-8
  2 +from flask import Flask
  3 +from app import create_app
  4 +import os
  5 +os.environ['AUTHLIB_INSECURE_TRANSPORT'] = '1'
  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)
... ...
注册登录 后发表评论