fart
This commit is contained in:
parent
f7d22cf36c
commit
ad0fdeba35
74
main
74
main
|
@ -10,6 +10,8 @@ from itertools import groupby
|
|||
from werkzeug.utils import secure_filename
|
||||
from werkzeug.security import generate_password_hash, check_password_hash
|
||||
from flask import Flask, render_template, request, url_for, flash, redirect, session, make_response, send_from_directory, stream_with_context, Response, request
|
||||
from flask_limiter import Limiter
|
||||
from flask_limiter.util import get_remote_address
|
||||
|
||||
# read config file
|
||||
config = configparser.ConfigParser()
|
||||
|
@ -26,6 +28,14 @@ app = Flask(__name__)
|
|||
app.config["SECRET_KEY"] = SECRET_KEY
|
||||
app.config["MAX_CONTENT_LENGTH"] = int(UPLOAD_LIMIT) * 1000 * 1000
|
||||
|
||||
limiter = Limiter(
|
||||
get_remote_address,
|
||||
app = app,
|
||||
default_limits = ["3 per second"],
|
||||
storage_uri = "memory://",
|
||||
strategy = "fixed-window"
|
||||
)
|
||||
|
||||
if SECRET_KEY == "placeholder":
|
||||
print("[WARNING] Secret key is not set")
|
||||
|
||||
|
@ -85,8 +95,8 @@ app.jinja_env.globals.update(getUser=get_user)
|
|||
|
||||
def check_username_taken(username):
|
||||
conn = get_db_connection()
|
||||
post = conn.execute("SELECT * FROM users WHERE username = ?",
|
||||
(username,)).fetchone()
|
||||
post = conn.execute("SELECT * FROM users WHERE lower(username) = ?",
|
||||
(username.lower(),)).fetchone()
|
||||
conn.close()
|
||||
if post is None:
|
||||
return "error"
|
||||
|
@ -125,6 +135,53 @@ def main():
|
|||
else:
|
||||
return render_template("main.html", posts=posts)
|
||||
|
||||
@app.route("/@<pageusername>", methods=("GET", "POST"))
|
||||
def user(pageusername):
|
||||
usersession = request.cookies.get("session_DO_NOT_SHARE")
|
||||
|
||||
checkusername = check_username_taken(pageusername)
|
||||
|
||||
if not checkusername == "error":
|
||||
pageuser = get_user(checkusername)
|
||||
if usersession:
|
||||
userCookie = get_session(usersession)
|
||||
user = get_user(userCookie["id"])
|
||||
return render_template("user.html", userdata=user, createddate=datetime.datetime.utcfromtimestamp(int(str(pageuser["created"]).split(".")[0])).strftime("%Y-%m-%d"), pageuser=pageuser)
|
||||
else:
|
||||
return render_template("user.html", createddate=datetime.datetime.utcfromtimestamp(int(str(pageuser["created"]).split(".")[0])).strftime("%Y-%m-%d"), pageuser=pageuser)
|
||||
else:
|
||||
return """<img src="https://http.cat/images/404.jpg">""", 404
|
||||
|
||||
@app.route("/@<pageusername>/edit", methods=("GET", "POST"))
|
||||
def edituser(pageusername):
|
||||
usersession = request.cookies.get("session_DO_NOT_SHARE")
|
||||
|
||||
checkusername = check_username_taken(pageusername)
|
||||
|
||||
if not checkusername == "error":
|
||||
pageuser = get_user(checkusername)
|
||||
if usersession:
|
||||
userCookie = get_session(usersession)
|
||||
user = get_user(userCookie["id"])
|
||||
if pageuser["username"] == user["username"]:
|
||||
if request.method == "POST":
|
||||
code = request.form["code"].replace("Content-Security-Policy", "")
|
||||
conn = get_db_connection()
|
||||
conn.execute("UPDATE users SET htmldescription = ? WHERE id = ?",
|
||||
(code, user["id"]))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return redirect("/@" + user["username"])
|
||||
else:
|
||||
return render_template("edituser.html", userdata=user, pageuser=pageuser)
|
||||
else:
|
||||
return """<img src="https://http.cat/images/403.jpg">""", 403
|
||||
else:
|
||||
return """<img src="https://http.cat/images/403.jpg">""", 403
|
||||
else:
|
||||
return """<img src="https://http.cat/images/404.jpg">""", 404
|
||||
|
||||
|
||||
@app.route("/api/frontpage", methods=("GET", "POST"))
|
||||
def apifrontpage():
|
||||
conn = get_db_connection()
|
||||
|
@ -332,6 +389,7 @@ def post():
|
|||
|
||||
|
||||
@app.route("/api/comment", methods=("GET", "POST"))
|
||||
@limiter.limit("1/second", override_defaults=False)
|
||||
def comment():
|
||||
usersession = request.cookies.get("session_DO_NOT_SHARE")
|
||||
if usersession:
|
||||
|
@ -377,12 +435,13 @@ def cdn(filename):
|
|||
|
||||
|
||||
@app.route("/signup", methods=("GET", "POST"))
|
||||
@limiter.limit("5/minute", override_defaults=False)
|
||||
def signup():
|
||||
usersession = request.cookies.get("session_DO_NOT_SHARE")
|
||||
if usersession:
|
||||
return redirect(url_for("main"))
|
||||
if request.method == "POST":
|
||||
if not check_username_taken(str(request.form["username"]).lower()) == "error":
|
||||
if not check_username_taken(request.form["username"]) == "error":
|
||||
flash("Username already taken :3")
|
||||
return redirect(url_for("signup"))
|
||||
|
||||
|
@ -397,8 +456,8 @@ def signup():
|
|||
hashedpassword = generate_password_hash(request.form["password"])
|
||||
|
||||
conn = get_db_connection()
|
||||
conn.execute("INSERT INTO users (username, password, created) VALUES (?, ?, ?)",
|
||||
(request.form["username"], hashedpassword, str(time.time())))
|
||||
conn.execute("INSERT INTO users (username, password, created, htmldescription) VALUES (?, ?, ?, ?)",
|
||||
(request.form["username"], hashedpassword, str(time.time()), ""))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
@ -408,6 +467,7 @@ def signup():
|
|||
|
||||
|
||||
@app.route("/login", methods=("GET", "POST"))
|
||||
@limiter.limit("10/minute", override_defaults=False)
|
||||
def login():
|
||||
usersession = request.cookies.get("session_DO_NOT_SHARE")
|
||||
if usersession:
|
||||
|
@ -508,6 +568,10 @@ def page_not_found(e):
|
|||
def page_not_found(e):
|
||||
return """<img src="https://http.cat/images/400.jpg">""", 400
|
||||
|
||||
@app.errorhandler(429)
|
||||
def page_not_found(e):
|
||||
return """<img src="https://http.cat/images/429.jpg">""", 429
|
||||
|
||||
@app.errorhandler(404)
|
||||
def page_not_found(e):
|
||||
return """<img src="https://http.cat/images/404.jpg">""", 404
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
flask
|
||||
Flask-Limiter
|
||||
werkzeug
|
||||
waitress
|
|
@ -9,7 +9,8 @@ CREATE TABLE users (
|
|||
username TEXT NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
banned TEXT NOT NULL DEFAULT 0,
|
||||
administrator INTEGER NOT NULL DEFAULT 0
|
||||
administrator INTEGER NOT NULL DEFAULT 0,
|
||||
htmldescription TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE posts (
|
||||
|
|
|
@ -25,7 +25,32 @@ body {
|
|||
.postDiv {
|
||||
padding-top: 120px;
|
||||
}
|
||||
|
||||
.profileDiv {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
.profileIFrame {
|
||||
border: solid;
|
||||
border-width: 0;
|
||||
border-top-width: 1px;
|
||||
border-color: rgb(241, 241, 241);
|
||||
width: 100%;
|
||||
height: calc(100vh - 295px);
|
||||
}
|
||||
.profileDiv .badgeDiv p {
|
||||
background-color: black;
|
||||
border-radius: 99px;
|
||||
color: white;
|
||||
padding: 5px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
display: inline;
|
||||
}
|
||||
.editThing .htmlBox {
|
||||
width: calc(100% - 10px);
|
||||
height: 300px;
|
||||
text-align: top;
|
||||
}
|
||||
.accountform {
|
||||
margin-left: 20%;
|
||||
margin-right: 20%;
|
||||
|
@ -85,6 +110,7 @@ body {
|
|||
.post img {
|
||||
min-height: 200px;
|
||||
max-height: 300px;
|
||||
max-width: 100%;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
|
@ -131,6 +157,11 @@ body {
|
|||
color: rgb(175, 175, 175);
|
||||
}
|
||||
|
||||
.usernamelink {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>burgercat</title>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="navbar">
|
||||
<h1>burgercat</h1>
|
||||
<a class="selected" href="/">home</a>
|
||||
<a href="/post">post</a>
|
||||
{% if userdata %}
|
||||
<a href="/settings/logout" class="right r">log out</a>
|
||||
<a href="/settings" class="right">{{ userdata.username }}</a>
|
||||
{% else %}
|
||||
<a href="/signup" class="right r">sign up</a>
|
||||
<a href="/login" class="right">log in</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="postDiv">
|
||||
<div class="profileDiv">
|
||||
{% if userdata %}
|
||||
{% if pageuser.id == userdata.id %}
|
||||
<h2>edit mode</h2>
|
||||
<form class="editThing" method="post" enctype="multipart/form-data">
|
||||
<textarea class="htmlBox" name="code" type="text" placeholder="<p>Hello World!</p>">{{ userdata.htmldescription }}</textarea>
|
||||
<br><br>
|
||||
<input class="submit" type="submit" value="save">
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -31,7 +31,7 @@
|
|||
<div class="postDiv">
|
||||
{% for post in posts %}
|
||||
<div class="post" id="post">
|
||||
<p class="username">{{ getUser(post["creator"])["username"] }}</p>
|
||||
<p><a href='/@{{ getUser(post["creator"])["username"] }}' class="username usernamelink">{{ getUser(post["creator"])["username"] }}</a></p>
|
||||
<p class="date" id='timestamp_{{post["id"]}}'> </p>
|
||||
{% if userdata %}
|
||||
{% if userdata.administrator == 1 %}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
{% endif %}
|
||||
Logged in as {{ userdata.username }}
|
||||
<br><br>
|
||||
<a href="/@{{ userdata.username }}">View my public profile</a><br>
|
||||
<a href="/settings/logout">Log out</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>burgercat</title>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/style.css" />
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self' fonts.gstatic.com fonts.googleapis.com" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="navbar">
|
||||
<h1>burgercat</h1>
|
||||
<a class="selected" href="/">home</a>
|
||||
<a href="/post">post</a>
|
||||
{% if userdata %}
|
||||
<a href="/settings/logout" class="right r">log out</a>
|
||||
<a href="/settings" class="right">{{ userdata.username }}</a>
|
||||
{% else %}
|
||||
<a href="/signup" class="right r">sign up</a>
|
||||
<a href="/login" class="right">log in</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="postDiv">
|
||||
<div class="profileDiv">
|
||||
<h2>{{ pageuser.username }}</h2>
|
||||
<div class="badgeDiv">
|
||||
{% if pageuser.administrator == 1 %}
|
||||
<p>Administrator</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<p>Joined on {{ createddate }}</p>
|
||||
{% if userdata %}
|
||||
{% if pageuser.id == userdata.id %}
|
||||
<a style="color: rgb(104, 104, 104); text-decoration: none;" href="/@{{ userdata.username }}/edit">edit page</a>
|
||||
<br><br>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<iframe class="profileIFrame" sandbox="" srcdoc="{{ pageuser.htmldescription }}"></iframe>
|
||||
</div>
|
||||
<style>
|
||||
body {
|
||||
overflow-y: hidden
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
|
||||
</html>
|
Reference in New Issue