reyserver 1.1.58__py3-none-any.whl → 1.1.59__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of reyserver might be problematic. Click here for more details.
- reyserver/rauth.py +191 -48
- reyserver/rbase.py +27 -14
- reyserver/rfile.py +4 -3
- reyserver/rserver.py +26 -7
- {reyserver-1.1.58.dist-info → reyserver-1.1.59.dist-info}/METADATA +1 -1
- reyserver-1.1.59.dist-info/RECORD +12 -0
- reyserver-1.1.58.dist-info/RECORD +0 -12
- {reyserver-1.1.58.dist-info → reyserver-1.1.59.dist-info}/WHEEL +0 -0
- {reyserver-1.1.58.dist-info → reyserver-1.1.59.dist-info}/licenses/LICENSE +0 -0
reyserver/rauth.py
CHANGED
|
@@ -9,14 +9,18 @@
|
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
from typing import Any, Literal
|
|
12
|
+
from typing import Any, TypedDict, NotRequired, Literal
|
|
13
13
|
from datetime import datetime as Datetime
|
|
14
|
+
from re import PatternError
|
|
14
15
|
from fastapi import APIRouter, Request
|
|
16
|
+
from fastapi.params import Depends
|
|
17
|
+
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
|
15
18
|
from reydb import rorm, DatabaseEngine, DatabaseEngineAsync
|
|
16
|
-
from reykit.rdata import encode_jwt, is_hash_bcrypt
|
|
19
|
+
from reykit.rdata import encode_jwt, decode_jwt, is_hash_bcrypt
|
|
20
|
+
from reykit.rre import search_batch
|
|
17
21
|
from reykit.rtime import now
|
|
18
22
|
|
|
19
|
-
from .rbase import
|
|
23
|
+
from .rbase import Bind, exit_api
|
|
20
24
|
|
|
21
25
|
|
|
22
26
|
__all__ = (
|
|
@@ -30,6 +34,34 @@ __all__ = (
|
|
|
30
34
|
)
|
|
31
35
|
|
|
32
36
|
|
|
37
|
+
UserInfo = TypedDict(
|
|
38
|
+
'UserInfo',
|
|
39
|
+
{
|
|
40
|
+
'create_time': float,
|
|
41
|
+
'udpate_time': float,
|
|
42
|
+
'user_id': int,
|
|
43
|
+
'user_name': str,
|
|
44
|
+
'role_names': list[str],
|
|
45
|
+
'perm_names': list[str],
|
|
46
|
+
'perm_apis': list[str],
|
|
47
|
+
'email': str | None,
|
|
48
|
+
'phone': str | None,
|
|
49
|
+
'avatar': int | None,
|
|
50
|
+
'password': NotRequired[str]
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
Token = TypedDict(
|
|
54
|
+
'Token',
|
|
55
|
+
{
|
|
56
|
+
'sub': int,
|
|
57
|
+
'iat': int,
|
|
58
|
+
'nbf': int,
|
|
59
|
+
'exp': int,
|
|
60
|
+
'user': UserInfo
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
33
65
|
class DatabaseORMTableUser(rorm.Table):
|
|
34
66
|
"""
|
|
35
67
|
Database `user` table ORM model.
|
|
@@ -202,40 +234,50 @@ def build_auth_db(engine: DatabaseEngine | DatabaseEngineAsync) -> None:
|
|
|
202
234
|
auth_router = APIRouter()
|
|
203
235
|
|
|
204
236
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
account: str
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
) -> dict:
|
|
237
|
+
async def get_user_info(
|
|
238
|
+
conn: Bind.Conn,
|
|
239
|
+
account: str,
|
|
240
|
+
account_type: Literal['name', 'email', 'phone'],
|
|
241
|
+
filter_invalid: bool = True
|
|
242
|
+
) -> UserInfo | None:
|
|
212
243
|
"""
|
|
213
|
-
|
|
244
|
+
Get user information.
|
|
214
245
|
|
|
215
246
|
Parameters
|
|
216
247
|
----------
|
|
217
|
-
|
|
218
|
-
|
|
248
|
+
conn: Asyncronous database connection.
|
|
249
|
+
account : User account.
|
|
219
250
|
account_type : User account type.
|
|
251
|
+
- `Literal['name']`: User name.
|
|
252
|
+
- `Literal['email']`: User Email.
|
|
253
|
+
- `Literal['phone']`: User phone mumber.
|
|
254
|
+
filter_invalid : Whether filter invalid user.
|
|
220
255
|
|
|
221
256
|
Returns
|
|
222
257
|
-------
|
|
223
|
-
|
|
258
|
+
User information or null.
|
|
224
259
|
"""
|
|
225
260
|
|
|
226
|
-
#
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
261
|
+
# Parameters.
|
|
262
|
+
if filter_invalid:
|
|
263
|
+
sql_where = (
|
|
264
|
+
' WHERE (\n'
|
|
265
|
+
f' `{account_type}` = :account\n'
|
|
266
|
+
' AND `is_valid` = 1\n'
|
|
267
|
+
' )\n'
|
|
268
|
+
)
|
|
269
|
+
else:
|
|
270
|
+
sql_where = ' WHERE `{account_type}` = :account\n'
|
|
271
|
+
|
|
272
|
+
# Get.
|
|
231
273
|
sql = (
|
|
232
274
|
'SELECT ANY_VALUE(`create_time`) AS `create_time`,\n'
|
|
275
|
+
' ANY_VALUE(`phone`) AS `phone`,\n'
|
|
233
276
|
' ANY_VALUE(`update_time`) AS `update_time`,\n'
|
|
234
277
|
' ANY_VALUE(`user`.`user_id`) AS `user_id`,\n'
|
|
235
278
|
' ANY_VALUE(`user`.`name`) AS `user_name`,\n'
|
|
236
279
|
' ANY_VALUE(`password`) AS `password`,\n'
|
|
237
280
|
' ANY_VALUE(`email`) AS `email`,\n'
|
|
238
|
-
' ANY_VALUE(`phone`) AS `phone`,\n'
|
|
239
281
|
' ANY_VALUE(`avatar`) AS `avatar`,\n'
|
|
240
282
|
" GROUP_CONCAT(DISTINCT `role`.`name` SEPARATOR ';') AS `role_names`,\n"
|
|
241
283
|
" GROUP_CONCAT(DISTINCT `perm`.`name` SEPARATOR ';') AS `perm_names`,\n"
|
|
@@ -243,8 +285,7 @@ async def create_sessions(
|
|
|
243
285
|
'FROM (\n'
|
|
244
286
|
' SELECT `create_time`, `update_time`, `user_id`, `password`, `name`, `email`, `phone`, `avatar`\n'
|
|
245
287
|
' FROM `test`.`user`\n'
|
|
246
|
-
f'
|
|
247
|
-
' LIMIT 1\n'
|
|
288
|
+
f'{sql_where}'
|
|
248
289
|
') as `user`\n'
|
|
249
290
|
'LEFT JOIN (\n'
|
|
250
291
|
' SELECT `user_id`, `role_id`\n'
|
|
@@ -262,7 +303,7 @@ async def create_sessions(
|
|
|
262
303
|
') as `role_perm`\n'
|
|
263
304
|
'ON `role_perm`.`role_id` = `role`.`role_id`\n'
|
|
264
305
|
'LEFT JOIN (\n'
|
|
265
|
-
" SELECT `perm_id`, `name`,
|
|
306
|
+
" SELECT `perm_id`, `name`, `api`\n"
|
|
266
307
|
' FROM `test`.`perm`\n'
|
|
267
308
|
') AS `perm`\n'
|
|
268
309
|
'ON `role_perm`.`perm_id` = `perm`.`perm_id`\n'
|
|
@@ -273,34 +314,136 @@ async def create_sessions(
|
|
|
273
314
|
account=account
|
|
274
315
|
)
|
|
275
316
|
|
|
276
|
-
#
|
|
317
|
+
# Extract.
|
|
277
318
|
if result.empty:
|
|
319
|
+
info = None
|
|
320
|
+
else:
|
|
321
|
+
row: dict[str, Datetime | Any] = result.to_row()
|
|
322
|
+
info: UserInfo = {
|
|
323
|
+
'create_time': row['create_time'].timestamp(),
|
|
324
|
+
'udpate_time': row['update_time'].timestamp(),
|
|
325
|
+
'user_id': row['user_id'],
|
|
326
|
+
'user_name': row['user_name'],
|
|
327
|
+
'role_names': row['role_names'].split(';'),
|
|
328
|
+
'perm_names': row['perm_names'].split(';'),
|
|
329
|
+
'perm_apis': row['perm_apis'].split(';'),
|
|
330
|
+
'email': row['email'],
|
|
331
|
+
'phone': row['phone'],
|
|
332
|
+
'avatar': row['avatar'],
|
|
333
|
+
'password': row['password']
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return info
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
@auth_router.post('/sessions')
|
|
340
|
+
async def create_sessions(
|
|
341
|
+
account: str = Bind.i.body,
|
|
342
|
+
password: str = Bind.i.body,
|
|
343
|
+
account_type: Literal['name', 'email', 'phone'] = Bind.Body('name'),
|
|
344
|
+
conn: Bind.Conn = Bind.conn.auth,
|
|
345
|
+
server: Bind.Server = Bind.server
|
|
346
|
+
) -> dict:
|
|
347
|
+
"""
|
|
348
|
+
Create session.
|
|
349
|
+
|
|
350
|
+
Parameters
|
|
351
|
+
----------
|
|
352
|
+
account : User account.
|
|
353
|
+
password : User password.
|
|
354
|
+
account_type : User account type.
|
|
355
|
+
- `Literal['name']`: User name.
|
|
356
|
+
- `Literal['email']`: User Email.
|
|
357
|
+
- `Literal['phone']`: User phone mumber.
|
|
358
|
+
|
|
359
|
+
Returns
|
|
360
|
+
-------
|
|
361
|
+
JSON with `token`.
|
|
362
|
+
"""
|
|
363
|
+
|
|
364
|
+
# Parameter.
|
|
365
|
+
key = server.api_auth_key
|
|
366
|
+
sess_seconds = server.api_auth_sess_seconds
|
|
367
|
+
|
|
368
|
+
# User information.
|
|
369
|
+
info = await get_user_info(conn, account, account_type)
|
|
370
|
+
|
|
371
|
+
# Check.
|
|
372
|
+
if info is None:
|
|
278
373
|
exit_api(401)
|
|
279
|
-
|
|
280
|
-
if not is_hash_bcrypt(password,
|
|
374
|
+
password_hash = info.pop('password')
|
|
375
|
+
if not is_hash_bcrypt(password, password_hash):
|
|
281
376
|
exit_api(401)
|
|
282
377
|
|
|
283
378
|
# JWT.
|
|
284
379
|
now_timestamp_s = now('timestamp_s')
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
380
|
+
user_id = info.pop('user_id')
|
|
381
|
+
data: Token = {
|
|
382
|
+
'sub': str(user_id),
|
|
383
|
+
'iat': now_timestamp_s,
|
|
384
|
+
'nbf': now_timestamp_s,
|
|
385
|
+
'exp': now_timestamp_s + sess_seconds,
|
|
386
|
+
'user': info
|
|
387
|
+
}
|
|
388
|
+
token = encode_jwt(data, key)
|
|
389
|
+
response = {'token': token}
|
|
390
|
+
|
|
391
|
+
return response
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
bearer = HTTPBearer(
|
|
395
|
+
scheme_name='RBACBearer',
|
|
396
|
+
description='Global authentication of based on RBAC model and Bearer framework.',
|
|
397
|
+
bearerFormat='JWT standard.',
|
|
398
|
+
auto_error=False
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
async def depend_auth(
|
|
403
|
+
request: Request,
|
|
404
|
+
server: Bind.Server = Bind.server,
|
|
405
|
+
auth: HTTPAuthorizationCredentials | None = Depends(bearer)
|
|
406
|
+
) -> None:
|
|
407
|
+
"""
|
|
408
|
+
Dependencie function of authentication.
|
|
409
|
+
|
|
410
|
+
Parameters
|
|
411
|
+
----------
|
|
412
|
+
request : Request.
|
|
413
|
+
server : Server.
|
|
414
|
+
auth : Authentication.
|
|
415
|
+
"""
|
|
416
|
+
|
|
417
|
+
# Check.
|
|
418
|
+
api_path = f'{request.method} {request.url.path}'
|
|
419
|
+
if (
|
|
420
|
+
not server.is_started_auth
|
|
421
|
+
or api_path == 'POST /sessions'
|
|
422
|
+
):
|
|
423
|
+
return
|
|
424
|
+
if auth is None:
|
|
425
|
+
exit_api(401)
|
|
426
|
+
|
|
427
|
+
# Parameter.
|
|
428
|
+
key = server.api_auth_key
|
|
429
|
+
token = auth.credentials
|
|
430
|
+
|
|
431
|
+
# Decode.
|
|
432
|
+
token = decode_jwt(token, key)
|
|
433
|
+
if token is None:
|
|
434
|
+
exit_api(401)
|
|
435
|
+
token: Token
|
|
436
|
+
request.state.token = token
|
|
437
|
+
|
|
438
|
+
# Check.
|
|
439
|
+
perm_apis = token['user']['perm_apis']
|
|
440
|
+
perm_apis = [
|
|
441
|
+
f'^{pattern}$'
|
|
442
|
+
for pattern in perm_apis
|
|
443
|
+
]
|
|
444
|
+
try:
|
|
445
|
+
result = search_batch(api_path, *perm_apis)
|
|
446
|
+
except PatternError:
|
|
447
|
+
exit_api(403)
|
|
448
|
+
if result is None:
|
|
449
|
+
exit_api(403)
|
reyserver/rbase.py
CHANGED
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
from typing import NoReturn, overload
|
|
12
|
+
from typing import Type, NoReturn, overload
|
|
13
13
|
from http import HTTPStatus
|
|
14
|
+
from fastapi import FastAPI
|
|
14
15
|
from fastapi import HTTPException, Request, UploadFile as File
|
|
15
16
|
from fastapi.params import (
|
|
16
17
|
Depends,
|
|
@@ -24,14 +25,13 @@ from fastapi.params import (
|
|
|
24
25
|
)
|
|
25
26
|
from reydb.rconn import DatabaseConnectionAsync
|
|
26
27
|
from reydb.rorm import DatabaseORMModel, DatabaseORMSessionAsync
|
|
27
|
-
from reykit.rbase import Base, Exit, StaticMeta,
|
|
28
|
+
from reykit.rbase import Base, Exit, StaticMeta, Singleton, throw
|
|
28
29
|
|
|
29
30
|
from . import rserver
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
__all__ = (
|
|
33
34
|
'ServerBase',
|
|
34
|
-
'ServerConfig',
|
|
35
35
|
'ServerExit',
|
|
36
36
|
'ServerExitAPI',
|
|
37
37
|
'exit_api',
|
|
@@ -50,15 +50,6 @@ class ServerBase(Base):
|
|
|
50
50
|
"""
|
|
51
51
|
|
|
52
52
|
|
|
53
|
-
class ServerConfig(ServerBase, metaclass=ConfigMeta):
|
|
54
|
-
"""
|
|
55
|
-
Config type.
|
|
56
|
-
"""
|
|
57
|
-
|
|
58
|
-
server: 'rserver.Server'
|
|
59
|
-
'Server instance.'
|
|
60
|
-
|
|
61
|
-
|
|
62
53
|
class ServerExit(ServerBase, Exit):
|
|
63
54
|
"""
|
|
64
55
|
Server exit type.
|
|
@@ -116,13 +107,13 @@ class ServerBindInstanceDatabaseSuper(ServerBase):
|
|
|
116
107
|
"""
|
|
117
108
|
|
|
118
109
|
|
|
119
|
-
async def depend_func():
|
|
110
|
+
async def depend_func(server: Bind.Server = Bind.server):
|
|
120
111
|
"""
|
|
121
112
|
Dependencie function of asynchronous database.
|
|
122
113
|
"""
|
|
123
114
|
|
|
124
115
|
# Parameter.
|
|
125
|
-
engine =
|
|
116
|
+
engine = server.db[name]
|
|
126
117
|
|
|
127
118
|
# Context.
|
|
128
119
|
match self:
|
|
@@ -320,6 +311,26 @@ class ServerBindInstance(ServerBase, Singleton):
|
|
|
320
311
|
return forms
|
|
321
312
|
|
|
322
313
|
|
|
314
|
+
async def depend_server(request: Request) -> 'rserver.Server':
|
|
315
|
+
"""
|
|
316
|
+
Dependencie function of now Server instance.
|
|
317
|
+
|
|
318
|
+
Parameters
|
|
319
|
+
----------
|
|
320
|
+
request : Request.
|
|
321
|
+
|
|
322
|
+
Returns
|
|
323
|
+
-------
|
|
324
|
+
Server.
|
|
325
|
+
"""
|
|
326
|
+
|
|
327
|
+
# Get.
|
|
328
|
+
app: FastAPI = request.app
|
|
329
|
+
server = app.extra['server']
|
|
330
|
+
|
|
331
|
+
return server
|
|
332
|
+
|
|
333
|
+
|
|
323
334
|
class ServerBind(ServerBase, metaclass=StaticMeta):
|
|
324
335
|
"""
|
|
325
336
|
Server API bind parameter type.
|
|
@@ -338,6 +349,8 @@ class ServerBind(ServerBase, metaclass=StaticMeta):
|
|
|
338
349
|
JSON = DatabaseORMModel
|
|
339
350
|
Conn = DatabaseConnectionAsync
|
|
340
351
|
Sess = DatabaseORMSessionAsync
|
|
352
|
+
Server = Type['rserver.Server']
|
|
353
|
+
server = Depends(depend_server)
|
|
341
354
|
i = ServerBindInstance()
|
|
342
355
|
conn = ServerBindInstanceDatabaseConnection()
|
|
343
356
|
sess = ServerBindInstanceDatabaseSession()
|
reyserver/rfile.py
CHANGED
|
@@ -14,7 +14,7 @@ from fastapi.responses import FileResponse
|
|
|
14
14
|
from reydb import rorm, DatabaseEngine, DatabaseEngineAsync
|
|
15
15
|
from reykit.ros import FileStore, get_md5
|
|
16
16
|
|
|
17
|
-
from .rbase import
|
|
17
|
+
from .rbase import Bind, exit_api
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
__all__ = (
|
|
@@ -212,7 +212,8 @@ async def upload_file(
|
|
|
212
212
|
file: Bind.File = Bind.i.forms,
|
|
213
213
|
name: str = Bind.i.forms_n,
|
|
214
214
|
note: str = Bind.i.forms_n,
|
|
215
|
-
sess: Bind.Sess = Bind.sess.file
|
|
215
|
+
sess: Bind.Sess = Bind.sess.file,
|
|
216
|
+
server: Bind.Server = Bind.server
|
|
216
217
|
) -> DatabaseORMTableInfo:
|
|
217
218
|
"""
|
|
218
219
|
Upload file.
|
|
@@ -229,7 +230,7 @@ async def upload_file(
|
|
|
229
230
|
"""
|
|
230
231
|
|
|
231
232
|
# Handle parameter.
|
|
232
|
-
file_store = FileStore(
|
|
233
|
+
file_store = FileStore(server.api_file_dir)
|
|
233
234
|
file_bytes = await file.read()
|
|
234
235
|
file_md5 = get_md5(file_bytes)
|
|
235
236
|
file_size = len(file_bytes)
|
reyserver/rserver.py
CHANGED
|
@@ -16,6 +16,7 @@ from contextlib import asynccontextmanager, _AsyncGeneratorContextManager
|
|
|
16
16
|
from uvicorn import run as uvicorn_run
|
|
17
17
|
from starlette.middleware.base import _StreamingResponse
|
|
18
18
|
from fastapi import FastAPI, Request
|
|
19
|
+
from fastapi.params import Depends
|
|
19
20
|
from fastapi.staticfiles import StaticFiles
|
|
20
21
|
from fastapi.middleware.gzip import GZipMiddleware
|
|
21
22
|
from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
|
|
@@ -23,7 +24,7 @@ from reydb import rorm, DatabaseAsync, DatabaseEngineAsync
|
|
|
23
24
|
from reykit.rbase import CoroutineFunctionSimple, Singleton, throw
|
|
24
25
|
from reykit.rrand import randchar
|
|
25
26
|
|
|
26
|
-
from .rbase import ServerBase,
|
|
27
|
+
from .rbase import ServerBase, Bind
|
|
27
28
|
from . import radmin
|
|
28
29
|
|
|
29
30
|
|
|
@@ -68,6 +69,8 @@ class Server(ServerBase, Singleton):
|
|
|
68
69
|
debug : Whether use development mode debug server.
|
|
69
70
|
"""
|
|
70
71
|
|
|
72
|
+
from .rauth import depend_auth
|
|
73
|
+
|
|
71
74
|
# Parameter.
|
|
72
75
|
if type(ssl_cert) != type(ssl_key):
|
|
73
76
|
throw(AssertionError, ssl_cert, ssl_key)
|
|
@@ -76,13 +79,14 @@ class Server(ServerBase, Singleton):
|
|
|
76
79
|
elif iscoroutinefunction(depend):
|
|
77
80
|
depend = (depend,)
|
|
78
81
|
depend = [
|
|
82
|
+
Bind.Depend(depend_auth)
|
|
83
|
+
] + [
|
|
79
84
|
Bind.Depend(task)
|
|
80
85
|
for task in depend
|
|
81
86
|
]
|
|
82
87
|
lifespan = self.__create_lifespan(before, after, db_warm)
|
|
83
88
|
|
|
84
89
|
# Build.
|
|
85
|
-
ServerConfig.server = self
|
|
86
90
|
self.db = db
|
|
87
91
|
self.ssl_cert = ssl_cert
|
|
88
92
|
self.ssl_key = ssl_key
|
|
@@ -91,7 +95,8 @@ class Server(ServerBase, Singleton):
|
|
|
91
95
|
self.app = FastAPI(
|
|
92
96
|
dependencies=depend,
|
|
93
97
|
lifespan=lifespan,
|
|
94
|
-
debug=debug
|
|
98
|
+
debug=debug,
|
|
99
|
+
server=self
|
|
95
100
|
)
|
|
96
101
|
|
|
97
102
|
if public is not None:
|
|
@@ -107,6 +112,8 @@ class Server(ServerBase, Singleton):
|
|
|
107
112
|
self.__add_default_middleware()
|
|
108
113
|
|
|
109
114
|
# API.
|
|
115
|
+
self.is_started_auth: bool = False
|
|
116
|
+
'Whether start authentication.'
|
|
110
117
|
self.api_auth_key: str
|
|
111
118
|
'Authentication API JWT encryption key.'
|
|
112
119
|
self.api_auth_sess_seconds: int
|
|
@@ -185,7 +192,7 @@ class Server(ServerBase, Singleton):
|
|
|
185
192
|
|
|
186
193
|
# Add.
|
|
187
194
|
@self.wrap_middleware
|
|
188
|
-
async def
|
|
195
|
+
async def middleware(
|
|
189
196
|
request: Request,
|
|
190
197
|
call_next: Callable[[Request], Coroutine[None, None, _StreamingResponse]]
|
|
191
198
|
) -> _StreamingResponse:
|
|
@@ -262,6 +269,16 @@ class Server(ServerBase, Singleton):
|
|
|
262
269
|
setattr(self.app, key, value)
|
|
263
270
|
|
|
264
271
|
|
|
272
|
+
def add_api_base(self) -> None:
|
|
273
|
+
"""
|
|
274
|
+
Add base API.
|
|
275
|
+
"""
|
|
276
|
+
from fastapi import Request
|
|
277
|
+
@self.app.get('/test')
|
|
278
|
+
async def test(request: Request) -> str:
|
|
279
|
+
return 'test'
|
|
280
|
+
|
|
281
|
+
|
|
265
282
|
def add_api_admin(self) -> None:
|
|
266
283
|
"""
|
|
267
284
|
Add admin API.
|
|
@@ -315,13 +332,14 @@ class Server(ServerBase, Singleton):
|
|
|
315
332
|
"""
|
|
316
333
|
|
|
317
334
|
from .rauth import (
|
|
318
|
-
build_auth_db,
|
|
319
|
-
auth_router,
|
|
320
335
|
DatabaseORMTableUser,
|
|
321
336
|
DatabaseORMTableRole,
|
|
322
337
|
DatabaseORMTablePerm,
|
|
323
338
|
DatabaseORMTableUserRole,
|
|
324
|
-
DatabaseORMTableRolePerm
|
|
339
|
+
DatabaseORMTableRolePerm,
|
|
340
|
+
build_auth_db,
|
|
341
|
+
auth_router,
|
|
342
|
+
depend_auth
|
|
325
343
|
)
|
|
326
344
|
|
|
327
345
|
# Parameter.
|
|
@@ -338,6 +356,7 @@ class Server(ServerBase, Singleton):
|
|
|
338
356
|
self.api_auth_key = key
|
|
339
357
|
self.api_auth_sess_seconds = sess_seconds
|
|
340
358
|
self.app.include_router(auth_router, tags=['auth'])
|
|
359
|
+
self.is_started_auth = True
|
|
341
360
|
|
|
342
361
|
## Admin.
|
|
343
362
|
self.add_admin_model(DatabaseORMTableUser, engine, category='auth', name='User', column_list=['user_id', 'name'])
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
reyserver/__init__.py,sha256=Oq-lOcQInzhgKt1_4OB2jNx0OO2d9qZg9iZqUx6YRr8,398
|
|
2
|
+
reyserver/radmin.py,sha256=Hwy8QsiQOyK2YP7abcS22IbRKB7sgcDGPHQ2-mHtf-8,3269
|
|
3
|
+
reyserver/rall.py,sha256=MI1NnqUpq22CK9w3XPPBS0K8lNuf0BnbI0pn4MGMx38,293
|
|
4
|
+
reyserver/rauth.py,sha256=irnwf1_OSOjB9fB7VBWY5RvpetPX2ydivMt_teXmDVs,15079
|
|
5
|
+
reyserver/rbase.py,sha256=kzSbo6yoPlWquR6XiseTKi5hEbllaG3qVmmwnnKKac0,6898
|
|
6
|
+
reyserver/rclient.py,sha256=Ffm66YuWupzEtQ6RqEm2KCc6jSF8JeMB7Xq6pzRFZ6M,5073
|
|
7
|
+
reyserver/rfile.py,sha256=0wS-ohsAOGcSCg07U66wpqJlxnCLWN6gkEQJK4qavWQ,8877
|
|
8
|
+
reyserver/rserver.py,sha256=mjc-SeE2RZZwB5Z1nUSMo_VMign3VcftIK1Kv7XIne8,11484
|
|
9
|
+
reyserver-1.1.59.dist-info/METADATA,sha256=oJNACNqqErBtx9jcDkkGRQoTyDaFT-T5tnfbEkVm-6E,1666
|
|
10
|
+
reyserver-1.1.59.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
11
|
+
reyserver-1.1.59.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
|
|
12
|
+
reyserver-1.1.59.dist-info/RECORD,,
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
reyserver/__init__.py,sha256=Oq-lOcQInzhgKt1_4OB2jNx0OO2d9qZg9iZqUx6YRr8,398
|
|
2
|
-
reyserver/radmin.py,sha256=Hwy8QsiQOyK2YP7abcS22IbRKB7sgcDGPHQ2-mHtf-8,3269
|
|
3
|
-
reyserver/rall.py,sha256=MI1NnqUpq22CK9w3XPPBS0K8lNuf0BnbI0pn4MGMx38,293
|
|
4
|
-
reyserver/rauth.py,sha256=5zQwi7eGjhHD2BHGQDQclLCn3HHg646Q4Cp2Bt6i3uc,11701
|
|
5
|
-
reyserver/rbase.py,sha256=_bP_suBPF7dLd4RNKn96-X4ZAEx3vAjMS6vnheCokU4,6617
|
|
6
|
-
reyserver/rclient.py,sha256=Ffm66YuWupzEtQ6RqEm2KCc6jSF8JeMB7Xq6pzRFZ6M,5073
|
|
7
|
-
reyserver/rfile.py,sha256=CH2uJbBNmBH9ISDirn1LWL5wsjGW5xjB9ZIrdc5UzL0,8864
|
|
8
|
-
reyserver/rserver.py,sha256=9-bhgVn_XZ6bvBl4GLdGkUs4UR1TSG08WC3F6ETQo7M,10986
|
|
9
|
-
reyserver-1.1.58.dist-info/METADATA,sha256=l98QLYqG9iBeisPA5SgdMpu-aEZll2tWYnG4u7lCgfM,1666
|
|
10
|
-
reyserver-1.1.58.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
11
|
-
reyserver-1.1.58.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
|
|
12
|
-
reyserver-1.1.58.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|