core/resolvers/collab.py

149 lines
6.2 KiB
Python
Raw Normal View History

2025-05-16 06:23:48 +00:00
from auth.orm import Author
2023-12-17 20:30:20 +00:00
from orm.invite import Invite, InviteStatus
from orm.shout import Shout
2023-11-28 10:46:06 +00:00
from services.auth import login_required
from services.db import local_session
from services.schema import mutation
2024-04-17 15:32:23 +00:00
@mutation.field("accept_invite")
2023-11-28 10:46:06 +00:00
@login_required
async def accept_invite(_: None, info, invite_id: int):
2024-04-19 15:22:07 +00:00
author_dict = info.context["author"]
author_id = author_dict.get("id")
if author_id:
author_id = int(author_id)
# Check if the user exists
with local_session() as session:
2023-11-28 10:46:06 +00:00
# Check if the invite exists
invite = session.query(Invite).filter(Invite.id == invite_id).first()
2024-05-30 04:12:00 +00:00
if invite and invite.author_id is author_id and invite.status is InviteStatus.PENDING.value:
2023-11-28 10:46:06 +00:00
# Add the user to the shout authors
shout = session.query(Shout).filter(Shout.id == invite.shout_id).first()
if shout:
2024-04-19 15:22:07 +00:00
if author_id not in shout.authors:
2024-05-30 04:12:00 +00:00
author = session.query(Author).filter(Author.id == author_id).first()
2024-04-19 15:22:07 +00:00
if author:
shout.authors.append(author)
session.add(shout)
session.delete(invite)
session.commit()
2024-04-17 15:32:23 +00:00
return {"success": True, "message": "Invite accepted"}
return {"error": "Shout not found"}
return {"error": "Invalid invite or already accepted/rejected"}
2024-04-19 15:22:07 +00:00
else:
return {"error": "Unauthorized"}
2023-11-28 10:46:06 +00:00
2024-04-17 15:32:23 +00:00
@mutation.field("reject_invite")
2023-11-28 10:46:06 +00:00
@login_required
async def reject_invite(_: None, info, invite_id: int):
2024-04-19 15:22:07 +00:00
author_dict = info.context["author"]
author_id = author_dict.get("id")
if author_id:
# Check if the user exists
with local_session() as session:
author_id = int(author_id)
2023-11-28 10:46:06 +00:00
# Check if the invite exists
invite = session.query(Invite).filter(Invite.id == invite_id).first()
2024-05-30 04:12:00 +00:00
if invite and invite.author_id is author_id and invite.status is InviteStatus.PENDING.value:
2023-11-28 10:46:06 +00:00
# Delete the invite
session.delete(invite)
session.commit()
2024-04-17 15:32:23 +00:00
return {"success": True, "message": "Invite rejected"}
return {"error": "Invalid invite or already accepted/rejected"}
2024-04-19 15:22:07 +00:00
return {"error": "User not found"}
2023-11-28 10:46:06 +00:00
2024-04-17 15:32:23 +00:00
@mutation.field("create_invite")
2023-11-28 10:46:06 +00:00
@login_required
async def create_invite(_: None, info, slug: str = "", author_id: int = 0):
2024-04-19 15:22:07 +00:00
author_dict = info.context["author"]
2025-05-22 01:34:30 +00:00
viewer_id = author_dict.get("id")
roles = info.context.get("roles", [])
is_admin = info.context.get("is_admin", False)
if not viewer_id and not is_admin and "admin" not in roles and "editor" not in roles:
return {"error": "Access denied"}
2024-04-19 15:22:07 +00:00
if author_id:
# Check if the inviter is the owner of the shout
with local_session() as session:
shout = session.query(Shout).filter(Shout.slug == slug).first()
2025-05-22 01:34:30 +00:00
inviter = session.query(Author).filter(Author.id == viewer_id).first()
2024-04-19 15:22:07 +00:00
if inviter and shout and shout.authors and inviter.id is shout.created_by:
2023-11-28 10:46:06 +00:00
# Check if an invite already exists
existing_invite = (
session.query(Invite)
.filter(
2023-11-28 12:56:32 +00:00
Invite.inviter_id == inviter.id,
2023-11-28 10:55:05 +00:00
Invite.author_id == author_id,
2023-11-28 10:46:06 +00:00
Invite.shout_id == shout.id,
2023-11-30 07:38:41 +00:00
Invite.status == InviteStatus.PENDING.value,
2023-11-28 10:46:06 +00:00
)
.first()
)
if existing_invite:
2024-04-17 15:32:23 +00:00
return {"error": "Invite already sent"}
2023-11-28 10:46:06 +00:00
# Create a new invite
new_invite = Invite(
2025-05-22 01:34:30 +00:00
inviter_id=viewer_id,
2024-02-21 07:27:16 +00:00
author_id=author_id,
shout_id=shout.id,
status=InviteStatus.PENDING.value,
2023-11-28 10:46:06 +00:00
)
session.add(new_invite)
session.commit()
2024-04-17 15:32:23 +00:00
return {"error": None, "invite": new_invite}
return {"error": "Invalid author"}
2024-04-19 15:22:07 +00:00
else:
return {"error": "Access denied"}
2023-11-28 10:46:06 +00:00
2024-04-17 15:32:23 +00:00
@mutation.field("remove_author")
2023-11-28 10:46:06 +00:00
@login_required
async def remove_author(_: None, info, slug: str = "", author_id: int = 0):
2025-05-22 01:34:30 +00:00
viewer_id = info.context.get("author", {}).get("id")
is_admin = info.context.get("is_admin", False)
roles = info.context.get("roles", [])
if not viewer_id and not is_admin and "admin" not in roles and "editor" not in roles:
return {"error": "Access denied"}
2023-11-28 10:46:06 +00:00
with local_session() as session:
2025-05-22 01:34:30 +00:00
author = session.query(Author).filter(Author.id == author_id).first()
2023-11-28 10:46:06 +00:00
if author:
shout = session.query(Shout).filter(Shout.slug == slug).first()
# NOTE: owner should be first in a list
2024-01-23 13:04:38 +00:00
if shout and author.id is shout.created_by:
2024-05-30 04:12:00 +00:00
shout.authors = [author for author in shout.authors if author.id != author_id]
2023-11-28 10:46:06 +00:00
session.commit()
return {}
2024-04-17 15:32:23 +00:00
return {"error": "Access denied"}
2023-11-28 10:46:06 +00:00
2024-04-17 15:32:23 +00:00
@mutation.field("remove_invite")
2023-11-28 10:46:06 +00:00
@login_required
async def remove_invite(_: None, info, invite_id: int):
2024-04-19 15:22:07 +00:00
author_dict = info.context["author"]
author_id = author_dict.get("id")
2024-04-23 11:31:34 +00:00
if isinstance(author_id, int):
2024-04-19 15:22:07 +00:00
# Check if the user exists
with local_session() as session:
2023-11-28 10:46:06 +00:00
# Check if the invite exists
invite = session.query(Invite).filter(Invite.id == invite_id).first()
2024-01-23 13:04:38 +00:00
if isinstance(invite, Invite):
shout = session.query(Shout).filter(Shout.id == invite.shout_id).first()
if shout and shout.deleted_at is None and invite:
2024-04-19 15:22:07 +00:00
if invite.inviter_id is author_id or author_id == shout.created_by:
2024-01-23 13:04:38 +00:00
if invite.status is InviteStatus.PENDING.value:
# Delete the invite
session.delete(invite)
session.commit()
return {}
return None
return None
return None
return {"error": "Invalid invite or already accepted/rejected"}
2024-04-19 15:22:07 +00:00
else:
return {"error": "Author not found"}