Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 0fcb708f

Přidáno uživatelem Matěj Zeman před téměř 3 roky(ů)

re #9846 Changed keyman devices, body devices views. Added Head devices view. Changed filtering of logs, ldlogs, body devices, head devices and keyman devices. Changed HTML tables style and few labels.

Zobrazit rozdíly:

server/doc/sql_app/api/auth.html
1
<!doctype html>
2
<html lang="en">
3
<head>
4
<meta charset="utf-8">
5
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
6
<meta name="generator" content="pdoc 0.10.0" />
7
<title>sql_app.api.auth API documentation</title>
8
<meta name="description" content="" />
9
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
10
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
11
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
12
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
13
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
14
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
15
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
16
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
17
</head>
18
<body>
19
<main>
20
<article id="content">
21
<header>
22
<h1 class="title">Module <code>sql_app.api.auth</code></h1>
23
</header>
24
<section id="section-intro">
25
<details class="source">
26
<summary>
27
<span>Expand source code</span>
28
</summary>
29
<pre><code class="python">from fastapi import Depends, APIRouter, Form
30
from fastapi import Request
31
from fastapi.responses import HTMLResponse, RedirectResponse
32
from fastapi.templating import Jinja2Templates
33
from fastapi_jwt_auth import AuthJWT
34
from sqlalchemy.orm import Session
35
from sql_app import crud
36
from passlib.context import CryptContext
37
from pydantic import BaseModel
38
from ..database import SessionLocal, engine
39

  
40
# Path to html templates used in this file
41
templates = Jinja2Templates(directory=&#34;../templates/auth&#34;)
42

  
43
pwd_context = CryptContext(schemes=[&#34;bcrypt&#34;], deprecated=&#34;auto&#34;)
44

  
45
# prefix used for all endpoints in this file
46
auth = APIRouter(prefix=&#34;&#34;)
47

  
48

  
49
# Dependency
50
def get_db():
51
    db = SessionLocal()
52
    try:
53
        yield db
54
    finally:
55
        db.close()
56

  
57

  
58
class Settings(BaseModel):
59
    authjwt_secret_key: str = &#34;secret&#34;
60
    # Configure application to store and get JWT from cookies
61
    authjwt_token_location: set = {&#34;cookies&#34;}
62
    # Disable CSRF Protection for this example. default is True
63
    authjwt_cookie_csrf_protect: bool = False
64

  
65

  
66
@AuthJWT.load_config
67
def get_config():
68
    return Settings()
69

  
70

  
71
# admin username and password
72
fake_users_db = {
73
    &#34;admin&#34;: {
74
        &#34;username&#34;: &#34;admin&#34;,
75
        &#34;password&#34;: &#34;admin&#34;
76
    }
77
}
78

  
79

  
80
def verify_password(plain_password, hashed_password):
81
    &#34;&#34;&#34;
82
    Verifies plain text password with hashed password
83
    &#34;&#34;&#34;
84
    return pwd_context.verify(plain_password, hashed_password)
85

  
86

  
87
def get_hash_password(password):
88
    &#34;&#34;&#34;
89
    Returns hashed password
90
    &#34;&#34;&#34;
91
    return pwd_context.hash(password)
92

  
93

  
94
def auth_user(db, username: str, password: str):
95
    &#34;&#34;&#34;
96
    Determines if given password belongs to user with given username
97
    &#34;&#34;&#34;
98
    user = crud.find_user(db, username)
99
    if not user:
100
        return None
101
    if not verify_password(password, user.password):
102
        return None
103
    return user
104

  
105

  
106
@auth.get(&#34;/signup&#34;, response_class=HTMLResponse)
107
async def signup_get(request: Request):
108
    &#34;&#34;&#34;
109
    return html template for signup
110
    &#34;&#34;&#34;
111
    return templates.TemplateResponse(&#34;signup.html&#34;, {&#34;request&#34;: request})
112

  
113

  
114
@auth.post(&#34;/signup&#34;, response_class=HTMLResponse)
115
async def signup(username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db)):
116
    &#34;&#34;&#34;
117
    Endpoint called form signup template. Creates new user with role guest that can be changed by admin user
118
    &#34;&#34;&#34;
119
    users = crud.get_users(db, 0, 100)
120
    users_names = []
121
    for u in users:
122
        users_names.append(u.username)
123
    if username not in users_names:
124
        new_user = crud.create_user(db, username, get_hash_password(password), &#34;guest&#34;)
125
        if new_user is None:
126
            print(&#34;something went wrong&#34;)
127
        return &#34;&#34;&#34;
128
            &lt;html&gt;
129
                &lt;head&gt;
130
                    &lt;title&gt;Signup&lt;/title&gt;
131
                &lt;/head&gt;
132
                &lt;body&gt;
133
                    &lt;h1&gt;New user created. You can go back to previous page.&lt;/h1&gt;
134
                    &lt;form action=&#34;/logs-web&#34; method=&#34;get&#34;&gt;
135
                        &lt;input type=&#34;submit&#34; value=&#34;Home Page&#34; /&gt;
136
                    &lt;/form&gt;
137
                &lt;/body&gt;
138
            &lt;/html&gt;
139
            &#34;&#34;&#34;
140
    else:
141
        return &#34;&#34;&#34;
142
                    &lt;html&gt;
143
                        &lt;head&gt;
144
                            &lt;title&gt;Signup&lt;/title&gt;
145
                        &lt;/head&gt;
146
                        &lt;body&gt;
147
                            &lt;h1&gt;Username taken. Try to choose different username.&lt;/h1&gt;
148
                            &lt;form action=&#34;/logs-web&#34; method=&#34;get&#34;&gt;
149
                                &lt;input type=&#34;submit&#34; value=&#34;Home Page&#34; /&gt;
150
                            &lt;/form&gt;
151
                        &lt;/body&gt;
152
                    &lt;/html&gt;
153
                    &#34;&#34;&#34;
154

  
155
@auth.get(&#34;/login&#34;, response_class=HTMLResponse)
156
async def login_get(request: Request):
157
    &#34;&#34;&#34;
158
    return html template for login
159
    &#34;&#34;&#34;
160
    return templates.TemplateResponse(&#34;login.html&#34;, {&#34;request&#34;: request})
161

  
162

  
163
@auth.post(&#34;/login&#34;, response_class=HTMLResponse)
164
async def login(username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db),
165
                Authorize: AuthJWT = Depends()):
166
    &#34;&#34;&#34;
167
    Endpoint called from login template. Checks if given username and password aligns with admin
168
    username and password and returns token for browser according to given username and password
169
    &#34;&#34;&#34;
170
    user = auth_user(db, username, password)
171
    if user != None:
172
        if user.role == &#34;admin&#34;:
173
            access_token = Authorize.create_access_token(subject=&#34;admin&#34;, expires_time=False)
174
            refresh_token = Authorize.create_refresh_token(subject=&#34;admin&#34;, expires_time=False)
175
        else:
176
            access_token = Authorize.create_access_token(subject=&#34;guest&#34;, expires_time=False)
177
            refresh_token = Authorize.create_refresh_token(subject=&#34;guest&#34;, expires_time=False)
178
    else:
179
        usr = fake_users_db.get(username)
180
        if usr != None:
181
            if usr[&#34;username&#34;] == username and usr[&#34;password&#34;] == password:
182
                access_token = Authorize.create_access_token(subject=&#34;admin&#34;, expires_time=False)
183
                refresh_token = Authorize.create_refresh_token(subject=&#34;admin&#34;, expires_time=False)
184
        else:
185
            return &#34;&#34;&#34;
186
                &lt;html&gt;
187
                    &lt;head&gt;
188
                        &lt;title&gt;Login&lt;/title&gt;
189
                    &lt;/head&gt;
190
                    &lt;body&gt;
191
                        &lt;h1&gt;Wrong Username or Password&lt;/h1&gt;
192
                        &lt;form action=&#34;/login&#34; method=&#34;get&#34;&gt;
193
                            &lt;input type=&#34;submit&#34; value=&#34;Log again&#34; /&gt;
194
                        &lt;/form&gt;
195
                        &lt;form action=&#34;/login&#34; method=&#34;get&#34;&gt;
196
                            &lt;input type=&#34;submit&#34; value=&#34;Home Page&#34; /&gt;
197
                        &lt;/form&gt;
198
                    &lt;/body&gt;
199
                &lt;/html&gt;
200
                &#34;&#34;&#34;
201

  
202
    # Set the JWT cookies in the response
203
    Authorize.set_access_cookies(access_token)
204
    Authorize.set_refresh_cookies(refresh_token)
205
    return &#34;&#34;&#34;
206
    &lt;html&gt;
207
        &lt;head&gt;
208
            &lt;title&gt;Login&lt;/title&gt;
209
        &lt;/head&gt;
210
        &lt;body&gt;
211
            &lt;h1&gt;Now you are logged in, you can continue to previous page.&lt;/h1&gt;
212
            &lt;form action=&#34;/logs-web&#34; method=&#34;get&#34;&gt;
213
                &lt;input type=&#34;submit&#34; value=&#34;Home Page&#34; /&gt;
214
            &lt;/form&gt;
215
        &lt;/body&gt;
216
    &lt;/html&gt;
217
    &#34;&#34;&#34;
218

  
219

  
220
@auth.post(&#39;/refresh&#39;)
221
def refresh(Authorize: AuthJWT = Depends()):
222
    &#34;&#34;&#34;
223
    endpoint for refreshing browser token. Not used at the moment since lifetime of given tokens are
224
    unlimited.
225
    &#34;&#34;&#34;
226
    Authorize.jwt_refresh_token_required()
227
    current_user = Authorize.get_jwt_subject()
228
    new_access_token = Authorize.create_access_token(subject=current_user)
229
    # Set the JWT cookies in the response
230
    Authorize.set_access_cookies(new_access_token)
231
    return {&#34;msg&#34;: &#34;The token has been refresh&#34;}
232

  
233

  
234
@auth.get(&#39;/logout&#39;, response_class=HTMLResponse)
235
def logout(Authorize: AuthJWT = Depends()):
236
    &#34;&#34;&#34;
237
    Endpoint for deleting cookie token with acces role.
238
    &#34;&#34;&#34;
239
    Authorize.jwt_optional()
240

  
241
    Authorize.unset_jwt_cookies()
242
    return &#34;&#34;&#34;
243
        &lt;html&gt;
244
            &lt;head&gt;
245
                &lt;title&gt;Logout&lt;/title&gt;
246
            &lt;/head&gt;
247
            &lt;body&gt;
248
                &lt;h1&gt;Logged Out&lt;/h1&gt;
249
                &lt;form action=&#34;/logs-web&#34; method=&#34;get&#34;&gt;
250
                    &lt;input type=&#34;submit&#34; value=&#34;Back&#34; /&gt;
251
                &lt;/form&gt;
252
            &lt;/body&gt;
253
        &lt;/html&gt;
254
        &#34;&#34;&#34;</code></pre>
255
</details>
256
</section>
257
<section>
258
</section>
259
<section>
260
</section>
261
<section>
262
<h2 class="section-title" id="header-functions">Functions</h2>
263
<dl>
264
<dt id="sql_app.api.auth.auth_user"><code class="name flex">
265
<span>def <span class="ident">auth_user</span></span>(<span>db, username: str, password: str)</span>
266
</code></dt>
267
<dd>
268
<div class="desc"><p>Determines if given password belongs to user with given username</p></div>
269
<details class="source">
270
<summary>
271
<span>Expand source code</span>
272
</summary>
273
<pre><code class="python">def auth_user(db, username: str, password: str):
274
    &#34;&#34;&#34;
275
    Determines if given password belongs to user with given username
276
    &#34;&#34;&#34;
277
    user = crud.find_user(db, username)
278
    if not user:
279
        return None
280
    if not verify_password(password, user.password):
281
        return None
282
    return user</code></pre>
283
</details>
284
</dd>
285
<dt id="sql_app.api.auth.get_db"><code class="name flex">
286
<span>def <span class="ident">get_db</span></span>(<span>)</span>
287
</code></dt>
288
<dd>
289
<div class="desc"></div>
290
<details class="source">
291
<summary>
292
<span>Expand source code</span>
293
</summary>
294
<pre><code class="python">def get_db():
295
    db = SessionLocal()
296
    try:
297
        yield db
298
    finally:
299
        db.close()</code></pre>
300
</details>
301
</dd>
302
<dt id="sql_app.api.auth.get_hash_password"><code class="name flex">
303
<span>def <span class="ident">get_hash_password</span></span>(<span>password)</span>
304
</code></dt>
305
<dd>
306
<div class="desc"><p>Returns hashed password</p></div>
307
<details class="source">
308
<summary>
309
<span>Expand source code</span>
310
</summary>
311
<pre><code class="python">def get_hash_password(password):
312
    &#34;&#34;&#34;
313
    Returns hashed password
314
    &#34;&#34;&#34;
315
    return pwd_context.hash(password)</code></pre>
316
</details>
317
</dd>
318
<dt id="sql_app.api.auth.login"><code class="name flex">
319
<span>async def <span class="ident">login</span></span>(<span>username: str = Form(Ellipsis), password: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
320
</code></dt>
321
<dd>
322
<div class="desc"><p>Endpoint called from login template. Checks if given username and password aligns with admin
323
username and password and returns token for browser according to given username and password</p></div>
324
<details class="source">
325
<summary>
326
<span>Expand source code</span>
327
</summary>
328
<pre><code class="python">@auth.post(&#34;/login&#34;, response_class=HTMLResponse)
329
async def login(username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db),
330
                Authorize: AuthJWT = Depends()):
331
    &#34;&#34;&#34;
332
    Endpoint called from login template. Checks if given username and password aligns with admin
333
    username and password and returns token for browser according to given username and password
334
    &#34;&#34;&#34;
335
    user = auth_user(db, username, password)
336
    if user != None:
337
        if user.role == &#34;admin&#34;:
338
            access_token = Authorize.create_access_token(subject=&#34;admin&#34;, expires_time=False)
339
            refresh_token = Authorize.create_refresh_token(subject=&#34;admin&#34;, expires_time=False)
340
        else:
341
            access_token = Authorize.create_access_token(subject=&#34;guest&#34;, expires_time=False)
342
            refresh_token = Authorize.create_refresh_token(subject=&#34;guest&#34;, expires_time=False)
343
    else:
344
        usr = fake_users_db.get(username)
345
        if usr != None:
346
            if usr[&#34;username&#34;] == username and usr[&#34;password&#34;] == password:
347
                access_token = Authorize.create_access_token(subject=&#34;admin&#34;, expires_time=False)
348
                refresh_token = Authorize.create_refresh_token(subject=&#34;admin&#34;, expires_time=False)
349
        else:
350
            return &#34;&#34;&#34;
351
                &lt;html&gt;
352
                    &lt;head&gt;
353
                        &lt;title&gt;Login&lt;/title&gt;
354
                    &lt;/head&gt;
355
                    &lt;body&gt;
356
                        &lt;h1&gt;Wrong Username or Password&lt;/h1&gt;
357
                        &lt;form action=&#34;/login&#34; method=&#34;get&#34;&gt;
358
                            &lt;input type=&#34;submit&#34; value=&#34;Log again&#34; /&gt;
359
                        &lt;/form&gt;
360
                        &lt;form action=&#34;/login&#34; method=&#34;get&#34;&gt;
361
                            &lt;input type=&#34;submit&#34; value=&#34;Home Page&#34; /&gt;
362
                        &lt;/form&gt;
363
                    &lt;/body&gt;
364
                &lt;/html&gt;
365
                &#34;&#34;&#34;
366

  
367
    # Set the JWT cookies in the response
368
    Authorize.set_access_cookies(access_token)
369
    Authorize.set_refresh_cookies(refresh_token)
370
    return &#34;&#34;&#34;
371
    &lt;html&gt;
372
        &lt;head&gt;
373
            &lt;title&gt;Login&lt;/title&gt;
374
        &lt;/head&gt;
375
        &lt;body&gt;
376
            &lt;h1&gt;Now you are logged in, you can continue to previous page.&lt;/h1&gt;
377
            &lt;form action=&#34;/logs-web&#34; method=&#34;get&#34;&gt;
378
                &lt;input type=&#34;submit&#34; value=&#34;Home Page&#34; /&gt;
379
            &lt;/form&gt;
380
        &lt;/body&gt;
381
    &lt;/html&gt;
382
    &#34;&#34;&#34;</code></pre>
383
</details>
384
</dd>
385
<dt id="sql_app.api.auth.login_get"><code class="name flex">
386
<span>async def <span class="ident">login_get</span></span>(<span>request: starlette.requests.Request)</span>
387
</code></dt>
388
<dd>
389
<div class="desc"><p>return html template for login</p></div>
390
<details class="source">
391
<summary>
392
<span>Expand source code</span>
393
</summary>
394
<pre><code class="python">@auth.get(&#34;/login&#34;, response_class=HTMLResponse)
395
async def login_get(request: Request):
396
    &#34;&#34;&#34;
397
    return html template for login
398
    &#34;&#34;&#34;
399
    return templates.TemplateResponse(&#34;login.html&#34;, {&#34;request&#34;: request})</code></pre>
400
</details>
401
</dd>
402
<dt id="sql_app.api.auth.logout"><code class="name flex">
403
<span>def <span class="ident">logout</span></span>(<span>Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
404
</code></dt>
405
<dd>
406
<div class="desc"><p>Endpoint for deleting cookie token with acces role.</p></div>
407
<details class="source">
408
<summary>
409
<span>Expand source code</span>
410
</summary>
411
<pre><code class="python">@auth.get(&#39;/logout&#39;, response_class=HTMLResponse)
412
def logout(Authorize: AuthJWT = Depends()):
413
    &#34;&#34;&#34;
414
    Endpoint for deleting cookie token with acces role.
415
    &#34;&#34;&#34;
416
    Authorize.jwt_optional()
417

  
418
    Authorize.unset_jwt_cookies()
419
    return &#34;&#34;&#34;
420
        &lt;html&gt;
421
            &lt;head&gt;
422
                &lt;title&gt;Logout&lt;/title&gt;
423
            &lt;/head&gt;
424
            &lt;body&gt;
425
                &lt;h1&gt;Logged Out&lt;/h1&gt;
426
                &lt;form action=&#34;/logs-web&#34; method=&#34;get&#34;&gt;
427
                    &lt;input type=&#34;submit&#34; value=&#34;Back&#34; /&gt;
428
                &lt;/form&gt;
429
            &lt;/body&gt;
430
        &lt;/html&gt;
431
        &#34;&#34;&#34;</code></pre>
432
</details>
433
</dd>
434
<dt id="sql_app.api.auth.refresh"><code class="name flex">
435
<span>def <span class="ident">refresh</span></span>(<span>Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
436
</code></dt>
437
<dd>
438
<div class="desc"><p>endpoint for refreshing browser token. Not used at the moment since lifetime of given tokens are
439
unlimited.</p></div>
440
<details class="source">
441
<summary>
442
<span>Expand source code</span>
443
</summary>
444
<pre><code class="python">@auth.post(&#39;/refresh&#39;)
445
def refresh(Authorize: AuthJWT = Depends()):
446
    &#34;&#34;&#34;
447
    endpoint for refreshing browser token. Not used at the moment since lifetime of given tokens are
448
    unlimited.
449
    &#34;&#34;&#34;
450
    Authorize.jwt_refresh_token_required()
451
    current_user = Authorize.get_jwt_subject()
452
    new_access_token = Authorize.create_access_token(subject=current_user)
453
    # Set the JWT cookies in the response
454
    Authorize.set_access_cookies(new_access_token)
455
    return {&#34;msg&#34;: &#34;The token has been refresh&#34;}</code></pre>
456
</details>
457
</dd>
458
<dt id="sql_app.api.auth.signup"><code class="name flex">
459
<span>async def <span class="ident">signup</span></span>(<span>username: str = Form(Ellipsis), password: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
460
</code></dt>
461
<dd>
462
<div class="desc"><p>Endpoint called form signup template. Creates new user with role guest that can be changed by admin user</p></div>
463
<details class="source">
464
<summary>
465
<span>Expand source code</span>
466
</summary>
467
<pre><code class="python">@auth.post(&#34;/signup&#34;, response_class=HTMLResponse)
468
async def signup(username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db)):
469
    &#34;&#34;&#34;
470
    Endpoint called form signup template. Creates new user with role guest that can be changed by admin user
471
    &#34;&#34;&#34;
472
    users = crud.get_users(db, 0, 100)
473
    users_names = []
474
    for u in users:
475
        users_names.append(u.username)
476
    if username not in users_names:
477
        new_user = crud.create_user(db, username, get_hash_password(password), &#34;guest&#34;)
478
        if new_user is None:
479
            print(&#34;something went wrong&#34;)
480
        return &#34;&#34;&#34;
481
            &lt;html&gt;
482
                &lt;head&gt;
483
                    &lt;title&gt;Signup&lt;/title&gt;
484
                &lt;/head&gt;
485
                &lt;body&gt;
486
                    &lt;h1&gt;New user created. You can go back to previous page.&lt;/h1&gt;
487
                    &lt;form action=&#34;/logs-web&#34; method=&#34;get&#34;&gt;
488
                        &lt;input type=&#34;submit&#34; value=&#34;Home Page&#34; /&gt;
489
                    &lt;/form&gt;
490
                &lt;/body&gt;
491
            &lt;/html&gt;
492
            &#34;&#34;&#34;
493
    else:
494
        return &#34;&#34;&#34;
495
                    &lt;html&gt;
496
                        &lt;head&gt;
497
                            &lt;title&gt;Signup&lt;/title&gt;
498
                        &lt;/head&gt;
499
                        &lt;body&gt;
500
                            &lt;h1&gt;Username taken. Try to choose different username.&lt;/h1&gt;
501
                            &lt;form action=&#34;/logs-web&#34; method=&#34;get&#34;&gt;
502
                                &lt;input type=&#34;submit&#34; value=&#34;Home Page&#34; /&gt;
503
                            &lt;/form&gt;
504
                        &lt;/body&gt;
505
                    &lt;/html&gt;
506
                    &#34;&#34;&#34;</code></pre>
507
</details>
508
</dd>
509
<dt id="sql_app.api.auth.signup_get"><code class="name flex">
510
<span>async def <span class="ident">signup_get</span></span>(<span>request: starlette.requests.Request)</span>
511
</code></dt>
512
<dd>
513
<div class="desc"><p>return html template for signup</p></div>
514
<details class="source">
515
<summary>
516
<span>Expand source code</span>
517
</summary>
518
<pre><code class="python">@auth.get(&#34;/signup&#34;, response_class=HTMLResponse)
519
async def signup_get(request: Request):
520
    &#34;&#34;&#34;
521
    return html template for signup
522
    &#34;&#34;&#34;
523
    return templates.TemplateResponse(&#34;signup.html&#34;, {&#34;request&#34;: request})</code></pre>
524
</details>
525
</dd>
526
<dt id="sql_app.api.auth.verify_password"><code class="name flex">
527
<span>def <span class="ident">verify_password</span></span>(<span>plain_password, hashed_password)</span>
528
</code></dt>
529
<dd>
530
<div class="desc"><p>Verifies plain text password with hashed password</p></div>
531
<details class="source">
532
<summary>
533
<span>Expand source code</span>
534
</summary>
535
<pre><code class="python">def verify_password(plain_password, hashed_password):
536
    &#34;&#34;&#34;
537
    Verifies plain text password with hashed password
538
    &#34;&#34;&#34;
539
    return pwd_context.verify(plain_password, hashed_password)</code></pre>
540
</details>
541
</dd>
542
</dl>
543
</section>
544
<section>
545
<h2 class="section-title" id="header-classes">Classes</h2>
546
<dl>
547
<dt id="sql_app.api.auth.Settings"><code class="flex name class">
548
<span>class <span class="ident">Settings</span></span>
549
<span>(</span><span>**data: Any)</span>
550
</code></dt>
551
<dd>
552
<div class="desc"><p>Create a new model by parsing and validating input data from keyword arguments.</p>
553
<p>Raises ValidationError if the input data cannot be parsed to form a valid model.</p></div>
554
<details class="source">
555
<summary>
556
<span>Expand source code</span>
557
</summary>
558
<pre><code class="python">class Settings(BaseModel):
559
    authjwt_secret_key: str = &#34;secret&#34;
560
    # Configure application to store and get JWT from cookies
561
    authjwt_token_location: set = {&#34;cookies&#34;}
562
    # Disable CSRF Protection for this example. default is True
563
    authjwt_cookie_csrf_protect: bool = False</code></pre>
564
</details>
565
<h3>Ancestors</h3>
566
<ul class="hlist">
567
<li>pydantic.main.BaseModel</li>
568
<li>pydantic.utils.Representation</li>
569
</ul>
570
<h3>Class variables</h3>
571
<dl>
572
<dt id="sql_app.api.auth.Settings.authjwt_cookie_csrf_protect"><code class="name">var <span class="ident">authjwt_cookie_csrf_protect</span> : bool</code></dt>
573
<dd>
574
<div class="desc"></div>
575
</dd>
576
<dt id="sql_app.api.auth.Settings.authjwt_secret_key"><code class="name">var <span class="ident">authjwt_secret_key</span> : str</code></dt>
577
<dd>
578
<div class="desc"></div>
579
</dd>
580
<dt id="sql_app.api.auth.Settings.authjwt_token_location"><code class="name">var <span class="ident">authjwt_token_location</span> : set</code></dt>
581
<dd>
582
<div class="desc"></div>
583
</dd>
584
</dl>
585
</dd>
586
</dl>
587
</section>
588
</article>
589
<nav id="sidebar">
590
<h1>Index</h1>
591
<div class="toc">
592
<ul></ul>
593
</div>
594
<ul id="index">
595
<li><h3>Super-module</h3>
596
<ul>
597
<li><code><a title="sql_app.api" href="index.html">sql_app.api</a></code></li>
598
</ul>
599
</li>
600
<li><h3><a href="#header-functions">Functions</a></h3>
601
<ul class="two-column">
602
<li><code><a title="sql_app.api.auth.auth_user" href="#sql_app.api.auth.auth_user">auth_user</a></code></li>
603
<li><code><a title="sql_app.api.auth.get_db" href="#sql_app.api.auth.get_db">get_db</a></code></li>
604
<li><code><a title="sql_app.api.auth.get_hash_password" href="#sql_app.api.auth.get_hash_password">get_hash_password</a></code></li>
605
<li><code><a title="sql_app.api.auth.login" href="#sql_app.api.auth.login">login</a></code></li>
606
<li><code><a title="sql_app.api.auth.login_get" href="#sql_app.api.auth.login_get">login_get</a></code></li>
607
<li><code><a title="sql_app.api.auth.logout" href="#sql_app.api.auth.logout">logout</a></code></li>
608
<li><code><a title="sql_app.api.auth.refresh" href="#sql_app.api.auth.refresh">refresh</a></code></li>
609
<li><code><a title="sql_app.api.auth.signup" href="#sql_app.api.auth.signup">signup</a></code></li>
610
<li><code><a title="sql_app.api.auth.signup_get" href="#sql_app.api.auth.signup_get">signup_get</a></code></li>
611
<li><code><a title="sql_app.api.auth.verify_password" href="#sql_app.api.auth.verify_password">verify_password</a></code></li>
612
</ul>
613
</li>
614
<li><h3><a href="#header-classes">Classes</a></h3>
615
<ul>
616
<li>
617
<h4><code><a title="sql_app.api.auth.Settings" href="#sql_app.api.auth.Settings">Settings</a></code></h4>
618
<ul class="">
619
<li><code><a title="sql_app.api.auth.Settings.authjwt_cookie_csrf_protect" href="#sql_app.api.auth.Settings.authjwt_cookie_csrf_protect">authjwt_cookie_csrf_protect</a></code></li>
620
<li><code><a title="sql_app.api.auth.Settings.authjwt_secret_key" href="#sql_app.api.auth.Settings.authjwt_secret_key">authjwt_secret_key</a></code></li>
621
<li><code><a title="sql_app.api.auth.Settings.authjwt_token_location" href="#sql_app.api.auth.Settings.authjwt_token_location">authjwt_token_location</a></code></li>
622
</ul>
623
</li>
624
</ul>
625
</li>
626
</ul>
627
</nav>
628
</main>
629
<footer id="footer">
630
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p>
631
</footer>
632
</body>
633
</html>
server/doc/sql_app/api/bodydevices_web.html
1
<!doctype html>
2
<html lang="en">
3
<head>
4
<meta charset="utf-8">
5
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
6
<meta name="generator" content="pdoc 0.10.0" />
7
<title>sql_app.api.bodydevices_web API documentation</title>
8
<meta name="description" content="" />
9
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
10
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
11
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
12
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
13
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
14
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
15
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
16
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
17
</head>
18
<body>
19
<main>
20
<article id="content">
21
<header>
22
<h1 class="title">Module <code>sql_app.api.bodydevices_web</code></h1>
23
</header>
24
<section id="section-intro">
25
<details class="source">
26
<summary>
27
<span>Expand source code</span>
28
</summary>
29
<pre><code class="python">from datetime import datetime
30

  
31
from fastapi import Depends, APIRouter, Form
32
from fastapi import Request
33
from fastapi.responses import HTMLResponse, RedirectResponse
34
from fastapi.templating import Jinja2Templates
35
from fastapi_jwt_auth import AuthJWT
36
from pydantic import BaseModel
37
from sqlalchemy.orm import Session
38
from sql_app.api.auth import fake_users_db
39
from sql_app import crud, models
40
from ..database import SessionLocal, engine
41

  
42
models.Base.metadata.create_all(bind=engine)
43

  
44
# Path to html templates used in this file
45
templates = Jinja2Templates(directory=&#34;../templates/body-devices&#34;)
46

  
47
# prefix used for all endpoints in this file
48
body_device_web = APIRouter(prefix=&#34;&#34;)
49

  
50

  
51
# Dependency
52
def get_db():
53
    db = SessionLocal()
54
    try:
55
        yield db
56
    finally:
57
        db.close()
58

  
59

  
60
@body_device_web.get(&#34;/body-devices-web&#34;, response_class=HTMLResponse)
61
async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
62
                       Authorize: AuthJWT = Depends()):
63
    &#34;&#34;&#34;
64
    Returns template with all body devices and necessary attributes
65
    &#34;&#34;&#34;
66
    Authorize.jwt_optional()
67
    current_user = Authorize.get_jwt_subject()
68

  
69
    device_dict = []
70
    devices = crud.get_body_devices(db, skip=skip, limit=limit)
71
    teams = crud.get_teams(db, skip=skip, limit=limit)
72
    for dev in devices:
73
        lic = crud.get_license(db, dev.license_id)
74
        device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: lic, &#34;log&#34;: dev.b_logs[len(dev.b_logs) - 1]})
75
    licenses = crud.get_licenses(db, skip=skip, limit=limit)
76
    if current_user == &#34;admin&#34;:
77
        return templates.TemplateResponse(&#34;body_devices.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
78
                                                                &#34;devs&#34;: devices, &#34;teams&#34;: teams, &#34;licenses&#34;: licenses,
79
                                                                &#34;user&#34;: current_user})
80
    else:
81
        current_user = &#34;guest&#34;
82
        return templates.TemplateResponse(&#34;body_devices_normal.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
83
                                                                &#34;devs&#34;: devices, &#34;teams&#34;: teams, &#34;licenses&#34;: licenses,
84
                                                                &#34;user&#34;: current_user})
85

  
86

  
87
@body_device_web.post(&#34;/body-devices-web&#34;, response_class=HTMLResponse)
88
async def filter_devices(request: Request, skip: int = 0, limit: int = 100,
89
                         body_id: str = Form(&#34;all&#34;), lic_id: str = Form(&#34;all&#34;), team: str = Form(&#34;all&#34;),
90
                         db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
91
    &#34;&#34;&#34;
92
    Endpoint used for filtering body devices by user given inputs. returns html template with only
93
    body devices that has attributes defined by user input
94
    &#34;&#34;&#34;
95
    Authorize.jwt_optional()
96
    current_user = Authorize.get_jwt_subject()
97
    device_dict = []
98
    devices_f = crud.get_filtered_bodydevices(db, body_id, lic_id, team)
99
    ids = []
100
    for d in devices_f:
101
        ids.append(d[0])
102
    devices = crud.get_bodydevices_with_ids(db, ids)
103
    teams = crud.get_teams(db, skip=skip, limit=limit)
104
    for dev in devices:
105
        lic = crud.get_license(db, dev.license_id)
106
        device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: lic, &#34;log&#34;: dev.b_logs[len(dev.b_logs) - 1]})
107
    licenses = crud.get_licenses(db, skip=skip, limit=limit)
108
    if current_user == &#34;admin&#34;:
109
        return templates.TemplateResponse(&#34;body_devices.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
110
                                                                &#34;devs&#34;: devices, &#34;teams&#34;: teams, &#34;licenses&#34;: licenses,
111
                                                                &#34;user&#34;: current_user})
112
    else:
113
        current_user = &#34;guest&#34;
114
        return templates.TemplateResponse(&#34;body_devices_normal.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
115
                                                                       &#34;devs&#34;: devices, &#34;teams&#34;: teams,
116
                                                                       &#34;licenses&#34;: licenses,
117
                                                                       &#34;user&#34;: current_user})
118

  
119

  
120
@body_device_web.get(&#34;/body-device-license/{device_id}&#34;, response_class=HTMLResponse)
121
async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db),
122
                          Authorize: AuthJWT = Depends()):
123
    &#34;&#34;&#34;
124
    Returns template with one body device and all available licenses that can be assigned to it. Plus available teams
125
    that can be assigned to device, inventory number and comment text input for this device.
126
    &#34;&#34;&#34;
127
    Authorize.jwt_optional()
128
    current_user = Authorize.get_jwt_subject()
129
    if current_user != &#34;admin&#34;:
130
        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
131
    device = crud.get_body_device(db, device_id)
132
    licenses = crud.get_licenses(db, 0, 100)
133
    lic_left = []
134
    for lic in licenses:
135
        if lic != device.license:
136
            lic_left.append(lic)
137
    teams = crud.get_teams(db, 0, 100)
138
    return templates.TemplateResponse(&#34;body_device_license.html&#34;,
139
                                      {&#34;request&#34;: request, &#34;device&#34;: device, &#34;licenses&#34;: lic_left, &#34;teams&#34;: teams})
140

  
141

  
142
@body_device_web.post(&#34;/body-devices-web-lic/{device_id}&#34;)
143
async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db),
144
                       Authorize: AuthJWT = Depends()):
145
    &#34;&#34;&#34;
146
    Endpoint called from template from body_device_license.html template. Connects body device with license
147
    and redirects to body-devices-web endpoint
148
    &#34;&#34;&#34;
149
    Authorize.jwt_optional()
150
    current_user = Authorize.get_jwt_subject()
151
    if current_user != &#34;admin&#34;:
152
        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
153
    crud.update_bodydevice_license(db, device_id, int(lic))
154
    return RedirectResponse(url=f&#34;/body-devices-web&#34;, status_code=303)
155

  
156

  
157
@body_device_web.post(&#34;/body-devices-web-team/{device_id}&#34;)
158
async def delete_post(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db),
159
                      Authorize: AuthJWT = Depends()):
160
    &#34;&#34;&#34;
161
    Endpoint called from template from body_device_license.html template, connects device with new team
162
    and redirects to body-devices-web endpoint
163
    &#34;&#34;&#34;
164
    Authorize.jwt_optional()
165
    current_user = Authorize.get_jwt_subject()
166
    if current_user != &#34;admin&#34;:
167
        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
168
    crud.update_bodydevice_team(db, device_id, int(team_con))
169
    return RedirectResponse(url=f&#34;/body-devices-web&#34;, status_code=303)
170

  
171

  
172
@body_device_web.post(&#34;/body-devices-inv/{device_id}&#34;)
173
async def device_inv(device_id: int, dev_inv: str = Form(...), db: Session = Depends(get_db),
174
                     Authorize: AuthJWT = Depends()):
175
    &#34;&#34;&#34;
176
    Endpoint called from template from body_device_license.html template, updates devices inventory number
177
    and redirects to body-devices-web endpoint
178
    &#34;&#34;&#34;
179
    Authorize.jwt_optional()
180
    current_user = Authorize.get_jwt_subject()
181
    if current_user != &#34;admin&#34;:
182
        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
183
    crud.update_bodydevice_inv(db, device_id, dev_inv)
184
    return RedirectResponse(url=f&#34;/body-devices-web&#34;, status_code=303)
185

  
186

  
187
@body_device_web.post(&#34;/body-devices-comm/{device_id}&#34;)
188
async def device_inv(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db),
189
                     Authorize: AuthJWT = Depends()):
190
    &#34;&#34;&#34;
191
    Endpoint called from template from body_device_license.html template, updates devices comment
192
    and redirects to body-devices-web endpoint
193
    &#34;&#34;&#34;
194
    Authorize.jwt_optional()
195
    current_user = Authorize.get_jwt_subject()
196
    if current_user != &#34;admin&#34;:
197
        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
198
    crud.update_bodydevice_comm(db, device_id, dev_com)
199
    return RedirectResponse(url=f&#34;/body-devices-web&#34;, status_code=303)</code></pre>
200
</details>
201
</section>
202
<section>
203
</section>
204
<section>
205
</section>
206
<section>
207
<h2 class="section-title" id="header-functions">Functions</h2>
208
<dl>
209
<dt id="sql_app.api.bodydevices_web.connect_dev_lic"><code class="name flex">
210
<span>async def <span class="ident">connect_dev_lic</span></span>(<span>request: starlette.requests.Request, device_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
211
</code></dt>
212
<dd>
213
<div class="desc"><p>Returns template with one body device and all available licenses that can be assigned to it. Plus available teams
214
that can be assigned to device, inventory number and comment text input for this device.</p></div>
215
<details class="source">
216
<summary>
217
<span>Expand source code</span>
218
</summary>
219
<pre><code class="python">@body_device_web.get(&#34;/body-device-license/{device_id}&#34;, response_class=HTMLResponse)
220
async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db),
221
                          Authorize: AuthJWT = Depends()):
222
    &#34;&#34;&#34;
223
    Returns template with one body device and all available licenses that can be assigned to it. Plus available teams
224
    that can be assigned to device, inventory number and comment text input for this device.
225
    &#34;&#34;&#34;
226
    Authorize.jwt_optional()
227
    current_user = Authorize.get_jwt_subject()
228
    if current_user != &#34;admin&#34;:
229
        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
230
    device = crud.get_body_device(db, device_id)
231
    licenses = crud.get_licenses(db, 0, 100)
232
    lic_left = []
233
    for lic in licenses:
234
        if lic != device.license:
235
            lic_left.append(lic)
236
    teams = crud.get_teams(db, 0, 100)
237
    return templates.TemplateResponse(&#34;body_device_license.html&#34;,
238
                                      {&#34;request&#34;: request, &#34;device&#34;: device, &#34;licenses&#34;: lic_left, &#34;teams&#34;: teams})</code></pre>
239
</details>
240
</dd>
241
<dt id="sql_app.api.bodydevices_web.connect_post"><code class="name flex">
242
<span>async def <span class="ident">connect_post</span></span>(<span>device_id: int, lic: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
243
</code></dt>
244
<dd>
245
<div class="desc"><p>Endpoint called from template from body_device_license.html template. Connects body device with license
246
and redirects to body-devices-web endpoint</p></div>
247
<details class="source">
248
<summary>
249
<span>Expand source code</span>
250
</summary>
251
<pre><code class="python">@body_device_web.post(&#34;/body-devices-web-lic/{device_id}&#34;)
252
async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db),
253
                       Authorize: AuthJWT = Depends()):
254
    &#34;&#34;&#34;
255
    Endpoint called from template from body_device_license.html template. Connects body device with license
256
    and redirects to body-devices-web endpoint
257
    &#34;&#34;&#34;
258
    Authorize.jwt_optional()
259
    current_user = Authorize.get_jwt_subject()
260
    if current_user != &#34;admin&#34;:
261
        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
262
    crud.update_bodydevice_license(db, device_id, int(lic))
263
    return RedirectResponse(url=f&#34;/body-devices-web&#34;, status_code=303)</code></pre>
264
</details>
265
</dd>
266
<dt id="sql_app.api.bodydevices_web.delete_post"><code class="name flex">
267
<span>async def <span class="ident">delete_post</span></span>(<span>device_id: int, team_con: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
268
</code></dt>
269
<dd>
270
<div class="desc"><p>Endpoint called from template from body_device_license.html template, connects device with new team
271
and redirects to body-devices-web endpoint</p></div>
272
<details class="source">
273
<summary>
274
<span>Expand source code</span>
275
</summary>
276
<pre><code class="python">@body_device_web.post(&#34;/body-devices-web-team/{device_id}&#34;)
277
async def delete_post(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db),
278
                      Authorize: AuthJWT = Depends()):
279
    &#34;&#34;&#34;
280
    Endpoint called from template from body_device_license.html template, connects device with new team
281
    and redirects to body-devices-web endpoint
282
    &#34;&#34;&#34;
283
    Authorize.jwt_optional()
284
    current_user = Authorize.get_jwt_subject()
285
    if current_user != &#34;admin&#34;:
286
        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
287
    crud.update_bodydevice_team(db, device_id, int(team_con))
288
    return RedirectResponse(url=f&#34;/body-devices-web&#34;, status_code=303)</code></pre>
289
</details>
290
</dd>
291
<dt id="sql_app.api.bodydevices_web.device_inv"><code class="name flex">
292
<span>async def <span class="ident">device_inv</span></span>(<span>device_id: int, dev_com: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
293
</code></dt>
294
<dd>
295
<div class="desc"><p>Endpoint called from template from body_device_license.html template, updates devices comment
296
and redirects to body-devices-web endpoint</p></div>
297
<details class="source">
298
<summary>
299
<span>Expand source code</span>
300
</summary>
301
<pre><code class="python">@body_device_web.post(&#34;/body-devices-comm/{device_id}&#34;)
302
async def device_inv(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db),
303
                     Authorize: AuthJWT = Depends()):
304
    &#34;&#34;&#34;
305
    Endpoint called from template from body_device_license.html template, updates devices comment
306
    and redirects to body-devices-web endpoint
307
    &#34;&#34;&#34;
308
    Authorize.jwt_optional()
309
    current_user = Authorize.get_jwt_subject()
310
    if current_user != &#34;admin&#34;:
311
        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
312
    crud.update_bodydevice_comm(db, device_id, dev_com)
313
    return RedirectResponse(url=f&#34;/body-devices-web&#34;, status_code=303)</code></pre>
314
</details>
315
</dd>
316
<dt id="sql_app.api.bodydevices_web.filter_devices"><code class="name flex">
317
<span>async def <span class="ident">filter_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, body_id: str = Form(all), lic_id: str = Form(all), team: str = Form(all), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
318
</code></dt>
319
<dd>
320
<div class="desc"><p>Endpoint used for filtering body devices by user given inputs. returns html template with only
321
body devices that has attributes defined by user input</p></div>
322
<details class="source">
323
<summary>
324
<span>Expand source code</span>
325
</summary>
326
<pre><code class="python">@body_device_web.post(&#34;/body-devices-web&#34;, response_class=HTMLResponse)
327
async def filter_devices(request: Request, skip: int = 0, limit: int = 100,
328
                         body_id: str = Form(&#34;all&#34;), lic_id: str = Form(&#34;all&#34;), team: str = Form(&#34;all&#34;),
329
                         db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
330
    &#34;&#34;&#34;
331
    Endpoint used for filtering body devices by user given inputs. returns html template with only
332
    body devices that has attributes defined by user input
333
    &#34;&#34;&#34;
334
    Authorize.jwt_optional()
335
    current_user = Authorize.get_jwt_subject()
336
    device_dict = []
337
    devices_f = crud.get_filtered_bodydevices(db, body_id, lic_id, team)
338
    ids = []
339
    for d in devices_f:
340
        ids.append(d[0])
341
    devices = crud.get_bodydevices_with_ids(db, ids)
342
    teams = crud.get_teams(db, skip=skip, limit=limit)
343
    for dev in devices:
344
        lic = crud.get_license(db, dev.license_id)
345
        device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: lic, &#34;log&#34;: dev.b_logs[len(dev.b_logs) - 1]})
346
    licenses = crud.get_licenses(db, skip=skip, limit=limit)
347
    if current_user == &#34;admin&#34;:
348
        return templates.TemplateResponse(&#34;body_devices.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
349
                                                                &#34;devs&#34;: devices, &#34;teams&#34;: teams, &#34;licenses&#34;: licenses,
350
                                                                &#34;user&#34;: current_user})
351
    else:
352
        current_user = &#34;guest&#34;
353
        return templates.TemplateResponse(&#34;body_devices_normal.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
354
                                                                       &#34;devs&#34;: devices, &#34;teams&#34;: teams,
355
                                                                       &#34;licenses&#34;: licenses,
356
                                                                       &#34;user&#34;: current_user})</code></pre>
357
</details>
358
</dd>
359
<dt id="sql_app.api.bodydevices_web.get_db"><code class="name flex">
360
<span>def <span class="ident">get_db</span></span>(<span>)</span>
361
</code></dt>
362
<dd>
363
<div class="desc"></div>
364
<details class="source">
365
<summary>
366
<span>Expand source code</span>
367
</summary>
368
<pre><code class="python">def get_db():
369
    db = SessionLocal()
370
    try:
371
        yield db
372
    finally:
373
        db.close()</code></pre>
374
</details>
375
</dd>
376
<dt id="sql_app.api.bodydevices_web.read_devices"><code class="name flex">
377
<span>async def <span class="ident">read_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
378
</code></dt>
379
<dd>
380
<div class="desc"><p>Returns template with all body devices and necessary attributes</p></div>
381
<details class="source">
382
<summary>
383
<span>Expand source code</span>
384
</summary>
385
<pre><code class="python">@body_device_web.get(&#34;/body-devices-web&#34;, response_class=HTMLResponse)
386
async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
387
                       Authorize: AuthJWT = Depends()):
388
    &#34;&#34;&#34;
389
    Returns template with all body devices and necessary attributes
390
    &#34;&#34;&#34;
391
    Authorize.jwt_optional()
392
    current_user = Authorize.get_jwt_subject()
393

  
394
    device_dict = []
395
    devices = crud.get_body_devices(db, skip=skip, limit=limit)
396
    teams = crud.get_teams(db, skip=skip, limit=limit)
397
    for dev in devices:
398
        lic = crud.get_license(db, dev.license_id)
399
        device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: lic, &#34;log&#34;: dev.b_logs[len(dev.b_logs) - 1]})
400
    licenses = crud.get_licenses(db, skip=skip, limit=limit)
401
    if current_user == &#34;admin&#34;:
402
        return templates.TemplateResponse(&#34;body_devices.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
403
                                                                &#34;devs&#34;: devices, &#34;teams&#34;: teams, &#34;licenses&#34;: licenses,
404
                                                                &#34;user&#34;: current_user})
405
    else:
406
        current_user = &#34;guest&#34;
407
        return templates.TemplateResponse(&#34;body_devices_normal.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
408
                                                                &#34;devs&#34;: devices, &#34;teams&#34;: teams, &#34;licenses&#34;: licenses,
409
                                                                &#34;user&#34;: current_user})</code></pre>
410
</details>
411
</dd>
412
</dl>
413
</section>
414
<section>
415
</section>
416
</article>
417
<nav id="sidebar">
418
<h1>Index</h1>
419
<div class="toc">
420
<ul></ul>
421
</div>
422
<ul id="index">
423
<li><h3>Super-module</h3>
424
<ul>
425
<li><code><a title="sql_app.api" href="index.html">sql_app.api</a></code></li>
426
</ul>
427
</li>
428
<li><h3><a href="#header-functions">Functions</a></h3>
429
<ul class="two-column">
430
<li><code><a title="sql_app.api.bodydevices_web.connect_dev_lic" href="#sql_app.api.bodydevices_web.connect_dev_lic">connect_dev_lic</a></code></li>
431
<li><code><a title="sql_app.api.bodydevices_web.connect_post" href="#sql_app.api.bodydevices_web.connect_post">connect_post</a></code></li>
432
<li><code><a title="sql_app.api.bodydevices_web.delete_post" href="#sql_app.api.bodydevices_web.delete_post">delete_post</a></code></li>
433
<li><code><a title="sql_app.api.bodydevices_web.device_inv" href="#sql_app.api.bodydevices_web.device_inv">device_inv</a></code></li>
434
<li><code><a title="sql_app.api.bodydevices_web.filter_devices" href="#sql_app.api.bodydevices_web.filter_devices">filter_devices</a></code></li>
435
<li><code><a title="sql_app.api.bodydevices_web.get_db" href="#sql_app.api.bodydevices_web.get_db">get_db</a></code></li>
436
<li><code><a title="sql_app.api.bodydevices_web.read_devices" href="#sql_app.api.bodydevices_web.read_devices">read_devices</a></code></li>
437
</ul>
438
</li>
439
</ul>
440
</nav>
441
</main>
442
<footer id="footer">
443
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p>
444
</footer>
445
</body>
446
</html>
server/doc/sql_app/api/devices.html
49 49

  
50 50

  
51 51
@device.post(&#34;/device&#34;, response_model=schemas.Device)
52
def create_device(device: schemas.DeviceCreate, db: Session = Depends(get_db)):
52
def create_device(device: schemas.DeviceTemp, db: Session = Depends(get_db)):
53 53
    &#34;&#34;&#34;
54 54
    Endpoint used for creating new device
55 55
    &#34;&#34;&#34;
......
84 84
<h2 class="section-title" id="header-functions">Functions</h2>
85 85
<dl>
86 86
<dt id="sql_app.api.devices.create_device"><code class="name flex">
87
<span>def <span class="ident">create_device</span></span>(<span>device: <a title="sql_app.schemas.DeviceCreate" href="../schemas.html#sql_app.schemas.DeviceCreate">DeviceCreate</a>, db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
87
<span>def <span class="ident">create_device</span></span>(<span>device: <a title="sql_app.schemas.DeviceTemp" href="../schemas.html#sql_app.schemas.DeviceTemp">DeviceTemp</a>, db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
88 88
</code></dt>
89 89
<dd>
90 90
<div class="desc"><p>Endpoint used for creating new device</p></div>
......
93 93
<span>Expand source code</span>
94 94
</summary>
95 95
<pre><code class="python">@device.post(&#34;/device&#34;, response_model=schemas.Device)
96
def create_device(device: schemas.DeviceCreate, db: Session = Depends(get_db)):
96
def create_device(device: schemas.DeviceTemp, db: Session = Depends(get_db)):
97 97
    &#34;&#34;&#34;
98 98
    Endpoint used for creating new device
99 99
    &#34;&#34;&#34;
server/doc/sql_app/api/devices_web.html
26 26
<summary>
27 27
<span>Expand source code</span>
28 28
</summary>
29
<pre><code class="python">from typing import List
29
<pre><code class="python">from datetime import datetime
30 30

  
31
from fastapi import Depends, FastAPI, HTTPException, APIRouter, Form
31
from fastapi import Depends, APIRouter, Form
32
from fastapi import Request
33
from fastapi.responses import HTMLResponse, RedirectResponse
34
from fastapi.templating import Jinja2Templates
35
from fastapi_jwt_auth import AuthJWT
36
from pydantic import BaseModel
32 37
from sqlalchemy.orm import Session
38
from sql_app.api.auth import fake_users_db
33 39
from sql_app import crud, models, schemas
34
from datetime import datetime
35 40
from ..database import SessionLocal, engine
36
from fastapi import FastAPI, Request
37
from fastapi.responses import HTMLResponse
38
from fastapi.staticfiles import StaticFiles
39
from fastapi.templating import Jinja2Templates
40 41

  
41 42
models.Base.metadata.create_all(bind=engine)
42 43

  
......
44 45
templates = Jinja2Templates(directory=&#34;../templates/devices&#34;)
45 46

  
46 47
# prefix used for all endpoints in this file
47
device_web = APIRouter(prefix=&#34;/api/v1&#34;)
48
device_web = APIRouter(prefix=&#34;&#34;)
48 49

  
49 50

  
50 51
# Dependency
......
57 58

  
58 59

  
59 60
@device_web.get(&#34;/devices-web&#34;, response_class=HTMLResponse)
60
async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
61
async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
62
                       Authorize: AuthJWT = Depends()):
61 63
    &#34;&#34;&#34;
62
    Returns template with all devices and its current states
64
    Returns template with all devices and its necessary attributes
63 65
    &#34;&#34;&#34;
66
    Authorize.jwt_optional()
67
    current_user = Authorize.get_jwt_subject()
68

  
69
    device_dict = []
64 70
    devices = crud.get_devices(db, skip=skip, limit=limit)
65
    statuses = []
66
    # adding state for each device in list
67
    for i in range(0, len(devices)):
68
        statuses.append(devices[i].logs[len(devices[i].logs)-1].status)
71
    teams = crud.get_teams(db, skip=skip, limit=limit)
72
    # adding dictionary entry with all inforamtions needed in template
73
    for dev in devices:
74
        if len(dev.licenses) &gt; 0:
75
            for lic in dev.licenses:
76
                device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: lic.licenses, &#34;log&#34;: dev.logs[len(dev.logs) - 1]})
77
        else:
78
            device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: dev.licenses, &#34;log&#34;: dev.logs[len(dev.logs) - 1]})
69 79
    licenses = crud.get_licenses(db, skip=skip, limit=limit)
70
    return templates.TemplateResponse(&#34;devices.html&#34;, {&#34;request&#34;: request, &#34;devs&#34;: len(devices), &#34;devices&#34;: devices,
71
                                                       &#34;statuses&#34;: statuses, &#34;licenses&#34;: licenses})
80
    if current_user == &#34;admin&#34;:
81
        return templates.TemplateResponse(&#34;devices.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
82
                                                           &#34;licenses&#34;: licenses, &#34;devs&#34;: devices,
83
                                                           &#34;teams&#34;: teams, &#34;user&#34;: current_user})
84
    else:
85
        current_user = &#34;guest&#34;
86
        return templates.TemplateResponse(&#34;devices_normal.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
87
                                                                  &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})
72 88

  
73 89

  
74 90
@device_web.post(&#34;/devices-web&#34;, response_class=HTMLResponse)
75
async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic: str = Form(&#34;all&#34;),
76
                         db: Session = Depends(get_db)):
91
async def filter_devices(request: Request, skip: int = 0, limit: int = 100,
92
                         keyman_id: str = Form(&#34;all&#34;), lic_name: str = Form(&#34;all&#34;),
93
                         lic_id: str = Form(&#34;all&#34;), team: str = Form(&#34;all&#34;),
94
                         db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
77 95
    &#34;&#34;&#34;
78
    Endpoint used for filtering devices by license. returns html template with only
96
    Endpoint used for filtering devices by user given inputs. returns html template with only
79 97
    devices that has assigned license defined by user input
80 98
    &#34;&#34;&#34;
81
    devices = crud.get_devices(db, skip=skip, limit=limit)
82
    def_devices = []
99
    Authorize.jwt_optional()
100
    current_user = Authorize.get_jwt_subject()
101
    device_dict = []
102
    devices_f = crud.get_filtered_devices(db, keyman_id, lic_name, lic_id, team)
103
    ids = []
104
    for d in devices_f:
105
        ids.append(d[0])
106
    devices = crud.get_devices_with_ids(db, ids)
107
    teams = crud.get_teams(db, skip=skip, limit=limit)
108
    # adding dictionary entry with all inforamtions needed in template
83 109
    for dev in devices:
84
        for l in dev.licenses:
85
            if dev not in def_devices and l.licenses.name == lic:
86
                def_devices.append(dev)
87
    # if input was default all
88
    if lic == &#34;all&#34;:
89
        def_devices = devices
90
    statuses = []
91
    for i in range(0, len(def_devices)):
92
        statuses.append(def_devices[i].logs[len(def_devices[i].logs) - 1].status)
110
        if len(dev.licenses) &gt; 0:
111
            for lic in dev.licenses:
112
                device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: lic.licenses, &#34;log&#34;: dev.logs[len(dev.logs) - 1]})
113
        else:
114
            device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: dev.licenses, &#34;log&#34;: dev.logs[len(dev.logs) - 1]})
93 115
    licenses = crud.get_licenses(db, skip=skip, limit=limit)
94
    return templates.TemplateResponse(&#34;devices.html&#34;, {&#34;request&#34;: request, &#34;devs&#34;: len(def_devices), &#34;devices&#34;: def_devices,
95
                                                       &#34;statuses&#34;: statuses, &#34;licenses&#34;: licenses})
116
    if current_user == &#34;admin&#34;:
117
        return templates.TemplateResponse(&#34;devices.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
118
                                                           &#34;licenses&#34;: licenses, &#34;devs&#34;: devices,
119
                                                           &#34;teams&#34;: teams, &#34;user&#34;: current_user})
120
    else:
121
        current_user = &#34;guest&#34;
122
        return templates.TemplateResponse(&#34;devices_normal.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
123
                                                                  &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})
96 124

  
97 125

  
98 126
@device_web.get(&#34;/device-license/{device_id}&#34;, response_class=HTMLResponse)
99
async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db)):
127
async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db),
128
                          Authorize: AuthJWT = Depends()):
100 129
    &#34;&#34;&#34;
101
    Returns template with one device and all available licenses that can be assigned to it.
130
    Returns template with one device and all available licenses that can be assigned to it. Plus all teams that can
131
    be assigned to device, inventory number text input and comment text input
102 132
    &#34;&#34;&#34;
133
    Authorize.jwt_optional()
134
    current_user = Authorize.get_jwt_subject()
135
    if current_user != &#34;admin&#34;:
136
        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
103 137
    device = crud.get_device(db, device_id)
138
    dev_licenses = crud.get_device_licenses(db, device_id)
139
    lic_ids = []
140
    dev_lics = []
141
    for dev_lic in dev_licenses:
142
        dev_lics.append(dev_lic.licenses)
143
    for dev_lic in dev_licenses:
144
        lic_ids.append(dev_lic.licenses.license_id)
104 145
    licenses = crud.get_licenses(db, 0, 100)
146
    lic_left = []
147
    for lic in licenses:
148
        if lic.license_id not in lic_ids and lic not in lic_left:
149
            lic_left.append(lic)
150
    teams = crud.get_teams(db, 0, 100)
105 151
    return templates.TemplateResponse(&#34;devicelicense.html&#34;,
106
                                      {&#34;request&#34;: request, &#34;device&#34;: device, &#34;licenses&#34;: licenses})
152
                                      {&#34;request&#34;: request, &#34;device&#34;: device, &#34;licenses&#34;: lic_left, &#34;dev_lic&#34;: dev_lics,
153
                                       &#34;teams&#34;: teams})
107 154

  
108 155

  
109
@device_web.post(&#34;/devices-web/{device_id}&#34;, response_class=HTMLResponse)
110
async def connect_post(request: Request, device_id: int, lic: str = Form(...), skip: int = 0, limit: int = 100,
111
                       db: Session = Depends(get_db)):
156
@device_web.post(&#34;/devices-web/{device_id}&#34;)
157
async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db),
158
                       Authorize: AuthJWT = Depends()):
112 159
    &#34;&#34;&#34;
113
    Endpoint called from template for connecting device with license. Adds entry to devices_licenses
114
    table and returns template with all devices in database
160
    Endpoint called from devicelicense.html template. Adds entry to devices_licenses
161
    table and redirects to devices-web endpoint
115 162
    &#34;&#34;&#34;
163
    Authorize.jwt_optional()
164
    current_user = Authorize.get_jwt_subject()
165
    if current_user != &#34;admin&#34;:
166
        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
116 167
    crud.create_device_license(db, device_id, int(lic), datetime.now())
117
    devices = crud.get_devices(db, skip=skip, limit=limit)
118
    statuses = []
119
    # adding state for each device in list
120
    for i in range(0, len(devices)):
121
        statuses.append(devices[i].logs[len(devices[i].logs) - 1].status)
122
    licenses = crud.get_licenses(db, skip=skip, limit=limit)
123
    return templates.TemplateResponse(&#34;devices.html&#34;, {&#34;request&#34;: request, &#34;devs&#34;: len(devices), &#34;devices&#34;: devices,
124
                                                       &#34;statuses&#34;: statuses, &#34;licenses&#34;: licenses})</code></pre>
168
    return RedirectResponse(url=f&#34;/devices-web&#34;, status_code=303)
169

  
170

  
171
@device_web.post(&#34;/devices-web-del/{device_id}&#34;)
172
async def delete_post(device_id: int, lic_del: str = Form(...), db: Session = Depends(get_db),
173
                      Authorize: AuthJWT = Depends()):
174
    &#34;&#34;&#34;
175
    Endpoint called from devicelicense.html template for deleting device-license connection. Deletes entry in
176
    bodydevices_licenses table and redirects to devices-web endpoint
177
    &#34;&#34;&#34;
178
    Authorize.jwt_optional()
179
    current_user = Authorize.get_jwt_subject()
180
    if current_user != &#34;admin&#34;:
181
        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
182
    crud.delete_device_license(db, device_id, int(lic_del))
183
    return RedirectResponse(url=f&#34;/devices-web&#34;, status_code=303)
184

  
185

  
186
@device_web.post(&#34;/devices-web-team/{device_id}&#34;)
187
async def dev_team_con(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db),
188
                       Authorize: AuthJWT = Depends()):
189
    &#34;&#34;&#34;
190
    Endpoint called from devicelicense.html template, connects device with team and redirects to devices-web endpoint
191
    &#34;&#34;&#34;
192
    Authorize.jwt_optional()
193
    current_user = Authorize.get_jwt_subject()
194
    if current_user != &#34;admin&#34;:
195
        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
196
    crud.update_device(db, device_id, team_con)
197
    return RedirectResponse(url=f&#34;/devices-web&#34;, status_code=303)
198

  
199

  
200
@device_web.post(&#34;/devices-web-inv/{device_id}&#34;)
201
async def dev_inv_new(device_id: int, dev_inv: str = Form(...), db: Session = Depends(get_db),
202
                      Authorize: AuthJWT = Depends()):
203
    &#34;&#34;&#34;
204
    Endpoint called from template devicelicense.html, updates inventory number of device and redirects to devices-web
205
    endpoint
206
    &#34;&#34;&#34;
207
    Authorize.jwt_optional()
208
    current_user = Authorize.get_jwt_subject()
209
    if current_user != &#34;admin&#34;:
210
        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
211
    crud.update_device_inv(db, device_id, dev_inv)
212
    return RedirectResponse(url=f&#34;/devices-web&#34;, status_code=303)
213

  
214

  
215
@device_web.post(&#34;/devices-web-comment/{device_id}&#34;)
216
async def dev_comm_new(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db),
217
                       Authorize: AuthJWT = Depends()):
218
    &#34;&#34;&#34;
219
    Endpoint called from template devicelicense.html, updates comment of device and redirects to devices-web
220
    endpoint
221
    &#34;&#34;&#34;
222
    Authorize.jwt_optional()
223
    current_user = Authorize.get_jwt_subject()
224
    if current_user != &#34;admin&#34;:
225
        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
226
    crud.update_device_com(db, device_id, dev_com)
227
    return RedirectResponse(url=f&#34;/devices-web&#34;, status_code=303)</code></pre>
125 228
</details>
126 229
</section>
127 230
<section>
......
132 235
<h2 class="section-title" id="header-functions">Functions</h2>
133 236
<dl>
134 237
<dt id="sql_app.api.devices_web.connect_dev_lic"><code class="name flex">
135
<span>async def <span class="ident">connect_dev_lic</span></span>(<span>request: starlette.requests.Request, device_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
238
<span>async def <span class="ident">connect_dev_lic</span></span>(<span>request: starlette.requests.Request, device_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
136 239
</code></dt>
137 240
<dd>
138
<div class="desc"><p>Returns template with one device and all available licenses that can be assigned to it.</p></div>
241
<div class="desc"><p>Returns template with one device and all available licenses that can be assigned to it. Plus all teams that can
242
be assigned to device, inventory number text input and comment text input</p></div>
139 243
<details class="source">
140 244
<summary>
141 245
<span>Expand source code</span>
142 246
</summary>
143 247
<pre><code class="python">@device_web.get(&#34;/device-license/{device_id}&#34;, response_class=HTMLResponse)
144
async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db)):
248
async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db),
249
                          Authorize: AuthJWT = Depends()):
145 250
    &#34;&#34;&#34;
146
    Returns template with one device and all available licenses that can be assigned to it.
251
    Returns template with one device and all available licenses that can be assigned to it. Plus all teams that can
252
    be assigned to device, inventory number text input and comment text input
147 253
    &#34;&#34;&#34;
254
    Authorize.jwt_optional()
255
    current_user = Authorize.get_jwt_subject()
256
    if current_user != &#34;admin&#34;:
257
        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
148 258
    device = crud.get_device(db, device_id)
259
    dev_licenses = crud.get_device_licenses(db, device_id)
260
    lic_ids = []
261
    dev_lics = []
262
    for dev_lic in dev_licenses:
263
        dev_lics.append(dev_lic.licenses)
264
    for dev_lic in dev_licenses:
265
        lic_ids.append(dev_lic.licenses.license_id)
149 266
    licenses = crud.get_licenses(db, 0, 100)
267
    lic_left = []
268
    for lic in licenses:
269
        if lic.license_id not in lic_ids and lic not in lic_left:
270
            lic_left.append(lic)
271
    teams = crud.get_teams(db, 0, 100)
150 272
    return templates.TemplateResponse(&#34;devicelicense.html&#34;,
151
                                      {&#34;request&#34;: request, &#34;device&#34;: device, &#34;licenses&#34;: licenses})</code></pre>
273
                                      {&#34;request&#34;: request, &#34;device&#34;: device, &#34;licenses&#34;: lic_left, &#34;dev_lic&#34;: dev_lics,
274
                                       &#34;teams&#34;: teams})</code></pre>
152 275
</details>
153 276
</dd>
154 277
<dt id="sql_app.api.devices_web.connect_post"><code class="name flex">
155
<span>async def <span class="ident">connect_post</span></span>(<span>request: starlette.requests.Request, device_id: int, lic: str = Form(Ellipsis), skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
278
<span>async def <span class="ident">connect_post</span></span>(<span>device_id: int, lic: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
156 279
</code></dt>
157 280
<dd>
158
<div class="desc"><p>Endpoint called from template for connecting device with license. Adds entry to devices_licenses
159
table and returns template with all devices in database</p></div>
281
<div class="desc"><p>Endpoint called from devicelicense.html template. Adds entry to devices_licenses
282
table and redirects to devices-web endpoint</p></div>
160 283
<details class="source">
161 284
<summary>
162 285
<span>Expand source code</span>
163 286
</summary>
164
<pre><code class="python">@device_web.post(&#34;/devices-web/{device_id}&#34;, response_class=HTMLResponse)
165
async def connect_post(request: Request, device_id: int, lic: str = Form(...), skip: int = 0, limit: int = 100,
166
                       db: Session = Depends(get_db)):
287
<pre><code class="python">@device_web.post(&#34;/devices-web/{device_id}&#34;)
288
async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db),
289
                       Authorize: AuthJWT = Depends()):
167 290
    &#34;&#34;&#34;
168
    Endpoint called from template for connecting device with license. Adds entry to devices_licenses
169
    table and returns template with all devices in database
291
    Endpoint called from devicelicense.html template. Adds entry to devices_licenses
292
    table and redirects to devices-web endpoint
170 293
    &#34;&#34;&#34;
294
    Authorize.jwt_optional()
295
    current_user = Authorize.get_jwt_subject()
296
    if current_user != &#34;admin&#34;:
297
        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
171 298
    crud.create_device_license(db, device_id, int(lic), datetime.now())
172
    devices = crud.get_devices(db, skip=skip, limit=limit)
173
    statuses = []
174
    # adding state for each device in list
175
    for i in range(0, len(devices)):
176
        statuses.append(devices[i].logs[len(devices[i].logs) - 1].status)
177
    licenses = crud.get_licenses(db, skip=skip, limit=limit)
178
    return templates.TemplateResponse(&#34;devices.html&#34;, {&#34;request&#34;: request, &#34;devs&#34;: len(devices), &#34;devices&#34;: devices,
179
                                                       &#34;statuses&#34;: statuses, &#34;licenses&#34;: licenses})</code></pre>
299
    return RedirectResponse(url=f&#34;/devices-web&#34;, status_code=303)</code></pre>
300
</details>
301
</dd>
302
<dt id="sql_app.api.devices_web.delete_post"><code class="name flex">
303
<span>async def <span class="ident">delete_post</span></span>(<span>device_id: int, lic_del: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
304
</code></dt>
305
<dd>
306
<div class="desc"><p>Endpoint called from devicelicense.html template for deleting device-license connection. Deletes entry in
307
bodydevices_licenses table and redirects to devices-web endpoint</p></div>
308
<details class="source">
309
<summary>
310
<span>Expand source code</span>
311
</summary>
312
<pre><code class="python">@device_web.post(&#34;/devices-web-del/{device_id}&#34;)
313
async def delete_post(device_id: int, lic_del: str = Form(...), db: Session = Depends(get_db),
314
                      Authorize: AuthJWT = Depends()):
315
    &#34;&#34;&#34;
316
    Endpoint called from devicelicense.html template for deleting device-license connection. Deletes entry in
317
    bodydevices_licenses table and redirects to devices-web endpoint
318
    &#34;&#34;&#34;
319
    Authorize.jwt_optional()
320
    current_user = Authorize.get_jwt_subject()
321
    if current_user != &#34;admin&#34;:
322
        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
323
    crud.delete_device_license(db, device_id, int(lic_del))
324
    return RedirectResponse(url=f&#34;/devices-web&#34;, status_code=303)</code></pre>
325
</details>
326
</dd>
327
<dt id="sql_app.api.devices_web.dev_comm_new"><code class="name flex">
328
<span>async def <span class="ident">dev_comm_new</span></span>(<span>device_id: int, dev_com: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
329
</code></dt>
330
<dd>
... Rozdílový soubor je zkrácen, protože jeho délka přesahuje max. limit.

Také k dispozici: Unified diff