Enforce permissions on submissions via email

This commit is contained in:
Drew DeVault 2019-04-29 14:48:20 -04:00
parent b765014994
commit 9a5d256e53
3 changed files with 19 additions and 12 deletions

View File

@ -42,3 +42,4 @@ tasks:
- deploy: |
ssh $master doas apk upgrade -U
ssh -t $master doas service $project restart
ssh -t $master doas service $project-lmtp restart

View File

@ -22,7 +22,7 @@ import sys
loop = asyncio.new_event_loop()
class MailHandler:
def lookup_destination(self, address):
def lookup_destination(self, address, sender):
# Address formats are:
# Tracker (opening a new ticket):
# ~username/tracker@todo.sr.ht
@ -65,7 +65,7 @@ class MailHandler:
else:
# TODO: user groups
return None, None
return get_tracker(owner, tracker_name)
return get_tracker(owner, tracker_name, sender)
async def handle_RCPT(self, server, session,
envelope, address, rcpt_options):
@ -99,17 +99,21 @@ class MailHandler:
async def handle_DATA(self, server, session, envelope):
address = envelope.rcpt_tos[0]
dest, access = self.lookup_destination(address)
_from = parseaddr(mail["From"])
sender = User.query.filter(User.email == _from[1]).one_or_none()
dest, access = self.lookup_destination(address, sender)
if dest is None:
print("Rejected, destination not found")
return "550 The tracker or ticket you requested does not exist."
if not TicketAccess.submit in access:
print("Rejected, insufficient permissions")
return "550 You do not have permission to post on this tracker."
mail = email.message_from_bytes(envelope.content,
policy=email.policy.SMTP)
_from = parseaddr(mail["From"])
sender = User.query.filter(User.email == _from[1]).one_or_none()
body = None
for part in mail.walk():
if part.is_multipart():

View File

@ -2,12 +2,14 @@ from flask_login import current_user
from todosrht.types import User, Tracker, Ticket
from todosrht.types import TicketAccess
def get_access(tracker, ticket):
def get_access(tracker, ticket, user=None):
if user == None:
user = current_user
# TODO: flesh out
if current_user and current_user.id == tracker.owner_id:
if user and user.id == tracker.owner_id:
return TicketAccess.all
elif current_user:
if ticket and current_user.id == ticket.submitter_id:
elif user:
if ticket and user.id == ticket.submitter_id:
return ticket.submitter_perms or tracker.default_submitter_perms
return tracker.default_user_perms
@ -18,7 +20,7 @@ def get_access(tracker, ticket):
def get_owner(owner):
pass
def get_tracker(owner, name, with_for_update=False):
def get_tracker(owner, name, with_for_update=False, user=None):
if not owner:
return None, None
@ -36,7 +38,7 @@ def get_tracker(owner, name, with_for_update=False):
tracker = tracker.one_or_none()
if not tracker:
return None, None
access = get_access(tracker, None)
access = get_access(tracker, None, user=user)
if access:
return tracker, access