Projekt

Obecné

Profil

Stáhnout (7.14 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 1ad8f5ba Matej Zeman
        if usr is not None and (usr["username"] == username and usr["password"] == password):
153
            access_token = Authorize.create_access_token(subject="admin", expires_time=False)
154
            refresh_token = Authorize.create_refresh_token(subject="admin", expires_time=False)
155 cbd239c6 Matej Zeman
        else:
156
            return """
157
                <html>
158
                    <head>
159
                        <title>Login</title>
160
                    </head>
161
                    <body>
162
                        <h1>Wrong Username or Password</h1>
163
                        <form action="/login" method="get">
164 2552e614 Matej Zeman
                            <input type="submit" value="Log again" />
165
                        </form>
166
                        <form action="/login" method="get">
167
                            <input type="submit" value="Home Page" />
168 cbd239c6 Matej Zeman
                        </form>
169
                    </body>
170
                </html>
171
                """
172 2fe004b1 Matej Zeman
173
    # Set the JWT cookies in the response
174
    Authorize.set_access_cookies(access_token)
175
    Authorize.set_refresh_cookies(refresh_token)
176
    return """
177
    <html>
178
        <head>
179
            <title>Login</title>
180
        </head>
181
        <body>
182 2552e614 Matej Zeman
            <h1>Now you are logged in, you can continue to previous page.</h1>
183 2fe004b1 Matej Zeman
            <form action="/logs-web" method="get">
184 2552e614 Matej Zeman
                <input type="submit" value="Home Page" />
185 2fe004b1 Matej Zeman
            </form>
186
        </body>
187
    </html>
188
    """
189
190
191
@auth.post('/refresh')
192
def refresh(Authorize: AuthJWT = Depends()):
193 7fe7be79 zemanm98@students.zcu.cz
    """
194
    endpoint for refreshing browser token. Not used at the moment since lifetime of given tokens are
195
    unlimited.
196
    """
197 2fe004b1 Matej Zeman
    Authorize.jwt_refresh_token_required()
198
    current_user = Authorize.get_jwt_subject()
199
    new_access_token = Authorize.create_access_token(subject=current_user)
200
    # Set the JWT cookies in the response
201
    Authorize.set_access_cookies(new_access_token)
202
    return {"msg": "The token has been refresh"}
203
204
205
@auth.get('/logout', response_class=HTMLResponse)
206
def logout(Authorize: AuthJWT = Depends()):
207
    """
208 7fe7be79 zemanm98@students.zcu.cz
    Endpoint for deleting cookie token with acces role.
209 2fe004b1 Matej Zeman
    """
210
    Authorize.jwt_optional()
211
212
    Authorize.unset_jwt_cookies()
213
    return """
214
        <html>
215
            <head>
216
                <title>Logout</title>
217
            </head>
218
            <body>
219
                <h1>Logged Out</h1>
220
                <form action="/logs-web" method="get">
221
                    <input type="submit" value="Back" />
222
                </form>
223
            </body>
224
        </html>
225 cbd239c6 Matej Zeman
        """