Compare commits

...

4 Commits

Author SHA1 Message Date
Aevann b17f4b7319 add discord linking for rdrama 2024-04-24 14:16:31 +02:00
Aevann 73649e987c remove unnecessary function 2024-04-24 14:16:08 +02:00
Aevann b950c9107a add 1/second ratelimit to all POST 2024-04-24 14:14:59 +02:00
Aevann 7fc91eb6ef fix plural + dedup 2024-04-24 14:07:10 +02:00
14 changed files with 71 additions and 22 deletions

View File

@ -1091,7 +1091,7 @@ class User(Base):
@property
@lazy
def json(self):
if self.is_suspended:
if self.is_banned:
return {'username': self.username,
'original_username': self.original_username,
'url': self.url,
@ -1138,12 +1138,6 @@ class User(Base):
self.ban_reason = reason
@property
@lazy
def is_suspended(self):
return (self.is_banned and (not self.unban_utc or self.unban_utc > time.time()))
@property
@lazy
def is_permabanned(self):

View File

@ -982,7 +982,7 @@ forced_hats = {
"sharpen": ("Bane Mask", "No one understands..."),
"earlylife": ("The Merchant", "SHUT IT DOWN, the goys know!"),
"marsify": ("Marsified", "I can't pick my own Marseys, help!"),
"is_suspended": ("Behind Bars", "This user is banned and needs to do better!"),
"is_banned": ("Behind Bars", "This user is banned and needs to do better!"),
"chud": (
("Egg_irl", "This user is getting in touch with xir identity!"),
("Trans Flag", "Just in case you forgot, trans lives matter."),

View File

@ -1034,18 +1034,15 @@ def ban_user(fullname, v):
reason = reason_regex_post.sub(r'<a href="\1">\1</a>', reason)
reason = reason_regex_comment.sub(r'<a href="\1#context">\1</a>', reason)
duration = "permanently"
if days:
days_txt = str(days)
if days_txt.endswith('.0'): days_txt = days_txt[:-2]
duration = f"for {days_txt} day"
if days != 1: duration += "s"
if reason: text = f"@{v.username} (a site admin) has banned you for **{days_txt}** days for the following reason:\n\n> {reason}"
else: text = f"@{v.username} (a site admin) has banned you for **{days_txt}** days."
else:
if reason: text = f"@{v.username} (a site admin) has banned you permanently for the following reason:\n\n> {reason}"
else: text = f"@{v.username} (a site admin) has banned you permanently."
duration = "permanently"
text = f"@{v.username} (a site admin) has banned you {duration} for the following reason:\n\n> {reason}"
user.ban(admin=v, reason=reason, days=days)
send_repeatable_notification(user.id, text)
@ -1998,6 +1995,8 @@ def change_under_siege(v):
return render_template('admin/under_siege.html', v=v, thresholds=thresholds)
@app.post("/admin/under_siege")
@limiter.limit('1/second', scope=rpath)
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
@admin_level_required(PERMS['CHANGE_UNDER_SIEGE'])

View File

@ -364,13 +364,13 @@ def award_thing(v, thing_type, id):
if not emoji:
abort(404, f'an Emoji with the name "{award.note}" was not found!')
elif kind == "ban":
if not author.is_suspended:
if not author.is_banned:
author.ban(reason=ban_reason, days=quantity)
elif author.unban_utc:
author.unban_utc += 86400 * quantity
send_repeatable_notification(author.id, f"Your account has been banned for **{quantity} day{s}** for {obj.textlink}. It sucked and you should feel bad.")
elif kind == "unban":
if not author.is_suspended or not author.unban_utc:
if not author.is_banned or not author.unban_utc:
abort(403)
if not author.ban_reason.startswith('Ban award'):

View File

@ -103,6 +103,8 @@ def chat(v, chat_id):
@app.post("/chat/<int:chat_id>/name")
@limiter.limit('1/second', scope=rpath)
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
@auth_required
@ -125,6 +127,8 @@ def change_chat_name(v, chat_id):
return redirect(f"/chat/{chat.id}")
@app.post("/chat/<int:chat_id>/leave")
@limiter.limit('1/second', scope=rpath)
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
@auth_required

View File

@ -939,6 +939,8 @@ def profile_pin(post_id, v):
return abort(404, "Post not found!")
@app.post("/post/<int:post_id>/new")
@limiter.limit('1/second', scope=rpath)
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
@auth_required
@ -961,6 +963,8 @@ def set_new_sort(post_id, v):
@app.post("/post/<int:post_id>/hot")
@limiter.limit('1/second', scope=rpath)
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
@auth_required

View File

@ -41,7 +41,33 @@ def settings(v):
def settings_personal(v):
return render_template("settings/personal.html", v=v, msg=get_msg(), error=get_error())
@app.post('/settings/discord')
@limiter.limit('1/second', scope=rpath)
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
@auth_required
def link_discord(v):
if v.is_banned:
return {"message": "You're already banned!"}
reason = "Rule 4"
v.ban(reason=reason, days=1)
text = f"@AutoJanny has banned you for 1 day for the following reason:\n\n> {reason}"
send_repeatable_notification(v.id, text)
ma = ModAction(
kind="ban_user",
user_id=AUTOJANNY_ID,
target_user_id=v.id,
_note=f'duration: for 1 day, reason: "{reason}"'
)
g.db.add(ma)
return {"message": "You have been banned for 1 day!"}
@app.post('/settings/remove_background')
@limiter.limit('1/second', scope=rpath)
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
@auth_required

View File

@ -1282,6 +1282,8 @@ def subscribed_posts(v, username):
return get_saves_and_subscribes(v, "userpage/posts.html", Subscription, page, False)
@app.post("/toggle_pins/<hole>/<sort>")
@limiter.limit('1/second', scope=rpath)
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
def toggle_pins(hole, sort):
if sort == 'hot': default = True

View File

@ -162,7 +162,7 @@ def is_not_banned(f):
v = get_logged_in_user()
if not v:
abort(401, "You need to login to perform this action!")
if v.is_suspended:
if v.is_banned:
abort(403, "You can't perform this action while banned!")
return make_response(f(*args, v=v, **kwargs))
wrapper.__name__ = f.__name__

View File

@ -504,7 +504,7 @@
{% if v.admin_level >= PERMS['USER_BAN'] and v.id != c.author_id %}
<button type="button" class="{% if c.author.switched.is_permabanned %}d-none{% endif %} dropdown-item list-inline-item d-mob-none text-danger" data-bs-toggle="modal" data-bs-target="#banModal" data-nonce="{{g.nonce}}" data-onclick="punishModal(this, 'ban', '/comment/{{c.id}}', '{{c.author_name_punish_modal}}', '{{c.fullname}}')"><i class="fas fa-user-slash text-danger fa-fw"></i>Ban user</button>
<button type="button" id="unban-{{c.fullname}}" class="dropdown-item list-inline-item d-mob-none {% if not c.author.switched.is_suspended %}d-none{% endif %} text-success" data-nonce="{{g.nonce}}" data-onclick="unchud_or_unban(this,'/unban_user/{{c.fullname}}')"><i class="fas fa-user-slash text-success fa-fw"></i>Unban user</button>
<button type="button" id="unban-{{c.fullname}}" class="dropdown-item list-inline-item d-mob-none {% if not c.author.switched.is_banned %}d-none{% endif %} text-success" data-nonce="{{g.nonce}}" data-onclick="unchud_or_unban(this,'/unban_user/{{c.fullname}}')"><i class="fas fa-user-slash text-success fa-fw"></i>Unban user</button>
{% endif %}
{% if v.admin_level >= PERMS['USER_CHUD'] and v.id != c.author_id %}
@ -736,7 +736,7 @@
{% if v.id != c.author_id and v.admin_level >= PERMS['USER_BAN'] %}
<button type="button" class="list-group-item text-danger {% if c.author.switched.is_permabanned %}d-none{% endif %}" data-bs-dismiss="modal" data-bs-toggle="modal" data-bs-target="#banModal" data-nonce="{{g.nonce}}" data-onclick="punishModal(this, 'ban', '/comment/{{c.id}}', '{{c.author_name_punish_modal}}', '{{c.fullname}}')"><i class="fas fa-user-slash text-danger fa-fw mr-2"></i>Ban user</button>
<button type="button" id="unban2-{{c.fullname}}" class="{% if not c.author.switched.is_suspended %}d-none{% endif %} list-group-item text-success" data-nonce="{{g.nonce}}" data-onclick="unchud_or_unban(this,'/unban_user/{{c.fullname}}')" data-bs-dismiss="modal"><i class="fas fa-user-minus fa-fw text-success mr-2"></i>Unban user</button>
<button type="button" id="unban2-{{c.fullname}}" class="{% if not c.author.switched.is_banned %}d-none{% endif %} list-group-item text-success" data-nonce="{{g.nonce}}" data-onclick="unchud_or_unban(this,'/unban_user/{{c.fullname}}')" data-bs-dismiss="modal"><i class="fas fa-user-minus fa-fw text-success mr-2"></i>Unban user</button>
{% endif %}
{% if v.id != c.author_id and v.admin_level >= PERMS['USER_CHUD'] %}

View File

@ -113,7 +113,7 @@
{% if v.admin_level >= PERMS['USER_BAN'] and v.id != p.author_id %}
<button type="button" class="dropdown-item list-inline-item text-danger {% if p.author.is_permabanned %}d-none{% endif %}" data-bs-toggle="modal" data-bs-target="#banModal" data-nonce="{{g.nonce}}" data-onclick="punishModal(this, 'ban', '/post/{{p.id}}', '{{p.author_name_punish_modal}}', '{{p.fullname}}')"><i class="fas fa-user-slash text-danger fa-fw"></i>Ban user</button>
<button type="button" id="unban-{{p.fullname}}" class="dropdown-item list-inline-item text-success {% if not p.author.is_suspended %}d-none{% endif %}" id="unexile2-user-{{p.id}}" data-nonce="{{g.nonce}}" data-onclick="unchud_or_unban(this,'/unban_user/{{p.fullname}}')"><i class="fas fa-user-slash"></i>Unban user</button>
<button type="button" id="unban-{{p.fullname}}" class="dropdown-item list-inline-item text-success {% if not p.author.is_banned %}d-none{% endif %}" id="unexile2-user-{{p.id}}" data-nonce="{{g.nonce}}" data-onclick="unchud_or_unban(this,'/unban_user/{{p.fullname}}')"><i class="fas fa-user-slash"></i>Unban user</button>
{% endif %}
{% if v.admin_level >= PERMS['USER_CHUD'] and v.id != p.author_id %}

View File

@ -61,7 +61,7 @@
{% if v.id != p.author_id and v.admin_level >= PERMS['USER_BAN'] %}
<button type="button" data-bs-dismiss="modal" data-bs-toggle="modal" data-bs-target="#banModal" data-nonce="{{g.nonce}}" data-onclick="punishModal(this, 'ban', '/post/{{p.id}}', '{{p.author_name_punish_modal}}', '{{p.fullname}}')" class="nobackground btn btn-link btn-block btn-lg text-danger text-left {% if p.author.is_permabanned %}d-none{% endif %}"><i class="fas fa-user-minus mr-2"></i>Ban user</button>
<button type="button" id="unban2-{{p.fullname}}" class="{% if not p.author.is_suspended %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-success text-left" data-nonce="{{g.nonce}}" data-onclick="unchud_or_unban(this,'/unban_user/{{p.fullname}}')" data-bs-dismiss="modal"><i class="fas fa-user-minus mr-2"></i>Unban user</button>
<button type="button" id="unban2-{{p.fullname}}" class="{% if not p.author.is_banned %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-success text-left" data-nonce="{{g.nonce}}" data-onclick="unchud_or_unban(this,'/unban_user/{{p.fullname}}')" data-bs-dismiss="modal"><i class="fas fa-user-minus mr-2"></i>Unban user</button>
{% endif %}
{% if v.id != p.author_id and v.admin_level >= PERMS['USER_CHUD'] %}

View File

@ -224,6 +224,26 @@
</div>
</section>
{% if SITE_NAME == 'rDrama' %}
<section id="site-settings-linked-accounts-section" class="settings-section-section">
<h5>Linked Accounts</h5>
<div class="settings-section rounded">
<div id="discord-section" class="d-lg-flex border-bottom">
<div class="title w-lg-25">
<label for="discord">Discord</label>
</div>
<div class="body w-lg-100">
<form id="discord" action="/settings/discord" method="post" data-nonce="{{g.nonce}}" data-onsubmit="sendFormXHR(this)">
<input hidden name="formkey" value="{{v|formkey}}" class="notranslate" translate="no">
<input autocomplete="off" class="btn btn-primary" type="submit" value="Link Discord">
</form>
<small class="d-block mt-2">Link your Discord account to join the {{SITE_NAME}} Discord server.</small>
</div>
</div>
</div>
</section>
{% endif %}
<section id="site-settings-sort-time-filter-section" class="settings-section-section">
<h5>RSS Feed</h5>
<p class="text-small text-muted">Subscribe to the {{SITE_NAME}} RSS feed.</p>

View File

@ -4,7 +4,7 @@
(by {{u.chudder | safe}}) - {{u.unchud_string}}
</h5>
{% endif %}
{% if u.is_suspended %}
{% if u.is_banned %}
<h5 class="text-primary" id="profile-{{deviceType}}--banned">BANNED USER:
{{u.ban_reason | safe}}
@ -60,7 +60,7 @@
<input autocomplete="off" id="user-ban-submit-{{deviceType}}" type="submit" class="btn btn-danger" value="Ban user" disabled>
</form>
<button type="button" id="unban-{{deviceType}}" class="mt-1 {% if not u.is_suspended %}d-none{% endif %} btn btn-success" data-nonce="{{g.nonce}}" data-onclick="unchud_or_unban(this,'/unban_user/{{u.id}}')">Unban user</button>
<button type="button" id="unban-{{deviceType}}" class="mt-1 {% if not u.is_banned %}d-none{% endif %} btn btn-success" data-nonce="{{g.nonce}}" data-onclick="unchud_or_unban(this,'/unban_user/{{u.id}}')">Unban user</button>
{% endif %}
{% if v.admin_level >= PERMS['USER_SHADOWBAN'] %}
<form id="shadowban-{{deviceType}}" class="mt-3 {% if u.shadowbanned %}d-none{% endif %}" action="/shadowban/{{u.id}}" method="post" data-nonce="{{g.nonce}}" data-onsubmit="sendFormXHRSwitch(this)">