-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.py
150 lines (130 loc) · 4.47 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
from typing import Optional
from fastapi import FastAPI, Form, Request, Cookie
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from deta import Deta
from datetime import datetime
from utils.url_inspector import validate_url
from utils.archive import archive
from starlette.responses import RedirectResponse
from starlette import status
from utils.user import hash_pw, auth_user, validate_token
# secrets file:
from config import deta_private_key
app = FastAPI(
title="SaveMyPage API",
description="An API so save and archive pages for later access",
)
templates = Jinja2Templates(directory="templates")
deta = Deta(deta_private_key)
# creates databases
db = deta.Base("saved_urls")
db_users = deta.Base("users_db")
# read with cookies
@app.get("/", response_class=HTMLResponse)
async def user_get_all_url(request: Request, token: Optional[str] = Cookie(None)):
if token is None:
return templates.TemplateResponse("login.html", {"request": request})
else:
try:
username = validate_token(token, db_users)
# fetches all records from db
all_user_urls = db.fetch({"username": username})
return templates.TemplateResponse(
"index.html", {"request": request, "items": all_user_urls.items}
)
except Exception:
# login unsucessful, token expired
return templates.TemplateResponse("login.html", {"request": request})
# authenticates user log in
@app.post("/auth", response_class=HTMLResponse)
async def auth(username: str = Form(), password: str = Form()):
response = RedirectResponse("/", status_code=status.HTTP_302_FOUND)
# get db_user record
user_in_db = db_users.get(username)
# auth
authenticated, user_token = auth_user(username, password, user_in_db)
if authenticated is True:
response.set_cookie(key="token", value=user_token)
return response
@app.get("/logout", response_class=HTMLResponse)
async def logout(token: Optional[str] = Cookie(None)):
response = RedirectResponse("/")
# valiate token
try:
validate_token(token, db_users)
# removes token cookie
response.set_cookie(key="token", value="")
except Exception as ex:
print(ex)
return response
# user signup
@app.post("/createUser", response_class=HTMLResponse)
async def createuser(username: str = Form(), password: str = Form()):
response = RedirectResponse("/", status_code=status.HTTP_302_FOUND)
if len(username) < 6 or len(password) < 8:
return response
# insert to the database
password_hash = hash_pw(password)
try:
db_users.insert(
{
"key": username,
"password_hash": password_hash,
"create_timestamp": datetime.now().timestamp(),
}
)
except Exception:
# user already exists
return response
# auth and redirect
user_in_db = db_users.get(username)
# auth
authenticated, user_token = auth_user(username, password, user_in_db)
if authenticated is True:
response.set_cookie(key="token", value=user_token)
return response
# deletes record
@app.get("/deleteUI/{key}", response_class=HTMLResponse)
async def deleteUI(request: Request, key: str, token: Optional[str] = Cookie(None)):
# fetches all records from db
try:
validate_token(token, db_users)
db.delete(key)
except Exception as ex:
print(ex)
return RedirectResponse("/")
# creates new record
@app.post("/saveUI", response_class=HTMLResponse)
async def saveUI(
request: Request,
title: str = Form(),
url: str = Form(),
token: Optional[str] = Cookie(None),
):
# check token:
response = RedirectResponse("/", status_code=status.HTTP_302_FOUND)
try:
username = validate_token(token, db_users)
# validate url
if validate_url(url) is False:
return response
# insert to the database
db.insert(
{
"title": title,
"url": url,
"timestamp": datetime.now().timestamp(),
"username": username,
}
)
except Exception as ex:
print(ex)
return response
# archive url
@app.get("/archiveUI/{url:path}", response_class=HTMLResponse)
async def archiveUI(request: Request, url: str):
# insert to the database
# not working due to timeout
archive(url, db)
return RedirectResponse("/")