todo.sr.ht/todosrht/access.py

73 lines
2.2 KiB
Python
Raw Normal View History

2019-11-30 16:17:42 +01:00
from srht.oauth import current_user
from todosrht.types import User, Tracker, Ticket
from todosrht.types import TicketAccess, UserAccess
def _get_permissions(tracker, ticket, name):
"""
Return ticket permissions of given name, fall back to tracker defaults.
"""
if ticket and getattr(ticket, f"{name}_perms"):
return getattr(ticket, f"{name}_perms")
return getattr(tracker, f"default_{name}_perms")
2019-08-21 08:35:44 +02:00
# TODO: get_access for any participant
def get_access(tracker, ticket, user=None):
user = user or current_user
# Anonymous
if not user:
return _get_permissions(tracker, ticket, "anonymous")
# Owner
if user.id == tracker.owner_id:
return TicketAccess.all
# Per-user access specified
user_access = UserAccess.query.filter_by(tracker=tracker, user=user).first()
if user_access:
return user_access.permissions
# Submitter
2019-08-21 08:35:44 +02:00
if ticket and user.id == ticket.submitter.user_id:
return _get_permissions(tracker, ticket, "submitter")
# Any logged in user
return _get_permissions(tracker, ticket, "user")
def get_tracker(owner, name, with_for_update=False, user=None):
if not owner:
return None, None
if not isinstance(owner, User):
if owner.startswith("~"):
owner = owner[1:]
owner = User.query.filter(User.username == owner).one_or_none()
if not owner:
return None, None
2018-07-11 14:21:20 +02:00
tracker = (Tracker.query
.filter(Tracker.owner_id == owner.id)
2019-11-06 20:04:21 +01:00
.filter(Tracker.name.ilike(name)))
2018-07-11 14:21:20 +02:00
if with_for_update:
tracker = tracker.with_for_update()
tracker = tracker.one_or_none()
if not tracker:
return None, None
access = get_access(tracker, None, user=user)
2018-07-11 14:21:20 +02:00
if access:
return tracker, access
# TODO: org trackers
return None, None
def get_ticket(tracker, ticket_id, user=None):
ticket = (Ticket.query
.filter(Ticket.scoped_id == ticket_id)
2018-06-26 02:52:25 +02:00
.filter(Ticket.tracker_id == tracker.id)).one_or_none()
if not ticket:
return None, None
access = get_access(tracker, ticket, user=user)
if not TicketAccess.browse in access:
return None, None
return ticket, access