Projekt

Obecné

Profil

Stáhnout (6.96 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
    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 2552e614 Matej Zeman
                    <h1>New user created. You can go back to previous page.</h1>
97 cbd239c6 Matej Zeman
                    <form action="/logs-web" method="get">
98 2552e614 Matej Zeman
                        <input type="submit" value="Home Page" />
99 cbd239c6 Matej Zeman
                    </form>
100
                </body>
101
            </html>
102
            """
103
    else:
104
        return """
105
                    <html>
106
                        <head>
107
                            <title>Signup</title>
108
                        </head>
109
                        <body>
110 2552e614 Matej Zeman
                            <h1>Username taken. Try to choose different username.</h1>
111 cbd239c6 Matej Zeman
                            <form action="/logs-web" method="get">
112 2552e614 Matej Zeman
                                <input type="submit" value="Home Page" />
113 cbd239c6 Matej Zeman
                            </form>
114
                        </body>
115
                    </html>
116
                    """
117
118 2fe004b1 Matej Zeman
@auth.get("/login", response_class=HTMLResponse)
119
async def login_get(request: Request):
120 7fe7be79 zemanm98@students.zcu.cz
    """
121
    return html template for login
122
    """
123 2fe004b1 Matej Zeman
    return templates.TemplateResponse("login.html", {"request": request})
124
125
126
@auth.post("/login", response_class=HTMLResponse)
127 cbd239c6 Matej Zeman
async def login(username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db),
128
                Authorize: AuthJWT = Depends()):
129 7fe7be79 zemanm98@students.zcu.cz
    """
130
    Endpoint called from login template. Checks if given username and password aligns with admin
131
    username and password and returns token for browser according to given username and password
132
    """
133 cbd239c6 Matej Zeman
    user = auth_user(db, username, password)
134
    if user != None:
135
        if user.role == "admin":
136 2fe004b1 Matej Zeman
            access_token = Authorize.create_access_token(subject="admin", expires_time=False)
137
            refresh_token = Authorize.create_refresh_token(subject="admin", expires_time=False)
138
        else:
139 cbd239c6 Matej Zeman
            access_token = Authorize.create_access_token(subject="guest", expires_time=False)
140
            refresh_token = Authorize.create_refresh_token(subject="guest", expires_time=False)
141 2fe004b1 Matej Zeman
    else:
142 cbd239c6 Matej Zeman
        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 2552e614 Matej Zeman
                            <input type="submit" value="Log again" />
157
                        </form>
158
                        <form action="/login" method="get">
159
                            <input type="submit" value="Home Page" />
160 cbd239c6 Matej Zeman
                        </form>
161
                    </body>
162
                </html>
163
                """
164 2fe004b1 Matej Zeman
165
    # Set the JWT cookies in the response
166
    Authorize.set_access_cookies(access_token)
167
    Authorize.set_refresh_cookies(refresh_token)
168
    return """
169
    <html>
170
        <head>
171
            <title>Login</title>
172
        </head>
173
        <body>
174 2552e614 Matej Zeman
            <h1>Now you are logged in, you can continue to previous page.</h1>
175 2fe004b1 Matej Zeman
            <form action="/logs-web" method="get">
176 2552e614 Matej Zeman
                <input type="submit" value="Home Page" />
177 2fe004b1 Matej Zeman
            </form>
178
        </body>
179
    </html>
180
    """
181
182
183
@auth.post('/refresh')
184
def refresh(Authorize: AuthJWT = Depends()):
185 7fe7be79 zemanm98@students.zcu.cz
    """
186
    endpoint for refreshing browser token. Not used at the moment since lifetime of given tokens are
187
    unlimited.
188
    """
189 2fe004b1 Matej Zeman
    Authorize.jwt_refresh_token_required()
190
    current_user = Authorize.get_jwt_subject()
191
    new_access_token = Authorize.create_access_token(subject=current_user)
192
    # Set the JWT cookies in the response
193
    Authorize.set_access_cookies(new_access_token)
194
    return {"msg": "The token has been refresh"}
195
196
197
@auth.get('/logout', response_class=HTMLResponse)
198
def logout(Authorize: AuthJWT = Depends()):
199
    """
200 7fe7be79 zemanm98@students.zcu.cz
    Endpoint for deleting cookie token with acces role.
201 2fe004b1 Matej Zeman
    """
202
    Authorize.jwt_optional()
203
204
    Authorize.unset_jwt_cookies()
205
    return """
206
        <html>
207
            <head>
208
                <title>Logout</title>
209
            </head>
210
            <body>
211
                <h1>Logged Out</h1>
212
                <form action="/logs-web" method="get">
213
                    <input type="submit" value="Back" />
214
                </form>
215
            </body>
216
        </html>
217 cbd239c6 Matej Zeman
        """