Revize cbd239c6
Přidáno uživatelem Matěj Zeman před téměř 3 roky(ů)
server/requirements.txt | ||
---|---|---|
5 | 5 |
psycopg2-binary==2.8.6 |
6 | 6 |
jinja2==3.1.1 |
7 | 7 |
python-multipart==0.0.5 |
8 |
fastapi-jwt-auth==0.5.0 |
|
8 |
fastapi-jwt-auth==0.5.0 |
|
9 |
passlib==1.7.4 |
|
10 |
bcrypt==3.2.2 |
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 |
""" |
server/sql_app/api/ld_logs_web.py | ||
---|---|---|
44 | 44 |
pc_obj = crud.find_pcs(db, pcs) |
45 | 45 |
teams = crud.get_teams(db, skip=skip, limit=limit) |
46 | 46 |
licenses = crud.get_licenses(db, skip=skip, limit=limit) |
47 |
if current_user != "admin": |
|
47 |
if current_user == "admin": |
|
48 |
return templates.TemplateResponse("ldlogs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, |
|
49 |
"licenses": licenses, "user": current_user}) |
|
50 |
else: |
|
48 | 51 |
current_user = "guest" |
49 |
return templates.TemplateResponse("ldlogs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, |
|
50 |
"licenses": licenses, "user": current_user}) |
|
52 |
return templates.TemplateResponse("ldlogs_normal.html", |
|
53 |
{"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, |
|
54 |
"licenses": licenses, "user": current_user}) |
|
51 | 55 |
|
52 | 56 |
|
53 | 57 |
@ldlogs_web.post("/ldlogs-web", response_class=HTMLResponse) |
... | ... | |
67 | 71 |
pc_obj = crud.get_pcs(db, skip=skip, limit=limit) |
68 | 72 |
teams = crud.get_teams(db, skip=skip, limit=limit) |
69 | 73 |
licenses = crud.get_licenses(db, skip=skip, limit=limit) |
70 |
if current_user != "admin": |
|
74 |
if current_user == "admin": |
|
75 |
return templates.TemplateResponse("ldlogs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, |
|
76 |
"licenses": licenses, "user": current_user}) |
|
77 |
else: |
|
71 | 78 |
current_user = "guest" |
72 |
return templates.TemplateResponse("ldlogs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, |
|
73 |
"licenses": licenses, "user": current_user}) |
|
79 |
return templates.TemplateResponse("ldlogs_normal.html", |
|
80 |
{"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, |
|
81 |
"licenses": licenses, "user": current_user}) |
server/sql_app/api/usb_logs_web.py | ||
---|---|---|
44 | 44 |
pc_obj = crud.find_pcs(db, pcs) |
45 | 45 |
teams = crud.get_teams(db, skip=skip, limit=limit) |
46 | 46 |
licenses = crud.get_licenses(db, skip=skip, limit=limit) |
47 |
if current_user != "admin": |
|
47 |
if current_user == "admin": |
|
48 |
return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, |
|
49 |
"licenses": licenses, "user": current_user}) |
|
50 |
else: |
|
48 | 51 |
current_user = "guest" |
49 |
return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams,
|
|
50 |
"licenses": licenses, "user": current_user}) |
|
52 |
return templates.TemplateResponse("logs_normal.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams,
|
|
53 |
"licenses": licenses, "user": current_user})
|
|
51 | 54 |
|
52 | 55 |
|
53 | 56 |
@usblogs_web.post("/logs-web", response_class=HTMLResponse) |
... | ... | |
67 | 70 |
pc_obj = crud.get_pcs(db, skip=skip, limit=limit) |
68 | 71 |
teams = crud.get_teams(db, skip=skip, limit=limit) |
69 | 72 |
licenses = crud.get_licenses(db, skip=skip, limit=limit) |
70 |
if current_user != "admin": |
|
73 |
if current_user == "admin": |
|
74 |
return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams, |
|
75 |
"licenses": licenses, "user": current_user}) |
|
76 |
else: |
|
71 | 77 |
current_user = "guest" |
72 |
return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams,
|
|
73 |
"licenses": licenses, "user": current_user}) |
|
78 |
return templates.TemplateResponse("logs_normal.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams,
|
|
79 |
"licenses": licenses, "user": current_user})
|
|
74 | 80 |
|
75 | 81 |
|
76 | 82 |
@usblogs_web.get("/", response_class=HTMLResponse) |
server/sql_app/api/users_web.py | ||
---|---|---|
1 |
from typing import List |
|
2 |
from fastapi import Depends, FastAPI, HTTPException, APIRouter, Form |
|
3 |
from sqlalchemy.orm import Session |
|
4 |
from sql_app import crud, models, schemas |
|
5 |
from ..database import SessionLocal, engine |
|
6 |
from fastapi import FastAPI, Request |
|
7 |
from fastapi.responses import HTMLResponse, RedirectResponse |
|
8 |
from fastapi_jwt_auth import AuthJWT |
|
9 |
from fastapi.staticfiles import StaticFiles |
|
10 |
from fastapi.templating import Jinja2Templates |
|
11 |
|
|
12 |
models.Base.metadata.create_all(bind=engine) |
|
13 |
|
|
14 |
# Path to html templates used in this file |
|
15 |
templates = Jinja2Templates(directory="templates/users") |
|
16 |
|
|
17 |
# prefix used for all endpoints in this file |
|
18 |
users = APIRouter(prefix="") |
|
19 |
|
|
20 |
|
|
21 |
# Dependency |
|
22 |
def get_db(): |
|
23 |
db = SessionLocal() |
|
24 |
try: |
|
25 |
yield db |
|
26 |
finally: |
|
27 |
db.close() |
|
28 |
|
|
29 |
|
|
30 |
@users.get("/users-web", response_class=HTMLResponse) |
|
31 |
async def read_usrs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), |
|
32 |
Authorize: AuthJWT = Depends()): |
|
33 |
""" |
|
34 |
Returns template with all users currently saved in database |
|
35 |
""" |
|
36 |
Authorize.jwt_optional() |
|
37 |
current_user = Authorize.get_jwt_subject() |
|
38 |
users = crud.get_users(db, skip, limit) |
|
39 |
if current_user == "admin": |
|
40 |
return templates.TemplateResponse("users.html", {"request": request, "users": users}) |
|
41 |
else: |
|
42 |
return RedirectResponse(url=f"/logs-web", status_code=303) |
|
43 |
|
|
44 |
|
|
45 |
@users.get("/user-role/{usr_id}", response_class=HTMLResponse) |
|
46 |
async def connect_pc_team(usr_id: int, db: Session = Depends(get_db), Authorize: AuthJWT = Depends()): |
|
47 |
""" |
|
48 |
Changes role of user to either guest or admin depending on old role. |
|
49 |
""" |
|
50 |
Authorize.jwt_optional() |
|
51 |
current_user = Authorize.get_jwt_subject() |
|
52 |
if current_user != "admin": |
|
53 |
return RedirectResponse(url=f"/logs-web", status_code=303) |
|
54 |
user = crud.find_user_byid(db, usr_id) |
|
55 |
if user.role == "admin": |
|
56 |
crud.change_role(db, usr_id, "guest") |
|
57 |
else: |
|
58 |
crud.change_role(db, usr_id, "admin") |
|
59 |
return RedirectResponse(url=f"/users-web", status_code=303) |
server/sql_app/crud.py | ||
---|---|---|
99 | 99 |
returns entry in bodydevices_licenses table with given body device id and license id |
100 | 100 |
""" |
101 | 101 |
return db.query(models.BodyDeviceLicense).filter(and_(models.BodyDeviceLicense.bodydevice_id == device_id, |
102 |
models.BodyDeviceLicense.license_id == license_id)).first() |
|
102 |
models.BodyDeviceLicense.license_id == license_id)).first()
|
|
103 | 103 |
|
104 | 104 |
|
105 | 105 |
def get_license_bodydevice(db: Session, license_id: int): |
... | ... | |
188 | 188 |
db.refresh(old_pc) |
189 | 189 |
return old_pc |
190 | 190 |
|
191 |
def change_role(db: Session, usr_id: int, role: str): |
|
192 |
""" |
|
193 |
Updates team of one specific pc |
|
194 |
""" |
|
195 |
old_usr = find_user_byid(db, usr_id) |
|
196 |
new = {'id': old_usr.id, 'username': old_usr.username, 'password': old_usr.password, 'role': role} |
|
197 |
for key, value in new.items(): |
|
198 |
setattr(old_usr, key, value) |
|
199 |
db.commit() |
|
200 |
db.refresh(old_usr) |
|
201 |
return old_usr |
|
202 |
|
|
191 | 203 |
|
192 | 204 |
def get_pcs(db: Session, skip: int = 0, limit: int = 100): |
193 | 205 |
""" |
... | ... | |
482 | 494 |
db.commit() |
483 | 495 |
db.refresh(db_log) |
484 | 496 |
return db_log |
497 |
|
|
498 |
|
|
499 |
def get_users(db: Session, skip: int = 0, limit: int = 100): |
|
500 |
""" |
|
501 |
Returns all users saved in database |
|
502 |
""" |
|
503 |
return db.query(models.User).offset(skip).limit(limit).all() |
|
504 |
|
|
505 |
|
|
506 |
def find_user(db: Session, name: str): |
|
507 |
""" |
|
508 |
Finds one user by given username |
|
509 |
""" |
|
510 |
return db.query(models.User).filter(models.User.username == name).first() |
|
511 |
|
|
512 |
|
|
513 |
def find_user_byid(db: Session, id: int): |
|
514 |
""" |
|
515 |
Finds one user by given id |
|
516 |
""" |
|
517 |
return db.query(models.User).filter(models.User.id == id).first() |
|
518 |
|
|
519 |
|
|
520 |
def create_user(db: Session, name: str, passw: str, rol: str): |
|
521 |
""" |
|
522 |
Creates new user |
|
523 |
""" |
|
524 |
db_user = models.User(username=name, password=passw, role=rol) |
|
525 |
db.add(db_user) |
|
526 |
db.commit() |
|
527 |
db.refresh(db_user) |
|
528 |
return db_user |
server/sql_app/main.py | ||
---|---|---|
12 | 12 |
from sql_app.api.auth import auth |
13 | 13 |
from sql_app.api.ld_logs_web import ldlogs_web |
14 | 14 |
from sql_app.api.bodydevices_web import body_device_web |
15 |
from sql_app.api.users_web import users |
|
15 | 16 |
from fastapi import FastAPI |
16 | 17 |
|
17 | 18 |
|
... | ... | |
32 | 33 |
app.include_router(usblogs_web) |
33 | 34 |
app.include_router(ldlogs_web) |
34 | 35 |
app.include_router(body_device_web) |
36 |
app.include_router(users) |
|
35 | 37 |
app.include_router(auth) |
36 | 38 |
|
37 | 39 |
''' |
server/sql_app/models.py | ||
---|---|---|
165 | 165 |
ldpc = relationship("PC", back_populates="ld_pc") |
166 | 166 |
head_device = relationship("HeadDevice", back_populates="h_logs") |
167 | 167 |
body_device = relationship("BodyDevice", back_populates="b_logs") |
168 |
|
|
169 |
class User(Base): |
|
170 |
""" |
|
171 |
Class defining user in database with its own role |
|
172 |
""" |
|
173 |
__tablename__ = "users" |
|
174 |
|
|
175 |
id = Column(Integer, primary_key=True, index=True) |
|
176 |
username = Column(String, index=True, nullable=False) |
|
177 |
password = Column(String, index=True, nullable=False) |
|
178 |
role = Column(String, index=True, nullable=False) |
server/sql_app/schemas.py | ||
---|---|---|
232 | 232 |
|
233 | 233 |
class Config: |
234 | 234 |
orm_mode = True |
235 |
|
|
236 |
|
|
237 |
class UserBase(BaseModel): |
|
238 |
""" |
|
239 |
Classes used for creating new User entry |
|
240 |
""" |
|
241 |
username: str |
|
242 |
password: str |
|
243 |
role: str |
|
244 |
|
|
245 |
class UserCreate(UserBase): |
|
246 |
pass |
|
247 |
|
|
248 |
|
|
249 |
class User(UserCreate): |
|
250 |
id: int |
|
251 |
|
|
252 |
class Config: |
|
253 |
orm_mode = True |
server/templates/auth/login.html | ||
---|---|---|
8 | 8 |
<form action="/login" method="post"> |
9 | 9 |
<label for="username">Username:</label><br> |
10 | 10 |
<input type="text" id="username" name="username"><br><br> |
11 |
<label for="password">Password</label> |
|
11 |
<label for="password">Password:</label>
|
|
12 | 12 |
<input type="password" id="password" name="password"> |
13 |
<input type="submit" value="Submit">
|
|
13 |
<input type="submit" value="LogIn">
|
|
14 | 14 |
</form> |
15 | 15 |
</body> |
16 | 16 |
</html> |
server/templates/auth/signup.html | ||
---|---|---|
1 |
<!DOCTYPE html> |
|
2 |
<html lang="en"> |
|
3 |
<head> |
|
4 |
<meta charset="UTF-8"> |
|
5 |
<title>Sign Up</title> |
|
6 |
</head> |
|
7 |
<body> |
|
8 |
<form action="/signup" method="post"> |
|
9 |
<label for="username">Username:</label><br> |
|
10 |
<input type="text" id="username" name="username"><br><br> |
|
11 |
<label for="password">Password:</label> |
|
12 |
<input type="password" id="password" name="password"> |
|
13 |
<input type="submit" value="Signup"> |
|
14 |
</form> |
|
15 |
</body> |
|
16 |
</html> |
server/templates/body-devices/body_devices.html | ||
---|---|---|
15 | 15 |
<option value="/teams-web">Teams</option> |
16 | 16 |
<option value="/pcs-web">PCs</option> |
17 | 17 |
<option value="/licenses-web">Licenses</option> |
18 |
<option value="/users-web">Users</option> |
|
18 | 19 |
</select> |
19 | 20 |
<input type="submit" value="OK"> |
20 | 21 |
</form> |
... | ... | |
25 | 26 |
</form> |
26 | 27 |
</div> |
27 | 28 |
<div style='float:left'> |
29 |
<form action="/signup" method="get"> |
|
30 |
<input type="submit" value="Sign Up" /> |
|
31 |
</form> |
|
32 |
</div> |
|
33 |
<div style='float:left'> |
|
28 | 34 |
<form action="/logout" method="get"> |
29 | 35 |
<input type="submit" value="Logout" /> |
30 | 36 |
</form> |
server/templates/body-devices/body_devices_normal.html | ||
---|---|---|
25 | 25 |
</form> |
26 | 26 |
</div> |
27 | 27 |
<div style='float:left'> |
28 |
<form action="/signup" method="get"> |
|
29 |
<input type="submit" value="Sign Up" /> |
|
30 |
</form> |
|
31 |
</div> |
|
32 |
<div style='float:left'> |
|
28 | 33 |
<form action="/logout" method="get"> |
29 | 34 |
<input type="submit" value="Logout" /> |
30 | 35 |
</form> |
server/templates/devices/devices.html | ||
---|---|---|
15 | 15 |
<option value="/teams-web">Teams</option> |
16 | 16 |
<option value="/pcs-web">PCs</option> |
17 | 17 |
<option value="/licenses-web">Licenses</option> |
18 |
<option value="/users-web">Users</option> |
|
18 | 19 |
</select> |
19 | 20 |
<input type="submit" value="OK"> |
20 | 21 |
</form> |
... | ... | |
25 | 26 |
</form> |
26 | 27 |
</div> |
27 | 28 |
<div style='float:left'> |
29 |
<form action="/signup" method="get"> |
|
30 |
<input type="submit" value="Sign Up" /> |
|
31 |
</form> |
|
32 |
</div> |
|
33 |
<div style='float:left'> |
|
28 | 34 |
<form action="/logout" method="get"> |
29 | 35 |
<input type="submit" value="Logout" /> |
30 | 36 |
</form> |
server/templates/devices/devices_normal.html | ||
---|---|---|
25 | 25 |
</form> |
26 | 26 |
</div> |
27 | 27 |
<div style='float:left'> |
28 |
<form action="/signup" method="get"> |
|
29 |
<input type="submit" value="Sign Up" /> |
|
30 |
</form> |
|
31 |
</div> |
|
32 |
<div style='float:left'> |
|
28 | 33 |
<form action="/logout" method="get"> |
29 | 34 |
<input type="submit" value="Logout" /> |
30 | 35 |
</form> |
server/templates/ld-logs/ldlogs.html | ||
---|---|---|
15 | 15 |
<option value="/teams-web">Teams</option> |
16 | 16 |
<option value="/pcs-web">PCs</option> |
17 | 17 |
<option value="/licenses-web">Licenses</option> |
18 |
<option value="/users-web">Users</option> |
|
18 | 19 |
</select> |
19 | 20 |
<input type="submit" value="OK"> |
20 | 21 |
</form> |
... | ... | |
25 | 26 |
</form> |
26 | 27 |
</div> |
27 | 28 |
<div style='float:left'> |
29 |
<form action="/signup" method="get"> |
|
30 |
<input type="submit" value="Sign Up" /> |
|
31 |
</form> |
|
32 |
</div> |
|
33 |
<div style='float:left'> |
|
28 | 34 |
<form action="/logout" method="get"> |
29 | 35 |
<input type="submit" value="Logout" /> |
30 | 36 |
</form> |
server/templates/ld-logs/ldlogs_normal.html | ||
---|---|---|
1 |
<html> |
|
2 |
<head> |
|
3 |
<title> LD Logs Details</title> |
|
4 |
</head> |
|
5 |
<body> |
|
6 |
<div style='float:left'> |
|
7 |
<form action="" method="get"> |
|
8 |
<label for="view">Choose view:</label> |
|
9 |
<select id="view" name="view" onchange="this.form.action=this.value;"> |
|
10 |
<option value=""></option> |
|
11 |
<option value="/logs-web">Logs</option> |
|
12 |
<option value="/ldlogs-web">LD Logs</option> |
|
13 |
<option value="/devices-web">Devices</option> |
|
14 |
<option value="/body-devices-web">Body Devices</option> |
|
15 |
<option value="/teams-web">Teams</option> |
|
16 |
<option value="/pcs-web">PCs</option> |
|
17 |
<option value="/licenses-web">Licenses</option> |
|
18 |
</select> |
|
19 |
<input type="submit" value="OK"> |
|
20 |
</form> |
|
21 |
</div> |
|
22 |
<div style='float:left'> |
|
23 |
<form action="/login" method="get"> |
|
24 |
<input type="submit" value="Login" /> |
|
25 |
</form> |
|
26 |
</div> |
|
27 |
<div style='float:left'> |
|
28 |
<form action="/signup" method="get"> |
|
29 |
<input type="submit" value="Sign Up" /> |
|
30 |
</form> |
|
31 |
</div> |
|
32 |
<div style='float:left'> |
|
33 |
<form action="/logout" method="get"> |
|
34 |
<input type="submit" value="Logout" /> |
|
35 |
</form> |
|
36 |
</div> |
|
37 |
<h4>{{user}}</h4> |
|
38 |
<form action="/ldlogs-web" method="post"> |
|
39 |
<label for="pc">PC:</label> |
|
40 |
<input id="pc" name="pc" type="text" list="pcs" value="" placeholder="all"> |
|
41 |
<datalist id="pcs"> |
|
42 |
{% for pc in pcs %} |
|
43 |
<option value="{{pc.username}}"></option> |
|
44 |
{% endfor %} |
|
45 |
</datalist> |
|
46 |
<label for="team">Team:</label> |
|
47 |
<input id="team" name="team" type="text" list="teams" value="" placeholder="all"> |
|
48 |
<datalist id="teams"> |
|
49 |
{% for team in teams %} |
|
50 |
<option value="{{team.name}}"></option> |
|
51 |
{% endfor %} |
|
52 |
</datalist> |
|
53 |
<label for="lic">License:</label> |
|
54 |
<input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all"> |
|
55 |
<datalist id="licenses"> |
|
56 |
{% for license in licenses %} |
|
57 |
<option value="{{license.name}}"></option> |
|
58 |
{% endfor %} |
|
59 |
</datalist> |
|
60 |
<input type="submit" value="Filter"> |
|
61 |
</form> |
|
62 |
<table> |
|
63 |
<TR> |
|
64 |
<TH>ID</TH> |
|
65 |
<TH>PC Username</TH> |
|
66 |
<TH>PC Hostname</TH> |
|
67 |
<TH>Team</TH> |
|
68 |
<TH>Timestamp</TH> |
|
69 |
<TH>Status</TH> |
|
70 |
<TH>Head Device Serial Number</TH> |
|
71 |
<TH>Body Device Serial Number</TH> |
|
72 |
</TR> |
|
73 |
{% for log in logs %} |
|
74 |
<TR> |
|
75 |
<TD class="ID">{{log.id}}</TD> |
|
76 |
<TD class="Username">{{log.ldpc.username}}</TD> |
|
77 |
<TD class="Hostname">{{log.ldpc.hostname}}</TD> |
|
78 |
{% if log.ldpc.team == None %} |
|
79 |
<TD class="Team">NONE</TD> |
|
80 |
{% else %} |
|
81 |
<TD class="Team">{{log.ldpc.team.name}}</TD> |
|
82 |
{% endif %} |
|
83 |
<TD class="Timestamp">{{log.timestamp}}</TD> |
|
84 |
<TD class="Status">{{log.status}}</TD> |
|
85 |
<TD class="HeadDeviceSerialNumber">{{log.head_device.serial_number}}</TD> |
|
86 |
<TD class="BodyDeviceSerialNumber">{{log.body_device.serial_number}}</TD> |
|
87 |
</TR> |
|
88 |
{% endfor %} |
|
89 |
</table> |
|
90 |
</body> |
|
91 |
</html> |
server/templates/licenses/licenses.html | ||
---|---|---|
15 | 15 |
<option value="/teams-web">Teams</option> |
16 | 16 |
<option value="/pcs-web">PCs</option> |
17 | 17 |
<option value="/licenses-web">Licenses</option> |
18 |
<option value="/users-web">Users</option> |
|
18 | 19 |
</select> |
19 | 20 |
<input type="submit" value="OK"> |
20 | 21 |
</form> |
... | ... | |
25 | 26 |
</form> |
26 | 27 |
</div> |
27 | 28 |
<div style='float:left'> |
29 |
<form action="/signup" method="get"> |
|
30 |
<input type="submit" value="Sign Up" /> |
|
31 |
</form> |
|
32 |
</div> |
|
33 |
<div style='float:left'> |
|
28 | 34 |
<form action="/logout" method="get"> |
29 | 35 |
<input type="submit" value="Logout" /> |
30 | 36 |
</form> |
server/templates/licenses/licenses_normal.html | ||
---|---|---|
25 | 25 |
</form> |
26 | 26 |
</div> |
27 | 27 |
<div style='float:left'> |
28 |
<form action="/signup" method="get"> |
|
29 |
<input type="submit" value="Sign Up" /> |
|
30 |
</form> |
|
31 |
</div> |
|
32 |
<div style='float:left'> |
|
28 | 33 |
<form action="/logout" method="get"> |
29 | 34 |
<input type="submit" value="Logout" /> |
30 | 35 |
</form> |
server/templates/pcs/pcs.html | ||
---|---|---|
15 | 15 |
<option value="/teams-web">Teams</option> |
16 | 16 |
<option value="/pcs-web">PCs</option> |
17 | 17 |
<option value="/licenses-web">Licenses</option> |
18 |
<option value="/users-web">Users</option> |
|
18 | 19 |
</select> |
19 | 20 |
<input type="submit" value="OK"> |
20 | 21 |
</form> |
... | ... | |
25 | 26 |
</form> |
26 | 27 |
</div> |
27 | 28 |
<div style='float:left'> |
29 |
<form action="/signup" method="get"> |
|
30 |
<input type="submit" value="Sign Up" /> |
|
31 |
</form> |
|
32 |
</div> |
|
33 |
<div style='float:left'> |
|
28 | 34 |
<form action="/logout" method="get"> |
29 | 35 |
<input type="submit" value="Logout" /> |
30 | 36 |
</form> |
server/templates/pcs/pcs_normal.html | ||
---|---|---|
25 | 25 |
</form> |
26 | 26 |
</div> |
27 | 27 |
<div style='float:left'> |
28 |
<form action="/signup" method="get"> |
|
29 |
<input type="submit" value="Sign Up" /> |
|
30 |
</form> |
|
31 |
</div> |
|
32 |
<div style='float:left'> |
|
28 | 33 |
<form action="/logout" method="get"> |
29 | 34 |
<input type="submit" value="Logout" /> |
30 | 35 |
</form> |
server/templates/teams/teams.html | ||
---|---|---|
15 | 15 |
<option value="/teams-web">Teams</option> |
16 | 16 |
<option value="/pcs-web">PCs</option> |
17 | 17 |
<option value="/licenses-web">Licenses</option> |
18 |
<option value="/users-web">Users</option> |
|
18 | 19 |
</select> |
19 | 20 |
<input type="submit" value="OK"> |
20 | 21 |
</form> |
... | ... | |
25 | 26 |
</form> |
26 | 27 |
</div> |
27 | 28 |
<div style='float:left'> |
29 |
<form action="/signup" method="get"> |
|
30 |
<input type="submit" value="Sign Up" /> |
|
31 |
</form> |
|
32 |
</div> |
|
33 |
<div style='float:left'> |
|
28 | 34 |
<form action="/logout" method="get"> |
29 | 35 |
<input type="submit" value="Logout" /> |
30 | 36 |
</form> |
server/templates/teams/teams_normal.html | ||
---|---|---|
25 | 25 |
</form> |
26 | 26 |
</div> |
27 | 27 |
<div style='float:left'> |
28 |
<form action="/signup" method="get"> |
|
29 |
<input type="submit" value="Sign Up" /> |
|
30 |
</form> |
|
31 |
</div> |
|
32 |
<div style='float:left'> |
|
28 | 33 |
<form action="/logout" method="get"> |
29 | 34 |
<input type="submit" value="Logout" /> |
30 | 35 |
</form> |
server/templates/usb-logs/logs.html | ||
---|---|---|
15 | 15 |
<option value="/teams-web">Teams</option> |
16 | 16 |
<option value="/pcs-web">PCs</option> |
17 | 17 |
<option value="/licenses-web">Licenses</option> |
18 |
<option value="/users-web">Users</option> |
|
18 | 19 |
</select> |
19 | 20 |
<input type="submit" value="OK"> |
20 | 21 |
</form> |
... | ... | |
25 | 26 |
</form> |
26 | 27 |
</div> |
27 | 28 |
<div style='float:left'> |
29 |
<form action="/signup" method="get"> |
|
30 |
<input type="submit" value="Sign Up" /> |
|
31 |
</form> |
|
32 |
</div> |
|
33 |
<div style='float:left'> |
|
28 | 34 |
<form action="/logout" method="get"> |
29 | 35 |
<input type="submit" value="Logout" /> |
30 | 36 |
</form> |
server/templates/usb-logs/logs_normal.html | ||
---|---|---|
1 |
<html> |
|
2 |
<head> |
|
3 |
<title>Logs Details</title> |
|
4 |
</head> |
|
5 |
<body> |
|
6 |
<div style='float:left'> |
|
7 |
<form action="" method="get"> |
|
8 |
<label for="view">Choose view:</label> |
|
9 |
<select id="view" name="view" onchange="this.form.action=this.value;"> |
|
10 |
<option value=""></option> |
|
11 |
<option value="/logs-web">Logs</option> |
|
12 |
<option value="/ldlogs-web">LD Logs</option> |
|
13 |
<option value="/devices-web">Devices</option> |
|
14 |
<option value="/body-devices-web">Body Devices</option> |
|
15 |
<option value="/teams-web">Teams</option> |
|
16 |
<option value="/pcs-web">PCs</option> |
|
17 |
<option value="/licenses-web">Licenses</option> |
|
18 |
</select> |
|
19 |
<input type="submit" value="OK"> |
|
20 |
</form> |
|
21 |
</div> |
|
22 |
<div style='float:left'> |
|
23 |
<form action="/login" method="get"> |
|
24 |
<input type="submit" value="Login" /> |
|
25 |
</form> |
|
26 |
</div> |
|
27 |
<div style='float:left'> |
|
28 |
<form action="/signup" method="get"> |
|
29 |
<input type="submit" value="Sign Up" /> |
|
30 |
</form> |
|
31 |
</div> |
|
32 |
<div style='float:left'> |
|
33 |
<form action="/logout" method="get"> |
|
34 |
<input type="submit" value="Logout" /> |
|
35 |
</form> |
|
36 |
</div> |
|
37 |
<h4>{{user}}</h4> |
|
38 |
<form action="/logs-web" method="post"> |
|
39 |
<label for="pc">PC:</label> |
|
40 |
<input id="pc" name="pc" type="text" list="pcs" value="" placeholder="all"> |
|
41 |
<datalist id="pcs"> |
|
42 |
{% for pc in pcs %} |
|
43 |
<option value="{{pc.username}}"></option> |
|
44 |
{% endfor %} |
|
45 |
</datalist> |
|
46 |
<label for="team">Team:</label> |
|
47 |
<input id="team" name="team" type="text" list="teams" value="" placeholder="all"> |
|
48 |
<datalist id="teams"> |
|
49 |
{% for team in teams %} |
|
50 |
<option value="{{team.name}}"></option> |
|
51 |
{% endfor %} |
|
52 |
</datalist> |
|
53 |
<label for="lic">License:</label> |
|
54 |
<input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all"> |
|
55 |
<datalist id="licenses"> |
|
56 |
{% for license in licenses %} |
|
57 |
<option value="{{license.name}}"></option> |
|
58 |
{% endfor %} |
|
59 |
</datalist> |
|
60 |
<input type="submit" value="Filter"> |
|
61 |
</form> |
|
62 |
<table> |
|
63 |
<TR> |
|
64 |
<TH>ID</TH> |
|
65 |
<TH>PC Username</TH> |
|
66 |
<TH>PC Hostname</TH> |
|
67 |
<TH>Team</TH> |
|
68 |
<TH>Timestamp</TH> |
|
69 |
<TH>Status</TH> |
|
70 |
<TH>Device Product ID</TH> |
|
71 |
<TH>Device Serial Number</TH> |
|
72 |
</TR> |
|
73 |
{% for log in logs %} |
|
74 |
<TR> |
|
75 |
<TD class="ID">{{log.id}}</TD> |
|
76 |
<TD class="Username">{{log.pc.username}}</TD> |
|
77 |
<TD class="Hostname">{{log.pc.hostname}}</TD> |
|
78 |
{% if log.pc.team == None %} |
|
79 |
<TD class="Team">NONE</TD> |
|
80 |
{% else %} |
|
81 |
<TD class="Team">{{log.pc.team.name}}</TD> |
|
82 |
{% endif %} |
|
83 |
<TD class="Timestamp">{{log.timestamp}}</TD> |
|
84 |
<TD class="Status">{{log.status}}</TD> |
|
85 |
<TD class="DeviceProductID">{{log.device.product_id}}</TD> |
|
86 |
<TD class="DeviceSerialNumber">{{log.device.serial_number}}</TD> |
|
87 |
</TR> |
|
88 |
{% endfor %} |
|
89 |
</table> |
|
90 |
</body> |
|
91 |
</html> |
server/templates/users/users.html | ||
---|---|---|
1 |
<html> |
|
2 |
<head> |
|
3 |
<title>Users Details</title> |
|
4 |
</head> |
|
5 |
<body> |
|
6 |
<div style='float:left'> |
|
7 |
<form action="" method="get"> |
|
8 |
<label for="view">Choose view:</label> |
|
9 |
<select id="view" name="view" onchange="this.form.action=this.value;"> |
|
10 |
<option value=""></option> |
|
11 |
<option value="/logs-web">Logs</option> |
|
12 |
<option value="/ldlogs-web">LD Logs</option> |
|
13 |
<option value="/devices-web">Devices</option> |
|
14 |
<option value="/body-devices-web">Body Devices</option> |
|
15 |
<option value="/teams-web">Teams</option> |
|
16 |
<option value="/pcs-web">PCs</option> |
|
17 |
<option value="/licenses-web">Licenses</option> |
|
18 |
</select> |
|
19 |
<input type="submit" value="OK"> |
|
20 |
</form> |
|
21 |
</div> |
|
22 |
<div style='float:left'> |
|
23 |
<form action="/login" method="get"> |
|
24 |
<input type="submit" value="Login" /> |
|
25 |
</form> |
|
26 |
</div> |
|
27 |
<div style='float:left'> |
|
28 |
<form action="/signup" method="get"> |
|
29 |
<input type="submit" value="Sign Up" /> |
|
30 |
</form> |
|
31 |
</div> |
|
32 |
<form action="/logout" method="get"> |
|
33 |
<input type="submit" value="Logout" /> |
|
34 |
</form> |
|
35 |
<table> |
|
36 |
<TR> |
|
37 |
<TH>ID</TH> |
|
38 |
<TH>Username</TH> |
|
39 |
<TH>Role</TH> |
|
40 |
</TR> |
|
41 |
{% for user in users %} |
|
42 |
<TR> |
|
43 |
<TD class="ID"><a href="/user-role/{{user.id}}">{{user.id}}</a></TD> |
|
44 |
<TD class="Username">{{user.username}}</TD> |
|
45 |
<TD class="Role">{{user.role}}</TD> |
|
46 |
</TR> |
|
47 |
{% endfor %} |
|
48 |
</table> |
|
49 |
</body> |
|
50 |
</html> |
Také k dispozici: Unified diff
Added signup and users table in database. Passwords are hashed. Added view for changing users roles.