def _accept_comm(self, comm, text): """Accept a communication onto the site""" comm.communication = text comm.hidden = False comm.create_agency_notifications() comm.save() task = ResponseTask.objects.create(communication=comm) classify_status.apply_async(args=(task.pk,), countdown=30 * 60) PortalCommunication.objects.create( communication=comm, sent_datetime=timezone.now(), portal=self.portal, direction='incoming', )
def _handle_request(request, mail_id): """Handle incoming mailgun FOI request messages""" # this function needs to be refactored # pylint: disable=broad-except # pylint: disable=too-many-locals # pylint: disable=too-many-branches # pylint: disable=too-many-statements post = request.POST from_email, to_emails, cc_emails = _parse_email_headers(post) subject = post.get('Subject') or post.get('subject', '') try: foia = FOIARequest.objects.get(mail_id=mail_id) # extra logging for next request portals for now if foia.portal and foia.portal.type == 'nextrequest': _log_mail(request) if foia.deleted: if from_email is not None: EmailMessage( subject='Request Withdrawn: {}'.format(subject), body=render_to_string('text/foia/deleted_autoreply.txt'), from_email=foia.get_request_email(), to=[unicode(from_email)], bcc=['*****@*****.**'], ).send(fail_silently=False) return HttpResponse('WARNING') if from_email is not None: email_allowed = from_email.allowed(foia) else: email_allowed = False if not email_allowed: msg, reason = ('Bad Sender', 'bs') if foia.block_incoming: msg, reason = ('Incoming Blocked', 'ib') if not email_allowed or foia.block_incoming: logger.warning('%s: %s', msg, from_email) comm = _make_orphan_comm( from_email, to_emails, cc_emails, subject, post, request.FILES, foia, ) OrphanTask.objects.create(reason=reason, communication=comm, address=mail_id) return HttpResponse('WARNING') # if this isn't a known email for this agency, add it if not from_email.agencies.filter(pk=foia.agency.pk).exists(): AgencyEmail.objects.create( agency=foia.agency, email=from_email, ) # if this request is using a portal, hide the incoming messages hidden = foia.portal is not None with transaction.atomic(): comm = FOIACommunication.objects.create( foia=foia, from_user=foia.agency.get_user(), to_user=foia.user, subject=subject[:255], response=True, datetime=timezone.now(), communication=_get_mail_body(post, foia), hidden=hidden, ) email_comm = EmailCommunication.objects.create( communication=comm, sent_datetime=timezone.now(), from_email=from_email, ) email_comm.to_emails.set(to_emails) email_comm.cc_emails.set(cc_emails) RawEmail.objects.create( email=email_comm, raw_email='%s\n%s' % (post.get('message-headers', ''), post.get('body-plain', ''))) comm.process_attachments(request.FILES) transaction.on_commit(lambda: download_links(comm.pk)) # attempt to autodetect a known portal _detect_portal(comm, from_email.email, post) # if agency isn't currently using an outgoing email or a portal, flag it if (not foia.agency.get_emails().exists() and not foia.agency.portal and not FlaggedTask.objects.filter( agency=foia.agency, category='agency new email').exists()): FlaggedTask.objects.create( agency=foia.agency, foia=foia, category='agency new email', text='We received an email from {} for a request to this ' 'agency, but this agency does not currently have a primary ' 'email address set'.format(from_email, ), ) comm.extract_tracking_id() if foia.portal: foia.portal.receive_msg(comm) else: task = comm.responsetask_set.create() classify_status.apply_async(args=(task.pk, ), countdown=30 * 60) comm.create_agency_notifications() muckrock_domains = (settings.MAILGUN_SERVER_NAME, 'muckrock.com') new_cc_emails = [ e for e in (to_emails + cc_emails) if e.domain not in muckrock_domains ] if from_email.domain not in muckrock_domains: foia.email = from_email foia.cc_emails.set(new_cc_emails) if foia.status == 'ack': foia.status = 'processed' foia.save(comment='incoming mail') except FOIARequest.DoesNotExist: logger.warning('Invalid Address: %s', mail_id) try: # try to get the foia by the PK before the dash foia = FOIARequest.objects.get(pk=mail_id.split('-')[0]) except FOIARequest.DoesNotExist: foia = None comm = _make_orphan_comm( from_email, to_emails, cc_emails, subject, post, request.FILES, foia, ) OrphanTask.objects.create(reason='ia', communication=comm, address=mail_id) return HttpResponse('WARNING') except Exception as exc: # If anything I haven't accounted for happens, at the very least forward # the email to requests so it isn't lost logger.error( 'Uncaught Mailgun Exception - %s: %s', mail_id, exc, exc_info=sys.exc_info(), ) _forward(post, request.FILES, 'Uncaught Mailgun Exception', info=True) return HttpResponse('ERROR') return HttpResponse('OK')
def _handle_request(request, mail_id): """Handle incoming mailgun FOI request messages""" # pylint: disable=broad-except # pylint: disable=too-many-locals post = request.POST from_ = post.get('From') to_ = post.get('To') or post.get('to') subject = post.get('Subject') or post.get('subject', '') try: from_realname, from_email = parseaddr(from_) foia = FOIARequest.objects.get(mail_id=mail_id) if not _allowed_email(from_email, foia): msg, reason = ('Bad Sender', 'bs') if foia.block_incoming: msg, reason = ('Incoming Blocked', 'ib') if not _allowed_email(from_email, foia) or foia.block_incoming: logger.warning('%s: %s', msg, from_) comm = _make_orphan_comm(from_, to_, subject, post, request.FILES, foia) OrphanTask.objects.create( reason=reason, communication=comm, address=mail_id) return HttpResponse('WARNING') comm = FOIACommunication.objects.create( foia=foia, from_who=from_realname[:255], priv_from_who=from_[:255], to_who=foia.user.get_full_name(), priv_to_who=to_[:255], subject=subject[:255], response=True, date=datetime.now(), full_html=False, delivered='email', communication=_get_mail_body(post), ) RawEmail.objects.create( communication=comm, raw_email='%s\n%s' % (post.get('message-headers', ''), post.get('body-plain', ''))) comm.process_attachments(request.FILES) task = ResponseTask.objects.create(communication=comm) classify_status.apply_async(args=(task.pk,), countdown=30 * 60) # resolve any stale agency tasks for this agency if foia.agency: foia.agency.unmark_stale() foia.email = from_email foia.other_emails = ','.join( email for name, email in getaddresses([post.get('To', ''), post.get('Cc', '')]) if email and not email.endswith('muckrock.com')) while len(foia.other_emails) > 255: # drop emails until it fits in db foia.other_emails = foia.other_emails[:foia.other_emails.rindex(',')] if foia.status == 'ack': foia.status = 'processed' foia.save(comment='incoming mail') comm.create_agency_notifications() except FOIARequest.DoesNotExist: logger.warning('Invalid Address: %s', mail_id) foia = None try: # try to get the foia by the PK before the dash foia = FOIARequest.objects.get(pk=mail_id.split('-')[0]) except FOIARequest.DoesNotExist: pass comm = _make_orphan_comm(from_, to_, subject, post, request.FILES, foia) OrphanTask.objects.create( reason='ia', communication=comm, address=mail_id) return HttpResponse('WARNING') except Exception: # If anything I haven't accounted for happens, at the very least forward # the email to requests so it isn't lost logger.error('Uncaught Mailgun Exception: %s', mail_id, exc_info=sys.exc_info()) _forward(post, request.FILES, 'Uncaught Mailgun Exception', info=True) return HttpResponse('ERROR') return HttpResponse('OK')
def _handle_request(request, mail_id): """Handle incoming mailgun FOI request messages""" # this function needs to be refactored # pylint: disable=broad-except # pylint: disable=too-many-locals # pylint: disable=too-many-branches # pylint: disable=too-many-statements post = request.POST from_email, to_emails, cc_emails = _parse_email_headers(post) subject = post.get("Subject") or post.get("subject", "") try: foia = FOIARequest.objects.get(mail_id=mail_id) # extra logging for next request portals for now if foia.portal and foia.portal.type == "nextrequest": _log_mail(request) if foia.deleted: if from_email is not None: EmailMessage( subject="Request Withdrawn: {}".format(subject), body=render_to_string("text/foia/deleted_autoreply.txt"), from_email=foia.get_request_email(), to=[str(from_email)], bcc=[settings.DIAGNOSTIC_EMAIL], ).send(fail_silently=False) return HttpResponse("WARNING") if from_email is not None: email_allowed = from_email.allowed(foia) else: email_allowed = False if not email_allowed: msg, reason = ("Bad Sender", "bs") if foia.block_incoming: msg, reason = ("Incoming Blocked", "ib") if not email_allowed or foia.block_incoming: logger.warning("%s: %s", msg, from_email) comm = _make_orphan_comm(from_email, to_emails, cc_emails, subject, post, request.FILES, foia) OrphanTask.objects.create(reason=reason, communication=comm, address=mail_id) return HttpResponse("WARNING") # if this isn't a known email for this agency, add it if not from_email.agencies.filter(pk=foia.agency.pk).exists(): AgencyEmail.objects.create(agency=foia.agency, email=from_email) # if this request is using a portal, hide the incoming messages hidden = foia.portal is not None with transaction.atomic(): comm = FOIACommunication.objects.create( foia=foia, from_user=foia.agency.get_user(), to_user=foia.user, subject=subject[:255], response=True, datetime=timezone.now(), communication=_get_mail_body(post, foia), hidden=hidden, ) email_comm = EmailCommunication.objects.create( communication=comm, sent_datetime=timezone.now(), from_email=from_email) email_comm.to_emails.set(to_emails) email_comm.cc_emails.set(cc_emails) RawEmail.objects.create( email=email_comm, raw_email="%s\n%s" % (post.get("message-headers", ""), post.get("body-plain", "")), ) comm.process_attachments(request.FILES) transaction.on_commit(lambda: download_links(comm.pk)) if foia.portal: transaction.on_commit(lambda: foia.portal.receive_msg(comm)) else: task = comm.responsetask_set.create() transaction.on_commit(lambda: classify_status.apply_async( args=(task.pk, ), countdown=30 * 60)) comm.create_agency_notifications() # attempt to autodetect a known portal _detect_portal(comm, from_email.email, post) # attempt to find file download links _detect_file_download_links(comm) # if agency isn't currently using an outgoing email or a portal, flag it if (not foia.agency.get_emails().exists() and not foia.agency.portal and not FlaggedTask.objects.filter( agency=foia.agency, category="agency new email").exists()): FlaggedTask.objects.create( agency=foia.agency, foia=foia, category="agency new email", text="We received an email from {} for a request to this " "agency, but this agency does not currently have a primary " "email address set".format(from_email), ) comm.extract_tracking_id() muckrock_domains = (settings.MAILGUN_SERVER_NAME, "muckrock.com") new_cc_emails = [ e for e in (to_emails + cc_emails) if e.domain not in muckrock_domains ] if from_email.domain not in muckrock_domains: foia.email = from_email foia.cc_emails.set(new_cc_emails) if foia.status == "ack": foia.status = "processed" foia.save(comment="incoming mail") except FOIARequest.DoesNotExist: logger.warning("Invalid Address: %s", mail_id) try: # try to get the foia by the PK before the dash foia = FOIARequest.objects.get(pk=mail_id.split("-")[0]) except FOIARequest.DoesNotExist: foia = None comm = _make_orphan_comm(from_email, to_emails, cc_emails, subject, post, request.FILES, foia) OrphanTask.objects.create(reason="ia", communication=comm, address=mail_id) return HttpResponse("WARNING") except Exception as exc: # If anything I haven't accounted for happens, at the very least forward # the email to requests so it isn't lost logger.error("Uncaught Mailgun Exception - %s: %s", mail_id, exc, exc_info=sys.exc_info()) _forward(post, request.FILES, "Uncaught Mailgun Exception", info=True) return HttpResponse("ERROR") return HttpResponse("OK")