Projekt

Obecné

Profil

« Předchozí | Další » 

Revize cbd239c6

Přidáno uživatelem Matěj Zeman před asi 2 roky(ů)

Added signup and users table in database. Passwords are hashed. Added view for changing users roles.

Zobrazit rozdíly:

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