1
- from fastapi import APIRouter , Depends , HTTPException , status , Query
1
+ import hashlib
2
+ import os
3
+
4
+ import aiofiles
5
+ from fastapi import APIRouter , Depends , HTTPException , status , Query , UploadFile
2
6
from fastapi .security import OAuth2PasswordRequestForm
3
7
from pydantic .schema import timedelta
4
- from sqlalchemy .orm import Session
8
+ from sqlalchemy .ext .asyncio import AsyncSession
9
+ from starlette .requests import Request
5
10
6
11
from config import Config
7
12
from sql import crud
8
13
from sql .database import get_session
14
+ from .adminapi import get_is_Allow_register , limiter
9
15
from .token import authenticate_user , create_access_token , get_current_user
10
- from .verifyModel import UserCreate , RegisterSuccess , UserOut , Token , TokenData , Userbase , UpdateSuccess , PubUserInfo
16
+ from .verifyModel import UserCreate , RegisterSuccess , UserOut , Token , TokenData , Userbase , UpdateSuccess , PubUserInfo , \
17
+ UploadSuccess
11
18
12
19
userapp = APIRouter ()
13
20
14
21
15
22
@userapp .post ("/token" , response_model = Token )
16
- async def login_for_access_token (form_data : OAuth2PasswordRequestForm = Depends (),
17
- session : Session = Depends (get_session )):
23
+ @limiter .limit (limit_value = "5/minute" )
24
+ async def login_for_access_token (request : Request , form_data : OAuth2PasswordRequestForm = Depends (),
25
+ session : AsyncSession = Depends (get_session )):
18
26
user = await authenticate_user (session = session , username = form_data .username , password = form_data .password )
19
27
if not user :
20
28
raise HTTPException (
@@ -31,16 +39,22 @@ async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends(
31
39
32
40
33
41
@userapp .post ("/register" , description = '用户注册' , response_model = RegisterSuccess )
34
- async def register (user_in : UserCreate , session : Session = Depends (get_session )):
35
- await crud .create_user (session , user_in )
36
- u = crud .findUser_by_name (session , user_in .username )
37
- return RegisterSuccess .from_userOut (userout = u , detail = "注册成功" , )
42
+ @limiter .limit (limit_value = "5/minute" )
43
+ async def register (request : Request , user_in : UserCreate , session : AsyncSession = Depends (get_session )):
44
+ if get_is_Allow_register ():
45
+ await crud .create_user (session , user_in )
46
+ u = await crud .findUser_by_name (session , user_in .username )
47
+ return RegisterSuccess .from_userOut (userout = u , detail = "注册成功" , )
48
+ else :
49
+ raise HTTPException (status_code = status .HTTP_400_BAD_REQUEST , detail = '不允许注册' )
38
50
39
51
40
52
@userapp .get ("/pubInfo" , response_model = PubUserInfo )
53
+ @limiter .limit (limit_value = "10/minute" )
41
54
async def publish_user_info (
55
+ request : Request ,
42
56
username : str = Query (default = ..., max_length = 30 ),
43
- session : Session = Depends (get_session )
57
+ session : AsyncSession = Depends (get_session )
44
58
):
45
59
user = await crud .findPubUser_by_name (session , username )
46
60
if user is not None :
@@ -50,7 +64,7 @@ async def publish_user_info(
50
64
51
65
52
66
@userapp .get ("/info" , response_model = UserOut )
53
- async def userinfo (session : Session = Depends (get_session ), current_user : TokenData = Depends (get_current_user )):
67
+ async def userinfo (session : AsyncSession = Depends (get_session ), current_user : TokenData = Depends (get_current_user )):
54
68
user = await crud .findUser_by_name (session , current_user .username )
55
69
if user is not None :
56
70
return user
@@ -60,26 +74,57 @@ async def userinfo(session: Session = Depends(get_session), current_user: TokenD
60
74
61
75
@userapp .put ("/update_username" , response_model = UpdateSuccess )
62
76
async def update_username (old_password : str , username_new : str ,
63
- session : Session = Depends (get_session ),
77
+ session : AsyncSession = Depends (get_session ),
64
78
current_user : TokenData = Depends (get_current_user )):
65
- r = await crud .change_user_name (session ,
66
- user_old = Userbase (username = current_user .username , password = old_password ),
67
- username_new = username_new )
79
+ try :
80
+ user_old = Userbase (username = current_user .username , password = old_password )
81
+ except Exception as e :
82
+ raise HTTPException (status_code = status .HTTP_406_NOT_ACCEPTABLE , detail = str (e ))
83
+ r = await crud .change_user_name (session , user_old = user_old , username_new = username_new )
68
84
return r
69
85
70
86
71
87
@userapp .put ("/update_password" , response_model = UpdateSuccess )
72
88
async def update_password (old_password : str , password_new : str ,
73
- session : Session = Depends (get_session ),
89
+ session : AsyncSession = Depends (get_session ),
74
90
current_user : TokenData = Depends (get_current_user )):
75
- r = await crud .change_user_passwd (session ,
76
- user_old = Userbase (username = current_user .username , password = old_password ),
77
- password_new = password_new )
91
+ try :
92
+ user_old = Userbase (username = current_user .username , password = old_password )
93
+ except Exception as e :
94
+ raise HTTPException (status_code = status .HTTP_406_NOT_ACCEPTABLE , detail = str (e ))
95
+ r = await crud .change_user_passwd (session , user_old = user_old , password_new = password_new )
78
96
return r
79
97
80
98
81
- @userapp .put ("/update_avatar" , response_model = UpdateSuccess )
82
- async def update_username (avatar_new : str , session : Session = Depends (get_session ),
99
+ @userapp .put ("/update_avatar" , response_model = UploadSuccess )
100
+ @limiter .limit (limit_value = "5/minute" )
101
+ async def update_username (request : Request , avatar_new : UploadFile , session : AsyncSession = Depends (get_session ),
83
102
current_user : TokenData = Depends (get_current_user )):
84
- r = await crud .change_user_avatar (session , username = current_user .username , new_avatar = avatar_new )
103
+ fileinfo = await upload (avatar_new )
104
+ r = await crud .change_user_avatar (session , username = current_user .username , fileinfo = fileinfo )
85
105
return r
106
+
107
+
108
+ @userapp .post ("/upload_file/" , response_model = UploadSuccess , dependencies = [Depends (get_current_user )])
109
+ @limiter .limit (limit_value = "5/minute" )
110
+ async def create_upload_file (request : Request , file : UploadFile ):
111
+ return await upload (file )
112
+
113
+
114
+ async def upload (file : UploadFile ):
115
+ ext = os .path .splitext (file .filename )[1 ]
116
+ if ext not in {".jpg" , ".jpeg" , ".png" , ".gif" }:
117
+ raise HTTPException (status_code = 400 , detail = "Invalid file extension." )
118
+
119
+ data = await file .read ()
120
+ if len (data ) > Config ['MAX_FILE_SIZE_MB' ] * 1048576 :
121
+ raise HTTPException (status_code = 400 , detail = f"File size = { round (len (data ) / 1048576 , 2 )} MB exceeds the limit." )
122
+
123
+ md5 = hashlib .md5 (data ).hexdigest ()
124
+ filename = f"{ md5 } { ext } "
125
+ file_path = os .path .join (os .path .dirname (__file__ ), ".." , "uploads" , filename )
126
+ if os .path .exists (file_path ):
127
+ return UploadSuccess (filename = filename , content_type = file .content_type , detail = "文件已存在" )
128
+ async with aiofiles .open (file_path , "wb" ) as buffer :
129
+ await buffer .write (data )
130
+ return UploadSuccess (filename = filename + ext , content_type = file .content_type , detail = "上传成功" )
0 commit comments