Aevann 2023-08-08 21:08:29 +03:00
parent 8b1f7baa74
commit 6e02ea8abb
7 changed files with 89 additions and 8 deletions

View File

@ -7321,6 +7321,10 @@ input[type=number] {
height: 50px;
}
.group-mod {
height: 40px;
}
@media (max-width: 768px) {
.award-tab {
font-size: 10px !important;
@ -7343,6 +7347,10 @@ input[type=number] {
.group-owner {
height: 30px;
}
.group-mod {
height: 23px;
}
}
#input-message, #input-message-mobile {

View File

@ -6,6 +6,8 @@ function approve_membership(t, group, uid) {
{
},
() => {
const mod = document.getElementById(`mod-${uid}`)
if (mod) mod.classList.remove('d-none')
document.getElementById(`kick-${uid}`).classList.remove('d-none')
document.getElementById(`time-${uid}`).innerHTML = formatDate(new Date());
document.getElementById(`counter-${uid}`).innerHTML = parseInt(members_tbody.lastElementChild.firstElementChild.innerHTML) + 1

View File

@ -2,7 +2,7 @@ import time
from sqlalchemy import Column, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.types import Integer, String
from sqlalchemy.types import Integer, String, Boolean
from files.classes import Base
@ -12,6 +12,7 @@ class GroupMembership(Base):
group_name = Column(String, ForeignKey("groups.name"), primary_key=True)
created_utc = Column(Integer)
approved_utc = Column(Integer)
is_mod = Column(Boolean, default=False)
user = relationship("User", uselist=False)

View File

@ -393,6 +393,13 @@ class User(Base):
except:
return bool(g.db.query(Mod.user_id).filter_by(user_id=self.id, sub=sub).one_or_none())
@lazy
def mods_group(self, group):
if self.is_permabanned or self.shadowbanned: return False
if self.id == group.owner.id: return True
if self.admin_level >= PERMS['MODS_EVERY_GROUP']: return True
return bool(g.db.query(GroupMembership.user_id).filter_by(user_id=self.id, group_name=group.name, is_mod=True).one_or_none())
@lazy
def exiler_username(self, sub):
exile = g.db.query(Exile).options(load_only(Exile.exiler_id)).filter_by(user_id=self.id, sub=sub).one_or_none()

View File

@ -152,8 +152,8 @@ def group_approve(v, group_name, user_id):
group = g.db.get(Group, group_name)
if not group: abort(404)
if v.id != group.owner.id and v.admin_level < PERMS['MODS_EVERY_GROUP']:
abort(403, f"Only the group owner (@{group.owner.username}) can approve applications!")
if not v.mods_group(group):
abort(403, f"Only the group owner and its mods can approve applications!")
application = g.db.query(GroupMembership).filter_by(user_id=user_id, group_name=group.name).one_or_none()
if not application:
@ -178,8 +178,8 @@ def group_reject(v, group_name, user_id):
group = g.db.get(Group, group_name)
if not group: abort(404)
if v.id != group.owner.id and v.admin_level < PERMS['MODS_EVERY_GROUP']:
abort(403, f"Only the group owner (@{group.owner.username}) can reject memberships!")
if not v.mods_group(group):
abort(403, f"Only the group owner and its mods can reject memberships!")
membership = g.db.query(GroupMembership).filter_by(user_id=user_id, group_name=group.name).one_or_none()
if not membership:
@ -204,3 +204,55 @@ def group_reject(v, group_name, user_id):
g.db.delete(group)
return {"message": msg}
@app.post("/!<group_name>/<user_id>/add_mod")
@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 group_add_mod(v, group_name, user_id):
group_name = group_name.strip().lower()
group = g.db.get(Group, group_name)
if not group: abort(404)
if v.id != group.owner.id:
abort(403, f"Only the group owner (@{group.owner.username}) can add mods!")
membership = g.db.query(GroupMembership).filter_by(user_id=user_id, group_name=group.name).one_or_none()
if not membership:
abort(404, "The user is not a member of the group!")
membership.is_mod = True
g.db.add(membership)
send_repeatable_notification(membership.user_id, f"@{v.username} (!{group}'s owner) has added you as a mod!")
return {"message": f'You have added @{membership.user.username} as a mod successfully!'}
@app.post("/!<group_name>/<user_id>/remove_mod")
@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 group_remove_mod(v, group_name, user_id):
group_name = group_name.strip().lower()
group = g.db.get(Group, group_name)
if not group: abort(404)
if v.id != group.owner.id:
abort(403, f"Only the group owner (@{group.owner.username}) can remove mods!")
membership = g.db.query(GroupMembership).filter_by(user_id=user_id, group_name=group.name).one_or_none()
if not membership:
abort(404, "The user is not a member of the group!")
membership.is_mod = False
g.db.add(membership)
send_repeatable_notification(membership.user_id, f"@{v.username} (!{group}'s owner) has removed you as a mod!")
return {"message": f'You have removed @{membership.user.username} as a mod successfully!'}

View File

@ -31,7 +31,7 @@
<th>Applied on</th>
{% endif %}
{% if v.id == group.owner.id or v.admin_level >= PERMS['MODS_EVERY_GROUP'] %}
{% if v.mods_group(group) %}
<th class="disable-sort-click"></th>
{% endif %}
</tr>
@ -47,6 +47,8 @@
{% endwith %}
{% if owner %}
<img class="mx-2 group-owner" data-bs-toggle="tooltip" alt="Owner" title="Owner" src="{{SITE_FULL_IMAGES}}/e/marseykingretard.webp">
{% elif membership.is_mod %}
<img class="mx-2 group-mod" data-bs-toggle="tooltip" alt="Mod" title="Mod" src="{{SITE_FULL_IMAGES}}/e/marseyjanny.webp">
{% endif %}
</td>
@ -56,8 +58,15 @@
<td id="time-{{membership.user_id}}" data-time="{{membership.created_utc}}"></td>
{% endif %}
{% if v.id == group.owner.id or v.admin_level >= PERMS['MODS_EVERY_GROUP'] %}
{% if v.mods_group(group) %}
<td>
{% if v.id == group.owner.id and v.id != membership.user_id %}
<div id="mod-{{membership.user_id}}" class="mb-2 {% if name == 'applications' %}d-none{% endif %}">
<button id="add-mod-{{membership.user_id}}" type="button" class="btn btn-success btn-block {% if membership.is_mod %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/!{{group.name}}/{{membership.user_id}}/add_mod','add-mod-{{membership.user_id}}','remove-mod-{{membership.user_id}}','d-none')">Add as Mod</button>
<button id="remove-mod-{{membership.user_id}}" type="button" class="btn btn-danger btn-block {% if not membership.is_mod %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/!{{group.name}}/{{membership.user_id}}/remove_mod','add-mod-{{membership.user_id}}','remove-mod-{{membership.user_id}}','d-none')">Remove as Mod</button>
</div>
{% endif %}
<div id="kick-{{membership.user_id}}" {% if name == 'applications' %}class="d-none"{% endif %}>
<button type="button" class="btn btn-primary btn-block" data-nonce="{{g.nonce}}" data-onclick="reject_membership(this,'{{group}}','{{membership.user_id}}')">{% if v.id == membership.user_id %}Leave{% else %}Kick{% endif %}</button>
</div>
@ -75,7 +84,7 @@
</div>
{% endmacro %}
{% if v.id == group.owner.id or v.admin_level >= PERMS['MODS_EVERY_GROUP'] %}
{% if v.mods_group(group) %}
{{process_memberships(applications, 'applications')}}
{{process_memberships(members, 'members')}}
<script defer src="{{'js/group_members_owner.js' | asset}}"></script>

View File

@ -0,0 +1,2 @@
alter table group_memberships add column is_mod bool not null default false;
alter table group_memberships alter column is_mod drop default;