def unsubscribe(request, location_slug): ''' unsubscribe route ''' # fail gracefully if location does not exist try: location = get_location(location_slug) except: # XXX TODO reject and bounce back to sender? return HttpResponse(status=200) logger.debug('unsubscribe@ for location: %s' % location) logger.debug(request.POST) logger.debug(request.FILES) return HttpResponse(status=200)
def decorator(request, location_slug, *args, **kwargs): location = get_location(location_slug) user = request.user if user.is_authenticated() and location and user in location.house_admins.all(): return original_func(request, location_slug, *args, **kwargs) elif request.user.is_authenticated(): return HttpResponseRedirect("/") else: from django.contrib.auth.views import redirect_to_login path = request.get_full_path() login_url = settings.LOGIN_URL return redirect_to_login(path, login_url)
def unsubscribe(request, location_slug): ''' unsubscribe route ''' # fail gracefully if location does not exist try: location = get_location(location_slug) except: # XXX TODO reject and bounce back to sender? return HttpResponse(status=200) logger.debug('unsubscribe@ for location: %s' % location) logger.debug(request.POST) logger.debug(request.FILES) return HttpResponse(status=200)
def announce(request, location_slug): ''' email all people signed up for event activity notifications at this location.''' # fail gracefully if location does not exist try: location = get_location(location_slug) except: # XXX TODO reject and bounce back to sender? logger.error('location not found') return HttpResponse(status=200) logger.debug('announce@ for location: %s' % location) # Make sure this person can post to our list sender = request.POST.get('from') location_event_admins = EventAdminGroup.objects.get( location=location).users.all() allowed_senders = [user.email for user in location_event_admins] # have to be careful here because the "sender" email address is likely a # substring of the entire 'from' field in the POST request, ie, "Jessy Kate # Schingler <*****@*****.**>" this_sender_allowed = False for sender_email in allowed_senders: if sender_email in sender: this_sender_allowed = True break if not this_sender_allowed: # TODO - This could send a response so they know they were blocked logger.warn("Sender (%s) not allowed. Exiting quietly." % sender) return HttpResponse(status=200) weekly_notifications_on = EventNotifications.objects.filter( location_weekly=location) remindees_for_location = [ notify.user for notify in weekly_notifications_on ] # TESTING jessy = User.objects.get(id=1) for user in [ jessy, ]: #for user in remindees_for_location: send_announce(request, user, location) return HttpResponse(status=200)
def announce(request, location_slug): ''' email all people signed up for event activity notifications at this location.''' # fail gracefully if location does not exist try: location = get_location(location_slug) except: # XXX TODO reject and bounce back to sender? logger.error('location not found') return HttpResponse(status=200) logger.debug('announce@ for location: %s' % location) # Make sure this person can post to our list sender = request.POST.get('from') location_event_admins = EventAdminGroup.objects.get(location=location).users.all() allowed_senders = [user.email for user in location_event_admins] # have to be careful here because the "sender" email address is likely a # substring of the entire 'from' field in the POST request, ie, "Jessy Kate # Schingler <*****@*****.**>" this_sender_allowed = False for sender_email in allowed_senders: if sender_email in sender: this_sender_allowed = True break if not this_sender_allowed: # TODO - This could send a response so they know they were blocked logger.warn("Sender (%s) not allowed. Exiting quietly." % sender) return HttpResponse(status=200) weekly_notifications_on = EventNotifications.objects.filter(location_weekly = location) remindees_for_location = [notify.user for notify in weekly_notifications_on] # TESTING jessy = User.objects.get(id=1) for user in [jessy,]: #for user in remindees_for_location: send_announce(request, user, location) return HttpResponse(status=200)
def residents(request, location_slug): ''' email all residents at this location.''' # fail gracefully if location does not exist try: location = get_location(location_slug) except: # XXX TODO reject and bounce back to sender? logger.error('location not found') return HttpResponse(status=200) logger.debug('residents@ for location: %s' % location) # we think that message_headers is a list of strings header_txt = request.POST.get('message-headers') message_headers = json.loads(header_txt) message_header_keys = [item[0] for item in message_headers] # make sure this isn't an email we have already forwarded (cf. emailbombgate 2014) # A List-Id header will only be present if it has been added manually in # this function, ie, if we have already processed this message. if request.POST.get('List-Id') or 'List-Id' in message_header_keys: # mailgun requires a code 200 or it will continue to retry delivery logger.debug('List-Id header was found! Dropping message silently') return HttpResponse(status=200) #if 'Auto-Submitted' in message_headers or message_headers['Auto-Submitted'] != 'no': if 'Auto-Submitted' in message_header_keys: logger.info('message appears to be auto-submitted. reject silently') return HttpResponse(status=200) recipient = request.POST.get('recipient') from_address = request.POST.get('from') logger.debug('from: %s' % from_address) sender = request.POST.get('sender') logger.debug('sender: %s' % sender) subject = request.POST.get('subject') body_plain = request.POST.get('body-plain') body_html = request.POST.get('body-html') # Add all the residents at this location resident_emails = [] for r in location.residents(): resident_emails.append(r.email) # Now loop through all the emails and build the bcc list we will use. # This makes sure there are no duplicate emails. bcc_list = [] for email in resident_emails: if email not in bcc_list: bcc_list.append(email) logger.debug("bcc list: %s" % bcc_list) # Make sure this person can post to our list #if not sender in bcc_list: # # TODO - This shoud possibly send a response so they know they were blocked # logger.warn("Sender (%s) not allowed. Exiting quietly." % sender) # return HttpResponse(status=200) if sender in bcc_list: bcc_list.remove(sender) # Include attachements attachments = [] for attachment in request.FILES.values(): attachments.append(("attachment", attachment)) # prefix subject, but only if the prefix string isn't already in the # subject line (such as a reply) if subject.find(location.email_subject_prefix) < 0: prefix = "[" + location.email_subject_prefix + "] " subject = prefix + subject logger.debug("subject: %s" % subject) # add in footer text_footer = '''\n\n-------------------------------------------\n*~*~*~* %s residents email list *~*~*~* ''' % location.name body_plain = body_plain + text_footer if body_html: html_footer = '''<br><br>-------------------------------------------<br>*~*~*~* %s residents email list *~*~*~* ''' % location.name body_html = body_html + html_footer # send the message list_address = "residents@%s.%s" % (location.slug, settings.LIST_DOMAIN) mailgun_data = { "from": from_address, "to": [ recipient, ], "bcc": bcc_list, "subject": subject, "text": body_plain, "html": body_html, # attach some headers: LIST-ID, REPLY-TO, MSG-ID, precedence... # Precedence: list - helps some out of office auto responders know not to send their auto-replies. "h:List-Id": list_address, "h:Precedence": "list", # Reply-To: list email apparently has some religious debates # (http://www.gnu.org/software/mailman/mailman-admin/node11.html) but seems # to be common these days "h:Reply-To": list_address, } return mailgun_send(mailgun_data, attachments)
def test80085(request, location_slug): ''' test route ''' # fail gracefully if location does not exist try: location = get_location(location_slug) except: # XXX TODO reject and bounce back to sender? return HttpResponse(status=200) logger.debug('test80085@ for location: %s' % location) logger.debug(request.POST) logger.debug(request.FILES) # we think that message_headers is a list of strings header_txt = request.POST.get('message-headers') message_headers = json.loads(header_txt) message_header_keys = [item[0] for item in message_headers] # make sure this isn't an email we have already forwarded (cf. emailbombgate 2014) # A List-Id header will only be present if it has been added manually in # this function, ie, if we have already processed this message. if request.POST.get('List-Id') or 'List-Id' in message_header_keys: # mailgun requires a code 200 or it will continue to retry delivery logger.debug('List-Id header was found! Dropping message silently') return HttpResponse(status=200) #if 'Auto-Submitted' in message_headers or message_headers['Auto-Submitted'] != 'no': if 'Auto-Submitted' in message_header_keys: logger.info('message appears to be auto-submitted. reject silently') return HttpResponse(status=200) recipient = request.POST.get('recipient') to = request.POST.get('To') from_address = request.POST.get('from') logger.debug('from: %s' % from_address) sender = request.POST.get('sender') logger.debug('sender: %s' % sender) subject = request.POST.get('subject') body_plain = request.POST.get('body-plain') body_html = request.POST.get('body-html') # retrieve the current house admins for this location bcc_list = ['*****@*****.**', '*****@*****.**'] logger.debug("bcc list: %s" % bcc_list) # Make sure this person can post to our list #if not sender in bcc_list: # # TODO - This shoud possibly send a response so they know they were blocked # logger.warn("Sender (%s) not allowed. Exiting quietly." % sender) # return HttpResponse(status=200) # usually we would remove the sender from receiving the email but because # we're testing, let 'em have it. #if sender in bcc_list: # bcc_list.remove(sender) # pass through attachments # logger.debug(request) # logger.debug(request.FILES) # for attachment in request.FILES.values(): # # JKS NOTE! this does NOT work with unicode-encoded data. i'm not # # actually sure that we should *expect* to receive unicode-encoded # # attachments, but it definitely breaks (which i disocvered because # # mailgun sends its test POST with a unicode-encoded attachment). # a_file = default_storage.save(attachment.name, ContentFile(attachment.read())) # attachments = {} # num = 0 # for attachment in request.FILES.values(): # attachments["attachment-%d" % num] = (attachment.name, default_storage.open(attachment.name, 'rb').read()) # #default_storage.delete(attachment.name) # num+= 1 attachments = [] for attachment in request.FILES.values(): attachments.append(("inline", attachment)) # prefix subject, but only if the prefix string isn't already in the # subject line (such as a reply) if subject.find('EN Test') < 0: prefix = "[EN Test!] " subject = prefix + subject logger.debug("subject: %s" % subject) # add in footer text_footer = '''\n\n-------------------------------------------\nYou are receiving this email because someone at Embassy Network wanted to use you as a guinea pig. %mailing_list_unsubscribe_url%''' body_plain = body_plain + text_footer if body_html: html_footer = '''<br><br>-------------------------------------------<br>You are receiving this email because someone at Embassy Network wanted to use you as a guinea pig.''' body_html = body_html + html_footer # send the message list_address = "test80085@" + location.slug + ".mail.embassynetwork.com" mailgun_data = { "from": from_address, "to": [ recipient, ], "bcc": bcc_list, "subject": subject, "text": body_plain, "html": body_html, # attach some headers: LIST-ID, REPLY-TO, MSG-ID, precedence... # Precedence: list - helps some out of office auto responders know not to send their auto-replies. "h:List-Id": list_address, "h:Precedence": "list", # Reply-To: list email apparently has some religious debates # (http://www.gnu.org/software/mailman/mailman-admin/node11.html) but seems # to be common these days "h:Reply-To": from_address } return mailgun_send(mailgun_data, attachments)
def residents(request, location_slug): ''' email all residents at this location.''' # fail gracefully if location does not exist try: location = get_location(location_slug) except: # XXX TODO reject and bounce back to sender? logger.error('location not found') return HttpResponse(status=200) logger.debug('residents@ for location: %s' % location) # we think that message_headers is a list of strings header_txt = request.POST.get('message-headers') message_headers = json.loads(header_txt) message_header_keys = [item[0] for item in message_headers] # make sure this isn't an email we have already forwarded (cf. emailbombgate 2014) # A List-Id header will only be present if it has been added manually in # this function, ie, if we have already processed this message. if request.POST.get('List-Id') or 'List-Id' in message_header_keys: # mailgun requires a code 200 or it will continue to retry delivery logger.debug('List-Id header was found! Dropping message silently') return HttpResponse(status=200) #if 'Auto-Submitted' in message_headers or message_headers['Auto-Submitted'] != 'no': if 'Auto-Submitted' in message_header_keys: logger.info('message appears to be auto-submitted. reject silently') return HttpResponse(status=200) recipient = request.POST.get('recipient') from_address = request.POST.get('from') logger.debug('from: %s' % from_address) sender = request.POST.get('sender') logger.debug('sender: %s' % sender) subject = request.POST.get('subject') body_plain = request.POST.get('body-plain') body_html = request.POST.get('body-html') # Add all the residents at this location resident_emails = [] for r in location.residents(): resident_emails.append(r.email) # Now loop through all the emails and build the bcc list we will use. # This makes sure there are no duplicate emails. bcc_list = [] for email in resident_emails: if email not in bcc_list: bcc_list.append(email) logger.debug("bcc list: %s" % bcc_list) # Make sure this person can post to our list #if not sender in bcc_list: # # TODO - This shoud possibly send a response so they know they were blocked # logger.warn("Sender (%s) not allowed. Exiting quietly." % sender) # return HttpResponse(status=200) if sender in bcc_list: bcc_list.remove(sender) # Include attachements attachments = [] for attachment in request.FILES.values(): attachments.append(("attachment", attachment)) # prefix subject, but only if the prefix string isn't already in the # subject line (such as a reply) if subject.find(location.email_subject_prefix) < 0: prefix = "["+location.email_subject_prefix + "] " subject = prefix + subject logger.debug("subject: %s" % subject) # add in footer text_footer = '''\n\n-------------------------------------------\n*~*~*~* %s residents email list *~*~*~* '''% location.name body_plain = body_plain + text_footer if body_html: html_footer = '''<br><br>-------------------------------------------<br>*~*~*~* %s residents email list *~*~*~* '''% location.name body_html = body_html + html_footer # send the message list_address = "residents@%s.%s" % (location.slug, settings.LIST_DOMAIN) mailgun_data = {"from": from_address, "to": [recipient, ], "bcc": bcc_list, "subject": subject, "text": body_plain, "html": body_html, # attach some headers: LIST-ID, REPLY-TO, MSG-ID, precedence... # Precedence: list - helps some out of office auto responders know not to send their auto-replies. "h:List-Id": list_address, "h:Precedence": "list", # Reply-To: list email apparently has some religious debates # (http://www.gnu.org/software/mailman/mailman-admin/node11.html) but seems # to be common these days "h:Reply-To": list_address, } return mailgun_send(mailgun_data, attachments)
def test80085(request, location_slug): ''' test route ''' # fail gracefully if location does not exist try: location = get_location(location_slug) except: # XXX TODO reject and bounce back to sender? return HttpResponse(status=200) logger.debug('test80085@ for location: %s' % location) logger.debug(request.POST) logger.debug(request.FILES) # we think that message_headers is a list of strings header_txt = request.POST.get('message-headers') message_headers = json.loads(header_txt) message_header_keys = [item[0] for item in message_headers] # make sure this isn't an email we have already forwarded (cf. emailbombgate 2014) # A List-Id header will only be present if it has been added manually in # this function, ie, if we have already processed this message. if request.POST.get('List-Id') or 'List-Id' in message_header_keys: # mailgun requires a code 200 or it will continue to retry delivery logger.debug('List-Id header was found! Dropping message silently') return HttpResponse(status=200) #if 'Auto-Submitted' in message_headers or message_headers['Auto-Submitted'] != 'no': if 'Auto-Submitted' in message_header_keys: logger.info('message appears to be auto-submitted. reject silently') return HttpResponse(status=200) recipient = request.POST.get('recipient') to = request.POST.get('To') from_address = request.POST.get('from') logger.debug('from: %s' % from_address) sender = request.POST.get('sender') logger.debug('sender: %s' % sender) subject = request.POST.get('subject') body_plain = request.POST.get('body-plain') body_html = request.POST.get('body-html') # retrieve the current house admins for this location bcc_list = ['*****@*****.**', '*****@*****.**'] logger.debug("bcc list: %s" % bcc_list) # Make sure this person can post to our list #if not sender in bcc_list: # # TODO - This shoud possibly send a response so they know they were blocked # logger.warn("Sender (%s) not allowed. Exiting quietly." % sender) # return HttpResponse(status=200) # usually we would remove the sender from receiving the email but because # we're testing, let 'em have it. #if sender in bcc_list: # bcc_list.remove(sender) # pass through attachments # logger.debug(request) # logger.debug(request.FILES) # for attachment in request.FILES.values(): # # JKS NOTE! this does NOT work with unicode-encoded data. i'm not # # actually sure that we should *expect* to receive unicode-encoded # # attachments, but it definitely breaks (which i disocvered because # # mailgun sends its test POST with a unicode-encoded attachment). # a_file = default_storage.save(attachment.name, ContentFile(attachment.read())) # attachments = {} # num = 0 # for attachment in request.FILES.values(): # attachments["attachment-%d" % num] = (attachment.name, default_storage.open(attachment.name, 'rb').read()) # #default_storage.delete(attachment.name) # num+= 1 attachments = [] for attachment in request.FILES.values(): attachments.append(("inline", attachment)) # prefix subject, but only if the prefix string isn't already in the # subject line (such as a reply) if subject.find('EN Test') < 0: prefix = "[EN Test!] " subject = prefix + subject logger.debug("subject: %s" % subject) # add in footer text_footer = '''\n\n-------------------------------------------\nYou are receiving this email because someone at Embassy Network wanted to use you as a guinea pig. %mailing_list_unsubscribe_url%''' body_plain = body_plain + text_footer if body_html: html_footer = '''<br><br>-------------------------------------------<br>You are receiving this email because someone at Embassy Network wanted to use you as a guinea pig.''' body_html = body_html + html_footer # send the message list_address = "test80085@"+location.slug+".mail.embassynetwork.com" mailgun_data = {"from": from_address, "to": [recipient, ], "bcc": bcc_list, "subject": subject, "text": body_plain, "html": body_html, # attach some headers: LIST-ID, REPLY-TO, MSG-ID, precedence... # Precedence: list - helps some out of office auto responders know not to send their auto-replies. "h:List-Id": list_address, "h:Precedence": "list", # Reply-To: list email apparently has some religious debates # (http://www.gnu.org/software/mailman/mailman-admin/node11.html) but seems # to be common these days "h:Reply-To": from_address } return mailgun_send(mailgun_data, attachments)