-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
91 lines (67 loc) · 2.63 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import jwt
from enum import unique
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from tortoise.models import Model
from passlib.hash import bcrypt
from tortoise import fields
from tortoise.contrib.fastapi import register_tortoise
from tortoise.contrib.pydantic import pydantic_model_creator
app = FastAPI()
JWT_SECRET = 'myjwtsecret'
class User(Model):
id = fields.IntField(pk=True)
username = fields.CharField(50, unique=True)
password_hash = fields.CharField(255)
# @classmethod
# async def get_user(cls, username):
# return cls.get(username=username)
def verify_password(self, password):
return bcrypt.verify(password, self.password_hash)
User_Pydantic = pydantic_model_creator(User, name='User')
UserIn_Pydantic = pydantic_model_creator(User, name='UserIn', exclude_readonly=True)
oauth2_scheme = OAuth2PasswordBearer(tokenUrl='token')
async def authenticate_user(username: str, password: str):
user = await User.get(username=username)
if not user:
return False
if not user.verify_password(password):
return False
return user
@app.post('/token')
async def generate_token(form_data: OAuth2PasswordRequestForm = Depends()):
user = await authenticate_user(form_data.username, form_data.password)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail='Invalid username or password'
)
user_obj = await User_Pydantic.from_tortoise_orm(user)
print(user_obj.id)
token = jwt.encode(user_obj.dict(), JWT_SECRET)
return {'access_token': token, 'token_type': 'bearer'}
async def get_current_user(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, JWT_SECRET, algorithms=['HS256'])
user = await User.get(id=payload.get('id'))
except:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail='Invalid username or password'
)
return await User_Pydantic.from_tortoise_orm(user)
@app.post('/users')
async def create_user(user: UserIn_Pydantic):
user_obj = User(username=user.username, password_hash=bcrypt.hash(user.password_hash))
await user_obj.save()
return await User_Pydantic.from_tortoise_orm(user_obj)
@app.get('/users/me', response_model=User_Pydantic)
async def get_user(user: User_Pydantic = Depends(get_current_user)):
return user
register_tortoise(
app,
db_url='sqlite://db.sqlite3',
modules={'models': ['main']},
generate_schemas=True,
add_exception_handlers=True
)