正在显示
11 个修改的文件
包含
468 行增加
和
52 行删除
... | ... | @@ -7,8 +7,8 @@ import time |
7 | 7 | import configure |
8 | 8 | from app.util import BlueprintApi |
9 | 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 | 12 | from flasgger import Swagger |
13 | 13 | # from rtree import index |
14 | 14 | import logging |
... | ... | @@ -28,6 +28,13 @@ from app.util.component.StructuredPrint import StructurePrint |
28 | 28 | from app.util.component.PGUtil import PGUtil |
29 | 29 | import os |
30 | 30 | |
31 | +<<<<<<< HEAD | |
32 | +======= | |
33 | +""" | |
34 | +因为decimal不能序列化,增加Flask对decimal类的解析 | |
35 | +""" | |
36 | + | |
37 | +>>>>>>> 62c596fe02f871582dc30904695c665d1c3fc006 | |
31 | 38 | |
32 | 39 | class JSONEncoder(_JSONEncoder): |
33 | 40 | """ |
... | ... | @@ -38,6 +45,7 @@ class JSONEncoder(_JSONEncoder): |
38 | 45 | return float(o) |
39 | 46 | super(JSONEncoder, self).default(o) |
40 | 47 | |
48 | + | |
41 | 49 | class Flask(_Flask): |
42 | 50 | json_encoder = JSONEncoder |
43 | 51 | |
... | ... | @@ -57,12 +65,18 @@ def create_app(): |
57 | 65 | app.config['echo'] = True |
58 | 66 | app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True |
59 | 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 | 74 | # app.config['SQLALCHEMY_ECHO'] = True |
61 | 75 | |
62 | 76 | # 跨域设置 |
63 | 77 | CORS(app) |
64 | 78 | |
65 | - #swagger设置 | |
79 | + # swagger设置 | |
66 | 80 | swagger_config = Swagger.DEFAULT_CONFIG |
67 | 81 | swagger_config.update(configure.swagger_configure) |
68 | 82 | Swagger(app, config=swagger_config) |
... | ... | @@ -71,41 +85,47 @@ def create_app(): |
71 | 85 | db.init_app(app) |
72 | 86 | db.create_all(app=app) |
73 | 87 | |
74 | - | |
75 | 88 | # 日志 |
76 | 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 | 96 | handler.setFormatter(logging_format) |
81 | 97 | app.logger.addHandler(handler) |
82 | - | |
83 | - | |
98 | + | |
99 | + # 配置使用鉴权组件,不写无法认证授权 | |
100 | + config_oauth(app) | |
101 | + | |
84 | 102 | # 注册blueprint,查找BlueprintApi的子类 |
85 | 103 | for scan in configure.scan_module: |
86 | 104 | for api in find_class(scan, BlueprintApi): |
87 | 105 | app.register_blueprint(api.bp) |
88 | 106 | |
89 | - | |
90 | 107 | # 入库监测线程 |
108 | + | |
91 | 109 | @app.before_first_request |
92 | 110 | def data_entry_process(): |
93 | 111 | StructurePrint.print("start listen") |
94 | 112 | process = threading.Thread(target=data_entry_center) |
95 | 113 | process.start() |
114 | + | |
115 | + # 不检测https | |
116 | + os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' | |
117 | + | |
96 | 118 | |
97 | 119 | return app |
98 | 120 | |
99 | 121 | |
100 | - | |
101 | - | |
102 | 122 | def data_entry_center(): |
103 | 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 | 127 | while True: |
107 | 128 | |
108 | - | |
109 | 129 | try: |
110 | 130 | time.sleep(3) |
111 | 131 | |
... | ... | @@ -114,10 +134,11 @@ def data_entry_center(): |
114 | 134 | |
115 | 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 | 138 | if not process.is_alive(): |
119 | 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 | 142 | if inserted: |
122 | 143 | sys_session.delete(inserted) |
123 | 144 | sys_session.commit() |
... | ... | @@ -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 | 156 | if inter_size < configure.entry_data_thread: |
135 | 157 | # 锁表啊 |
... | ... | @@ -139,28 +161,28 @@ def data_entry_center(): |
139 | 161 | try: |
140 | 162 | parameter = json.loads(ready_task.parameter) |
141 | 163 | StructurePrint.print("检测到入库任务") |
142 | - ready_task.state=2 | |
143 | - ready_task.process="入库中" | |
164 | + ready_task.state = 2 | |
165 | + ready_task.process = "入库中" | |
144 | 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 | 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 | 177 | this_task_layer = [] |
154 | 178 | for meta in metas: |
155 | 179 | overwrite = parameter.get("overwrite", "no") |
156 | 180 | |
157 | - | |
158 | - | |
159 | 181 | for layer_name_origin, layer_name in meta.get("layer").items(): |
160 | 182 | origin_name = layer_name |
161 | 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 | 186 | layer_name = origin_name + "_{}".format(no) |
165 | 187 | no += 1 |
166 | 188 | |
... | ... | @@ -176,7 +198,8 @@ def data_entry_center(): |
176 | 198 | meta["layer"][layer_name_origin] = layer_name |
177 | 199 | |
178 | 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 | 203 | entry_data_process.start() |
181 | 204 | running_dict[entry_data_process] = this_task_layer |
182 | 205 | except Exception as e: |
... | ... | @@ -189,4 +212,4 @@ def data_entry_center(): |
189 | 212 | sys_session.commit() |
190 | 213 | except Exception as e: |
191 | 214 | sys_session.commit() |
192 | - StructurePrint.print(e.__str__(),"error") | |
\ No newline at end of file | ||
215 | + StructurePrint.print(e.__str__(), "error") | ... | ... |
app/modules/auth/__init__.py
0 → 100644
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)) | ... | ... |
app/modules/auth/models/__init__.py
0 → 100644
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') | ... | ... |
app/modules/auth/oauth2.py
0 → 100644
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()) | ... | ... |
app/templates/auth/authorize.html
0 → 100644
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> | ... | ... |
app/templates/auth/create_client.html
0 → 100644
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> | ... | ... |
app/templates/auth/login.html
0 → 100644
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 | 3 | # 程序部署ip:host |
4 | 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 | 9 | # 部署模式cluster,standalone |
10 | -deployment_mode="cluster" | |
10 | +deployment_mode = "cluster" | |
11 | 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 | 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 | |
\ No newline at end of file | ||
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 | 3 | from app import create_app |
4 | 4 | app:Flask = create_app() |
5 | 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) | |
\ No newline at end of file | ... | ... |
请
注册
或
登录
后发表评论