users: get_alt_graph function

shadowbans: propagate to entire graph
pull/68/head
justcool393 2022-12-13 18:41:43 -06:00
parent 5be1fbd3fb
commit 2cb02341e3
4 changed files with 30 additions and 28 deletions

View File

@ -1,11 +1,11 @@
import random
from operator import *
from typing import Any, Union
from typing import Callable, Union
import pyotp
from sqlalchemy import Column, ForeignKey
from sqlalchemy.orm import aliased, deferred
from sqlalchemy.sql import func
from sqlalchemy.orm import aliased, deferred, Query
from sqlalchemy.sql import case, func, literal
from sqlalchemy.sql.expression import not_, and_, or_
from sqlalchemy.sql.sqltypes import *
@ -35,6 +35,8 @@ from .subscriptions import *
from .userblock import *
class User(Base):
_is_alt_func = lambda u:or_(Alt.user1 == u.id, Alt.user2 == u.id)
__tablename__ = "users"
if SITE == "pcmemes.net":
@ -478,9 +480,30 @@ class User(Base):
@lazy
def alts_patron(self):
for u in self.alts_unique:
if u.patron: return True
if not u._deleted and u.patron: return True
return False
@lazy
def get_alt_graph(self, db:scoped_session, alt_filter:Optional[Callable[[Query], Query]]=None) -> Query:
'''
Gets the full graph of alts (optionally filtering `Alt` objects by criteria using a callable,
such as by `deleted` to only get linked alts) as a query of users that can be filtered further
'''
if not alt_filter: alt_filter = lambda q:q
alt_graph_cte = db.query(literal(self.id).label('user_id')).select_from(Alt).cte('alt_graph', recursive=True)
alt_graph_cte_inner = alt_filter(db.query(
case(
(Alt.user1 == alt_graph_cte.c.user_id, Alt.user2),
(Alt.user2 == alt_graph_cte.c.user_id, Alt.user1),
)
)).select_from(Alt, alt_graph_cte).filter(
or_(alt_graph_cte.user_id == Alt.user1, alt_graph_cte.user_id == Alt.user2)
)
alt_graph_cte = alt_graph_cte.union(alt_graph_cte_inner)
return db.query(User).filter(User.id == alt_graph_cte.c.user_id)
@property
@lazy
def follow_count(self):

View File

@ -465,7 +465,7 @@ def execute_antispam_comment_check(body:str, v:User):
g.db.commit()
abort(403, "Too much spam!")
def execute_under_siege(v:User, target:Optional[Union[Submission, Comment]], body, type:str):
def execute_under_siege(v:User, target:Optional[Union[Submission, Comment]], body, type:str) -> bool:
if not get_setting("under_siege"): return True
if v.age < UNDER_SIEGE_AGE_THRESHOLD and not v.admin_level >= PERMS['SITE_BYPASS_UNDER_SIEGE_MODE']:
v.shadowbanned = AUTOJANNY_ID

View File

@ -159,13 +159,11 @@ def merge_all(v:User, id):
@app.get('/admin/edit_rules')
@admin_level_required(PERMS['EDIT_RULES'])
def edit_rules_get(v):
try:
with open(f'files/templates/rules_{SITE_NAME}.html', 'r', encoding="utf-8") as f:
rules = f.read()
except:
rules = None
return render_template('admin/edit_rules.html', v=v, rules=rules)
@ -184,11 +182,8 @@ def edit_rules_post(v):
user_id=v.id,
)
g.db.add(ma)
return render_template('admin/edit_rules.html', v=v, rules=rules, msg='Rules edited successfully!')
@app.post("/@<username>/make_admin")
@admin_level_required(PERMS['ADMIN_ADD'])
def make_admin(v:User, username):
@ -214,7 +209,7 @@ def make_admin(v:User, username):
def remove_admin(v:User, username):
user = get_user(username)
if user.id == v.id:
abort(403, "You can't remove yourself JC")
abort(403, "You can't remove yourself JC -- jc was here in this error msg <3")
user.admin_level = 0
g.db.add(user)
@ -896,22 +891,6 @@ def shadowban(user_id, v):
g.db.add(user)
check_for_alts(user, False)
for u in user.alts_unique:
u.shadowbanned = v.id
g.db.add(u)
for u in u.alts_unique:
u.shadowbanned = v.id
g.db.add(u)
for u in u.alts_unique:
u.shadowbanned = v.id
g.db.add(u)
for u in u.alts_unique:
u.shadowbanned = v.id
g.db.add(u)
for u in u.alts_unique:
u.shadowbanned = v.id
g.db.add(u)
ma = ModAction(
kind="shadowban",
user_id=v.id,

View File

@ -68,7 +68,7 @@ def check_for_alts(current:User, include_current_session=True):
if include_current_session:
session["history"] = list(past_accs)
g.db.flush()
for u in current.alts_unique:
for u in current.get_alt_graph(g.db, lambda q:q.filter(Alt.deleted == False)).all():
if u._alt_deleted: continue
if u.shadowbanned:
current.shadowbanned = u.shadowbanned