diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..f1e5b454c3 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @Aevann1 \ No newline at end of file diff --git a/files/__main__.py b/files/__main__.py index effabd220b..e58ed42846 100644 --- a/files/__main__.py +++ b/files/__main__.py @@ -6,20 +6,18 @@ from flask import * from flask_caching import Cache from flask_limiter import Limiter from flask_compress import Compress -from flask_limiter.util import get_ipaddr from flask_mail import Mail from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker, scoped_session from sqlalchemy import * import gevent -from werkzeug.middleware.proxy_fix import ProxyFix import redis import time from sys import stdout import faulthandler +from json import loads app = Flask(__name__, template_folder='templates') -app.wsgi_app = ProxyFix(app.wsgi_app, x_for=3) app.url_map.strict_slashes = False app.jinja_env.cache = {} app.jinja_env.auto_reload = True @@ -63,9 +61,13 @@ app.config['DESCRIPTION'] = environ.get("DESCRIPTION", "rdrama.net caters to dra r=redis.Redis(host=environ.get("REDIS_URL", "redis://localhost"), decode_responses=True, ssl_cert_reqs=None) +def get_CF() -> str: + with app.app_context(): + return request.headers.get('CF-Connecting-IP') + limiter = Limiter( app, - key_func=get_ipaddr, + key_func=get_CF, default_limits=["3/second;30/minute;200/hour;1000/day"], application_limits=["10/second;200/minute;5000/hour;10000/day"], storage_uri=environ.get("REDIS_URL", "redis://localhost") @@ -83,7 +85,6 @@ mail = Mail(app) @app.before_request def before_request(): - if request.method.lower() != "get" and app.config["READ_ONLY"]: return {"error":f"{app.config['SITE_NAME']} is currently in read-only mode."}, 500 @@ -104,9 +105,10 @@ def teardown_request(error): @app.after_request def after_request(response): - response.headers.add("Strict-Transport-Security", "max-age=31536000") response.headers.add("X-Frame-Options", "deny") return response +with open("marsey_count.json", 'r') as f: cache.set("marsey_count", loads(f.read())) + from files.routes import * \ No newline at end of file diff --git a/files/classes/user.py b/files/classes/user.py index eeba5aa7f5..f7fd02ef65 100644 --- a/files/classes/user.py +++ b/files/classes/user.py @@ -315,7 +315,7 @@ class User(Base): return f"/@{self.username}" def __repr__(self): - return f"" + return f"" @property @lazy diff --git a/files/helpers/const.py b/files/helpers/const.py index 4f7a01c45f..fccfb47a6c 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -477,6 +477,10 @@ BADGES = { 'name': 'Benefactor', 'description': 'Gave the Benefactor award to someone' }, + 104: { + 'name': 'BADASS OUTLAW', + 'description': 'Bad boy who does not play by the rules' + }, } AWARDS = { diff --git a/files/helpers/sanitize.py b/files/helpers/sanitize.py index d205648f46..4733686527 100644 --- a/files/helpers/sanitize.py +++ b/files/helpers/sanitize.py @@ -178,7 +178,7 @@ def sanitize(sanitized, noimages=False, alert=False, comment=False, edit=False): sanitized = re.sub('\|\|(.*?)\|\|', r'\1', sanitized) if comment: - with open("marsey_count.json", 'r') as f: marsey_count = loads(f.read()) + marsey_count = cache.get("marsey_count") marseys_used = set() for i in re.finditer("[^a]>\s*(:[!#]{0,2}\w+:\s*)+<\/", sanitized): @@ -260,7 +260,7 @@ def sanitize(sanitized, noimages=False, alert=False, comment=False, edit=False): if comment: for emoji in marseys_used: if emoji in marsey_count: marsey_count[emoji] += 1 - with open('marsey_count.json', 'w') as f: dump(marsey_count, f) + cache.set("marsey_count", marsey_count) return sanitized diff --git a/files/routes/admin.py b/files/routes/admin.py index f83209d96d..34e142d942 100644 --- a/files/routes/admin.py +++ b/files/routes/admin.py @@ -1170,7 +1170,7 @@ def api_unban_comment(c_id, v): comment = g.db.query(Comment).filter_by(id=c_id).one_or_none() if not comment: abort(404) - if comment.author.agendaposter and 'black lives matters' not in comment.body.lower(): + if comment.author.agendaposter and AGENDAPOSTER_PHRASE not in comment.body.lower(): return {"error": "You can't bypass the agendaposter award!"} if comment.is_banned: @@ -1211,6 +1211,7 @@ def admin_distinguish_comment(c_id, v): @app.get("/admin/dump_cache") @admin_level_required(2) def admin_dump_cache(v): + with open('marsey_count.json', 'w') as f: dump(cache.get("marsey_count"), f) cache.clear() return {"message": "Internal cache cleared."} diff --git a/files/routes/comments.py b/files/routes/comments.py index a771710bb6..e2bb0e51b2 100644 --- a/files/routes/comments.py +++ b/files/routes/comments.py @@ -481,7 +481,7 @@ def api_comment(v): 'body': notifbody, }, 'data': { - 'url': f'comment/{c.id}?context=9&read=true#context', + 'url': f'/comment/{c.id}?context=9&read=true#context', } } }, diff --git a/files/routes/login.py b/files/routes/login.py index c263cb6002..0aa7d51959 100644 --- a/files/routes/login.py +++ b/files/routes/login.py @@ -396,6 +396,8 @@ def get_reset(): user = g.db.query(User).filter_by(id=user_id).one_or_none() + if not user: abort(400) + if not validate_hash(f"{user_id}+{timestamp}+forgot+{user.login_nonce}", token): abort(400) diff --git a/files/routes/settings.py b/files/routes/settings.py index 427e3fe1b0..d81b5b9551 100644 --- a/files/routes/settings.py +++ b/files/routes/settings.py @@ -857,7 +857,7 @@ def settings_name_change(v): v=v, error=f"Username `{new_name}` is already in use.") - v=g.db.query(User).with_for_update().filter_by(id=v.id).one_or_none() + v=g.db.query(User).filter_by(id=v.id).one_or_none() v.username=new_name v.name_changed_utc=int(time.time()) @@ -876,8 +876,9 @@ def settings_name_change(v): def settings_song_change(v): song=request.values.get("song").strip() - if song == "" and v.song and path.isfile(f"/songs/{v.song}.mp3") and g.db.query(User.id).filter_by(song=v.song).count() == 1: - os.remove(f"/songs/{v.song}.mp3") + if song == "" and v.song: + if path.isfile(f"/songs/{v.song}.mp3") and g.db.query(User.id).filter_by(song=v.song).count() == 1: + os.remove(f"/songs/{v.song}.mp3") v.song = None g.db.add(v) g.db.commit() diff --git a/files/routes/static.py b/files/routes/static.py index 2f78698fab..462ac9521e 100644 --- a/files/routes/static.py +++ b/files/routes/static.py @@ -17,8 +17,7 @@ def privacy(v): @app.get("/marseys") @auth_required def emojis(v): - with open("marsey_count.json", 'r') as file: - marsey_count = loads(file.read()) + marsey_count = cache.get("marsey_count") marsey_counted = [] for k, val in marseys.items(): marsey_counted.append((k, val, marsey_count[k])) diff --git a/files/routes/users.py b/files/routes/users.py index e24dd18095..75fa36059c 100644 --- a/files/routes/users.py +++ b/files/routes/users.py @@ -503,7 +503,7 @@ def message2(v, username): 'body': notifbody, }, 'data': { - 'url': 'notifications?messages=true', + 'url': '/notifications?messages=true', } } }, @@ -570,7 +570,7 @@ def messagereply(v): 'body': notifbody, }, 'data': { - 'url': 'notifications?messages=true', + 'url': '/notifications?messages=true', } } }, diff --git a/files/templates/authforms.html b/files/templates/authforms.html index 9216802092..5993154bf9 100644 --- a/files/templates/authforms.html +++ b/files/templates/authforms.html @@ -15,7 +15,7 @@ {% if v %} - + {% if v.agendaposter %} - + {% endif %} diff --git a/files/templates/default.html b/files/templates/default.html index 73109ff078..3592523341 100644 --- a/files/templates/default.html +++ b/files/templates/default.html @@ -7,8 +7,8 @@ {% if v %} - - + + {% if v.agendaposter %} - + {% endif %} diff --git a/files/templates/log.html b/files/templates/log.html index 84841813e0..281e10d403 100644 --- a/files/templates/log.html +++ b/files/templates/log.html @@ -6,7 +6,7 @@ {% block content %} {% if v %} - + {% if v.agendaposter %} - + {% endif %}
diff --git a/files/templates/login.html b/files/templates/login.html index 7063169ddc..1fc69d8a25 100644 --- a/files/templates/login.html +++ b/files/templates/login.html @@ -18,8 +18,8 @@ {% endblock %} - - + + diff --git a/files/templates/login_2fa.html b/files/templates/login_2fa.html index 9ba4654a1a..031d6e5b11 100644 --- a/files/templates/login_2fa.html +++ b/files/templates/login_2fa.html @@ -14,7 +14,7 @@ 2-Step Login - {{SITE_NAME}} - + diff --git a/files/templates/settings.html b/files/templates/settings.html index 1a30655c4e..f403c45f98 100644 --- a/files/templates/settings.html +++ b/files/templates/settings.html @@ -34,7 +34,7 @@ - + {% if v.agendaposter %} - + {% else %} - + {% endif %} diff --git a/files/templates/sign_up.html b/files/templates/sign_up.html index b927f57529..db4f5991e8 100644 --- a/files/templates/sign_up.html +++ b/files/templates/sign_up.html @@ -31,7 +31,7 @@ {% if ref_user %}{{ref_user.username}} invites you to {{SITE_NAME}}{% else %}Sign up - {{SITE_NAME}}{% endif %} - + diff --git a/files/templates/sign_up_failed_ref.html b/files/templates/sign_up_failed_ref.html index 04855c638f..f8902b593d 100644 --- a/files/templates/sign_up_failed_ref.html +++ b/files/templates/sign_up_failed_ref.html @@ -32,7 +32,7 @@ {% if ref_user %}{{ref_user.username}} invites you to {{SITE_NAME}}{% else %}{{SITE_NAME}}{% endif %} - + diff --git a/files/templates/submit.html b/files/templates/submit.html index d02d803db1..e50330ae03 100644 --- a/files/templates/submit.html +++ b/files/templates/submit.html @@ -26,7 +26,7 @@ {% block stylesheets %} {% if v %} - + {% if v.agendaposter %} - - + + {% endif %} {% endblock %} diff --git a/requirements.txt b/requirements.txt index f444eafa54..0a46c4b26b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,12 +3,12 @@ bleach Flask Flask-Caching Flask-Compress -Flask-Limiter==1.1.0 -Flask-Mail==0.9.1 +Flask-Limiter +Flask-Mail gevent greenlet gunicorn -markdown +mistletoe matplotlib Pillow psutil