add jl5 (for me)

pull/90/head
Aevann 2023-01-22 10:04:49 +02:00
parent 75cb26ccf4
commit 24edb49f3b
17 changed files with 244 additions and 264 deletions

View File

@ -320,7 +320,7 @@ class User(Base):
@lazy
def mods(self, sub):
if self.is_suspended_permanently or self.shadowbanned: return False
if self.id in {AEVANN_ID}: return True
if self.admin_level >= PERMS['MODS_EVERY_HOLE']: return True
try:
return any(map(lambda x: x.sub == sub, self.sub_mods))
except:

View File

@ -377,28 +377,27 @@ def execute_blackjack(v, target, body, type):
elif hasattr(target, 'is_banned'):
target.is_banned = True
if CARP_ID and AEVANN_ID:
extra_info = "unknown entity"
notified_ids = [x[0] for x in g.db.query(User.id).filter(User.admin_level >= PERMS['BLACKJACK_NOTIFICATIONS'])]
extra_info = "unknown entity"
if type == 'submission':
extra_info = target.permalink
elif type == 'chat':
extra_info = "chat message"
elif type == 'flag':
extra_info = f"reports on {target.permalink}"
elif type == 'modmail':
extra_info = "modmail"
elif type in {'comment', 'message'}:
for id in (CARP_ID, AEVANN_ID):
n = Notification(comment_id=target.id, user_id=id)
g.db.add(n)
g.db.flush()
extra_info = None
if type == 'submission':
extra_info = target.permalink
elif type == 'chat':
extra_info = "chat message"
elif type == 'flag':
extra_info = f"reports on {target.permalink}"
elif type == 'modmail':
extra_info = "modmail"
elif type in {'comment', 'message'}:
for id in notified_ids:
n = Notification(comment_id=target.id, user_id=id)
g.db.add(n)
g.db.flush()
extra_info = None
if extra_info:
for id in (CARP_ID, AEVANN_ID):
send_repeatable_notification(id, f"Blackjack for @{v.username}: {extra_info}")
return False
if extra_info:
for id in notified_ids:
send_repeatable_notification(id, f"Blackjack for @{v.username}: {extra_info}")
return True
def execute_antispam_duplicate_comment_check(v:User, body_html:str):

View File

@ -397,77 +397,78 @@ SUB_MARSEY_URL_LENGTH = 60
################################################################################
PERMS = { # Minimum admin_level to perform action.
'ADMIN_ADD': 3,
'ADMIN_REMOVE': 3,
'ADMIN_ADD_PERM_LEVEL': 2, # permission level given when user added via site
'ADMIN_ACTIONS_REVERT': 3,
'ADMIN_MOP_VISIBLE': 2,
'ADMIN_HOME_VISIBLE': 2,
'CHAT': 0,
'CHAT_BYPASS_MUTE': 2,
'DOMAINS_BAN': 3,
'HOLE_CREATE': 0,
'EDIT_RULES': 3,
'FLAGS_REMOVE': 2,
'USER_BLOCKS_VISIBLE': 0,
'USER_FOLLOWS_VISIBLE': 0,
'USER_VOTERS_VISIBLE': 0,
'POST_COMMENT_INFINITE_PINGS': 1,
'POST_COMMENT_MODERATION': 2,
'POST_COMMENT_DISTINGUISH': 1,
'POST_COMMENT_MODERATION_TOOLS_VISIBLE': 2, # note: does not affect API at all
'POST_BYPASS_REPOST_CHECKING': 1,
'POST_EDITING': 4,
'USER_BADGES': 2,
'USER_BAN': 2,
'USER_SHADOWBAN': 2,
'USER_AGENDAPOSTER': 2,
'USER_LINK': 2,
'USER_MERGE': 3, # note: extra check for Aevann
'USER_TITLE_CHANGE': 2,
'USER_MODERATION_TOOLS_VISIBLE': 2, # note: does not affect API at all
'POST_IN_GHOST_THREADS': 1,
'POST_TO_CHANGELOG': 1, # note: code contributors can also post to changelog
'POST_TO_POLL_THREAD': 2,
'POST_BETS': 3,
'POST_BETS_DISTRIBUTE': 3, # probably should be the same as POST_BETS but w/e
'VIEW_PENDING_SUBMITTED_MARSEYS': 3,
'VIEW_PENDING_SUBMITTED_HATS': 3,
'MODERATE_PENDING_SUBMITTED_MARSEYS': 3, # note: there is an extra check so that only """carp""" can approve them
'MODERATE_PENDING_SUBMITTED_HATS': 3, # note: there is an extra check so that only """carp""" can approve them
'UPDATE_MARSEYS': 3, # note: extra check is here for 4 different users
'UPDATE_HATS': 3, # note: extra check is here for 4 different users
'BUY_GHOST_AWARD': 2,
'LOTTERY_ADMIN': 3,
'LOTTERY_VIEW_PARTICIPANTS': 2,
'VIEW_MODMAIL': 2,
'VIEW_CLUB': 1,
'VIEW_CHUDRAMA': 1,
'VIEW_PRIVATE_PROFILES': 2,
'VIEW_ALTS': 2,
'VIEW_ACTIVE_USERS': 2,
'VIEW_ALT_VOTES': 2,
'VIEW_LAST_ACTIVE': 2,
'VIEW_PATRONS': 3, # note: extra check for Aevann, carp, or snakes
'VIEW_VOTE_BUTTONS_ON_USER_PAGE': 2,
'SITE_BYPASS_READ_ONLY_MODE': 1,
'SITE_BYPASS_UNDER_SIEGE_MODE': 1,
'SITE_SETTINGS': 3,
'SITE_SETTINGS_SIDEBARS_BANNERS_BADGES': 3,
'SITE_SETTINGS_SNAPPY_QUOTES': 3,
'SITE_SETTINGS_UNDER_ATTACK': 3,
'SITE_CACHE_PURGE_CDN': 3,
'SITE_WARN_ON_INVALID_AUTH': 1,
'NOTIFICATIONS_ADMIN_PING': 2,
'NOTIFICATIONS_HOLE_INACTIVITY_DELETION': 2,
'NOTIFICATIONS_HOLE_CREATION': 2,
'NOTIFICATIONS_FROM_SHADOWBANNED_USERS': 3,
'NOTIFICATIONS_MODMAIL': 3,
'NOTIFICATIONS_MODERATOR_ACTIONS': 2,
'NOTIFICATIONS_REDDIT': 1,
'NOTIFICATIONS_SPECIFIC_WPD_COMMENTS': 1,
'MESSAGE_BLOCKED_USERS': 1,
'APPS_MODERATION': 3,
'CHAT': 0,
'HOLE_CREATE': 0,
'USER_BLOCKS_VISIBLE': 0,
'USER_FOLLOWS_VISIBLE': 0,
'USER_VOTERS_VISIBLE': 0,
'POST_COMMENT_INFINITE_PINGS': 1,
'POST_COMMENT_DISTINGUISH': 1,
'POST_BYPASS_REPOST_CHECKING': 1,
'POST_IN_GHOST_THREADS': 1,
'POST_TO_CHANGELOG': 1,
'VIEW_CLUB': 1,
'VIEW_CHUDRAMA': 1,
'SITE_BYPASS_READ_ONLY_MODE': 1,
'SITE_BYPASS_UNDER_SIEGE_MODE': 1,
'SITE_WARN_ON_INVALID_AUTH': 1,
'NOTIFICATIONS_REDDIT': 1,
'NOTIFICATIONS_SPECIFIC_WPD_COMMENTS': 1,
'MESSAGE_BLOCKED_USERS': 1,
'ADMIN_ADD_PERM_LEVEL': 2,
'ADMIN_MOP_VISIBLE': 2,
'ADMIN_HOME_VISIBLE': 2,
'CHAT_BYPASS_MUTE': 2,
'FLAGS_REMOVE': 2,
'POST_COMMENT_MODERATION': 2,
'POST_COMMENT_MODERATION_TOOLS_VISIBLE': 2,
'USER_BADGES': 2,
'USER_BAN': 2,
'USER_SHADOWBAN': 2,
'USER_AGENDAPOSTER': 2,
'USER_LINK': 2,
'USER_TITLE_CHANGE': 2,
'USER_MODERATION_TOOLS_VISIBLE': 2,
'POST_TO_POLL_THREAD': 2,
'BUY_GHOST_AWARD': 2,
'LOTTERY_VIEW_PARTICIPANTS': 2,
'VIEW_MODMAIL': 2,
'VIEW_PRIVATE_PROFILES': 2,
'VIEW_ALTS': 2,
'VIEW_ACTIVE_USERS': 2,
'VIEW_ALT_VOTES': 2,
'VIEW_LAST_ACTIVE': 2,
'VIEW_VOTE_BUTTONS_ON_USER_PAGE': 2,
'NOTIFICATIONS_ADMIN_PING': 2,
'NOTIFICATIONS_HOLE_INACTIVITY_DELETION': 2,
'NOTIFICATIONS_HOLE_CREATION': 2,
'NOTIFICATIONS_MODERATOR_ACTIONS': 2,
'ADMIN_ADD': 3,
'ADMIN_REMOVE': 3,
'ADMIN_ACTIONS_REVERT': 3,
'DOMAINS_BAN': 3,
'EDIT_RULES': 3,
'POST_BETS': 3,
'POST_BETS_DISTRIBUTE': 3,
'VIEW_PENDING_SUBMITTED_MARSEYS': 3,
'VIEW_PENDING_SUBMITTED_HATS': 3,
'LOTTERY_ADMIN': 3,
'SITE_SETTINGS': 3,
'SITE_SETTINGS_SIDEBARS_BANNERS_BADGES': 3,
'SITE_SETTINGS_SNAPPY_QUOTES': 3,
'SITE_SETTINGS_UNDER_ATTACK': 3,
'SITE_CACHE_PURGE_CDN': 3,
'NOTIFICATIONS_FROM_SHADOWBANNED_USERS': 3,
'NOTIFICATIONS_MODMAIL': 3,
'APPS_MODERATION': 3,
'POST_EDITING': 4,
'MODERATE_PENDING_SUBMITTED_ASSETS': 4,
'UPDATE_ASSETS': 4,
'VIEW_PATRONS': 4,
'BLACKJACK_NOTIFICATIONS': 4,
'IGNORE_BADGE_BLACKLIST': 4,
'SEE_GHOST_VOTES': 5,
'MODS_EVERY_HOLE': 5
}
FEATURES = {
@ -660,7 +661,7 @@ TIERS_ID_TO_NAME = {
6: "Rich Bich",
}
BADGE_BLACKLIST = { # only grantable by AEVANN_ID
BADGE_BLACKLIST = { # only grantable by admins higher than PERMS['IGNORE_BADGE_BLACKLIST']
1, 2, 6, 10, 11, 12, # Alpha, Verified Email, Beta, Recruiter x3
16, 17, 143, 21, 22, 23, 24, 25, 26, 27, # Marsey Artist x3 / Patron Tiers
94, 95, 96, 97, 98, 109, 67, 68, 83, 84, 87, 90, 179, 185, # Award Status except Y'all-seeing eye

View File

@ -39,155 +39,153 @@ def loggedout_list(v):
return render_template("admin/loggedout.html", v=v, users=users)
@app.get('/admin/move/<int:old_id>/<int:new_id>')
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_MERGE'])
def move_acc(v:User, new_id, old_id):
if v.id != AEVANN_ID: abort(403)
# @app.get('/admin/move/<int:old_id>/<int:new_id>')
# @limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
# @admin_level_required(PERMS['USER_MERGE'])
# def move_acc(v:User, new_id, old_id):
# if time.time() - session.get('verified', 0) > 10:
# session.pop("lo_user", None)
# path = request.path
# qs = urlencode(dict(request.values))
# argval = quote(f"{path}?{qs}", safe='')
# return redirect(f"/login?redirect={argval}")
if time.time() - session.get('verified', 0) > 10:
session.pop("lo_user", None)
path = request.path
qs = urlencode(dict(request.values))
argval = quote(f"{path}?{qs}", safe='')
return redirect(f"/login?redirect={argval}")
# old_id = int(old_id)
# new_id = int(new_id)
old_id = int(old_id)
new_id = int(new_id)
# olduser = g.db.get(User, old_id)
# newuser = g.db.get(User, new_id)
olduser = g.db.get(User, old_id)
newuser = g.db.get(User, new_id)
# attrs = {
# 'coins',
# 'coins_spent',
# 'coins_spent_on_hats',
# 'comment_count',
# 'currently_held_lottery_tickets',
# 'lootboxes_bought',
# 'marseybux',
# 'post_count',
# 'received_award_count',
# 'total_held_lottery_tickets',
# 'total_lottery_winnings',
# 'truescore',
# }
attrs = {
'coins',
'coins_spent',
'coins_spent_on_hats',
'comment_count',
'currently_held_lottery_tickets',
'lootboxes_bought',
'marseybux',
'post_count',
'received_award_count',
'total_held_lottery_tickets',
'total_lottery_winnings',
'truescore',
}
# for attr in attrs:
# amount = getattr(newuser, attr) + getattr(olduser, attr)
# setattr(newuser, attr, amount)
for attr in attrs:
amount = getattr(newuser, attr) + getattr(olduser, attr)
setattr(newuser, attr, amount)
# if newuser.created_utc > olduser.created_utc:
# newuser.created_utc = olduser.created_utc
if newuser.created_utc > olduser.created_utc:
newuser.created_utc = olduser.created_utc
# g.db.add(newuser)
g.db.add(newuser)
# g.db.commit()
g.db.commit()
# classes = {
# (AwardRelationship, "user_id"),
# (Badge, "user_id"),
# (CasinoGame, "user_id"),
# (Hat, "user_id"),
# (HatDef, "author_id"),
# (Lottery, "winner_id"),
# (Marsey, "author_id"),
# (Media, "user_id"),
# (Notification, "user_id"),
# (PushSubscription, "user_id"),
classes = {
(AwardRelationship, "user_id"),
(Badge, "user_id"),
(CasinoGame, "user_id"),
(Hat, "user_id"),
(HatDef, "author_id"),
(Lottery, "winner_id"),
(Marsey, "author_id"),
(Media, "user_id"),
(Notification, "user_id"),
(PushSubscription, "user_id"),
# #mod actions
# (ModAction, "user_id"),
# (ModAction, "target_user_id"),
# (SubAction, "user_id"),
# (SubAction, "target_user_id"),
#mod actions
(ModAction, "user_id"),
(ModAction, "target_user_id"),
(SubAction, "user_id"),
(SubAction, "target_user_id"),
# #holes
# (Mod, "user_id"),
# (Exile, "exiler_id"),
# (Exile, "user_id"),
# (SubBlock, "user_id"),
# (SubJoin, "user_id"),
# (SubSubscription, "user_id"),
# (Subscription, "user_id"),
#holes
(Mod, "user_id"),
(Exile, "exiler_id"),
(Exile, "user_id"),
(SubBlock, "user_id"),
(SubJoin, "user_id"),
(SubSubscription, "user_id"),
(Subscription, "user_id"),
# #other users
# (User, "is_banned"),
# (User, "referred_by"),
# (User, "shadowbanned"),
# (Follow, "target_id"),
# (Follow, "user_id"),
# (UserBlock, "user_id"),
# (UserBlock, "target_id"),
# (ViewerRelationship, "user_id"),
# (ViewerRelationship, "viewer_id"),
#other users
(User, "is_banned"),
(User, "referred_by"),
(User, "shadowbanned"),
(Follow, "target_id"),
(Follow, "user_id"),
(UserBlock, "user_id"),
(UserBlock, "target_id"),
(ViewerRelationship, "user_id"),
(ViewerRelationship, "viewer_id"),
# #posts and comments
# (Submission, "author_id"),
# (Submission, "is_approved"),
# (Comment, "author_id"),
# (Comment, "is_approved"),
# (Comment, "sentto"),
# (Comment, "wall_user_id"),
# (Vote, "user_id"),
# (CommentVote, "user_id"),
# (Flag, "user_id"),
# (CommentFlag, "user_id"),
# (SaveRelationship, "user_id"),
# (CommentSaveRelationship, "user_id"),
# (SubmissionOptionVote, "user_id"),
# (CommentOptionVote, "user_id"),
# }
#posts and comments
(Submission, "author_id"),
(Submission, "is_approved"),
(Comment, "author_id"),
(Comment, "is_approved"),
(Comment, "sentto"),
(Comment, "wall_user_id"),
(Vote, "user_id"),
(CommentVote, "user_id"),
(Flag, "user_id"),
(CommentFlag, "user_id"),
(SaveRelationship, "user_id"),
(CommentSaveRelationship, "user_id"),
(SubmissionOptionVote, "user_id"),
(CommentOptionVote, "user_id"),
}
# for cls, attr in classes:
# items = g.db.query(cls).filter(getattr(cls, attr) == olduser.id)
# for item in items:
# setattr(item, attr, newuser.id)
# g.db.add(item)
# try: g.db.commit()
# except IntegrityError as e:
# if isinstance(e.orig, UniqueViolation):
# g.db.rollback()
# g.db.delete(item)
# g.db.commit()
# else:
# print(e, flush=True)
# abort(500, str(e))
for cls, attr in classes:
items = g.db.query(cls).filter(getattr(cls, attr) == olduser.id)
for item in items:
setattr(item, attr, newuser.id)
g.db.add(item)
try: g.db.commit()
except IntegrityError as e:
if isinstance(e.orig, UniqueViolation):
g.db.rollback()
g.db.delete(item)
g.db.commit()
else:
print(e, flush=True)
abort(500, str(e))
# newuser.stored_subscriber_count = g.db.query(Follow).filter_by(target_id=newuser.id).count()
newuser.stored_subscriber_count = g.db.query(Follow).filter_by(target_id=newuser.id).count()
# g.db.add(newuser)
g.db.add(newuser)
# update_statement = f'''
# update submissions set body_html=replace(body_html, '<a href="/id/{olduser.id}">', '<a href="/id/{newuser.id}">') where body_html like '%<a href="/id/{olduser.id}">%';
# update comments set body_html=replace(body_html, '<a href="/id/{olduser.id}">', '<a href="/id/{newuser.id}">') where body_html like '%<a href="/id/{olduser.id}">%';
# update subs set sidebar_html=replace(sidebar_html, '<a href="/id/{olduser.id}">', '<a href="/id/{newuser.id}">') where sidebar_html like '%<a href="/id/{olduser.id}">%';
# update users set bio_html=replace(bio_html, '<a href="/id/{olduser.id}">', '<a href="/id/{newuser.id}">') where bio_html like '%<a href="/id/{olduser.id}">%';
# update users set sig_html=replace(sig_html, '<a href="/id/{olduser.id}">', '<a href="/id/{newuser.id}">') where sig_html like '%<a href="/id/{olduser.id}">%';
# update users set friends_html=replace(friends_html, '<a href="/id/{olduser.id}">', '<a href="/id/{newuser.id}">') where friends_html like '%<a href="/id/{olduser.id}">%';
# update users set enemies_html=replace(enemies_html, '<a href="/id/{olduser.id}">', '<a href="/id/{newuser.id}">') where enemies_html like '%<a href="/id/{olduser.id}">%';
update_statement = f'''
update submissions set body_html=replace(body_html, '<a href="/id/{olduser.id}">', '<a href="/id/{newuser.id}">') where body_html like '%<a href="/id/{olduser.id}">%';
update comments set body_html=replace(body_html, '<a href="/id/{olduser.id}">', '<a href="/id/{newuser.id}">') where body_html like '%<a href="/id/{olduser.id}">%';
update subs set sidebar_html=replace(sidebar_html, '<a href="/id/{olduser.id}">', '<a href="/id/{newuser.id}">') where sidebar_html like '%<a href="/id/{olduser.id}">%';
update users set bio_html=replace(bio_html, '<a href="/id/{olduser.id}">', '<a href="/id/{newuser.id}">') where bio_html like '%<a href="/id/{olduser.id}">%';
update users set sig_html=replace(sig_html, '<a href="/id/{olduser.id}">', '<a href="/id/{newuser.id}">') where sig_html like '%<a href="/id/{olduser.id}">%';
update users set friends_html=replace(friends_html, '<a href="/id/{olduser.id}">', '<a href="/id/{newuser.id}">') where friends_html like '%<a href="/id/{olduser.id}">%';
update users set enemies_html=replace(enemies_html, '<a href="/id/{olduser.id}">', '<a href="/id/{newuser.id}">') where enemies_html like '%<a href="/id/{olduser.id}">%';
# update submissions set body_html=replace(body_html, '<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">', '<a href="/id/{newuser.id}"><img loading="lazy" src="/pp/{newuser.id}">') where body_html like '%<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">%';
# update comments set body_html=replace(body_html, '<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">', '<a href="/id/{newuser.id}"><img loading="lazy" src="/pp/{newuser.id}">') where body_html like '%<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">%';
# update subs set sidebar_html=replace(sidebar_html, '<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">', '<a href="/id/{newuser.id}"><img loading="lazy" src="/pp/{newuser.id}">') where sidebar_html like '%<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">%';
# update users set bio_html=replace(bio_html, '<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">', '<a href="/id/{newuser.id}"><img loading="lazy" src="/pp/{newuser.id}">') where bio_html like '%<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">%';
# update users set sig_html=replace(sig_html, '<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">', '<a href="/id/{newuser.id}"><img loading="lazy" src="/pp/{newuser.id}">') where sig_html like '%<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">%';
# update users set friends_html=replace(friends_html, '<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">', '<a href="/id/{newuser.id}"><img loading="lazy" src="/pp/{newuser.id}">') where friends_html like '%<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">%';
# update users set enemies_html=replace(enemies_html, '<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">', '<a href="/id/{newuser.id}"><img loading="lazy" src="/pp/{newuser.id}">') where enemies_html like '%<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">%'; '''
update submissions set body_html=replace(body_html, '<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">', '<a href="/id/{newuser.id}"><img loading="lazy" src="/pp/{newuser.id}">') where body_html like '%<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">%';
update comments set body_html=replace(body_html, '<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">', '<a href="/id/{newuser.id}"><img loading="lazy" src="/pp/{newuser.id}">') where body_html like '%<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">%';
update subs set sidebar_html=replace(sidebar_html, '<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">', '<a href="/id/{newuser.id}"><img loading="lazy" src="/pp/{newuser.id}">') where sidebar_html like '%<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">%';
update users set bio_html=replace(bio_html, '<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">', '<a href="/id/{newuser.id}"><img loading="lazy" src="/pp/{newuser.id}">') where bio_html like '%<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">%';
update users set sig_html=replace(sig_html, '<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">', '<a href="/id/{newuser.id}"><img loading="lazy" src="/pp/{newuser.id}">') where sig_html like '%<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">%';
update users set friends_html=replace(friends_html, '<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">', '<a href="/id/{newuser.id}"><img loading="lazy" src="/pp/{newuser.id}">') where friends_html like '%<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">%';
update users set enemies_html=replace(enemies_html, '<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">', '<a href="/id/{newuser.id}"><img loading="lazy" src="/pp/{newuser.id}">') where enemies_html like '%<a href="/id/{olduser.id}"><img loading="lazy" src="/pp/{olduser.id}">%'; '''
# g.db.execute(update_statement)
g.db.execute(update_statement)
# g.db.delete(olduser)
g.db.delete(olduser)
# g.db.commit()
g.db.commit()
# stats = cache.get(f'{SITE}_stats')
# online = cache.get(CHAT_ONLINE_CACHE_KEY)
# cache.clear()
# cache.set(f'{SITE}_stats', stats)
# cache.set(CHAT_ONLINE_CACHE_KEY, online)
stats = cache.get(f'{SITE}_stats')
online = cache.get(CHAT_ONLINE_CACHE_KEY)
cache.clear()
cache.set(f'{SITE}_stats', stats)
cache.set(CHAT_ONLINE_CACHE_KEY, online)
return redirect(f"/@{olduser.username}")
# return redirect(f"/@{olduser.username}")
@ -532,7 +530,7 @@ def under_attack(v):
def admin_badges_grantable_list(v):
query = g.db.query(BadgeDef)
if BADGE_BLACKLIST and v.id not in {AEVANN_ID}:
if BADGE_BLACKLIST and v.admin_level < PERMS['IGNORE_BADGE_BLACKLIST']:
query = query.filter(BadgeDef.id.notin_(BADGE_BLACKLIST))
badge_types = query.order_by(BadgeDef.id).all()

View File

@ -13,8 +13,6 @@ from files.routes.wrappers import *
from files.__main__ import app, cache, limiter
ASSET_TYPES = (Marsey, HatDef)
CAN_APPROVE_ASSETS = (AEVANN_ID, CARP_ID)
CAN_UPDATE_ASSETS = (AEVANN_ID, CARP_ID)
@app.get("/submit/marseys")
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@ -95,8 +93,6 @@ def submit_marsey(v:User):
def verify_permissions_and_get_asset(cls, asset_type:str, v:User, name:str, make_lower=False):
if cls not in ASSET_TYPES: raise Exception("not a valid asset type")
if AEVANN_ID and v.id not in CAN_APPROVE_ASSETS:
abort(403, f"Only Carp can approve {asset_type}!")
name = name.strip()
if make_lower: name = name.lower()
asset = None
@ -110,7 +106,7 @@ def verify_permissions_and_get_asset(cls, asset_type:str, v:User, name:str, make
@app.post("/admin/approve/marsey/<name>")
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['MODERATE_PENDING_SUBMITTED_MARSEYS'])
@admin_level_required(PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'])
def approve_marsey(v, name):
marsey = verify_permissions_and_get_asset(Marsey, "marsey", v, name, True)
tags = request.values.get('tags').lower().strip()
@ -180,8 +176,8 @@ def remove_asset(cls, type_name:str, v:User, name:str) -> dict[str, str]:
asset = g.db.get(cls, name)
if not asset:
abort(404, f"This {type_name} '{name}' doesn't exist!")
if v.id != asset.submitter_id and v.id not in CAN_APPROVE_ASSETS:
abort(403, f"Only Carp can remove {type_name}s!")
if v.id != asset.submitter_id and v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_ASSETS']:
abort(403)
name = asset.name
if v.id != asset.submitter_id:
msg = f"@{v.username} has rejected a {type_name} you submitted: `'{name}'`"
@ -271,7 +267,7 @@ def submit_hat(v:User):
@app.post("/admin/approve/hat/<name>")
@limiter.limit("3/second;120/minute;200/hour;1000/day")
@limiter.limit("3/second;120/minute;200/hour;1000/day", key_func=get_ID)
@admin_level_required(PERMS['MODERATE_PENDING_SUBMITTED_HATS'])
@admin_level_required(PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'])
def approve_hat(v, name):
hat = verify_permissions_and_get_asset(HatDef, "hat", v, name, False)
description = request.values.get('description').strip()
@ -340,10 +336,8 @@ def remove_hat(v:User, name):
@app.get("/admin/update/marseys")
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['UPDATE_MARSEYS'])
@admin_level_required(PERMS['UPDATE_ASSETS'])
def update_marseys(v):
if AEVANN_ID and v.id not in CAN_UPDATE_ASSETS:
abort(403)
name = request.values.get('name')
tags = None
error = None
@ -360,11 +354,8 @@ def update_marseys(v):
@app.post("/admin/update/marseys")
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['UPDATE_MARSEYS'])
@admin_level_required(PERMS['UPDATE_ASSETS'])
def update_marsey(v):
if AEVANN_ID and v.id not in CAN_UPDATE_ASSETS:
abort(403)
file = request.files["image"]
name = request.values.get('name', '').lower().strip()
tags = request.values.get('tags', '').lower().strip()
@ -414,20 +405,15 @@ def update_marsey(v):
@app.get("/admin/update/hats")
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['UPDATE_HATS'])
@admin_level_required(PERMS['UPDATE_ASSETS'])
def update_hats(v):
if AEVANN_ID and v.id not in CAN_UPDATE_ASSETS:
abort(403)
return render_template("update_assets.html", v=v, type="Hat")
@app.post("/admin/update/hats")
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['UPDATE_HATS'])
@admin_level_required(PERMS['UPDATE_ASSETS'])
def update_hat(v):
if AEVANN_ID and v.id not in CAN_UPDATE_ASSETS:
abort(403)
file = request.files["image"]
name = request.values.get('name', '').strip()

View File

@ -171,7 +171,7 @@ def award_thing(v, thing_type, id):
else:
safe_username = f"@{author.username}"
if SITE == 'rdrama.net' and author.id == PIZZASHILL_ID and v.id not in {AEVANN_ID}:
if SITE == 'rdrama.net' and author.id == PIZZASHILL_ID:
abort(403, f"{safe_username} is immune to awards.")
if kind == "benefactor" and author.id == v.id:

View File

@ -98,7 +98,7 @@ def git_head():
def inject_constants():
return {"environ":environ, "SITE":SITE, "SITE_NAME":SITE_NAME, "SITE_FULL":SITE_FULL,
"AUTOJANNY_ID":AUTOJANNY_ID, "MODMAIL_ID":MODMAIL_ID, "VAPID_PUBLIC_KEY":VAPID_PUBLIC_KEY,
"listdir":listdir, "os_path":path, "AEVANN_ID":AEVANN_ID,
"listdir":listdir, "os_path":path,
"PIZZASHILL_ID":PIZZASHILL_ID, "DEFAULT_COLOR":DEFAULT_COLOR,
"COLORS":COLORS, "time":time, "PERMS":PERMS, "FEATURES":FEATURES,
"HOLE_NAME":HOLE_NAME, "HOLE_STYLE_FLAIR":HOLE_STYLE_FLAIR, "HOLE_REQUIRED":HOLE_REQUIRED,

View File

@ -122,7 +122,6 @@ def on_login(account, redir=None):
session.permanent = True
session["lo_user"] = account.id
session["login_nonce"] = account.login_nonce
if account.id == AEVANN_ID: session["verified"] = time.time()
check_for_alts(account)
@ -319,7 +318,7 @@ def sign_up_post(v:Optional[User]):
)
if users_count == 4:
new_user.admin_level = 3
new_user.admin_level = 5
session["history"] = []
g.db.add(new_user)

View File

@ -111,12 +111,9 @@ def daily_chart(v:User):
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['VIEW_PATRONS'])
def patrons(v):
if AEVANN_ID and v.id not in {AEVANN_ID, CARP_ID}:
abort(404)
users = g.db.query(User).filter(User.patron > 0).order_by(User.patron.desc(), User.id).all()
return render_template("patrons.html", v=v, users=users, benefactor_def=AWARDS['benefactor'])
return render_template("admin/patrons.html", v=v, users=users, benefactor_def=AWARDS['benefactor'])
@app.get("/admins")
@app.get("/badmins")

View File

@ -15,7 +15,7 @@ def vote_info_get(v, link):
else: abort(400)
except: abort(400)
if thing.ghost and v.id != AEVANN_ID:
if thing.ghost and v.admin_level < PERMS['SEE_GHOST_VOTES']:
abort(403)
if thing.author.shadowbanned and not (v and v.admin_level >= PERMS['USER_SHADOWBAN']):

View File

@ -53,7 +53,7 @@
<li><a href="/chuds">Chudded Users</a></li>
<li><a href="/grassed">Currently Grassed Users</a></li>
{%- endif %}
{% if FEATURES['MARSEYBUX'] and (not AEVANN_ID or v.id in (AEVANN_ID, CARP_ID)) -%}
{% if FEATURES['MARSEYBUX'] and v.admin_level >= PERMS['VIEW_PATRONS'] -%}
<li><a href="/patrons">Patrons</a></li>
{%- endif %}
{% if v.admin_level >= PERMS['VIEW_ACTIVE_USERS'] %}

View File

@ -369,7 +369,7 @@
{% endif %}
{% if not c.ghost or (v and v.id == AEVANN_ID) %}
{% if not c.ghost or (v and v.admin_level >= PERMS['SEE_GHOST_VOTES']) %}
<a href="/votes/{{c.fullname}}" class="btn caction nobackground px-1 text-muted"><i class="fas fa-arrows-v"></i>Votes</a>
{% endif %}
@ -555,7 +555,7 @@
<div class="modal-body">
<ul class="list-group comment-actions">
{% if not c.ghost or (v and v.id == AEVANN_ID) %}
{% if not c.ghost or (v and v.admin_level >= PERMS['SEE_GHOST_VOTES']) %}
<a href="/votes/{{c.fullname}}"><li class="list-group-item"><i class="fas fa-arrows-v mr-2"></i>Votes</li></a>
{% endif %}

View File

@ -6,7 +6,7 @@
{% endif %}
{% if not p.ghost or (v and v.id == AEVANN_ID) %}
{% if not p.ghost or (v and v.admin_level >= PERMS['SEE_GHOST_VOTES']) %}
<a class="list-inline-item" href="/votes/{{p.fullname}}"><i class="fas fa-arrows-v"></i>Votes</a>
{% endif %}

View File

@ -6,7 +6,7 @@
{% endif %}
{% if not p.ghost or (v and v.id == AEVANN_ID) %}
{% if not p.ghost or (v and v.admin_level >= PERMS['SEE_GHOST_VOTES']) %}
<a class="nobackground btn btn-link btn-block btn-lg text-left text-muted" href="/votes/{{p.fullname}}">
<i class="fas fa-arrows-v text-center text-muted mr-2"></i>Votes
</a>

View File

@ -76,19 +76,19 @@
<input autocomplete="off" type="text" id="{{hat.name}}-author" class="form-control" maxlength="30" value="{{hat.author.username}}" readonly>
<label class="mt-3" for="{{hat.name}}-name">Name</label>
<input autocomplete="off" type="text" id="{{hat.name}}-name" class="form-control" name="name" maxlength="30" value="{{hat.name}}" pattern='hat[a-zA-Z0-9]{1,24}' placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_HATS'] %}readonly{% endif %}>
<input autocomplete="off" type="text" id="{{hat.name}}-name" class="form-control" name="name" maxlength="30" value="{{hat.name}}" pattern='hat[a-zA-Z0-9]{1,24}' placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}readonly{% endif %}>
>
<label class="mt-3" for="{{hat.name}}-description">Description</label>
<input autocomplete="off" type="text" id="{{hat.name}}-description" class="form-control" name="description" maxlength="300" value="{{hat.description}}" pattern='[^<>&\n\t]{1,300}' placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_HATS'] %}readonly{% endif %}>
<input autocomplete="off" type="text" id="{{hat.name}}-description" class="form-control" name="description" maxlength="300" value="{{hat.description}}" pattern='[^<>&\n\t]{1,300}' placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}readonly{% endif %}>
<div><label class="mt-3" for="{{hat.name}}-price">Price</label></div>
<input autocomplete="off" type="number" id="{{hat.name}}-price" class="form-control" name="price" min="0" value="{{hat.price}}" placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_HATS'] %}readonly{% endif %}>
<input autocomplete="off" type="number" id="{{hat.name}}-price" class="form-control" name="price" min="0" value="{{hat.price}}" placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}readonly{% endif %}>
</div>
</div>
<div class="d-flex my-4 mx-3">
<button type="button" class="btn btn-primary ml-auto" data-nonce="{{g.nonce}}" data-onclick="remove_hat(this, '{{hat.name}}')">Remove</button>
{% if v.admin_level >= PERMS['MODERATE_PENDING_SUBMITTED_HATS'] %}
{% if v.admin_level >= PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}
<button type="button" class="btn btn-primary ml-3" data-nonce="{{g.nonce}}" data-onclick="approve_hat(this, '{{hat.name}}')">Approve</button>
{% endif %}
</div>

View File

@ -66,15 +66,15 @@
<input autocomplete="off" type="text" id="{{marsey.name}}-author" class="form-control" maxlength="30" value="{{marsey.author}}" readonly>
<label class="mt-3" for="{{marsey.name}}-name">Name</label>
<input autocomplete="off" type="text" id="{{marsey.name}}-name" class="form-control" name="name" maxlength="30" value="{{marsey.name}}" pattern='marsey[a-z0-9]{1,24}' placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_MARSEYS'] %}readonly{% endif %}>
<input autocomplete="off" type="text" id="{{marsey.name}}-name" class="form-control" name="name" maxlength="30" value="{{marsey.name}}" pattern='marsey[a-z0-9]{1,24}' placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}readonly{% endif %}>
<label class="mt-3" for="{{marsey.name}}-tags">Tags</label>
<input autocomplete="off" type="text" id="{{marsey.name}}-tags" class="form-control" name="tags" maxlength="200" value="{{marsey.tags}}" pattern='[a-z0-9: ]{1,200}' placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_MARSEYS'] %}readonly{% endif %}>
<input autocomplete="off" type="text" id="{{marsey.name}}-tags" class="form-control" name="tags" maxlength="200" value="{{marsey.tags}}" pattern='[a-z0-9: ]{1,200}' placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}readonly{% endif %}>
</div>
</div>
<div class="d-flex my-4 mx-3">
<button type="button" class="btn btn-primary ml-auto" data-nonce="{{g.nonce}}" data-onclick="remove_marsey(this, '{{marsey.name}}')">Remove</button>
{% if v.admin_level >= PERMS['MODERATE_PENDING_SUBMITTED_MARSEYS'] %}
{% if v.admin_level >= PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}
<button type="button" class="btn btn-primary ml-3" data-nonce="{{g.nonce}}" data-onclick="approve_marsey(this, '{{marsey.name}}')">Approve</button>
{% endif %}
</div>