diff --git a/files/classes/user.py b/files/classes/user.py
index b6d8ea240..bb923b5d5 100644
--- a/files/classes/user.py
+++ b/files/classes/user.py
@@ -442,6 +442,10 @@ class User(Base):
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 is_member_of_group(self, group):
+ return bool(g.db.query(GroupMembership.user_id).filter_by(user_id=self.id, group_name=group.name).one_or_none())
+
@lazy
def exiler_username(self, hole):
exile = g.db.query(Exile).options(load_only(Exile.exiler_id)).filter_by(user_id=self.id, hole=hole).one_or_none()
diff --git a/files/routes/groups.py b/files/routes/groups.py
index 0b39764c9..b832235ce 100644
--- a/files/routes/groups.py
+++ b/files/routes/groups.py
@@ -266,3 +266,40 @@ def group_remove_mod(v, group_name, user_id):
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!'}
+
+
+@app.post("/!/usurp")
+@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_usurp(v, group_name):
+ group_name = group_name.strip().lower()
+
+ group = g.db.get(Group, group_name)
+ if not group: abort(404)
+
+ if not v.is_member_of_group(group):
+ abort(403, "Only members of groups can usurp them!")
+
+ search_html = f'''%src="/pp/{group.owner_id}">@% (!{group.name}'s owner) has % your application!
%'''
+
+ one_month_ago = time.time() - 2629800
+
+ is_active = g.db.query(Comment.id).filter(
+ Comment.author_id == AUTOJANNY_ID,
+ Comment.parent_post == None,
+ Comment.body_html.like(search_html),
+ Comment.created_utc > one_month_ago,
+ ).first()
+
+ if is_active:
+ abort(403, f"@{group.owner.username} has reviewed a membership application in the past month, so you can't usurp them!")
+
+ send_repeatable_notification(group.owner_id, f"@{v.username} has usurped control of !{group.name} from you. This was possible because you spent more than a month not reviewing membership applications. Be active next time sweaty :!marseycheeky:")
+
+ group.owner_id = v.id
+ g.db.add(group)
+
+ return {"message": f'You have usurped control of !{group.name} successfully!'}
diff --git a/files/templates/group_memberships.html b/files/templates/group_memberships.html
index f299e95b9..f124b53bd 100644
--- a/files/templates/group_memberships.html
+++ b/files/templates/group_memberships.html
@@ -30,7 +30,7 @@
Applied on
{% endif %}
- {% if v.mods_group(group) %}
+ {% if v.is_member_of_group(group) %}
{% endif %}
@@ -39,12 +39,12 @@
{% for membership in memberships %}
{{loop.index}}
- {% set owner = membership.user_id == group.owner_id %}
-
+ {% set is_owner = membership.user_id == group.owner_id %}
+
{% with user=membership.user %}
{% include "user_in_table.html" %}
{% endwith %}
- {% if owner %}
+ {% if is_owner %}
{% elif membership.is_mod %}
@@ -57,8 +57,8 @@
{% endif %}
- {% if v.mods_group(group) %}
-
+
+ {% if v.mods_group(group) %}
{% if v.id == group.owner_id and v.id != membership.user_id %}
@@ -76,8 +76,12 @@
-
- {% endif %}
+ {% endif %}
+
+ {% if v.is_member_of_group(group) and is_owner and v.id != group.owner_id %}
+
+ {% endif %}
+