diff --git a/.gitignore b/.gitignore index 209ca9214..901c3face 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,4 @@ venv/ .vscode/ .sass-cache/ flask_session/ -.DS_Store -disable_signups -fart_mode \ No newline at end of file +.DS_Store \ No newline at end of file diff --git a/env b/env index b8cbc544c..a9192d3cf 100644 --- a/env +++ b/env @@ -16,8 +16,6 @@ export SPAM_URL_SIMILARITY_THRESHOLD="0.1" export SPAM_SIMILAR_COUNT_THRESHOLD="10" export COMMENT_SPAM_SIMILAR_THRESHOLD="0.5" export COMMENT_SPAM_COUNT_THRESHOLD="10" -export READ_ONLY="0" -export BOT_DISABLE="0" export DEFAULT_TIME_FILTER="all" export GUMROAD_TOKEN="blahblahblah" export GUMROAD_LINK="https://marsey1.gumroad.com/l/tfcvri" diff --git a/files/__main__.py b/files/__main__.py index 6c4a81441..08d9553fa 100644 --- a/files/__main__.py +++ b/files/__main__.py @@ -15,11 +15,7 @@ import redis import time from sys import stdout, argv import faulthandler -from json import loads - -for f in (f'files/templates/sidebar_{environ.get("SITE_NAME").strip()}.html', 'disable_signups', 'fart_mode'): - if not path.exists(f): - with open(f, 'w', encoding="utf-8"): pass +import json app = Flask(__name__, template_folder='templates') app.url_map.strict_slashes = False @@ -51,8 +47,6 @@ app.config["SPAM_URL_SIMILARITY_THRESHOLD"] = float(environ.get("SPAM_URL_SIMILA app.config["SPAM_SIMILAR_COUNT_THRESHOLD"] = int(environ.get("SPAM_SIMILAR_COUNT_THRESHOLD", 10)) app.config["COMMENT_SPAM_SIMILAR_THRESHOLD"] = float(environ.get("COMMENT_SPAM_SIMILAR_THRESHOLD", 0.5)) app.config["COMMENT_SPAM_COUNT_THRESHOLD"] = int(environ.get("COMMENT_SPAM_COUNT_THRESHOLD", 10)) -app.config["READ_ONLY"]=bool(int(environ.get("READ_ONLY", "0"))) -app.config["BOT_DISABLE"]=bool(int(environ.get("BOT_DISABLE", False))) app.config["CACHE_TYPE"] = "RedisCache" app.config["CACHE_REDIS_URL"] = environ.get("REDIS_URL", "redis://localhost") app.config['MAIL_SERVER'] = 'smtp.gmail.com' @@ -61,6 +55,7 @@ app.config['MAIL_USE_TLS'] = True app.config['MAIL_USERNAME'] = environ.get("MAIL_USERNAME", "").strip() app.config['MAIL_PASSWORD'] = environ.get("MAIL_PASSWORD", "").strip() app.config['DESCRIPTION'] = environ.get("DESCRIPTION", "rdrama.net caters to drama in all forms such as: Real life, videos, photos, gossip, rumors, news sites, Reddit, and Beyond™. There isn't drama we won't touch, and we want it all!").strip() +app.config['SETTINGS'] = {} r=redis.Redis(host=environ.get("REDIS_URL", "redis://localhost"), decode_responses=True, ssl_cert_reqs=None) @@ -88,13 +83,14 @@ mail = Mail(app) @app.before_request def before_request(): + + with open('site_settings.json', 'r') as f: + app.config['SETTINGS'] = json.load(f) + if request.host != app.config["SERVER_NAME"]: return {"error":"Unauthorized host provided."}, 401 if request.headers.get("CF-Worker"): return {"error":"Cloudflare workers are not allowed to access this website."}, 401 - if request.method.lower() != "get" and app.config["READ_ONLY"]: - return {"error":f"{app.config['SITE_NAME']} is currently in read-only mode."}, 500 - - if app.config["BOT_DISABLE"] and request.headers.get("Authorization"): abort(503) + if not app.config['SETTINGS']['Bots'] and request.headers.get("Authorization"): abort(503) g.db = db_session() diff --git a/files/classes/mod_logs.py b/files/classes/mod_logs.py index e16e6cea6..26795daff 100644 --- a/files/classes/mod_logs.py +++ b/files/classes/mod_logs.py @@ -175,13 +175,23 @@ ACTIONTYPES = { "icon": 'fa-flag', "color": 'bg-danger' }, - 'disable_fart_mode': { + 'disable_Bots': { + "str": 'disabled Bots', + "icon": 'fa-robot', + "color": 'bg-danger' + }, + 'disable_Fart mode': { "str": 'disabled fart mode', "icon": 'fa-gas-pump-slash', "color": 'bg-danger' }, - 'disable_signups': { - "str": 'disabled signups', + 'disable_Readonly mode': { + "str": 'disabled readonly mode', + "icon": 'fa-book', + "color": 'bg-danger' + }, + 'disable_Signups': { + "str": 'disabled Signups', "icon": 'fa-users', "color": 'bg-danger' }, @@ -215,13 +225,23 @@ ACTIONTYPES = { "icon": 'fa-edit', "color": 'bg-primary' }, - 'enable_fart_mode': { + 'enable_Bots': { + "str": 'enabled Bots', + "icon": 'fa-robot', + "color": 'bg-success' + }, + 'enable_Fart mode': { "str": 'enabled fart mode', "icon": 'fa-gas-pump', "color": 'bg-success' }, - 'enable_signups': { - "str": 'enabled signups', + 'enable_Readonly mode': { + "str": 'enabled readonly mode', + "icon": 'fa-book', + "color": 'bg-success' + }, + 'enable_Signups': { + "str": 'enabled Signups', "icon": 'fa-users', "color": 'bg-success' }, diff --git a/files/helpers/wrappers.py b/files/helpers/wrappers.py index c5f7fbfaf..4a75c9546 100644 --- a/files/helpers/wrappers.py +++ b/files/helpers/wrappers.py @@ -7,30 +7,32 @@ from random import randint def get_logged_in_user(): if not (hasattr(g, 'db') and g.db): g.db = db_session() + v = None + token = request.headers.get("Authorization","").strip() if token: client = g.db.query(ClientAuth).filter(ClientAuth.access_token == token).one_or_none() - - if not client: return None - - v = client.user - v.client = client + if client: + v = client.user + v.client = client else: lo_user = session.get("lo_user") - if not lo_user: return None + if lo_user: + nonce = session.get("login_nonce", 0) + id = int(lo_user) + v = g.db.query(User).filter_by(id=id).one_or_none() + if v and nonce >= v.login_nonce: + if v.id != id: abort(400) + v.client = None - nonce = session.get("login_nonce", 0) - id = int(lo_user) - v = g.db.query(User).filter_by(id=id).one_or_none() - if not v or nonce < v.login_nonce: return None + if request.method != "GET": + submitted_key = request.values.get("formkey") + if not submitted_key: abort(401) + elif not v.validate_formkey(submitted_key): abort(401) - if v.id != id: abort(400) - v.client = None - if request.method != "GET": - submitted_key = request.values.get("formkey") - if not submitted_key: abort(401) - elif not v.validate_formkey(submitted_key): abort(401) + if request.method.lower() != "get" and app.config['SETTINGS']['Readonly mode'] and not (v and v.admin_level): + abort(403) return v diff --git a/files/routes/admin.py b/files/routes/admin.py index 27419a1e7..bdaaab5a8 100644 --- a/files/routes/admin.py +++ b/files/routes/admin.py @@ -521,66 +521,53 @@ def reported_comments(v): @app.get("/admin") @admin_level_required(2) def admin_home(v): - with open('disable_signups', 'r') as f: x = f.read() - if CF_ZONE == 'blahblahblah': response = 'high' else: response = requests.get(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/settings/security_level', headers=CF_HEADERS, timeout=5).json()['result']['value'] - - x2 = response == 'under_attack' + under_attack = response == 'under_attack' - with open('fart_mode', 'r') as f: x3 = f.read() + return render_template("admin/admin_home.html", v=v, under_attack=under_attack, site_settings=app.config['SETTINGS']) - return render_template("admin/admin_home.html", v=v, x=x, x2=x2, x3=x3) -@app.post("/admin/disable_signups") +@app.post("/admin/site_settings/") @admin_level_required(3) -def disable_signups(v): - with open('disable_signups', 'r') as f: content = f.read() +def change_settings(v, setting): + site_settings = app.config['SETTINGS'] + site_settings[setting] = not site_settings[setting] + with open("site_settings.json", "w") as f: + json.dump(site_settings, f) - with open('disable_signups', 'w') as f: - if content == "yes": - f.write("no") - ma = ModAction( - kind="enable_signups", - user_id=v.id, - ) - g.db.add(ma) - g.db.commit() - return {"message": "Signups enabled!"} - else: - f.write("yes") - ma = ModAction( - kind="disable_signups", - user_id=v.id, - ) - g.db.add(ma) - g.db.commit() - return {"message": "Signups disabled!"} + if site_settings[setting]: word = 'enable' + else: word = 'disable' -@app.post("/admin/fart_mode") -@admin_level_required(3) -def fart_mode(v): - with open('fart_mode', 'r') as f: content = f.read() + body = f"@{v.username} has {word}d `{setting}` in the [admin dashboard](/admin)!" - with open('fart_mode', 'w') as f: - if content == "yes": - f.write("no") - ma = ModAction( - kind="enable_fart_mode", - user_id=v.id, - ) - g.db.add(ma) - g.db.commit() - return {"message": "Fart mode disabled!"} - else: - f.write("yes") - ma = ModAction( - kind="disable_fart_mode", - user_id=v.id, - ) - g.db.add(ma) - g.db.commit() - return {"message": "Fart mode enabled!"} + body_html = sanitize(body, noimages=True) + + new_comment = Comment(author_id=NOTIFICATIONS_ID, + parent_submission=None, + level=1, + body_html=body_html, + sentto=2, + distinguish_level=6 + ) + g.db.add(new_comment) + g.db.flush() + + new_comment.top_comment_id = new_comment.id + + for admin in g.db.query(User).filter(User.admin_level > 2, User.id != v.id).all(): + notif = Notification(comment_id=new_comment.id, user_id=admin.id) + g.db.add(notif) + + ma = ModAction( + kind=f"{word}_{setting}", + user_id=v.id, + ) + g.db.add(ma) + + g.db.commit() + + return {'message': f"{setting} {word}d successfully!"} @app.post("/admin/purge_cache") diff --git a/files/routes/login.py b/files/routes/login.py index d0385ed95..0b308ef01 100644 --- a/files/routes/login.py +++ b/files/routes/login.py @@ -179,9 +179,8 @@ def logout(v): @app.get("/signup") @auth_desired def sign_up_get(v): - with open('disable_signups', 'r') as f: - if f.read() == "yes": - return {"error": "New account registration is currently closed. Please come back later."}, 403 + if not app.config['SETTINGS']['Signups']: + return {"error": "New account registration is currently closed. Please come back later."}, 403 if v: return redirect(SITE_FULL) @@ -226,9 +225,8 @@ def sign_up_get(v): @limiter.limit("10/day") @auth_desired def sign_up_post(v): - with open('disable_signups', 'r') as f: - if f.read() == "yes": - return {"error": "New account registration is currently closed. Please come back later."}, 403 + if not app.config['SETTINGS']['Signups']: + return {"error": "New account registration is currently closed. Please come back later."}, 403 if v: abort(403) diff --git a/files/routes/oauth.py b/files/routes/oauth.py index 5c7d2893f..51c44cc3f 100644 --- a/files/routes/oauth.py +++ b/files/routes/oauth.py @@ -52,7 +52,7 @@ def request_api_keys(v): g.db.add(new_app) - body = f"{v.username} has requested API keys for `{request.values.get('name')}`. You can approve or deny the request [here](/admin/apps)." + body = f"@{v.username} has requested API keys for `{request.values.get('name')}`. You can approve or deny the request [here](/admin/apps)." body_html = sanitize(body, noimages=True) diff --git a/files/routes/posts.py b/files/routes/posts.py index 1f0a20b7d..7c8806d2a 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -253,13 +253,9 @@ def post_id(pid, anything=None, v=None, sub=None): g.db.commit() if request.headers.get("Authorization"): return post.json else: - with open('fart_mode', 'r') as f: - if f.read() == "yes": fart = True - else: fart = False - if post.is_banned and not (v and (v.admin_level > 1 or post.author_id == v.id)): template = "submission_banned.html" else: template = "submission.html" - return render_template(template, v=v, p=post, ids=list(ids), sort=sort, render_replies=True, offset=offset, sub=post.subr, fart=fart) + return render_template(template, v=v, p=post, ids=list(ids), sort=sort, render_replies=True, offset=offset, sub=post.subr, fart=app.config['SETTINGS']['Fart mode']) @app.get("/viewmore///") @limiter.limit("1/second;30/minute;200/hour;1000/day") diff --git a/files/templates/admin/admin_home.html b/files/templates/admin/admin_home.html index 98c300e5f..e2a6eb89c 100644 --- a/files/templates/admin/admin_home.html +++ b/files/templates/admin/admin_home.html @@ -58,21 +58,32 @@ {% endif %} {% if v.admin_level > 2 %} +
- - + +
- + + +
+ +
+ + +
+ +
+ + +
+ +
+
-
- - -
- {% endif %} diff --git a/site_settings.json b/site_settings.json new file mode 100644 index 000000000..de9580f7a --- /dev/null +++ b/site_settings.json @@ -0,0 +1 @@ +{"Bots": true, "Fart mode": false, "Readonly mode": false, "Signups": true} \ No newline at end of file