Projekt

Obecné

Profil

Stáhnout (7.15 KB) Statistiky
| Větev: | Tag: | Revize:
1 2fe004b1 Matej Zeman
from fastapi import Depends, APIRouter, Form
2
from fastapi import Request
3 5dc6d077 Matej Zeman
from fastapi.responses import HTMLResponse, RedirectResponse
4 2fe004b1 Matej Zeman
from fastapi.templating import Jinja2Templates
5
from fastapi_jwt_auth import AuthJWT
6 cbd239c6 Matej Zeman
from sqlalchemy.orm import Session
7
from sql_app import crud
8
from passlib.context import CryptContext
9 2fe004b1 Matej Zeman
from pydantic import BaseModel
10 cbd239c6 Matej Zeman
from ..database import SessionLocal, engine
11 2fe004b1 Matej Zeman
12
# Path to html templates used in this file
13
templates = Jinja2Templates(directory="templates/auth")
14
15 cbd239c6 Matej Zeman
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
16
17 2fe004b1 Matej Zeman
# prefix used for all endpoints in this file
18
auth = APIRouter(prefix="")
19
20
21 cbd239c6 Matej Zeman
# Dependency
22
def get_db():
23
    db = SessionLocal()
24
    try:
25
        yield db
26
    finally:
27
        db.close()
28
29 2fe004b1 Matej Zeman
30
class Settings(BaseModel):
31
    authjwt_secret_key: str = "secret"
32
    # Configure application to store and get JWT from cookies
33
    authjwt_token_location: set = {"cookies"}
34
    # Disable CSRF Protection for this example. default is True
35
    authjwt_cookie_csrf_protect: bool = False
36
37
38
@AuthJWT.load_config
39
def get_config():
40
    return Settings()
41
42 cbd239c6 Matej Zeman
43 7fe7be79 zemanm98@students.zcu.cz
# admin username and password
44 2fe004b1 Matej Zeman
fake_users_db = {
45
    "admin": {
46
        "username": "admin",
47
        "password": "admin"
48
    }
49
}
50
51
52 cbd239c6 Matej Zeman
def verify_password(plain_password, hashed_password):
53 0fcb708f Matej Zeman
    """
54
    Verifies plain text password with hashed password
55
    """
56 cbd239c6 Matej Zeman
    return pwd_context.verify(plain_password, hashed_password)
57
58
59
def get_hash_password(password):
60 0fcb708f Matej Zeman
    """
61
    Returns hashed password
62
    """
63 cbd239c6 Matej Zeman
    return pwd_context.hash(password)
64
65
66
def auth_user(db, username: str, password: str):
67 0fcb708f Matej Zeman
    """
68
    Determines if given password belongs to user with given username
69
    """
70 cbd239c6 Matej Zeman
    user = crud.find_user(db, username)
71
    if not user:
72
        return None
73
    if not verify_password(password, user.password):
74
        return None
75
    return user
76
77
78
@auth.get("/signup", response_class=HTMLResponse)
79
async def signup_get(request: Request):
80
    """
81
    return html template for signup
82
    """
83
    return templates.TemplateResponse("signup.html", {"request": request})
84
85
86
@auth.post("/signup", response_class=HTMLResponse)
87
async def signup(username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db)):
88
    """
89
    Endpoint called form signup template. Creates new user with role guest that can be changed by admin user
90
    """
91
    users = crud.get_users(db, 0, 100)
92
    users_names = []
93
    for u in users:
94
        users_names.append(u.username)
95
    if username not in users_names:
96
        new_user = crud.create_user(db, username, get_hash_password(password), "guest")
97
        if new_user is None:
98
            print("something went wrong")
99
        return """
100
            <html>
101
                <head>
102
                    <title>Signup</title>
103
                </head>
104
                <body>
105 2552e614 Matej Zeman
                    <h1>New user created. You can go back to previous page.</h1>
106 cbd239c6 Matej Zeman
                    <form action="/logs-web" method="get">
107 2552e614 Matej Zeman
                        <input type="submit" value="Home Page" />
108 cbd239c6 Matej Zeman
                    </form>
109
                </body>
110
            </html>
111
            """
112
    else:
113
        return """
114
                    <html>
115
                        <head>
116
                            <title>Signup</title>
117
                        </head>
118
                        <body>
119 2552e614 Matej Zeman
                            <h1>Username taken. Try to choose different username.</h1>
120 cbd239c6 Matej Zeman
                            <form action="/logs-web" method="get">
121 2552e614 Matej Zeman
                                <input type="submit" value="Home Page" />
122 cbd239c6 Matej Zeman
                            </form>
123
                        </body>
124
                    </html>
125
                    """
126
127 2fe004b1 Matej Zeman
@auth.get("/login", response_class=HTMLResponse)
128
async def login_get(request: Request):
129 7fe7be79 zemanm98@students.zcu.cz
    """
130
    return html template for login
131
    """
132 2fe004b1 Matej Zeman
    return templates.TemplateResponse("login.html", {"request": request})
133
134
135
@auth.post("/login", response_class=HTMLResponse)
136 cbd239c6 Matej Zeman
async def login(username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db),
137
                Authorize: AuthJWT = Depends()):
138 7fe7be79 zemanm98@students.zcu.cz
    """
139
    Endpoint called from login template. Checks if given username and password aligns with admin
140
    username and password and returns token for browser according to given username and password
141
    """
142 cbd239c6 Matej Zeman
    user = auth_user(db, username, password)
143
    if user != None:
144
        if user.role == "admin":
145 2fe004b1 Matej Zeman
            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 cbd239c6 Matej Zeman
            access_token = Authorize.create_access_token(subject="guest", expires_time=False)
149
            refresh_token = Authorize.create_refresh_token(subject="guest", expires_time=False)
150 2fe004b1 Matej Zeman
    else:
151 cbd239c6 Matej Zeman
        usr = fake_users_db.get(username)
152
        if usr != None:
153
            if usr["username"] == username and usr["password"] == password:
154
                access_token = Authorize.create_access_token(subject="admin", expires_time=False)
155
                refresh_token = Authorize.create_refresh_token(subject="admin", expires_time=False)
156
        else:
157
            return """
158
                <html>
159
                    <head>
160
                        <title>Login</title>
161
                    </head>
162
                    <body>
163
                        <h1>Wrong Username or Password</h1>
164
                        <form action="/login" method="get">
165 2552e614 Matej Zeman
                            <input type="submit" value="Log again" />
166
                        </form>
167
                        <form action="/login" method="get">
168
                            <input type="submit" value="Home Page" />
169 cbd239c6 Matej Zeman
                        </form>
170
                    </body>
171
                </html>
172
                """
173 2fe004b1 Matej Zeman
174
    # Set the JWT cookies in the response
175
    Authorize.set_access_cookies(access_token)
176
    Authorize.set_refresh_cookies(refresh_token)
177
    return """
178
    <html>
179
        <head>
180
            <title>Login</title>
181
        </head>
182
        <body>
183 2552e614 Matej Zeman
            <h1>Now you are logged in, you can continue to previous page.</h1>
184 2fe004b1 Matej Zeman
            <form action="/logs-web" method="get">
185 2552e614 Matej Zeman
                <input type="submit" value="Home Page" />
186 2fe004b1 Matej Zeman
            </form>
187
        </body>
188
    </html>
189
    """
190
191
192
@auth.post('/refresh')
193
def refresh(Authorize: AuthJWT = Depends()):
194 7fe7be79 zemanm98@students.zcu.cz
    """
195
    endpoint for refreshing browser token. Not used at the moment since lifetime of given tokens are
196
    unlimited.
197
    """
198 2fe004b1 Matej Zeman
    Authorize.jwt_refresh_token_required()
199
    current_user = Authorize.get_jwt_subject()
200
    new_access_token = Authorize.create_access_token(subject=current_user)
201
    # Set the JWT cookies in the response
202
    Authorize.set_access_cookies(new_access_token)
203
    return {"msg": "The token has been refresh"}
204
205
206
@auth.get('/logout', response_class=HTMLResponse)
207
def logout(Authorize: AuthJWT = Depends()):
208
    """
209 7fe7be79 zemanm98@students.zcu.cz
    Endpoint for deleting cookie token with acces role.
210 2fe004b1 Matej Zeman
    """
211
    Authorize.jwt_optional()
212
213
    Authorize.unset_jwt_cookies()
214
    return """
215
        <html>
216
            <head>
217
                <title>Logout</title>
218
            </head>
219
            <body>
220
                <h1>Logged Out</h1>
221
                <form action="/logs-web" method="get">
222
                    <input type="submit" value="Back" />
223
                </form>
224
            </body>
225
        </html>
226 cbd239c6 Matej Zeman
        """