Exemple #1
0
def unsubscribe_manual(request, mailing_list_uuid):
    mailing_list = get_object_or_404(MailingList, uuid=mailing_list_uuid)
    is_limited = getattr(request, 'limited', False)

    if is_limited:
        messages.warning(
            request,
            _('Too many requests. Your IP address is blocked for 5 minutes.'))
        logger.warning(
            'IP address "%s" exceeded rate limit 5/5m for unsubscribe view.' %
            get_client_ip(request))

    if request.method == 'POST' and not is_limited:
        form = UnsubscribeForm(mailing_list=mailing_list, data=request.POST)
        if form.is_valid():
            form.unsubscribe(request)
            # If the unsubscribe was done manually, force send good bye email
            goodbye_email = mailing_list.get_goodbye_email_template()
            goodbye_email.send(form.cleaned_data.get('email'))
            return redirect('subscribers:goodbye',
                            mailing_list_uuid=mailing_list_uuid)
    else:
        form = UnsubscribeForm(mailing_list=mailing_list)

    content = mailing_list.get_unsubscribe_form_template().content_html

    return render(request, 'subscribers/unsubscribe_form.html', {
        'form': form,
        'mailing_list': mailing_list,
        'content': content
    })
Exemple #2
0
def track_click(request: HttpRequest,
                link_uuid: UUID,
                subscriber_uuid: UUID) -> HttpResponseRedirect:
    """
    Track subscriber's click on links on email from campaigns.
    Triggers celery tasks to update total and unique click count.
    Affects subscriber click rate, mailing list click rate and campaign click
    rate.

    This view can only be accessed via GET request and has a limit of 100
    requests per hour per IP address.

    :param request: A Django HTTP Request object
    :param link_uuid: A Link instance uuid field
    :param subscriber_uuid: A Subscriber instance uuid field
    :return: Redirection to the link's target URL
    """
    link: Link
    try:
        link = Link.objects.filter(uuid=link_uuid).select_related('email').get()
        subscriber = Subscriber.objects.get(uuid=subscriber_uuid)
        ip_address = get_client_ip(request)
        subscriber.click(link, ip_address)
    except Link.DoesNotExist:
        raise Http404
    except Subscriber.DoesNotExist:
        # fail silently
        logger.info('track_click call to non-existing Subscriber instance'
                    'uuid = "%s"' % str(subscriber_uuid))
    except Exception:
        logger.exception('Failed to track click on link "%s" from subscriber '
                         '"%s"' % (str(link_uuid), str(subscriber_uuid)))
    return HttpResponseRedirect(link.url)
Exemple #3
0
def track_click(request: HttpRequest,
                link_uuid: UUID,
                subscriber_uuid: UUID) -> HttpResponseRedirect:
    """
    Track subscriber's click on links on email from campaigns.
    Triggers celery tasks to update total and unique click count.
    Affects subscriber click rate, mailing list click rate and campaign click
    rate.

    This view can only be accessed via GET request and has a limit of 100
    requests per hour per IP address.

    :param request: A Django HTTP Request object
    :param link_uuid: A Link instance uuid field
    :param subscriber_uuid: A Subscriber instance uuid field
    :return: Redirection to the link's target URL
    """
    link: Link
    try:
        link = Link.objects.filter(uuid=link_uuid).select_related('email').get()
        subscriber = Subscriber.objects.get(uuid=subscriber_uuid)
        ip_address = get_client_ip(request)
        subscriber.click(link, ip_address)
    except Link.DoesNotExist:
        raise Http404
    except Subscriber.DoesNotExist:
        # fail silently
        logger.info('track_click call to non-existing Subscriber instance'
                    'uuid = "%s"' % str(subscriber_uuid))
    except Exception:
        logger.exception('Failed to track click on link "%s" from subscriber '
                         '"%s"' % (str(link_uuid), str(subscriber_uuid)))
    return HttpResponseRedirect(link.url)
Exemple #4
0
    def subscribe(self, request):
        email = self.cleaned_data.get('email')

        email_name, domain_part = email.rsplit('@', 1)
        domain_name = '@' + domain_part
        email_domain, created = Domain.objects.get_or_create(name=domain_name)

        subscriber, created = Subscriber.objects.get_or_create(email=email, mailing_list=self.mailing_list, defaults={
            'domain': email_domain
        })
        subscriber.status = Status.PENDING
        subscriber.optin_ip_address = get_client_ip(request)
        subscriber.optin_date = timezone.now()
        subscriber.save()

        if not created:
            subscriber.tokens.filter(description='confirm_subscription').delete()

        token = subscriber.tokens.create(description='confirm_subscription')
        current_site = get_current_site(request)
        protocol = 'https' if request.is_secure() else 'http'
        domain = current_site.domain
        path = reverse('subscribers:confirm_double_optin_token', kwargs={
            'mailing_list_uuid': self.mailing_list.uuid,
            'token': token.text
        })
        confirm_link = '%s://%s%s' % (protocol, domain, path)

        confirm_email = self.mailing_list.get_confirm_email_template()
        confirm_email.send(subscriber.get_email(), {
            'confirm_link': confirm_link
        })

        return subscriber
Exemple #5
0
def subscribe(request, mailing_list_uuid):
    mailing_list = get_object_or_404(MailingList, uuid=mailing_list_uuid)
    is_limited = getattr(request, 'limited', False)

    if is_limited:
        logger.warning(
            'IP address "%s" exceeded rate limit 10/5m for subscribe view.' %
            get_client_ip(request))
        messages.warning(
            request,
            _('Too many requests. Your IP address is blocked for 5 minutes.'))

    if request.method == 'POST' and not is_limited:
        form = SubscribeForm(mailing_list=mailing_list, data=request.POST)
        if form.is_valid():
            form.subscribe(request)
            return redirect('subscribers:confirm_subscription',
                            mailing_list_uuid=mailing_list_uuid)
    else:
        form = SubscribeForm(mailing_list=mailing_list)

    content = mailing_list.get_subscribe_form_template().content_html

    return render(request, 'subscribers/subscribe_form.html', {
        'mailing_list': mailing_list,
        'form': form,
        'content': content
    })
Exemple #6
0
 def confirm_subscription(self, request):
     ip_address = get_client_ip(request)
     self.status = Status.SUBSCRIBED
     self.confirm_ip_address = ip_address
     self.confirm_date = timezone.now()
     self.save()
     self.create_activity(ActivityTypes.SUBSCRIBED, ip_address=ip_address)
     self.tokens.filter(description='confirm_subscription').delete()
Exemple #7
0
    def unsubscribe(self, request, campaign=None):
        self.status = Status.UNSUBSCRIBED
        self.save()
        self.create_activity(ActivityTypes.UNSUBSCRIBED,
                             campaign=campaign,
                             ip_address=get_client_ip(request))

        goodbye_email = self.mailing_list.get_goodbye_email_template()
        if goodbye_email.send_email:
            goodbye_email.send(self.get_email())
Exemple #8
0
def track_open(request, email_uuid, subscriber_uuid):
    try:
        email = Email.objects.get(uuid=email_uuid)
        subscriber = Subscriber.objects.get(uuid=subscriber_uuid)
        ip_address = get_client_ip(request)
        subscriber.open(email, ip_address)
    except Exception:
        pass  # fail silently

    pixel = base64.b64decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=')  # noqa
    return HttpResponse(pixel, content_type='image/png')
Exemple #9
0
    def confirm_subscription(self, request):
        ip_address = get_client_ip(request)
        self.status = Status.SUBSCRIBED
        self.confirm_ip_address = ip_address
        self.confirm_date = timezone.now()
        self.save()
        self.create_activity(ActivityTypes.SUBSCRIBED, ip_address=ip_address)
        self.tokens.filter(description='confirm_subscription').delete()

        welcome_email = self.mailing_list.get_welcome_email_template()
        if welcome_email.send_email:
            welcome_email.send(self.get_email())
Exemple #10
0
def log_user_logged_out(sender, request, user, **kwargs):
    """
    A function to log an entry whenever a user successfully logs out.
    This function gets called automatically whenever the logout is successful.

    Keyword arguments:
    sender -- The class of the user that just logged in.
    request -- The current HttpRequest instance.
    user -- The user instance that just logged in.
    """
    ip_address = get_client_ip(request)
    logger.info('User "%s" logged out with IP address "%s".' %
                (user, ip_address))
Exemple #11
0
def log_user_login_failed(sender, credentials, request, **kwargs):
    """
    A function to log an entry whenever a user fails to login.
    This function gets called automatically whenever the login is failed.

    Keyword arguments:
    sender -- The class of the user that just logged in.
    request -- The current HttpRequest instance.
    user -- The user instance that just logged in.
    """
    ip_address = get_client_ip(request)
    logger.warning('Log in failed for credentials "%s" with IP address "%s".' %
                   (credentials, ip_address))
Exemple #12
0
    def unsubscribe(self, request, campaign=None):
        ip_address = get_client_ip(request)

        with transaction.atomic():
            self.status = Status.UNSUBSCRIBED
            self.last_seen_ip_address = ip_address
            self.save()
            self.create_activity(ActivityTypes.UNSUBSCRIBED, campaign=campaign, ip_address=ip_address)

        update_subscriber_location.delay(ip_address, self.pk)

        goodbye_email = self.mailing_list.get_goodbye_email_template()
        if goodbye_email.send_email:
            goodbye_email.send(self.get_email())
Exemple #13
0
def subscribe(request, mailing_list_uuid):
    mailing_list = get_object_or_404(MailingList, uuid=mailing_list_uuid)
    is_limited = getattr(request, 'limited', False)

    if is_limited:
        logger.warning(
            'IP address "%s" exceeded rate limit 10/5m for subscribe view.' %
            get_client_ip(request))
        messages.warning(
            request,
            _('Too many requests. Your IP address is blocked for 5 minutes.'))

    if request.method == 'POST' and not is_limited:
        valid_recaptcha_or_skip_recaptcha_validation = True
        if mailing_list.enable_recaptcha:
            # reCAPTCHA validation
            recaptcha_response = request.POST.get('g-recaptcha-response')
            data = {
                'secret': mailing_list.recaptcha_secret_key,
                'response': recaptcha_response
            }
            r = requests.post(
                'https://www.google.com/recaptcha/api/siteverify', data=data)
            recaptcha_result = r.json()
            valid_recaptcha_or_skip_recaptcha_validation = recaptcha_result[
                'success']

        form = SubscribeForm(mailing_list=mailing_list, data=request.POST)

        if valid_recaptcha_or_skip_recaptcha_validation:
            if form.is_valid():
                form.subscribe(request)
                return redirect('subscribers:confirm_subscription',
                                mailing_list_uuid=mailing_list_uuid)
        else:
            messages.info(
                request,
                _('Please check the reCAPTCHA and submit the form again.'))
    else:
        form = SubscribeForm(mailing_list=mailing_list)

    content = mailing_list.get_subscribe_form_template().content_html

    return render(request, 'subscribers/subscribe_form.html', {
        'mailing_list': mailing_list,
        'form': form,
        'content': content
    })
Exemple #14
0
    def confirm_subscription(self, request):
        ip_address = get_client_ip(request)

        with transaction.atomic():
            self.status = Status.SUBSCRIBED
            self.confirm_ip_address = ip_address
            self.last_seen_ip_address = ip_address
            self.confirm_date = timezone.now()
            self.save()
            self.create_activity(ActivityTypes.SUBSCRIBED, ip_address=ip_address)
            self.tokens.filter(description='confirm_subscription').delete()

        update_subscriber_location.delay(ip_address, self.pk)

        welcome_email = self.mailing_list.get_welcome_email_template()
        if welcome_email.send_email:
            welcome_email.send(self.get_email())
Exemple #15
0
    def subscribe(self, request):
        email = self.cleaned_data.get('email')
        subscriber, created = Subscriber.objects.get_or_create(
            email=email, mailing_list=self.mailing_list)
        subscriber.status = Status.PENDING
        subscriber.optin_ip_address = get_client_ip(request)
        subscriber.optin_date = timezone.now()
        subscriber.save()

        if not created:
            subscriber.tokens.filter(
                description='confirm_subscription').delete()

        token = subscriber.tokens.create(description='confirm_subscription')
        current_site = get_current_site(request)
        protocol = 'https' if request.is_secure() else 'http'
        domain = current_site.domain
        path = reverse('subscribers:confirm_double_optin_token',
                       kwargs={
                           'mailing_list_uuid': self.mailing_list.uuid,
                           'token': token.text
                       })
        confirm_link = '%s://%s%s' % (protocol, domain, path)

        context = {
            'confirm_link': confirm_link,
            'list_name': self.mailing_list.name,
            'contact_email': self.mailing_list.contact_email_address
        }

        subject = loader.render_to_string(
            'subscribers/confirm_email_subject.txt', context)
        subject = ''.join(
            subject.splitlines())  # Email subject *must not* contain newlines
        plain_text_message = loader.render_to_string(
            'subscribers/confirm_email.txt', context)
        rich_text_message = loader.render_to_string(
            'subscribers/confirm_email.html', context)

        message = EmailMultiAlternatives(subject=subject,
                                         body=plain_text_message,
                                         to=[subscriber.get_email()])
        message.attach_alternative(rich_text_message, 'text/html')
        message.send()

        return subscriber
Exemple #16
0
def subscribe(request, mailing_list_uuid):
    mailing_list = get_object_or_404(MailingList, uuid=mailing_list_uuid)
    is_limited = getattr(request, 'limited', False)

    if is_limited:
        logger.warning('IP address "%s" exceeded rate limit 10/5m for subscribe view.' % get_client_ip(request))
        messages.warning(request, _('Too many requests. Your IP address is blocked for 5 minutes.'))

    if request.method == 'POST' and not is_limited:
        valid_recaptcha_or_skip_recaptcha_validation = True
        if mailing_list.enable_recaptcha:
            # reCAPTCHA validation
            recaptcha_response = request.POST.get('g-recaptcha-response')
            data = {
                'secret': mailing_list.recaptcha_secret_key,
                'response': recaptcha_response
            }
            r = requests.post('https://www.google.com/recaptcha/api/siteverify', data=data)
            recaptcha_result = r.json()
            valid_recaptcha_or_skip_recaptcha_validation = recaptcha_result['success']

        form = SubscribeForm(mailing_list=mailing_list, data=request.POST)

        if valid_recaptcha_or_skip_recaptcha_validation:
            if form.is_valid():
                form.subscribe(request)
                return redirect('subscribers:confirm_subscription', mailing_list_uuid=mailing_list_uuid)
        else:
            messages.info(request, _('Please check the reCAPTCHA and submit the form again.'))
    else:
        form = SubscribeForm(mailing_list=mailing_list)

    content = mailing_list.get_subscribe_form_template().content_html

    return render(request, 'subscribers/subscribe_form.html', {
        'mailing_list': mailing_list,
        'form': form,
        'content': content
    })
Exemple #17
0
def unsubscribe_manual(request, mailing_list_uuid):
    mailing_list = get_object_or_404(MailingList, uuid=mailing_list_uuid)
    is_limited = getattr(request, 'limited', False)

    if is_limited:
        messages.warning(request, _('Too many requests. Your IP address is blocked for 5 minutes.'))
        logger.warning('IP address "%s" exceeded rate limit 5/5m for unsubscribe view.' % get_client_ip(request))

    if request.method == 'POST' and not is_limited:
        form = UnsubscribeForm(mailing_list=mailing_list, data=request.POST)
        if form.is_valid():
            form.unsubscribe(request)
            # If the unsubscribe was done manually, force send good bye email
            goodbye_email = mailing_list.get_goodbye_email_template()
            goodbye_email.send(form.cleaned_data.get('email'))
            return redirect('subscribers:goodbye', mailing_list_uuid=mailing_list_uuid)
    else:
        form = UnsubscribeForm(mailing_list=mailing_list)

    content = mailing_list.get_unsubscribe_form_template().content_html

    return render(request, 'subscribers/unsubscribe_form.html', {
        'form': form,
        'mailing_list': mailing_list,
        'content': content
    })
Exemple #18
0
def log_user_login_failed(sender, credentials, request, **kwargs):
    ip_address = get_client_ip(request)
    logger.warning('Log in failed for credentials "%s" with IP address "%s".' % (credentials, ip_address))
Exemple #19
0
def log_user_logged_out(sender, request, user, **kwargs):
    ip_address = get_client_ip(request)
    logger.info('User "%s" logged out with IP address "%s".' % (user, ip_address))
Exemple #20
0
 def unsubscribe(self, request, campaign=None):
     self.status = Status.UNSUBSCRIBED
     self.save()
     self.create_activity(ActivityTypes.UNSUBSCRIBED, campaign=campaign, ip_address=get_client_ip(request))