Revize cbd239c6
Přidáno uživatelem Matěj Zeman před asi 2 roky(ů)
server/sql_app/api/auth.py | ||
---|---|---|
3 | 3 |
from fastapi.responses import HTMLResponse, RedirectResponse |
4 | 4 |
from fastapi.templating import Jinja2Templates |
5 | 5 |
from fastapi_jwt_auth import AuthJWT |
6 |
from sqlalchemy.orm import Session |
|
7 |
from sql_app import crud |
|
8 |
from passlib.context import CryptContext |
|
6 | 9 |
from pydantic import BaseModel |
10 |
from ..database import SessionLocal, engine |
|
7 | 11 |
|
8 | 12 |
# Path to html templates used in this file |
9 | 13 |
templates = Jinja2Templates(directory="templates/auth") |
10 | 14 |
|
15 |
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") |
|
16 |
|
|
11 | 17 |
# prefix used for all endpoints in this file |
12 | 18 |
auth = APIRouter(prefix="") |
13 | 19 |
|
14 | 20 |
|
21 |
# Dependency |
|
22 |
def get_db(): |
|
23 |
db = SessionLocal() |
|
24 |
try: |
|
25 |
yield db |
|
26 |
finally: |
|
27 |
db.close() |
|
28 |
|
|
15 | 29 |
|
16 | 30 |
class Settings(BaseModel): |
17 | 31 |
authjwt_secret_key: str = "secret" |
... | ... | |
25 | 39 |
def get_config(): |
26 | 40 |
return Settings() |
27 | 41 |
|
42 |
|
|
28 | 43 |
# admin username and password |
29 | 44 |
fake_users_db = { |
30 | 45 |
"admin": { |
... | ... | |
34 | 49 |
} |
35 | 50 |
|
36 | 51 |
|
52 |
def verify_password(plain_password, hashed_password): |
|
53 |
return pwd_context.verify(plain_password, hashed_password) |
|
54 |
|
|
55 |
|
|
56 |
def get_hash_password(password): |
|
57 |
return pwd_context.hash(password) |
|
58 |
|
|
59 |
|
|
60 |
def auth_user(db, username: str, password: str): |
|
61 |
user = crud.find_user(db, username) |
|
62 |
if not user: |
|
63 |
return None |
|
64 |
if not verify_password(password, user.password): |
|
65 |
return None |
|
66 |
return user |
|
67 |
|
|
68 |
|
|
69 |
@auth.get("/signup", response_class=HTMLResponse) |
|
70 |
async def signup_get(request: Request): |
|
71 |
""" |
|
72 |
return html template for signup |
|
73 |
""" |
|
74 |
return templates.TemplateResponse("signup.html", {"request": request}) |
|
75 |
|
|
76 |
|
|
77 |
@auth.post("/signup", response_class=HTMLResponse) |
|
78 |
async def signup(username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db)): |
|
79 |
""" |
|
80 |
Endpoint called form signup template. Creates new user with role guest that can be changed by admin user |
|
81 |
""" |
|
82 |
users = crud.get_users(db, 0, 100) |
|
83 |
users_names = [] |
|
84 |
for u in users: |
|
85 |
users_names.append(u.username) |
|
86 |
if username not in users_names: |
|
87 |
new_user = crud.create_user(db, username, get_hash_password(password), "guest") |
|
88 |
if new_user is None: |
|
89 |
print("something went wrong") |
|
90 |
return """ |
|
91 |
<html> |
|
92 |
<head> |
|
93 |
<title>Signup</title> |
|
94 |
</head> |
|
95 |
<body> |
|
96 |
<h1>Signed in</h1> |
|
97 |
<form action="/logs-web" method="get"> |
|
98 |
<input type="submit" value="Back" /> |
|
99 |
</form> |
|
100 |
</body> |
|
101 |
</html> |
|
102 |
""" |
|
103 |
else: |
|
104 |
return """ |
|
105 |
<html> |
|
106 |
<head> |
|
107 |
<title>Signup</title> |
|
108 |
</head> |
|
109 |
<body> |
|
110 |
<h1>Username taken</h1> |
|
111 |
<form action="/logs-web" method="get"> |
|
112 |
<input type="submit" value="Back" /> |
|
113 |
</form> |
|
114 |
</body> |
|
115 |
</html> |
|
116 |
""" |
|
117 |
|
|
37 | 118 |
@auth.get("/login", response_class=HTMLResponse) |
38 | 119 |
async def login_get(request: Request): |
39 | 120 |
""" |
... | ... | |
43 | 124 |
|
44 | 125 |
|
45 | 126 |
@auth.post("/login", response_class=HTMLResponse) |
46 |
async def login(username: str = Form(...), password: str = Form(...), Authorize: AuthJWT = Depends()): |
|
127 |
async def login(username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db), |
|
128 |
Authorize: AuthJWT = Depends()): |
|
47 | 129 |
""" |
48 | 130 |
Endpoint called from login template. Checks if given username and password aligns with admin |
49 | 131 |
username and password and returns token for browser according to given username and password |
50 | 132 |
""" |
51 |
user_dict = fake_users_db.get(username)
|
|
52 |
if user_dict != None:
|
|
53 |
if user_dict["username"] == username and user_dict["password"] == password:
|
|
133 |
user = auth_user(db, username, password)
|
|
134 |
if user != None: |
|
135 |
if user.role == "admin":
|
|
54 | 136 |
access_token = Authorize.create_access_token(subject="admin", expires_time=False) |
55 | 137 |
refresh_token = Authorize.create_refresh_token(subject="admin", expires_time=False) |
56 | 138 |
else: |
57 |
access_token = Authorize.create_access_token(subject="host", expires_time=False)
|
|
58 |
refresh_token = Authorize.create_refresh_token(subject="host", expires_time=False)
|
|
139 |
access_token = Authorize.create_access_token(subject="guest", expires_time=False)
|
|
140 |
refresh_token = Authorize.create_refresh_token(subject="guest", expires_time=False)
|
|
59 | 141 |
else: |
60 |
access_token = Authorize.create_access_token(subject="host", expires_time=False) |
|
61 |
refresh_token = Authorize.create_refresh_token(subject="host", expires_time=False) |
|
142 |
usr = fake_users_db.get(username) |
|
143 |
if usr != None: |
|
144 |
if usr["username"] == username and usr["password"] == password: |
|
145 |
access_token = Authorize.create_access_token(subject="admin", expires_time=False) |
|
146 |
refresh_token = Authorize.create_refresh_token(subject="admin", expires_time=False) |
|
147 |
else: |
|
148 |
return """ |
|
149 |
<html> |
|
150 |
<head> |
|
151 |
<title>Login</title> |
|
152 |
</head> |
|
153 |
<body> |
|
154 |
<h1>Wrong Username or Password</h1> |
|
155 |
<form action="/login" method="get"> |
|
156 |
<input type="submit" value="Back" /> |
|
157 |
</form> |
|
158 |
</body> |
|
159 |
</html> |
|
160 |
""" |
|
62 | 161 |
|
63 | 162 |
# Set the JWT cookies in the response |
64 | 163 |
Authorize.set_access_cookies(access_token) |
... | ... | |
112 | 211 |
</form> |
113 | 212 |
</body> |
114 | 213 |
</html> |
115 |
""" |
|
214 |
""" |
Také k dispozici: Unified diff
Added signup and users table in database. Passwords are hashed. Added view for changing users roles.