add owner_id in preparation for next commits

pull/222/head
Aevann 2024-02-11 13:00:37 +02:00
parent 8fd6e59cd2
commit 2fe2264d5c
7 changed files with 21 additions and 20 deletions

View File

@ -14,8 +14,10 @@ class Group(Base):
__tablename__ = "groups"
name = Column(String, primary_key=True)
created_utc = Column(Integer)
owner_id = Column(Integer, ForeignKey("users.id"))
memberships = relationship("GroupMembership", primaryjoin="GroupMembership.group_name==Group.name", order_by="GroupMembership.approved_utc")
owner = relationship("User", primaryjoin="Group.owner_id==User.id")
def __init__(self, *args, **kwargs):
if "created_utc" not in kwargs: kwargs["created_utc"] = int(time.time())
@ -24,11 +26,6 @@ class Group(Base):
def __repr__(self):
return self.name
@property
@lazy
def owner(self):
return self.memberships[0].user
@property
@lazy
def membership_user_ids(self):

View File

@ -438,7 +438,7 @@ class User(Base):
@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.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())

View File

@ -87,7 +87,7 @@ def join_group(v, group_name):
if not existing:
join = GroupMembership(user_id=v.id, group_name=group_name)
g.db.add(join)
send_notification(group.owner.id, f"@{v.username} has applied to join !{group}. You can approve or reject the application [here](/!{group}).")
send_notification(group.owner_id, f"@{v.username} has applied to join !{group}. You can approve or reject the application [here](/!{group}).")
return {"message": f"Application submitted to !{group}'s owner (@{group.owner.username}) successfully!"}
@ -111,7 +111,7 @@ def leave_group(v, group_name):
text = f"@{v.username} has cancelled their application to !{group}"
msg = f"You have cancelled your application to !{group} successfully!"
send_notification(group.owner.id, text)
send_notification(group.owner_id, text)
g.db.delete(existing)
return {"message": msg}
@ -188,10 +188,10 @@ def group_reject(v, group_name, user_id):
abort(404, "There is no membership to reject!")
if v.id != membership.user_id: #implies kicking and not leaving
if membership.user_id == group.owner.id:
if membership.user_id == group.owner_id:
abort(403, "You can't kick the group owner!")
if v.id != group.owner.id and membership.is_mod:
if v.id != group.owner_id and membership.is_mod:
abort(403, "Only the group owner can kick mods!")
if v.id == membership.user_id:
@ -227,7 +227,7 @@ def group_add_mod(v, group_name, user_id):
group = g.db.get(Group, group_name)
if not group: abort(404)
if v.id != group.owner.id:
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()
@ -253,7 +253,7 @@ def group_remove_mod(v, group_name, user_id):
group = g.db.get(Group, group_name)
if not group: abort(404)
if v.id != group.owner.id:
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()

View File

@ -1,7 +1,7 @@
{% extends "default.html" %}
{% block pagetitle %}!{{group}}{% endblock %}
{% block content %}
{% if v.id != group.owner.id %}
{% if v.id != group.owner_id %}
<button id="leave-{{group}}" type="button" class="mt-4 btn btn-danger btn-block {% if v.id not in group.membership_user_ids %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/!{{group}}/leave','leave-{{group}}','apply-{{group}}','d-none')">
{%- if v.id in group.member_ids or group.name == 'verifiedrich' -%}
Leave
@ -39,7 +39,7 @@
{% for membership in memberships %}
<tr id="{{membership.user_id}}">
<td id="counter-{{membership.user_id}}">{{loop.index}}</td>
{% set owner = name == 'members' and loop.index == 1 %}
{% set owner = membership.user_id == group.owner_id %}
<td {% if owner %}class="unbreakable"{% endif %}>
{% with user=membership.user %}
{% include "user_in_table.html" %}
@ -59,14 +59,14 @@
{% if v.mods_group(group) %}
<td>
{% if v.id == group.owner.id and v.id != membership.user_id %}
{% 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 %}
{% if v.id == membership.user_id or v.id == group.owner.id or not membership.user.mods_group(group) %}
{% if v.id == membership.user_id or v.id == group.owner_id or not membership.user.mods_group(group) %}
<div id="kick-{{membership.user_id}}" {% if name == 'applications' %}class="d-none"{% endif %}>
<button type="button" class="btn btn-danger 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>

View File

@ -43,7 +43,7 @@
<td>{{group.name}}</td>
<td class="unbreakable">
<a href="/!{{group}}">{{group.member_ids | length}}</a>
{% if v.id != group.owner.id %}
{% if v.id != group.owner_id %}
<button id="leave-{{group}}" type="button" class="ml-3 ml-md-5 btn btn-primary {% if v.id not in group.membership_user_ids %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/!{{group}}/leave','leave-{{group}}','apply-{{group}}','d-none')">
{%- if v.id in group.member_ids or group.name == 'verifiedrich' -%}
Leave

View File

@ -170,8 +170,8 @@
<div class="text-white rounded p-2 mb-3" id="profile--groups" style="background-color: rgba(50, 50, 50, 0.6); width: 30%">
<p class="text-uppercase my-0 pb-1" style="font-weight: bold; font-size: 12px">Member of</p>
{% for i in u.group_memberships %}
{% set is_owner = (u.id == i[1].owner.id) %}
<span class="d-inline-block mx-1 {% if u.id == i[1].owner.id %}font-weight-bolder{% endif %}" {% if is_owner %}data-bs-toggle="tooltip" data-bs-placement="bottom" title="Owner"{% endif %}>
{% set is_owner = (u.id == i[1].owner_id) %}
<span class="d-inline-block mx-1 {% if u.id == i[1].owner_id %}font-weight-bolder{% endif %}" {% if is_owner %}data-bs-toggle="tooltip" data-bs-placement="bottom" title="Owner"{% endif %}>
<a href="/!{{i[0]}}" {% if is_owner %}style="color: #bbb !important"{% endif %}>!{{i[0]}}</a>
</span>
{% endfor %}
@ -476,7 +476,7 @@
<div class="text-white rounded p-2 mt-3 mb-3" id="profile-mobile--groups" style="background-color: rgba(50, 50, 50, 0.6)">
<p class="text-uppercase my-0 pb-1" style="font-weight: bold; font-size: 12px">Member of</p>
{% for i in u.group_memberships %}
{% set is_owner = (u.id == i[1].owner.id) %}
{% set is_owner = (u.id == i[1].owner_id) %}
<span class="d-inline-block mx-1 {% if is_owner %}font-weight-bolder{% endif %}" {% if is_owner %}data-bs-toggle="tooltip" data-bs-placement="bottom" title="Owner"{% endif %}>
<a href="/!{{i[0]}}" {% if is_owner %}style="color: #bbb !important"{% endif %}>!{{i[0]}}</a>
</span>

View File

@ -0,0 +1,4 @@
alter table groups add column owner_id int;
alter table only groups
add constraint groups_user_fkey foreign key (owner_id) references public.users(id);