提交 23d5795f0928f33313210af6bfc5fce6c639e9b5

作者 nheweijun
2 个父辈 f57fdbd3 62c596fe

2021.8.4

@@ -28,4 +28,5 @@ kservice/tmp @@ -28,4 +28,5 @@ kservice/tmp
28 dist/ 28 dist/
29 build/ 29 build/
30 *.egg-info/ 30 *.egg-info/
31 -.git/  
  31 +.git/
  32 +.vscode/
@@ -7,8 +7,8 @@ import time @@ -7,8 +7,8 @@ import time
7 import configure 7 import configure
8 from app.util import BlueprintApi 8 from app.util import BlueprintApi
9 from app.util import find_class 9 from app.util import find_class
10 -from app.models import db,Table,InsertingLayerName,Database,DES,Task  
11 - 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 12 from flasgger import Swagger
13 # from rtree import index 13 # from rtree import index
14 import logging 14 import logging
@@ -28,6 +28,13 @@ from app.util.component.StructuredPrint import StructurePrint @@ -28,6 +28,13 @@ from app.util.component.StructuredPrint import StructurePrint
28 from app.util.component.PGUtil import PGUtil 28 from app.util.component.PGUtil import PGUtil
29 import os 29 import os
30 30
  31 +<<<<<<< HEAD
  32 +=======
  33 +"""
  34 +因为decimal不能序列化,增加Flask对decimal类的解析
  35 +"""
  36 +
  37 +>>>>>>> 62c596fe02f871582dc30904695c665d1c3fc006
31 38
32 class JSONEncoder(_JSONEncoder): 39 class JSONEncoder(_JSONEncoder):
33 """ 40 """
@@ -38,6 +45,7 @@ class JSONEncoder(_JSONEncoder): @@ -38,6 +45,7 @@ class JSONEncoder(_JSONEncoder):
38 return float(o) 45 return float(o)
39 super(JSONEncoder, self).default(o) 46 super(JSONEncoder, self).default(o)
40 47
  48 +
41 class Flask(_Flask): 49 class Flask(_Flask):
42 json_encoder = JSONEncoder 50 json_encoder = JSONEncoder
43 51
@@ -57,12 +65,18 @@ def create_app(): @@ -57,12 +65,18 @@ def create_app():
57 app.config['echo'] = True 65 app.config['echo'] = True
58 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True 66 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
59 app.config['JSON_AS_ASCII'] = False 67 app.config['JSON_AS_ASCII'] = False
  68 + app.config['SECRET_KEY'] = configure.SECRET_KEY
  69 + app.config['OAUTH2_JWT_ENABLED'] = True
  70 +
  71 + app.config['OAUTH2_JWT_ISS'] = 'http://localhost:5000'
  72 + app.config['OAUTH2_JWT_KEY'] = 'secret-key'
  73 + app.config['OAUTH2_JWT_ALG'] = 'HS256'
60 # app.config['SQLALCHEMY_ECHO'] = True 74 # app.config['SQLALCHEMY_ECHO'] = True
61 75
62 # 跨域设置 76 # 跨域设置
63 CORS(app) 77 CORS(app)
64 78
65 - #swagger设置 79 + # swagger设置
66 swagger_config = Swagger.DEFAULT_CONFIG 80 swagger_config = Swagger.DEFAULT_CONFIG
67 swagger_config.update(configure.swagger_configure) 81 swagger_config.update(configure.swagger_configure)
68 Swagger(app, config=swagger_config) 82 Swagger(app, config=swagger_config)
@@ -71,41 +85,47 @@ def create_app(): @@ -71,41 +85,47 @@ def create_app():
71 db.init_app(app) 85 db.init_app(app)
72 db.create_all(app=app) 86 db.create_all(app=app)
73 87
74 -  
75 # 日志 88 # 日志
76 logging.basicConfig(level=logging.INFO) 89 logging.basicConfig(level=logging.INFO)
77 - log_file = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))),"logs","log.txt")  
78 - handler = logging.FileHandler(log_file, encoding='UTF-8') # 设置日志字符集和存储路径名字  
79 - logging_format = logging.Formatter('[%(levelname)s] %(asctime)s %(message)s') 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')
80 handler.setFormatter(logging_format) 96 handler.setFormatter(logging_format)
81 app.logger.addHandler(handler) 97 app.logger.addHandler(handler)
82 -  
83 - 98 +
  99 + # 配置使用鉴权组件,不写无法认证授权
  100 + config_oauth(app)
  101 +
84 # 注册blueprint,查找BlueprintApi的子类 102 # 注册blueprint,查找BlueprintApi的子类
85 for scan in configure.scan_module: 103 for scan in configure.scan_module:
86 for api in find_class(scan, BlueprintApi): 104 for api in find_class(scan, BlueprintApi):
87 app.register_blueprint(api.bp) 105 app.register_blueprint(api.bp)
88 106
89 -  
90 # 入库监测线程 107 # 入库监测线程
  108 +
91 @app.before_first_request 109 @app.before_first_request
92 def data_entry_process(): 110 def data_entry_process():
93 StructurePrint.print("start listen") 111 StructurePrint.print("start listen")
94 process = threading.Thread(target=data_entry_center) 112 process = threading.Thread(target=data_entry_center)
95 process.start() 113 process.start()
  114 +
  115 + # 不检测https
  116 + os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
  117 +
96 118
97 return app 119 return app
98 120
99 121
100 -  
101 -  
102 def data_entry_center(): 122 def data_entry_center():
103 running_dict = {} 123 running_dict = {}
104 - sys_session: Session = PGUtil.get_db_session(configure.SQLALCHEMY_DATABASE_URI) 124 + sys_session: Session = PGUtil.get_db_session(
  125 + configure.SQLALCHEMY_DATABASE_URI)
105 126
106 while True: 127 while True:
107 128
108 -  
109 try: 129 try:
110 time.sleep(3) 130 time.sleep(3)
111 131
@@ -114,10 +134,11 @@ def data_entry_center(): @@ -114,10 +134,11 @@ def data_entry_center():
114 134
115 # structured_print(running_dict.__len__().__str__()) 135 # structured_print(running_dict.__len__().__str__())
116 136
117 - for process,layer_names in running_dict.items(): 137 + for process, layer_names in running_dict.items():
118 if not process.is_alive(): 138 if not process.is_alive():
119 for l in layer_names: 139 for l in layer_names:
120 - inserted = sys_session.query(InsertingLayerName).filter_by(name=l).one_or_none() 140 + inserted = sys_session.query(
  141 + InsertingLayerName).filter_by(name=l).one_or_none()
121 if inserted: 142 if inserted:
122 sys_session.delete(inserted) 143 sys_session.delete(inserted)
123 sys_session.commit() 144 sys_session.commit()
@@ -129,7 +150,8 @@ def data_entry_center(): @@ -129,7 +150,8 @@ def data_entry_center():
129 150
130 # 入库进程少于阈值,开启入库进程 151 # 入库进程少于阈值,开启入库进程
131 152
132 - inter_size = sys_session.query(distinct(InsertingLayerName.task_guid)).count() 153 + inter_size = sys_session.query(
  154 + distinct(InsertingLayerName.task_guid)).count()
133 155
134 if inter_size < configure.entry_data_thread: 156 if inter_size < configure.entry_data_thread:
135 # 锁表啊 157 # 锁表啊
@@ -139,28 +161,28 @@ def data_entry_center(): @@ -139,28 +161,28 @@ def data_entry_center():
139 try: 161 try:
140 parameter = json.loads(ready_task.parameter) 162 parameter = json.loads(ready_task.parameter)
141 StructurePrint.print("检测到入库任务") 163 StructurePrint.print("检测到入库任务")
142 - ready_task.state=2  
143 - ready_task.process="入库中" 164 + ready_task.state = 2
  165 + ready_task.process = "入库中"
144 sys_session.commit() 166 sys_session.commit()
145 167
146 - metas: list = json.loads(parameter.get("meta").__str__()) 168 + metas: list = json.loads(
  169 + parameter.get("meta").__str__())
147 parameter["meta"] = metas 170 parameter["meta"] = metas
148 171
149 -  
150 - database = sys_session.query(Database).filter_by(guid=ready_task.database_guid).one_or_none()  
151 - pg_ds: DataSource = PGUtil.open_pg_data_source(1,DES.decode(database.sqlalchemy_uri)) 172 + database = sys_session.query(Database).filter_by(
  173 + guid=ready_task.database_guid).one_or_none()
  174 + pg_ds: DataSource = PGUtil.open_pg_data_source(
  175 + 1, DES.decode(database.sqlalchemy_uri))
152 176
153 this_task_layer = [] 177 this_task_layer = []
154 for meta in metas: 178 for meta in metas:
155 overwrite = parameter.get("overwrite", "no") 179 overwrite = parameter.get("overwrite", "no")
156 180
157 -  
158 -  
159 for layer_name_origin, layer_name in meta.get("layer").items(): 181 for layer_name_origin, layer_name in meta.get("layer").items():
160 origin_name = layer_name 182 origin_name = layer_name
161 no = 1 183 no = 1
162 184
163 - while (overwrite.__eq__("no") and pg_ds.GetLayerByName(layer_name)) or sys_session.query(InsertingLayerName).filter_by(name=layer_name).one_or_none() : 185 + while (overwrite.__eq__("no") and pg_ds.GetLayerByName(layer_name)) or sys_session.query(InsertingLayerName).filter_by(name=layer_name).one_or_none():
164 layer_name = origin_name + "_{}".format(no) 186 layer_name = origin_name + "_{}".format(no)
165 no += 1 187 no += 1
166 188
@@ -176,7 +198,8 @@ def data_entry_center(): @@ -176,7 +198,8 @@ def data_entry_center():
176 meta["layer"][layer_name_origin] = layer_name 198 meta["layer"][layer_name_origin] = layer_name
177 199
178 pg_ds.Destroy() 200 pg_ds.Destroy()
179 - entry_data_process = multiprocessing.Process(target=EntryDataVacuate().entry,args=(parameter,)) 201 + entry_data_process = multiprocessing.Process(
  202 + target=EntryDataVacuate().entry, args=(parameter,))
180 entry_data_process.start() 203 entry_data_process.start()
181 running_dict[entry_data_process] = this_task_layer 204 running_dict[entry_data_process] = this_task_layer
182 except Exception as e: 205 except Exception as e:
@@ -189,4 +212,4 @@ def data_entry_center(): @@ -189,4 +212,4 @@ def data_entry_center():
189 sys_session.commit() 212 sys_session.commit()
190 except Exception as e: 213 except Exception as e:
191 sys_session.commit() 214 sys_session.commit()
192 - StructurePrint.print(e.__str__(),"error")  
  215 + StructurePrint.print(e.__str__(), "error")
  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 .models import *
  5 +from werkzeug.security import gen_salt
  6 +import time
  7 +from .oauth2 import authorization, require_oauth, generate_user_info
  8 +from authlib.oauth2 import OAuth2Error
  9 +from authlib.integrations.flask_oauth2 import current_token
  10 +
  11 +def current_user():
  12 + if 'id' in session:
  13 + uid = session['id']
  14 + return User.query.get(uid)
  15 + return None
  16 +
  17 +
  18 +def split_by_crlf(s):
  19 + return [v for v in s.splitlines() if v]
  20 +
  21 +
  22 +class DataManager(BlueprintApi):
  23 + bp = Blueprint("Auth", __name__, url_prefix="/auth")
  24 +
  25 + @staticmethod
  26 + @bp.route('/test', methods=('GET', 'POST'))
  27 + def Test():
  28 + res = {}
  29 + try:
  30 + res['user'] = User.query.all()
  31 + except Exception as e:
  32 + raise e
  33 + return res
  34 +
  35 + @staticmethod
  36 + @bp.route('/', methods=('GET', 'POST'))
  37 + def test():
  38 + if request.method == 'POST':
  39 + username = request.form['username']
  40 + password = request.form['password']
  41 + user = User.query.filter_by(username=username).first()
  42 + if not user:
  43 + user = User(username=username,
  44 + password=password, role='admin')
  45 + db.session.add(user)
  46 + db.session.commit()
  47 + session['id'] = user.id
  48 + return redirect('/auth')
  49 + user = current_user()
  50 + if user:
  51 + clients = OAuth2Client.query.filter_by(user_id=user.id).all()
  52 + else:
  53 + clients = []
  54 + return render_template('auth/login.html', user=user, clients=clients)
  55 +
  56 +
  57 +
  58 + @staticmethod
  59 + @bp.route('/create_client', methods=('GET', 'POST'))
  60 + def create_client():
  61 + user = current_user()
  62 + if not user:
  63 + return redirect('/auth')
  64 + if request.method == 'GET':
  65 + return render_template('auth/create_client.html')
  66 + form = request.form
  67 + client_id = gen_salt(24)
  68 + client = OAuth2Client(client_id=client_id, user_id=user.id)
  69 + # Mixin doesn't set the issue_at date
  70 + client.client_id_issued_at = int(time.time())
  71 + if client.token_endpoint_auth_method == 'none':
  72 + client.client_secret = ''
  73 + else:
  74 + client.client_secret = gen_salt(48)
  75 + client_metadata = {
  76 + "client_name": form["client_name"],
  77 + "client_uri": form["client_uri"],
  78 + "grant_types": split_by_crlf(form["grant_type"]),
  79 + "redirect_uris": split_by_crlf(form["redirect_uri"]),
  80 + "response_types": split_by_crlf(form["response_type"]),
  81 + "scope": form["scope"],
  82 + "token_endpoint_auth_method": form["token_endpoint_auth_method"]
  83 + }
  84 + client.set_client_metadata(client_metadata)
  85 + db.session.add(client)
  86 + db.session.commit()
  87 + return redirect('/auth')
  88 +
  89 + @staticmethod
  90 + @bp.route('/authorize', methods=('GET', 'POST'))
  91 + def authorize():
  92 + user = current_user()
  93 + if request.method == 'GET':
  94 + try:
  95 + grant = authorization.validate_consent_request(end_user=user)
  96 + except OAuth2Error as error:
  97 + return jsonify(dict(error.get_body()))
  98 + return render_template('auth/authorize.html', user=user, grant=grant)
  99 + if not user and 'username' in request.form:
  100 + username = request.form.get('username')
  101 + user = User.query.filter_by(username=username).first()
  102 + if request.form['confirm']:
  103 + grant_user = user
  104 + else:
  105 + grant_user = None
  106 + return authorization.create_authorization_response(grant_user=grant_user)
  107 +
  108 +
  109 + @staticmethod
  110 + @bp.route('/token', methods=['POST'])
  111 + def issue_token():
  112 + return authorization.create_token_response()
  113 +
  114 + @staticmethod
  115 + @bp.route('/userinfo')
  116 + @require_oauth('profile')
  117 + def api_me():
  118 + return jsonify(generate_user_info(current_token.user, current_token.scope))
  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 authlib.integrations.flask_oauth2 import (
  2 + AuthorizationServer, ResourceProtector)
  3 +from authlib.integrations.sqla_oauth2 import (
  4 + create_query_client_func,
  5 + create_save_token_func,
  6 + create_bearer_token_validator,
  7 +)
  8 +from authlib.oauth2.rfc6749.grants import (
  9 + AuthorizationCodeGrant as _AuthorizationCodeGrant,
  10 +)
  11 +from authlib.oidc.core.grants import (
  12 + OpenIDCode as _OpenIDCode,
  13 + OpenIDImplicitGrant as _OpenIDImplicitGrant,
  14 + OpenIDHybridGrant as _OpenIDHybridGrant,
  15 +)
  16 +from authlib.oidc.core import UserInfo
  17 +from werkzeug.security import gen_salt
  18 +from .models import db, User
  19 +from .models import OAuth2Client, OAuth2AuthorizationCode, OAuth2Token
  20 +
  21 +
  22 +DUMMY_JWT_CONFIG = {
  23 + 'key': 'secret-key',
  24 + 'alg': 'HS256',
  25 + 'iss': 'https://authlib.org',
  26 + 'exp': 7200,
  27 +}
  28 +
  29 +def exists_nonce(nonce, req):
  30 + exists = OAuth2AuthorizationCode.query.filter_by(
  31 + client_id=req.client_id, nonce=nonce
  32 + ).first()
  33 + return bool(exists)
  34 +
  35 +
  36 +def generate_user_info(user, scope):
  37 + return UserInfo(sub=str(user.id), name=user.username)
  38 +
  39 +
  40 +def create_authorization_code(client, grant_user, request):
  41 + code = gen_salt(48)
  42 + nonce = request.data.get('nonce')
  43 + item = OAuth2AuthorizationCode(
  44 + code=code,
  45 + client_id=client.client_id,
  46 + redirect_uri=request.redirect_uri,
  47 + scope=request.scope,
  48 + user_id=grant_user.id,
  49 + nonce=nonce,
  50 + )
  51 + db.session.add(item)
  52 + db.session.commit()
  53 + return code
  54 +
  55 +
  56 +class AuthorizationCodeGrant(_AuthorizationCodeGrant):
  57 + def create_authorization_code(self, client, grant_user, request):
  58 + return create_authorization_code(client, grant_user, request)
  59 +
  60 + def parse_authorization_code(self, code, client):
  61 + item = OAuth2AuthorizationCode.query.filter_by(
  62 + code=code, client_id=client.client_id).first()
  63 + if item and not item.is_expired():
  64 + return item
  65 +
  66 + def delete_authorization_code(self, authorization_code):
  67 + db.session.delete(authorization_code)
  68 + db.session.commit()
  69 +
  70 + def authenticate_user(self, authorization_code):
  71 + return User.query.get(authorization_code.user_id)
  72 +
  73 +
  74 +class OpenIDCode(_OpenIDCode):
  75 + def exists_nonce(self, nonce, request):
  76 + return exists_nonce(nonce, request)
  77 +
  78 + def get_jwt_config(self, grant):
  79 + return DUMMY_JWT_CONFIG
  80 +
  81 + def generate_user_info(self, user, scope):
  82 + return generate_user_info(user, scope)
  83 +
  84 +
  85 +class ImplicitGrant(_OpenIDImplicitGrant):
  86 + def exists_nonce(self, nonce, request):
  87 + return exists_nonce(nonce, request)
  88 +
  89 + def get_jwt_config(self, grant):
  90 + return DUMMY_JWT_CONFIG
  91 +
  92 + def generate_user_info(self, user, scope):
  93 + return generate_user_info(user, scope)
  94 +
  95 +
  96 +class HybridGrant(_OpenIDHybridGrant):
  97 + def create_authorization_code(self, client, grant_user, request):
  98 + return create_authorization_code(client, grant_user, request)
  99 +
  100 + def exists_nonce(self, nonce, request):
  101 + return exists_nonce(nonce, request)
  102 +
  103 + def get_jwt_config(self):
  104 + return DUMMY_JWT_CONFIG
  105 +
  106 + def generate_user_info(self, user, scope):
  107 + return generate_user_info(user, scope)
  108 +
  109 +
  110 +authorization = AuthorizationServer()
  111 +require_oauth = ResourceProtector()
  112 +
  113 +
  114 +def config_oauth(app):
  115 + query_client = create_query_client_func(db.session, OAuth2Client)
  116 + save_token = create_save_token_func(db.session, OAuth2Token)
  117 + authorization.init_app(
  118 + app,
  119 + query_client=query_client,
  120 + save_token=save_token
  121 + )
  122 +
  123 + # support all openid grants
  124 + authorization.register_grant(AuthorizationCodeGrant, [
  125 + OpenIDCode(require_nonce=True),
  126 + ])
  127 + authorization.register_grant(ImplicitGrant)
  128 + authorization.register_grant(HybridGrant)
  129 +
  130 + # protect resource
  131 + bearer_cls = create_bearer_token_validator(db.session, OAuth2Token)
  132 + require_oauth.register_token_validator(bearer_cls())
  1 +<p>{{grant.client.client_name}} is requesting:
  2 +<strong>{{ grant.request.scope }}</strong>
  3 +</p>
  4 +
  5 +<form action="" method="post">
  6 + <label>
  7 + <input type="checkbox" name="confirm">
  8 + <span>Consent?</span>
  9 + </label>
  10 + {% if not user %}
  11 + <p>You haven't logged in. Log in with:</p>
  12 + <div>
  13 + <input type="text" name="username">
  14 + </div>
  15 + {% endif %}
  16 + <br>
  17 + <button>Submit</button>
  18 +</form>
  1 +<style>
  2 + label, label > span { display: block; }
  3 + label { margin: 15px 0; }
  4 +</style>
  5 +
  6 +<a href="/">Home</a>
  7 +
  8 +<form action="" method="post">
  9 + <label>
  10 + <span>Client Name</span>
  11 + <input type="text" name="client_name">
  12 + </label>
  13 + <label>
  14 + <span>Client URI</span>
  15 + <input type="url" name="client_uri">
  16 + </label>
  17 + <label>
  18 + <span>Allowed Scope</span>
  19 + <input type="text" name="scope">
  20 + </label>
  21 + <label>
  22 + <span>Redirect URIs</span>
  23 + <textarea name="redirect_uri" cols="30" rows="10"></textarea>
  24 + </label>
  25 + <label>
  26 + <span>Allowed Grant Types</span>
  27 + <textarea name="grant_type" cols="30" rows="10"></textarea>
  28 + </label>
  29 + <label>
  30 + <span>Allowed Response Types</span>
  31 + <textarea name="response_type" cols="30" rows="10"></textarea>
  32 + </label>
  33 + <label>
  34 + <span>Token Endpoint Auth Method</span>
  35 + <select name="token_endpoint_auth_method">
  36 + <option value="client_secret_basic">client_secret_basic</option>
  37 + <option value="client_secret_post">client_secret_post</option>
  38 + <option value="none">none</option>
  39 + </select>
  40 + </label>
  41 + <button>Submit</button>
  42 +</form>
  1 +{% if user %}
  2 + <style>pre{white-space:wrap}</style>
  3 +<div>Logged in as <strong>{{user}}</strong></div>
  4 +
  5 +{% for client in clients %}
  6 +<pre>
  7 +{{ client.client_info|tojson }}
  8 +{{ client.client_metadata|tojson }}
  9 +</pre>
  10 +<hr>
  11 +{% endfor %}
  12 +
  13 +<br><a href="{{ url_for('.create_client') }}">Create Client</a>
  14 +
  15 +{% else %}
  16 +<form action="" method="post">
  17 + <input type="text" name="username" placeholder="账号">
  18 + <input type="text" name="password" placeholder="密码">
  19 + <button type="submit">Login / Signup</button>
  20 +</form>
  21 +{% endif %}
@@ -3,15 +3,16 @@ @@ -3,15 +3,16 @@
3 # 程序部署ip:host 3 # 程序部署ip:host
4 deploy_ip_host = "172.26.99.160:8840" 4 deploy_ip_host = "172.26.99.160:8840"
5 # 系统数据库 5 # 系统数据库
6 -SQLALCHEMY_DATABASE_URI = "postgresql://postgres:chinadci@172.26.99.160:5432/dmap_dms_test" 6 +SQLALCHEMY_DATABASE_URI = "postgresql://postgres:postgres@172.26.40.254:5433/dmap_dms_test"
7 7
8 8
9 # 部署模式cluster,standalone 9 # 部署模式cluster,standalone
10 -deployment_mode="cluster" 10 +deployment_mode = "cluster"
11 # 部署模式味cluster时有用,master,slave 11 # 部署模式味cluster时有用,master,slave
12 -application_name="master" 12 +application_name = "master"
13 13
14 # 固定配置不需要修改 14 # 固定配置不需要修改
15 -swagger_configure={"title":"DMapManager"} 15 +swagger_configure = {"title": "DMapManager"}
16 entry_data_thread = 3 16 entry_data_thread = 3
17 -scan_module = ["app.modules"]# API所在的模块 17 +scan_module = ["app.modules"] # API所在的模块
  18 +SECRET_KEY = b'_5#y2L"F4Q8z\n\xec]/'
1 -flask==1.1.2  
2 -SQLAlchemy==1.3.17  
3 -Flask-SQLAlchemy==2.4.3  
4 -gevent==20.9.0  
5 -gunicorn==20.0.4  
6 -flask_cors==3.0.8  
7 -flasgger==0.9.5  
8 -GDAL==3.2.1  
9 -psycopg2==2.8.5  
10 -pyDes==2.0.1  
11 -gevent-websocket==0.10.1  
12 -Pillow==8.1.2  
13 -#Rtree==0.9.7  
14 -opencv-python==4.5.1.48  
15 -psutil==5.8.0  
16 -mod_wsgi==4.8.0  
  1 +flask==1.1.2
  2 +SQLAlchemy==1.3.17
  3 +Flask-SQLAlchemy==2.4.3
  4 +gevent==20.9.0
  5 +gunicorn==20.0.4
  6 +flask_cors==3.0.8
  7 +flasgger==0.9.5
  8 +GDAL==3.2.1
  9 +psycopg2==2.8.5
  10 +pyDes==2.0.1
  11 +gevent-websocket==0.10.1
  12 +Pillow==8.1.2
  13 +#Rtree==0.9.7
  14 +opencv-python==4.5.1.48
  15 +pstuil==5.8.0
  16 +mod_wsgi==4.8.0
  17 +Authlib==0.13
  18 +
@@ -3,5 +3,4 @@ from flask import Flask @@ -3,5 +3,4 @@ from flask import Flask
3 from app import create_app 3 from app import create_app
4 app:Flask = create_app() 4 app:Flask = create_app()
5 if __name__ == '__main__': 5 if __name__ == '__main__':
6 - app.run(host="0.0.0.0", port="8840", threaded=True, debug=True)  
7 - 6 + app.run(host="0.0.0.0", port="8840", threaded=True, debug=True)
注册登录 后发表评论