Skip to content

Commit ef181b4

Browse files
Migrate to flatfile and get login,logout and basic dashboard functional
Co-authored-by: Audrey Roy Greenfeld <[email protected]>
1 parent c94fcf9 commit ef181b4

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

examples/adv_app2.py

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
from fasthtml.common import *
2+
from fasthtml.jupyter import *
3+
from functools import partial
4+
from dataclasses import dataclass
5+
from hmac import compare_digest
6+
from monsterui.all import *
7+
8+
db = database(':memory:')
9+
10+
class User: name:str; pwd:str
11+
12+
class Todo:
13+
id:int; title:str; done:bool; name:str; details:str; priority:int
14+
15+
db.users = db.create(User, transform=True, pk='name')
16+
db.todos = db.create(Todo, transform=True)
17+
18+
19+
def user_auth_before(req, sess):
20+
auth = req.scope['auth'] = sess.get('auth', None)
21+
if not auth: return login_redir
22+
db.todos.xtra(name=auth)
23+
24+
beforeware = Beforeware(
25+
user_auth_before,
26+
skip=[r'/favicon\.ico', r'/static/.*', r'.*\.css', r'.*\.js', '/login']
27+
)
28+
29+
30+
app, rt = fast_app(hdrs=Theme.blue.headers(),before=beforeware)
31+
32+
login_redir = Redirect('/login')
33+
34+
35+
@rt
36+
def index(auth):
37+
top = Grid(Div(A('logout', href=logout), style='text-align: right'))
38+
new_inp = Input(id="new-title", name="title", placeholder="New Todo")
39+
add = Form(Group(new_inp, Button("Add")),
40+
hx_post="/", target_id='todo-list', hx_swap="afterbegin")
41+
frm = Form(*db.todos(order_by='priority'),
42+
id='todo-list', cls='sortable', hx_post="/reorder", hx_trigger="end")
43+
44+
card = Card(Ul(frm), header=add, footer=Div(id='current-todo'))
45+
return Titled(f"{auth}'s Todo list", Container(top, card))
46+
47+
48+
@rt('/login')
49+
def get():
50+
frm = Form(
51+
LabelInput("Name", name='name'),
52+
LabelInput("Password", name='pwd'),
53+
Button('login'),
54+
action='/login', method='post')
55+
return Titled("Login", frm, cls=ContainerT.sm)
56+
57+
@dataclass
58+
class Login: name:str; pwd:str
59+
60+
@rt("/login")
61+
def post(login:Login, sess):
62+
if not login.name or not login.pwd: return login_redir
63+
try: u = db.users[login.name]
64+
except NotFoundError: u = db.users.insert(login)
65+
if not compare_digest(u.pwd.encode("utf-8"), login.pwd.encode("utf-8")): return login_redir
66+
sess['auth'] = u.name
67+
return Redirect('/')
68+
69+
@app.get("/logout")
70+
def logout(sess):
71+
del sess['auth']
72+
return login_redir
73+
74+
serve()

0 commit comments

Comments
 (0)