commit 5dc6d077ca29461d54a5e6778cc2e204c73b7621
Author: Matej Zeman <zeman339@gmail.com>
Date:   Mon May 9 14:43:49 2022 +0200

    security fix for all endpoints. Added view for Licenses and html template on "/" with information about server endpoints.

diff --git a/server/sql_app/api/auth.py b/server/sql_app/api/auth.py
index 069d27c..f01ef83 100644
--- a/server/sql_app/api/auth.py
+++ b/server/sql_app/api/auth.py
@@ -1,6 +1,6 @@
 from fastapi import Depends, APIRouter, Form
 from fastapi import Request
-from fastapi.responses import HTMLResponse
+from fastapi.responses import HTMLResponse, RedirectResponse
 from fastapi.templating import Jinja2Templates
 from fastapi_jwt_auth import AuthJWT
 from pydantic import BaseModel
diff --git a/server/sql_app/api/bodydevices_web.py b/server/sql_app/api/bodydevices_web.py
index 9b13bb7..48b345e 100644
--- a/server/sql_app/api/bodydevices_web.py
+++ b/server/sql_app/api/bodydevices_web.py
@@ -87,10 +87,15 @@ async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic:
 
 
 @body_device_web.get("/body-device-license/{device_id}", response_class=HTMLResponse)
-async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db)):
+async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db),
+                          Authorize: AuthJWT = Depends()):
     """
     Returns template with one body device and all available licenses that can be assigned to it.
     """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
     device = crud.get_body_device(db, device_id)
     dev_licenses = crud.get_bodydevice_license(db, device_id)
     lic_names = []
@@ -109,20 +114,30 @@ async def connect_dev_lic(request: Request, device_id: int, db: Session = Depend
 
 
 @body_device_web.post("/body-devices-web/{device_id}")
-async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db)):
+async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
     """
     Endpoint called from template for connecting body device with license. Adds entry to bodydevices_licenses
     table and redirects to body-devices-web endpoint
     """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
     crud.create_body_device_license(db, device_id, int(lic), datetime.now())
     return RedirectResponse(url=f"/body-devices-web", status_code=303)
 
 
 @body_device_web.post("/body-devices-web-del/{device_id}")
-async def delete_post(device_id: int, b_lic: str = Form(...), db: Session = Depends(get_db)):
+async def delete_post(device_id: int, b_lic: str = Form(...), db: Session = Depends(get_db),
+                      Authorize: AuthJWT = Depends()):
     """
     Endpoint called from template for connecting body device with license. Adds entry to devices_licenses
     table and redirects to body-devices-web endpoint
     """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
     crud.delete_bodydevice_license(db, device_id, int(b_lic))
     return RedirectResponse(url=f"/body-devices-web", status_code=303)
\ No newline at end of file
diff --git a/server/sql_app/api/devices_web.py b/server/sql_app/api/devices_web.py
index 97c38a5..0d82a6b 100644
--- a/server/sql_app/api/devices_web.py
+++ b/server/sql_app/api/devices_web.py
@@ -87,10 +87,15 @@ async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic:
 
 
 @device_web.get("/device-license/{device_id}", response_class=HTMLResponse)
-async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db)):
+async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db),
+                          Authorize: AuthJWT = Depends()):
     """
     Returns template with one device and all available licenses that can be assigned to it.
     """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
     device = crud.get_device(db, device_id)
     dev_licenses = crud.get_device_licenses(db, device_id)
     lic_names = []
@@ -109,20 +114,30 @@ async def connect_dev_lic(request: Request, device_id: int, db: Session = Depend
 
 
 @device_web.post("/devices-web/{device_id}")
-async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db)):
+async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
     """
     Endpoint called from template for connecting device with license. Adds entry to devices_licenses
     table and redirects to devices-web endpoint
     """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
     crud.create_device_license(db, device_id, int(lic), datetime.now())
     return RedirectResponse(url=f"/devices-web", status_code=303)
 
 
 @device_web.post("/devices-web-del/{device_id}")
-async def delete_post(device_id: int, lic_del: str = Form(...), db: Session = Depends(get_db)):
+async def delete_post(device_id: int, lic_del: str = Form(...), db: Session = Depends(get_db),
+                      Authorize: AuthJWT = Depends()):
     """
     Endpoint called from template for deleting device-license connection. Adds entry to bodydevices_licenses
     table and redirects to devices-web endpoint
     """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
     crud.delete_device_license(db, device_id, int(lic_del))
     return RedirectResponse(url=f"/devices-web", status_code=303)
diff --git a/server/sql_app/api/licenses_web.py b/server/sql_app/api/licenses_web.py
index 24de037..f402a1b 100644
--- a/server/sql_app/api/licenses_web.py
+++ b/server/sql_app/api/licenses_web.py
@@ -7,6 +7,7 @@ from sql_app import crud, models, schemas
 from ..database import SessionLocal, engine
 from fastapi import FastAPI, Request
 from fastapi.responses import HTMLResponse, RedirectResponse
+from fastapi_jwt_auth import AuthJWT
 from fastapi.staticfiles import StaticFiles
 from fastapi.templating import Jinja2Templates
 
@@ -30,28 +31,50 @@ def get_db():
 
 
 @licenses_web.get("/license-create", response_class=HTMLResponse)
-async def licenses_create_web(request: Request):
+async def licenses_create_web(request: Request, Authorize: AuthJWT = Depends()):
     """
     Returns template with Form for creating new license.
     """
-    return templates.TemplateResponse("license_create.html", {"request": request})
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
+    return templates.TemplateResponse("license_create.html", {"request": request, "minimum_date": date.today()})
 
 
 @licenses_web.get("/licenses-web", response_class=HTMLResponse)
-async def read_licenses_web(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
+async def read_licenses_web(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                            Authorize: AuthJWT = Depends()):
     """
     Returns template with all licenses currently saved in database
     """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
-    return templates.TemplateResponse("licenses.html", {"request": request, "licenses": licenses})
-
+    if current_user == "admin":
+        return templates.TemplateResponse("licenses.html", {"request": request, "licenses": licenses,
+                                                            "user": current_user})
+    else:
+        current_user = "guest"
+        return templates.TemplateResponse("licenses_normal.html", {"request": request, "licenses": licenses,
+                                                            "user": current_user})
 
 @licenses_web.post("/licenses-web")
-def create_license(name: str = Form(...), expdate: date = Form(...), db: Session = Depends(get_db)):
+def create_license(name: str = Form(...), expdate: date = Form(...), db: Session = Depends(get_db),
+                   Authorize: AuthJWT = Depends()):
     """
     Endpoint called from create license form. Creates new license and redirects to devices-web endpoint
     """
-    db_license = crud.create_license(db, name, expdate)
-    if db_license is None:
-        print("something went wrong")
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
+    licenses = crud.get_licenses(db, 0, 100)
+    licenses_names = []
+    for l in licenses:
+        licenses_names.append(l.name)
+    if name not in licenses_names:
+        db_license = crud.create_license(db, name, expdate)
+        if db_license is None:
+            print("something went wrong")
     return RedirectResponse(url=f"/devices-web", status_code=303)
diff --git a/server/sql_app/api/pcs_web.py b/server/sql_app/api/pcs_web.py
index 02303ab..2779e46 100644
--- a/server/sql_app/api/pcs_web.py
+++ b/server/sql_app/api/pcs_web.py
@@ -44,10 +44,15 @@ async def read_pcs(request: Request, skip: int = 0, limit: int = 100, db: Sessio
 
 
 @pcs_web.get("/pc-team/{pc_id}", response_class=HTMLResponse)
-async def connect_pc_team(request: Request, pc_id: int, db: Session = Depends(get_db)):
+async def connect_pc_team(request: Request, pc_id: int, db: Session = Depends(get_db),
+                          Authorize: AuthJWT = Depends()):
     """
     Returns template with Form for connecting pc with team
     """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
     pc = crud.get_pc(db, pc_id)
     teams = crud.get_teams(db, 0, 100)
     return templates.TemplateResponse("pcteam.html",
@@ -55,9 +60,14 @@ async def connect_pc_team(request: Request, pc_id: int, db: Session = Depends(ge
 
 
 @pcs_web.post("/pcs-web/{pc_id}")
-async def connect_post(pc_id: int, team: str = Form(...), db: Session = Depends(get_db)):
+async def connect_post(pc_id: int, team: str = Form(...), db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
     """
     Endpoint called from within form for connecting pc with team. Updates certain pc with new team.
     """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
     old_pc = crud.update_pc(db, pc_id, team)
     return RedirectResponse(url=f"/pcs-web", status_code=303)
diff --git a/server/sql_app/api/teams_web.py b/server/sql_app/api/teams_web.py
index c1752a1..616c1c7 100644
--- a/server/sql_app/api/teams_web.py
+++ b/server/sql_app/api/teams_web.py
@@ -45,19 +45,32 @@ async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Se
 
 
 @teams_web.get("/team-create", response_class=HTMLResponse)
-async def team_create_web(request: Request):
+async def team_create_web(request: Request, Authorize: AuthJWT = Depends()):
     """
     Returns template with form for creating new team
     """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
     return templates.TemplateResponse("team_create.html", {"request": request})
 
 
 @teams_web.post("/teams-web-con")
-def create_team(name: str = Form(...), db: Session = Depends(get_db)):
+def create_team(name: str = Form(...), db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
     """
     Endpoint called from within form for creating new team. Creates new team and returns all teams in database
     """
-    team = crud.create_team(db, name)
-    if team is None:
-        print("something went wrong")
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
+    teams = crud.get_teams(db, 0, 100)
+    teams_names = []
+    for t in teams:
+        teams_names.append(t.name)
+    if name not in teams_names:
+        team = crud.create_team(db, name)
+        if team is None:
+            print("something went wrong")
     return RedirectResponse(url=f"/teams-web", status_code=303)
diff --git a/server/sql_app/api/usb_logs_web.py b/server/sql_app/api/usb_logs_web.py
index cb83443..a4f57d0 100644
--- a/server/sql_app/api/usb_logs_web.py
+++ b/server/sql_app/api/usb_logs_web.py
@@ -53,10 +53,12 @@ async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Sessi
 @usblogs_web.post("/logs-web", response_class=HTMLResponse)
 async def filter_logs(request: Request, pc: str = Form("all"), team: str = Form("all"), lic: str = Form("all"),
                       skip: int = 0, limit: int = 100,
-                      db: Session = Depends(get_db)):
+                      db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
     """
     Endpoint used for filtering usb logs by user given form inputs.
     """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
     log = crud.get_filtered_logs(db, pc, team, lic)
     logs_ids = []
     for l in log:
@@ -65,6 +67,12 @@ async def filter_logs(request: Request, pc: str = Form("all"), team: str = Form(
     pc_obj = crud.get_pcs(db, skip=skip, limit=limit)
     teams = crud.get_teams(db, skip=skip, limit=limit)
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if current_user != "admin":
+        current_user = "guest"
     return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams,
-                                                    "licenses": licenses})
+                                                    "licenses": licenses, "user": current_user})
+
 
+@usblogs_web.get("/", response_class=HTMLResponse)
+async def crossroad(request: Request):
+    return templates.TemplateResponse("crossroad.html", {"request": request})
diff --git a/server/sql_app/main.py b/server/sql_app/main.py
index a77e626..99026c6 100644
--- a/server/sql_app/main.py
+++ b/server/sql_app/main.py
@@ -36,5 +36,5 @@ app.include_router(auth)
 
 '''
 if __name__ == "__main__":
-    uvicorn.run(app, host="192.168.176.1", port=8000)
+    uvicorn.run(app, host="192.168.0.22", port=8000)
 '''
diff --git a/server/templates/auth/login.html b/server/templates/auth/login.html
index 49fdcdf..0def994 100644
--- a/server/templates/auth/login.html
+++ b/server/templates/auth/login.html
@@ -8,8 +8,8 @@
 <form action="/login" method="post">
   <label for="username">Username:</label><br>
   <input type="text" id="username" name="username"><br><br>
-    <label for="password">Expiration Date</label>
-  <input type="text" id="password" name="password">
+    <label for="password">Password</label>
+  <input type="password" id="password" name="password">
   <input type="submit" value="Submit">
 </form>
 </body>
diff --git a/server/templates/body-devices/body_devices.html b/server/templates/body-devices/body_devices.html
index eb02d61..1116968 100644
--- a/server/templates/body-devices/body_devices.html
+++ b/server/templates/body-devices/body_devices.html
@@ -14,6 +14,7 @@
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
+      <option value="/licenses-web">Licenses</option>
   </select>
   <input type="submit" value="OK">
 </form>
diff --git a/server/templates/body-devices/body_devices_normal.html b/server/templates/body-devices/body_devices_normal.html
index a2c3da2..d0ce81b 100644
--- a/server/templates/body-devices/body_devices_normal.html
+++ b/server/templates/body-devices/body_devices_normal.html
@@ -14,6 +14,7 @@
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
+      <option value="/licenses-web">Licenses</option>
   </select>
   <input type="submit" value="OK">
 </form>
diff --git a/server/templates/devices/devices.html b/server/templates/devices/devices.html
index 93dee09..3685a70 100644
--- a/server/templates/devices/devices.html
+++ b/server/templates/devices/devices.html
@@ -14,6 +14,7 @@
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
+      <option value="/licenses-web">Licenses</option>
   </select>
   <input type="submit" value="OK">
 </form>
diff --git a/server/templates/devices/devices_normal.html b/server/templates/devices/devices_normal.html
index a87c3b2..7b5d898 100644
--- a/server/templates/devices/devices_normal.html
+++ b/server/templates/devices/devices_normal.html
@@ -14,6 +14,7 @@
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
+      <option value="/licenses-web">Licenses</option>
   </select>
   <input type="submit" value="OK">
 </form>
diff --git a/server/templates/ld-logs/ldlogs.html b/server/templates/ld-logs/ldlogs.html
index e6f6c27..a936ff4 100644
--- a/server/templates/ld-logs/ldlogs.html
+++ b/server/templates/ld-logs/ldlogs.html
@@ -14,6 +14,7 @@
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
+      <option value="/licenses-web">Licenses</option>
   </select>
   <input type="submit" value="OK">
 </form>
diff --git a/server/templates/licenses/license_create.html b/server/templates/licenses/license_create.html
index 709fb52..861174a 100644
--- a/server/templates/licenses/license_create.html
+++ b/server/templates/licenses/license_create.html
@@ -9,7 +9,7 @@
   <label for="name">Name:</label><br>
   <input type="text" id="name" name="name"><br><br>
     <label for="expdate">Expiration Date</label>
-  <input type="date" id="expdate" name="expdate">
+  <input type="date" id="expdate" name="expdate" min={{minimum_date}}>
   <input type="submit" value="Submit">
 </form>
 </body>
diff --git a/server/templates/licenses/licenses.html b/server/templates/licenses/licenses.html
index d9faf97..e66abfe 100644
--- a/server/templates/licenses/licenses.html
+++ b/server/templates/licenses/licenses.html
@@ -14,6 +14,7 @@
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
+      <option value="/licenses-web">Licenses</option>
   </select>
   <input type="submit" value="OK">
 </form>
@@ -23,9 +24,12 @@
     <input type="submit" value="Login" />
 </form>
 </div>
+<div style='float:left'>
 <form action="/logout" method="get">
     <input type="submit" value="Logout" />
 </form>
+</div>
+<h4>{{user}}</h4>
 <table>
     <TR>
         <TH>ID</TH>
@@ -40,5 +44,8 @@
     </TR>
     {% endfor %}
 </table>
+<form action="/license-create" method="get">
+    <input type="submit" value="Add">
+</form>
 </body>
 </html>
\ No newline at end of file
diff --git a/server/templates/licenses/licenses_normal.html b/server/templates/licenses/licenses_normal.html
new file mode 100644
index 0000000..7b5b644
--- /dev/null
+++ b/server/templates/licenses/licenses_normal.html
@@ -0,0 +1,48 @@
+<html>
+<head>
+    <title>Licenses Details</title>
+</head>
+<body>
+<div style='float:left'>
+<form action="" method="get">
+  <label for="view">Choose view:</label>
+  <select id="view" name="view" onchange="this.form.action=this.value;">
+      <option value=""></option>
+      <option value="/logs-web">Logs</option>
+      <option value="/ldlogs-web">LD Logs</option>
+      <option value="/devices-web">Devices</option>
+      <option value="/body-devices-web">Body Devices</option>
+      <option value="/teams-web">Teams</option>
+      <option value="/pcs-web">PCs</option>
+      <option value="/licenses-web">Licenses</option>
+  </select>
+  <input type="submit" value="OK">
+</form>
+</div>
+<div style='float:left'>
+<form action="/login" method="get">
+    <input type="submit" value="Login" />
+</form>
+</div>
+<div style='float:left'>
+<form action="/logout" method="get">
+    <input type="submit" value="Logout" />
+</form>
+</div>
+<h4>{{user}}</h4>
+<table>
+    <TR>
+        <TH>ID</TH>
+        <TH>Name</TH>
+        <TH>Expiration Date</TH>
+    </TR>
+    {% for license in licenses %}
+    <TR>
+        <TD class="ID">{{license.id}}</TD>
+        <TD class="Vendor ID">{{license.name}}</TD>
+        <TD class="Product ID">{{license.expiration_date}}</TD>
+    </TR>
+    {% endfor %}
+</table>
+</body>
+</html>
\ No newline at end of file
diff --git a/server/templates/pcs/pcs.html b/server/templates/pcs/pcs.html
index fa268a5..79f3156 100644
--- a/server/templates/pcs/pcs.html
+++ b/server/templates/pcs/pcs.html
@@ -14,6 +14,7 @@
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
+      <option value="/licenses-web">Licenses</option>
   </select>
   <input type="submit" value="OK">
 </form>
diff --git a/server/templates/pcs/pcs_normal.html b/server/templates/pcs/pcs_normal.html
index a17833a..52d9085 100644
--- a/server/templates/pcs/pcs_normal.html
+++ b/server/templates/pcs/pcs_normal.html
@@ -14,6 +14,7 @@
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
+      <option value="/licenses-web">Licenses</option>
   </select>
   <input type="submit" value="OK">
 </form>
diff --git a/server/templates/teams/teams.html b/server/templates/teams/teams.html
index f9889f0..546666b 100644
--- a/server/templates/teams/teams.html
+++ b/server/templates/teams/teams.html
@@ -14,6 +14,7 @@
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
+      <option value="/licenses-web">Licenses</option>
   </select>
   <input type="submit" value="OK">
 </form>
@@ -33,11 +34,17 @@
     <TR>
         <TH>ID</TH>
         <TH>Name</TH>
+        <TH>Members</TH>
     </TR>
     {% for team in teams %}
     <TR>
         <TD class="ID">{{team.id}}</TD>
-        <TD class="Vendor ID">{{team.name}}</TD>
+        <TD class="Name">{{team.name}}</TD>
+        <TD class="Members">
+        {% for ppl in team.pcs %}
+            {{ppl.username}}<BR>
+        {% endfor %}
+        </TD>
     </TR>
     {% endfor %}
 </table>
diff --git a/server/templates/teams/teams_normal.html b/server/templates/teams/teams_normal.html
index 1e3c70c..50a7883 100644
--- a/server/templates/teams/teams_normal.html
+++ b/server/templates/teams/teams_normal.html
@@ -14,6 +14,7 @@
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
+      <option value="/licenses-web">Licenses</option>
   </select>
   <input type="submit" value="OK">
 </form>
@@ -33,11 +34,17 @@
     <TR>
         <TH>ID</TH>
         <TH>Name</TH>
+        <TH>Members</TH>
     </TR>
     {% for team in teams %}
     <TR>
         <TD class="ID">{{team.id}}</TD>
         <TD class="Vendor ID">{{team.name}}</TD>
+        <TD class="Members">
+        {% for ppl in team.pcs %}
+            {{ppl.username}}<BR>
+        {% endfor %}
+        </TD>
     </TR>
     {% endfor %}
 </table>
diff --git a/server/templates/usb-logs/crossroad.html b/server/templates/usb-logs/crossroad.html
new file mode 100644
index 0000000..f553dc4
--- /dev/null
+++ b/server/templates/usb-logs/crossroad.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Crossroad</title>
+</head>
+<body>
+<form action="" method="get">
+  <label for="view">Choose view:</label>
+  <select id="view" name="view" onchange="this.form.action=this.value;">
+      <option value=""></option>
+      <option value="/logs-web">Logs</option>
+      <option value="/ldlogs-web">LD Logs</option>
+      <option value="/devices-web">Devices</option>
+      <option value="/body-devices-web">Body Devices</option>
+      <option value="/teams-web">Teams</option>
+      <option value="/pcs-web">PCs</option>
+      <option value="/licenses-web">Licenses</option>
+  </select>
+  <input type="submit" value="OK">
+</form>
+<h3>Available endpoints are accessible from selectBox above</h3>
+<h4>Endpoints are:</h4>
+<table>
+    <TR>
+        <TH>URL</TH>
+        <TH>Purpose</TH>
+    </TR>
+    <TR>
+        <TD class="URL">/logs-web</TD>
+        <TD class="Purpose">Shows all saves Keyman logs. User can filter through license, team and user</TD>
+    </TR>
+    <TR>
+        <TD class="URL">/ldlogs-web</TD>
+        <TD class="Purpose">Shows all saves LD debugger logs. User can filter through license, team and user</TD>
+    </TR>
+    <TR>
+        <TD class="URL">/devices-web</TD>
+        <TD class="Purpose">Shows all Keyman devices saved in database and its last state (connected, disconnected)</TD>
+    </TR>
+    <TR>
+        <TD class="URL">/body-devices-web</TD>
+        <TD class="Purpose">Shows all LD Body devices saved in database and its last state (connected, disconnected)</TD>
+    </TR>
+    <TR>
+        <TD class="URL">/teams-web</TD>
+        <TD class="Purpose">Shows all teams currently saved in database and its members</TD>
+    </TR>
+    <TR>
+        <TD class="URL">/pcs-web</TD>
+        <TD class="Purpose">Shows all PCS currently saved in database and its team</TD>
+    </TR>
+    <TR>
+        <TD class="URL">/licenses-web</TD>
+        <TD class="Purpose">Shows all Licenses currently saved in database and its expiration date</TD>
+    </TR>
+</table>
+</body>
+</html>
\ No newline at end of file
diff --git a/server/templates/usb-logs/logs.html b/server/templates/usb-logs/logs.html
index dc83324..e1d0a17 100644
--- a/server/templates/usb-logs/logs.html
+++ b/server/templates/usb-logs/logs.html
@@ -14,6 +14,7 @@
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
+      <option value="/licenses-web">Licenses</option>
   </select>
   <input type="submit" value="OK">
 </form>
