user can_view functions (#460)

* user: move can_see_to user class

* stub out can_see in comments and posts

* make can_see a classmethod so it's usable for loggedoutfriends

* test

* kill me now

* threelargeclassesmating

* dfdfdfdfdfdfd

* sdsdsdsd

* classmethod should be above i think

* Revert "classmethod should be above i think"

This reverts commit df1772eb9e7e71bf7b89123f6277b648de2b1af3.

* Revert "Revert "classmethod should be above i think""

This reverts commit 32883406c2e2916fc6c436611376a1817c16cb84.

* test rewritnig thing

* go home python

* what the fuck python

* fix AttributeError

* sdsdsdsdsdsd

* lazy and user and stuff

* test

* Revert "test"

This reverts commit 45af5bb3d45f3ec17126ab117d494ec978062a38.

* merge

* newline

* test

* test 2

* Revert "test"

This reverts commit 196dae677e2ee8cd29261c93dcb747087cb399b6.

* revert test

* fix merge error

* fix import error ciruclation i think

* sdsd

* add type annotations back

* deleted_utc

* isinstance

* user_can_see in jinja and remove unnecessary things

* a bunch of stuff
remove can_see from comment and post
expand can_see to messages

* antiannoyingamountsofwhitespace

* fix for chudrama

* improve prev
pull/20/head
justcool393 2022-11-17 13:02:08 -08:00 committed by GitHub
parent d80fa23409
commit 83963470e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 64 additions and 46 deletions

View File

@ -82,17 +82,6 @@ class Comment(Base):
def __repr__(self):
return f"<Comment(id={self.id})>"
@lazy
def can_see(self, v):
if SITE != 'rdrama.net': return True
if not self.parent_submission: return True
if self.post.sub != 'chudrama': return True
if v:
if v.can_see_chudrama: return True
if v.id == self.author_id: return True
if v.id == self.post.author_id: return True
return False
@lazy
def top_comment(self, db:scoped_session):
return db.get(Comment, self.top_comment_id)

View File

@ -76,22 +76,12 @@ class Submission(Base):
def __repr__(self):
return f"<Submission(id={self.id})>"
@lazy
def can_see(self, v):
if SITE != 'rdrama.net': return True
if self.sub != 'chudrama': return True
if v:
if v.can_see_chudrama: return True
if v.id == self.author_id: return True
return False
@property
@lazy
def controversial(self):
if self.downvotes > 5 and 0.25 < self.upvotes / self.downvotes < 4: return True
return False
@property
@lazy
def created_datetime(self):
@ -115,8 +105,7 @@ class Submission(Base):
@property
@lazy
def fullname(self):
return f"p_{self.id}"
return f"p_{self.id}"
@property
@lazy

View File

@ -1,5 +1,6 @@
import random
from operator import *
from typing import Union
import pyotp
from sqlalchemy import Column, ForeignKey
@ -943,7 +944,56 @@ class User(Base):
if self.patron == 6:
return 'Contributed at least $200'
return ''
@classmethod
def can_see_content(cls, user:Optional["User"], other:Union["Submission", "Comment", Sub]) -> bool:
'''
Whether a user can see this item (be it a submission or comment)'s content.
If False, they won't be able to view its content.
'''
from files.classes.submission import Submission
from files.classes.comment import Comment
if not cls.can_see(user, other): return False
if user and user.admin_level >= PERMS["POST_COMMENT_MODERATION"]: return True
if isinstance(other, (Submission, Comment)):
if user and user.id == other.author_id: return True
if other.is_banned: return False
if other.deleted_utc: return False
if other.author.shadowbanned and not (user and user.can_see_shadowbanned): return False
if isinstance(other, Submission):
if other.club and not (user and user.paid_dues): return False
if other.sub == 'chudrama' and not (user and user.can_see_chudrama): return False
else:
if other.parent_submission and not cls.can_see_content(user, other.post): return False
return True
@classmethod
def can_see(cls, user:Optional["User"], other:Union["Submission", "Comment", "Sub", "User"]) -> bool:
'''
Whether a user can strictly see this item. can_see_content is used where
content of a thing can be hidden from view
'''
from files.classes.submission import Submission
from files.classes.comment import Comment
if isinstance(other, (Submission, Comment)):
if not cls.can_see(user, other.author): return False
if user and user.id == other.author_id: return True
if isinstance(other, Submission):
if other.sub and not cls.can_see(user, other.subr): return False
else:
if not other.parent_submission:
if not user: return False
if other.sentto == 2: return user.admin_level >= PERMS['VIEW_MODMAIL'] # type: ignore
if other.sentto != user.id: return user.admin_level >= PERMS['POST_COMMENT_MODERATION'] # type: ignore
if other.parent_submission and other.post.sub and not cls.can_see(user, other.post.subr): return False
# if other.parent_submission and not cls.can_see(user, other.post): return False
elif isinstance(other, Sub):
return other.name != 'chudrama' or (user and user.can_see_chudrama)
elif isinstance(other, User):
return (user and user.id == other.id) or (user and user.can_see_shadowbanned) or not other.shadowbanned
return True
@property
@lazy
def can_see_chudrama(self):

View File

@ -32,19 +32,14 @@ WORDLE_COLOR_MAPPINGS = {-1: "🟥", 0: "🟨", 1: "🟩"}
@auth_desired_with_logingate
def post_pid_comment_cid(cid, pid=None, anything=None, v=None, sub=None):
comment = get_comment(cid, v=v)
if not comment.can_see(v): abort(403)
if comment.author.shadowbanned and not (v and v.can_see_shadowbanned):
abort(404)
if not User.can_see(v, comment): abort(404)
if comment.post and comment.post.club and not User.can_see_content(v, comment): abort(403)
if v and request.values.get("read"):
notif = g.db.query(Notification).filter_by(comment_id=cid, user_id=v.id, read=False).one_or_none()
if notif:
notif.read = True
g.db.add(notif)
if comment.post and comment.post.club and not (v and (v.paid_dues or v.id in [comment.author_id, comment.post.author_id])): abort(403)
if not comment.parent_submission and not (v and (comment.author.id == v.id or comment.sentto == v.id)) and not (v and v.admin_level >= PERMS['POST_COMMENT_MODERATION']) : abort(403)
if not pid:
if comment.parent_submission: pid = comment.parent_submission
@ -118,7 +113,7 @@ def comment(v):
if parent_post.club and not (v and (v.paid_dues or v.id == parent_post.author_id)): abort(403)
if not parent.can_see(v): abort(404)
if not User.can_see(v, parent): abort(404)
if parent.deleted_utc != 0: abort(404)
if level > COMMENT_MAX_DEPTH: abort(400, f"Max comment level is {COMMENT_MAX_DEPTH}")

View File

@ -42,9 +42,8 @@ def front_all(v, sub=None, subdomain=None):
return redirect('/')
#### WPD TEMP #### end special front logic
if sub:
sub = sub.strip().lower()
if sub == 'chudrama' and not (v and v.can_see_chudrama): abort(403)
sub = get_sub_by_name(sub, graceful=True)
if sub and not User.can_see(v, sub): abort(403)
if (request.path.startswith('/h/') or request.path.startswith('/s/')) and not sub: abort(404)
@ -172,12 +171,9 @@ def frontlist(v=None, sort="hot", page=1, t="all", ids_only=True, filter_words='
if SITE_NAME == 'rDrama':
pins = pins.order_by(Submission.author_id != LAWLZ_ID)
pins = pins.order_by(Submission.created_utc.desc()).all()
posts = pins + posts
if ids_only: posts = [x.id for x in posts]
return posts, next_exists

View File

@ -4,6 +4,7 @@ from os import environ, listdir, path
from jinja2 import pass_context
from files.classes.user import User
from files.helpers.assetcache import assetcache_path
from files.helpers.const import *
from files.helpers.settings import get_settings
@ -56,7 +57,7 @@ def inject_constants():
"KOFI_TOKEN":KOFI_TOKEN, "KOFI_LINK":KOFI_LINK,
"approved_embed_hosts":approved_embed_hosts,
"site_settings":get_settings(), "EMAIL":EMAIL, "calc_users":calc_users,
"max": max, "min": min,
"max": max, "min": min, "user_can_see":User.can_see,
"TELEGRAM_LINK":TELEGRAM_LINK, "EMAIL_REGEX_PATTERN":EMAIL_REGEX_PATTERN,
"CONTENT_SECURITY_POLICY_DEFAULT":CONTENT_SECURITY_POLICY_DEFAULT,
"CONTENT_SECURITY_POLICY_HOME":CONTENT_SECURITY_POLICY_HOME,
@ -65,5 +66,5 @@ def inject_constants():
"HOUSE_JOIN_COST":HOUSE_JOIN_COST, "HOUSE_SWITCH_COST":HOUSE_SWITCH_COST, "IMAGE_FORMATS":IMAGE_FORMATS,
"PAGE_SIZES":PAGE_SIZES, "THEMES":THEMES, "COMMENT_SORTS":COMMENT_SORTS, "SORTS":SORTS,
"TIME_FILTERS":TIME_FILTERS, "HOUSES":HOUSES, "TIERS_ID_TO_NAME":TIERS_ID_TO_NAME,
"DEFAULT_CONFIG_VALUE":DEFAULT_CONFIG_VALUE
"DEFAULT_CONFIG_VALUE":DEFAULT_CONFIG_VALUE,
}

View File

@ -137,7 +137,8 @@ def submit_get(v, sub=None):
@auth_desired_with_logingate
def post_id(pid, anything=None, v=None, sub=None):
post = get_post(pid, v=v)
if not post.can_see(v): abort(403)
if not User.can_see(v, post): abort(403)
if not User.can_see_content(v, post) and post.club: abort(403)
if post.over_18 and not (v and v.over_18) and session.get('over_18', 0) < int(time.time()):
if g.is_api_or_xhr: return {"error":"Must be 18+ to view"}, 451
@ -148,8 +149,6 @@ def post_id(pid, anything=None, v=None, sub=None):
else: defaultsortingcomments = "hot"
sort = request.values.get("sort", defaultsortingcomments)
if post.club and not (v and (v.paid_dues or v.id == post.author_id)): abort(403)
if v:
execute_shadowban_viewers_and_voters(v, post)
# shadowban check is done in sort_objects

View File

@ -50,12 +50,11 @@ def vote_post_comment(target_id, new, v, cls, vote_cls):
target = get_post(target_id)
elif cls == Comment:
target = get_comment(target_id)
if not target.post: abort(404)
if not target.parent_submission: abort(404)
else:
abort(404)
if target.author.shadowbanned and not v.can_see_shadowbanned:
abort(404)
if not User.can_see(v, target): abort(404)
coin_delta = 1
if v.id == target.author.id:

View File

@ -739,7 +739,7 @@
{% endif %}
{% endmacro %}
{% for comment in comments if comment.can_see(v) %}
{% for comment in comments if user_can_see(v, comment) %}
{{single_comment(comment)}}
{% endfor %}

View File

@ -20,7 +20,7 @@
{% include "popover.html" %}
{% for p in listing if p.can_see(v) %}
{% for p in listing if user_can_see(v, p) %}
{% set ups=p.upvotes %}
{% set downs=p.downvotes %}