133 lines
3.6 KiB
Python
133 lines
3.6 KiB
Python
from argon2.exceptions import VerifyMismatchError
|
|
from basgi import HttpError, FileResponse, Request, Response, TemplateResponse, router
|
|
from blib import HttpDate
|
|
from datetime import timedelta
|
|
|
|
from ..misc import get_resource
|
|
|
|
|
|
@router.get("BarksharkSocial", "/")
|
|
async def handle_home(request: Request) -> Response:
|
|
if request.state.user is not None:
|
|
print(request.state.user.handle)
|
|
|
|
else:
|
|
print("no user")
|
|
|
|
return TemplateResponse("page/home.haml")
|
|
|
|
|
|
@router.get("BarksharkSocial", "/about")
|
|
async def handle_about(request: Request) -> Response:
|
|
return TemplateResponse("page/about.haml")
|
|
|
|
|
|
@router.get("BarksharkSocial", "/login")
|
|
async def handle_login_get(request: Request) -> Response:
|
|
if request.state.user is not None:
|
|
host = request.headers.get("Host", request.app.state.config.host)
|
|
return Response.new_redirect(f"https://{host}/", 303)
|
|
|
|
return TemplateResponse("page/login.haml")
|
|
|
|
|
|
@router.post("BarksharkSocial", "/login")
|
|
async def handle_login_post(request: Request) -> Response:
|
|
state = request.app.state
|
|
form = await request.form()
|
|
username, password = form.get("username"), form.get("password")
|
|
|
|
if username in [state.config.host, state.config.web_host, *state.config.alt_hosts, "relay"]:
|
|
raise HttpError(400, "User does not exist")
|
|
|
|
if username is None or password is None:
|
|
raise HttpError(400, "Missing username and/or password")
|
|
|
|
if not isinstance(username, str) or not isinstance(password, str):
|
|
raise HttpError(400, "Invalid field type")
|
|
|
|
with state.database.session(False) as s:
|
|
if (user := s.get_user(username.lower())) is None:
|
|
raise HttpError(400, "User does not exist")
|
|
|
|
try:
|
|
s.hasher.verify(user.password, password)
|
|
|
|
except VerifyMismatchError:
|
|
raise HttpError(400, "Password does not match")
|
|
|
|
cookie = s.put_cookie(user, request.headers.get("User-Agent"))
|
|
|
|
host = request.headers.get("Host", state.config.host)
|
|
|
|
response = Response.new_redirect(f"https://{host}/", 303)
|
|
response.set_cookie(
|
|
key = state.config.cookie_name,
|
|
value = cookie.code,
|
|
same_site = "strict",
|
|
expires = HttpDate.new_utc() + timedelta(days = 30),
|
|
path = "/",
|
|
domain = host,
|
|
secure = True
|
|
)
|
|
|
|
return response
|
|
|
|
|
|
@router.get("BarksharkSocial", "/logout")
|
|
async def handle_logout_get(request: Request) -> Response:
|
|
cname = request.app.state.config.cookie_name
|
|
response = Response.new_redirect("/")
|
|
|
|
try:
|
|
cookie = request.cookies[cname]
|
|
|
|
with request.app.state.database.session(True) as s:
|
|
s.del_cookie(cookie.value)
|
|
|
|
response.delete_cookie(cookie)
|
|
|
|
except KeyError:
|
|
pass
|
|
|
|
return response
|
|
|
|
|
|
@router.get("BarksharkSocial", "/register")
|
|
async def handle_register_get(request: Request) -> Response:
|
|
return TemplateResponse("page/login.haml")
|
|
|
|
|
|
@router.get("BarksharkSocial", "/@{username}", "/@{username}@{domain}")
|
|
async def handle_user_page(request: Request) -> Response:
|
|
with request.app.state.database.session(False) as s:
|
|
user = s.get_user(
|
|
request.params["username"],
|
|
request.params.get("domain", request.app.state.config.host)
|
|
)
|
|
|
|
if user is None or user.id < 1:
|
|
raise HttpError(404, "User not found")
|
|
|
|
context = {
|
|
"user": user,
|
|
"count": {
|
|
"following": s.get_following_count(user),
|
|
"followers": s.get_follower_count(user),
|
|
"posts": s.get_post_count(user)
|
|
}
|
|
}
|
|
|
|
return TemplateResponse("page/user.haml", context)
|
|
|
|
|
|
@router.get("BarksharkSocial", "/style/{filename}.css")
|
|
async def handle_style(request: Request) -> Response:
|
|
filename = request.params["filename"]
|
|
return TemplateResponse(f"style/{filename}.scss", mimetype = "text/css")
|
|
|
|
|
|
@router.get("BarksharkSocial", "/favicon.ico")
|
|
async def handle_favicon(request: Request) -> Response:
|
|
return FileResponse(get_resource("frontend/static/images/icon.svg"))
|