user private profile restrictions (#652)

This commit is contained in:
justcool393 2023-07-27 04:07:04 -07:00 committed by GitHub
parent 56cfed43f9
commit c6d3cbdba9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 70 additions and 8 deletions

View file

@ -171,6 +171,25 @@ class User(CreatedBase):
accountAgeDays = self.age_timedelta.days accountAgeDays = self.age_timedelta.days
return self.comment_count < minComments or accountAgeDays < minAge or self.truecoins < minKarma return self.comment_count < minComments or accountAgeDays < minAge or self.truecoins < minKarma
def can_change_user_privacy(self, v: "User") -> bool:
from files.__main__ import app # avoiding import loop
if v.admin_level >= PERMS['USER_SET_PROFILE_PRIVACY']: return True
if self.id != v.id: return False # non-admin changing someone else's things, hmm...
# TODO: move settings out of app.config
site_settings = app.config['SETTINGS']
min_comments: int = site_settings.get('min_comments_private_profile', 0)
min_truescore: int = site_settings.get('min_truescore_private_profile', 0)
min_age_days: int = site_settings.get('min_age_days_private_profile', 0)
user_age_days: int = self.age_timedelta.days
return (
self.comment_count >= min_comments
and self.truecoins >= min_truescore
and user_age_days >= min_age_days)
@property @property
@lazy @lazy
def csslazy(self): def csslazy(self):

View file

@ -152,6 +152,7 @@ PERMS = {
"SCHEDULER_POSTS": 2, "SCHEDULER_POSTS": 2,
"SCHEDULER_TASK_TRACEBACK": 3, "SCHEDULER_TASK_TRACEBACK": 3,
"USER_SHADOWBAN": 2, "USER_SHADOWBAN": 2,
'USER_SET_PROFILE_PRIVACY': 2,
} }
AWARDS = {} AWARDS = {}

View file

@ -65,10 +65,6 @@ def settings_profile_post(v):
updated = True updated = True
v.over_18 = request.values.get("over18") == 'true' v.over_18 = request.values.get("over18") == 'true'
elif request.values.get("private", v.is_private) != v.is_private:
updated = True
v.is_private = request.values.get("private") == 'true'
elif request.values.get("nofollow", v.is_nofollow) != v.is_nofollow: elif request.values.get("nofollow", v.is_nofollow) != v.is_nofollow:
updated = True updated = True
v.is_nofollow = request.values.get("nofollow") == 'true' v.is_nofollow = request.values.get("nofollow") == 'true'
@ -640,3 +636,16 @@ def settings_profile(v):
if v.flairchanged: ti = datetime.utcfromtimestamp(v.flairchanged).strftime('%Y-%m-%d %H:%M:%S') if v.flairchanged: ti = datetime.utcfromtimestamp(v.flairchanged).strftime('%Y-%m-%d %H:%M:%S')
else: ti = '' else: ti = ''
return render_template("settings_profile.html", v=v, ti=ti) return render_template("settings_profile.html", v=v, ti=ti)
# other settings i guess
@app.post("/id/<int:id>/private/<int:enabled>")
@auth_required
def post_set_user_profile_privacy(v: User, id: int, enabled: int):
if enabled != 0 and enabled != 1: abort(400, "'enabled' must be '0' or '1'")
user: User = get_account(id)
if not user.can_change_user_privacy(v): abort(403)
user.is_private = bool(enabled)
g.db.commit()
return {"message": f"{'Enabled' if user.is_private else 'Disabled'} private mode successfully!"}

View file

@ -803,6 +803,7 @@ def u_user_id_info(id, v=None):
return user.json return user.json
@app.post("/follow/<username>") @app.post("/follow/<username>")
@limiter.limit("1/second;30/minute;200/hour;1000/day") @limiter.limit("1/second;30/minute;200/hour;1000/day")
@auth_required @auth_required

View file

@ -103,6 +103,11 @@
{{site_setting_int('FilterCommentsMinKarma', 'Minimum Karma')}} {{site_setting_int('FilterCommentsMinKarma', 'Minimum Karma')}}
{{site_setting_int('FilterCommentsMinAgeDays', 'Minimum Account Age (Days)')}} {{site_setting_int('FilterCommentsMinAgeDays', 'Minimum Account Age (Days)')}}
<h4>Private Mode Requirements</h4>
{{site_setting_int('min_comments_private_profile', 'Minimum Comments')}}
{{site_setting_int('min_truescore_private_profile', 'Minimum Karma')}}
{{site_setting_int('min_age_days_private_profile', 'Minimum Account Age (Days)')}}
<button class="btn btn-primary mt-3" onclick="post_toast(this,'/admin/purge_cache');">PURGE CDN CACHE</button> <button class="btn btn-primary mt-3" onclick="post_toast(this,'/admin/purge_cache');">PURGE CDN CACHE</button>
<button class="btn btn-primary mt-3" onclick="post_toast(this,'/admin/dump_cache');">DUMP INTERNAL CACHE</button> <button class="btn btn-primary mt-3" onclick="post_toast(this,'/admin/dump_cache');">DUMP INTERNAL CACHE</button>
{% endif %} {% endif %}

View file

@ -274,16 +274,23 @@
</form> </form>
</div> </div>
</div> </div>
{%- set can_change_profile_privacy = v.can_change_user_privacy(v) -%}
<div class="d-lg-flex border-bottom"> <div class="d-lg-flex border-bottom">
<div class="title w-lg-25"> <div class="title w-lg-25">
<label for="privateswitch">Private Mode</label> <label for="privateswitch">Private Mode</label>
</div> </div>
<div class="body w-lg-100"> <div class="body w-lg-100">
<div class="custom-control custom-switch"> <div class="custom-control custom-switch">
<input autocomplete="off" type="checkbox" class="custom-control-input" id="privateswitch" name="private"{% if v.is_private%} checked{% endif %} onchange="post_toast(this,'/settings/profile?private='+document.getElementById('privateswitch').checked)"> <input autocomplete="off" type="checkbox" class="custom-control-input" id="privateswitch" name="private"{% if v.is_private %} checked{% endif %}{% if not can_change_profile_privacy %} disabled{% endif %} onchange="post_toast(this,'/id/{{v.id}}/private/' + (this.checked ? '1' : '0'));">
<label class="custom-control-label" for="privateswitch"></label> <label class="custom-control-label" for="privateswitch"></label>
</div> </div>
<span class="text-small-extra text-muted">This will hide your post and comment history from others. We will also ask search engines to not index your profile page. (Your content will still be accessible via direct link.)</span> <span class="text-small-extra text-muted">
{%- if can_change_profile_privacy -%}
This will hide your post and comment history from others. We will also ask search engines to not index your profile page. (Your content will still be accessible via direct link.)
{%- else -%}
If you want to hide your post and comment history from others, please <a href="/contact">contact us</a> and we'll review your request. (Your content will still be accessible via direct link.)
{%- endif -%}
</span>
</div> </div>
</div> </div>
<div class="d-lg-flex border-bottom"> <div class="d-lg-flex border-bottom">

View file

@ -250,6 +250,10 @@
<button id="grant2" class="{% if u.paid_dues %}d-none{% endif %} btn btn-success" onclick="post_toast2(this,'/@{{u.username}}/club_allow','grant2','bar2')">Grant club access</button> <button id="grant2" class="{% if u.paid_dues %}d-none{% endif %} btn btn-success" onclick="post_toast2(this,'/@{{u.username}}/club_allow','grant2','bar2')">Grant club access</button>
<button id="bar2" class="{% if u.club_allowed == False %}d-none{% endif %} btn btn-danger" onclick="post_toast2(this,'/@{{u.username}}/club_ban','grant2','bar2')">Bar from club</button> <button id="bar2" class="{% if u.club_allowed == False %}d-none{% endif %} btn btn-danger" onclick="post_toast2(this,'/@{{u.username}}/club_ban','grant2','bar2')">Bar from club</button>
{% endif %} {% endif %}
{% if v and v.admin_level >= PERMS['USER_SET_PROFILE_PRIVACY'] %}
<a id="private-desktop" class="{% if u.is_private %}d-none{% endif %} btn btn-danger" role="button" onclick="post_toast2(this,'/id/{{u.id}}/private/1','private-desktop','unprivate-desktop')">Set Private Mode</a>
<a id="unprivate-desktop" class="{% if not u.is_private %}d-none{% endif %} btn btn-danger" role="button" onclick="post_toast2(this,'/id/{{u.id}}/private/0','private-desktop','unprivate-desktop')">Unset Private Mode</a>
{% endif %}
<pre></pre> <pre></pre>
<p>User ID: {{u.id}}</p> <p>User ID: {{u.id}}</p>
@ -496,6 +500,10 @@
</form> </form>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if v and v.admin_level >= PERMS['USER_SET_PROFILE_PRIVACY'] %}
<a id="private-mobile" class="{% if u.is_private %}d-none{% endif %} btn btn-danger" role="button" onclick="post_toast2(this,'/id/{{u.id}}/private/1','private-mobile','unprivate-mobile')">Set Private Mode</a>
<a id="unprivate-mobile" class="{% if not u.is_private %}d-none{% endif %} btn btn-danger" role="button" onclick="post_toast2(this,'/id/{{u.id}}/private/0','private-mobile','unprivate-mobile')">Unset Private Mode</a>
{% endif %}
<pre></pre> <pre></pre>
<p>User ID: {{u.id}}</p> <p>User ID: {{u.id}}</p>
@ -513,6 +521,7 @@
{% if u.is_suspended %} {% if u.is_suspended %}
<p>Banned by: <a href="{{u.banned_by.url}}">@{{u.banned_by.username}}</a></p> <p>Banned by: <a href="{{u.banned_by.url}}">@{{u.banned_by.username}}</a></p>
{% endif %} {% endif %}
</div> </div>
</div> </div>
</div> </div>

View file

@ -1 +1,12 @@
{"Bots": true, "Read-only mode": false, "Signups": true, "FilterNewPosts": false, "FilterCommentsMinComments": 0, "FilterCommentsMinKarma": 0, "FilterCommentsMinAgeDays": 0} {
"Bots": true,
"Read-only mode": false,
"Signups": true,
"FilterNewPosts": false,
"FilterCommentsMinComments": 0,
"FilterCommentsMinKarma": 0,
"FilterCommentsMinAgeDays": 0,
"min_comments_private_profile": 0,
"min_truescore_private_profile": 0,
"min_age_days_private_profile": 0
}