def save(self, user, partner, commit=True): new_or_change = CHANGE if self.instance.pk else ADDITION self.instance.partner = partner if new_or_change == ADDITION: self.instance.created_by = user instance = super(ContactRecordForm, self).save(commit) self.instance.tags = self.cleaned_data.get('tags') attachments = self.cleaned_data.get('attachment', None) for attachment in attachments: if attachment: prm_attachment = PRMAttachment(attachment=attachment, contact_record=self.instance) prm_attachment.partner = self.instance.partner prm_attachment.save() for attachment in self.cleaned_data.get('attach_delete', []): PRMAttachment.objects.get(pk=attachment).delete() identifier = instance.contact.name log_change(instance, self, user, partner, identifier, action_type=new_or_change) return instance
def test_bad_filename(self): """ Confirms that non-alphanumeric or underscore characters are being stripped from file names. """ actual_file = path.join(path.abspath(path.dirname(__file__)), 'data', 'test.txt') f = File(open(actual_file)) filenames = [ ('zz\\x80\\xff*file(copy)na.me.htm)_-)l', 'zzx80xfffilecopyname.htm_l'), ('...', 'unnamed_file'), ('..', 'unnamed_file'), ('../../file.txt', 'file.txt'), ('../..', 'unnamed_file'), ('\.\./file.txt', 'file.txt'), ('fiяыle.txt', 'file.txt') ] for filename, expected_filename in filenames: f.name = filename prm_attachment = PRMAttachment(attachment=f) setattr(prm_attachment, 'partner', self.partner) prm_attachment.save() result = PRMAttachment.objects.get( attachment__contains=expected_filename) result.delete()
def save(self, request, partner, commit=True): new_or_change = CHANGE if self.instance.pk else ADDITION self.instance.partner = partner self.instance.update_last_action_time(False) if new_or_change == ADDITION: self.instance.created_by = request.user instance = super(ContactRecordForm, self).save(commit) self.instance.tags = self.cleaned_data.get('tags') attachments = self.cleaned_data.get('attachment', None) prm_attachments = [ PRMAttachment(attachment=attachment, contact_record=self.instance) for attachment in attachments if attachment ] PRMAttachment.objects.bulk_create(prm_attachments) PRMAttachment.objects.filter( pk__in=self.cleaned_data.get('attach_delete', [])).delete() if instance.contact: identifier = instance.contact.name else: identifier = { 'email': instance.contact_email, 'phone': instance.contact_phone }.get(instance.contact_type, 'unknown contact') log_change(instance, self, request.user, partner, identifier, action_type=new_or_change, impersonator=request.impersonator) return instance
def process_email(request): """ Creates a contact record from an email received via POST. """ if request.method != 'POST': return HttpResponse(status=200) admin_email = request.REQUEST.get('from') headers = request.REQUEST.get('headers') key = request.REQUEST.get('key') subject = request.REQUEST.get('subject') email_text = request.REQUEST.get('text') if key != settings.EMAIL_KEY: return HttpResponse(status=200) if headers: parser = HeaderParser() headers = parser.parsestr(headers) if headers and 'Date' in headers: try: date_time = get_datetime_from_str(headers.get('Date')) except Exception: date_time = now() else: date_time = now() to = request.REQUEST.get('to', '') cc = request.REQUEST.get('cc', '') recipient_emails_and_names = getaddresses(["%s, %s" % (to, cc)]) admin_email = getaddresses([admin_email])[0][1] contact_emails = filter(None, [email[1] for email in recipient_emails_and_names]) if contact_emails == [] or (len(contact_emails) == 1 and contact_emails[0].lower() == '*****@*****.**'): # If [email protected] is the only contact, assume it's a forward. fwd_headers = build_email_dicts(email_text) try: recipient_emails_and_names = fwd_headers[0]['recipients'] contact_emails = [recipient[1] for recipient in recipient_emails_and_names] date_time = fwd_headers[0]['date'] except IndexError: contact_emails = [] # Prevent duplicate contact records for an email address because # the address was in both To and CC. contact_emails = list(set(contact_emails)) validated_contacts = [] for element in contact_emails: if not element.lower() == '*****@*****.**' and validate_email(element): validated_contacts.append(element) contact_emails = validated_contacts try: contact_emails.remove(admin_email) except ValueError: pass admin_user = User.objects.get_email_owner(admin_email) if admin_user is None: return HttpResponse(status=200) if admin_user.company_set.count() > 1: error = "Your account is setup as the admin for multiple companies. " \ "Because of this we cannot match this email with a " \ "specific partner on a specific company with 100% certainty. " \ "You will need to login to My.jobs and go to " \ "https://secure.my.jobs/prm to create your record manually." send_contact_record_email_response([], [], [], contact_emails, error, admin_email) return HttpResponse(status=200) partners = list(chain(*[company.partner_set.all() for company in admin_user.company_set.all()])) possible_contacts, created_contacts, unmatched_contacts = [], [], [] for contact in contact_emails: try: matching_contacts = Contact.objects.filter(email=contact, partner__in=partners) [possible_contacts.append(x) for x in matching_contacts] if not matching_contacts: poss_partner = find_partner_from_email(partners, contact) if poss_partner: new_contact = Contact.objects.create(name=contact, email=contact, partner=poss_partner) change_msg = "Contact was created from email." log_change(new_contact, None, admin_user, new_contact.partner, new_contact.name, action_type=ADDITION, change_msg=change_msg) created_contacts.append(new_contact) else: unmatched_contacts.append(contact) except ValueError: unmatched_contacts.append(contact) num_attachments = int(request.POST.get('attachments', 0)) attachments = [] for file_number in range(1, num_attachments+1): try: attachment = request.FILES['attachment%s' % file_number] except KeyError: error = "There was an issue with the email attachments. The " \ "contact records for the email will need to be created " \ "manually." send_contact_record_email_response([], [], [], contact_emails, error, admin_email) return HttpResponse(status=200) attachments.append(attachment) created_records = [] attachment_failures = [] date_time = now() if not date_time else date_time all_contacts = possible_contacts + created_contacts if not all_contacts: error = "No contacts or contact records could be created " \ "from this email. You will need to log in and manually " \ "create contact records for this email." send_contact_record_email_response([], [], [], contact_emails, error, admin_email) return HttpResponse(status=200) for contact in all_contacts: change_msg = "Email was sent by %s to %s" % \ (admin_user.get_full_name(), contact.name) record = ContactRecord.objects.create(partner=contact.partner, contact_type='email', contact=contact, contact_email=contact.email, contact_phone=contact.phone, created_by=admin_user, date_time=date_time, subject=subject, notes=force_text(email_text)) try: for attachment in attachments: prm_attachment = PRMAttachment() prm_attachment.attachment = attachment prm_attachment.contact_record = record setattr(prm_attachment, 'partner', contact.partner) prm_attachment.save() # The file pointer for this attachment is now at the end of the # file; reset it to the beginning for future use. attachment.seek(0) except AttributeError: attachment_failures.append(record) log_change(record, None, admin_user, contact.partner, contact.name, action_type=ADDITION, change_msg=change_msg) created_records.append(record) send_contact_record_email_response(created_records, created_contacts, attachment_failures, unmatched_contacts, None, admin_email) return HttpResponse(status=200)