Пример #1
0
 def test_email_is_blocked(self, BlockedEmailMock):
     """Asking if blocked should only hit the DB once."""
     BlockedEmailMock.objects.values_list.return_value = ['.ninja', 'stuff.web']
     self.assertTrue(email_is_blocked('*****@*****.**'))
     self.assertTrue(email_is_blocked('*****@*****.**'))
     self.assertFalse(email_is_blocked('*****@*****.**'))
     self.assertEqual(BlockedEmailMock.objects.values_list.call_count, 1)
Пример #2
0
 def test_email_is_blocked(self, BlockedEmailMock):
     """Asking if blocked should only hit the DB once."""
     BlockedEmailMock.objects.values_list.return_value = ['.ninja', 'stuff.web']
     self.assertTrue(email_is_blocked('*****@*****.**'))
     self.assertTrue(email_is_blocked('*****@*****.**'))
     self.assertFalse(email_is_blocked('*****@*****.**'))
     self.assertEqual(BlockedEmailMock.objects.values_list.call_count, 1)
Пример #3
0
def send_recovery_message(request):
    """
    Send a recovery message to an email address.

    required form parameter: email

    If email not provided or not syntactically correct, returns 400.
    If email not known, returns 404.
    Otherwise, queues a task to send the message and returns 200.
    """
    try:
        validate_email(request.POST.get('email'))
    except EmailValidationError as e:
        return invalid_email_response(e)

    email = request.POST.get('email')
    if email_is_blocked(email):
        # don't let on there's a problem
        return HttpResponseJSON({'status': 'ok'})

    try:
        user_data = get_user_data(email=email)
    except NewsletterException as e:
        return newsletter_exception_response(e)

    if not user_data:
        return HttpResponseJSON({
            'status': 'error',
            'desc': 'Email address not known',
            'code': errors.BASKET_UNKNOWN_EMAIL,
        }, 404)  # Note: Bedrock looks for this 404

    send_recovery_message_task.delay(email)
    return HttpResponseJSON({'status': 'ok'})
Пример #4
0
def send_recovery_message(request):
    """
    Send a recovery message to an email address.

    required form parameter: email

    If email not provided or not syntactically correct, returns 400.
    If email not known, returns 404.
    Otherwise, queues a task to send the message and returns 200.
    """
    email = process_email(request.POST.get('email'))
    if not email:
        return invalid_email_response()

    if email_is_blocked(email):
        # don't let on there's a problem
        return HttpResponseJSON({'status': 'ok'})

    try:
        user_data = get_user_data(email=email)
    except NewsletterException as e:
        return newsletter_exception_response(e)

    if not user_data:
        return HttpResponseJSON({
            'status': 'error',
            'desc': 'Email address not known',
            'code': errors.BASKET_UNKNOWN_EMAIL,
        }, 404)  # Note: Bedrock looks for this 404

    send_recovery_message_task.delay(email)
    return HttpResponseJSON({'status': 'ok'})
Пример #5
0
def subscribe(request):
    data = request.POST.dict()
    newsletters = data.get('newsletters', None)
    if not newsletters:
        # request.body causes tests to raise exceptions
        # while request.read() works.
        raw_request = request.read()
        if 'newsletters=' in raw_request:
            # malformed request from FxOS
            # Can't use QueryDict since the string is not url-encoded.
            # It will convert '+' to ' ' for example.
            data = dict(pair.split('=') for pair in raw_request.split('&'))
            email = data.get('email')
            if email:
                data['email'] = force_unicode(email)
            statsd.incr('subscribe-fxos-workaround')
        else:
            return HttpResponseJSON({
                'status': 'error',
                'desc': 'newsletters is missing',
                'code': errors.BASKET_USAGE_ERROR,
            }, 400)

    if 'email' not in data:
        return HttpResponseJSON({
            'status': 'error',
            'desc': 'email is required',
            'code': errors.BASKET_USAGE_ERROR,
        }, 401)

    if email_is_blocked(data['email']):
        # don't let on there's a problem
        return HttpResponseJSON({'status': 'ok'})

    optin = data.get('optin', 'N').upper() == 'Y'
    sync = data.get('sync', 'N').upper() == 'Y'

    if optin and (not request.is_secure() or not has_valid_api_key(request)):
        # for backward compat we just ignore the optin if
        # no valid API key is sent.
        optin = False

    if sync:
        if not request.is_secure():
            return HttpResponseJSON({
                'status': 'error',
                'desc': 'subscribe with sync=Y requires SSL',
                'code': errors.BASKET_SSL_REQUIRED,
            }, 401)
        if not has_valid_api_key(request):
            return HttpResponseJSON({
                'status': 'error',
                'desc': 'Using subscribe with sync=Y, you need to pass a '
                        'valid `api-key` GET or POST parameter or X-api-key header',
                'code': errors.BASKET_AUTH_ERROR,
            }, 401)

    try:
        validate_email(data.get('email'))
    except EmailValidationError as e:
        return invalid_email_response(e)

    return update_user_task(request, SUBSCRIBE, data=data, optin=optin, sync=sync)
Пример #6
0
def get_involved(request):
    data = request.POST.dict()
    if 'email' not in data:
        return HttpResponseJSON({
            'status': 'error',
            'desc': 'email is required',
            'code': errors.BASKET_USAGE_ERROR,
        }, 401)
    if email_is_blocked(data['email']):
        # don't let on there's a problem
        return HttpResponseJSON({'status': 'ok'})
    if 'interest_id' not in data:
        return HttpResponseJSON({
            'status': 'error',
            'desc': 'interest_id is required',
            'code': errors.BASKET_USAGE_ERROR,
        }, 401)

    try:
        Interest.objects.get(interest_id=data['interest_id'])
    except Interest.DoesNotExist:
        return HttpResponseJSON({
            'status': 'error',
            'desc': 'invalid interest_id',
            'code': errors.BASKET_USAGE_ERROR,
        }, 401)

    if 'lang' not in data:
        return HttpResponseJSON({
            'status': 'error',
            'desc': 'lang is required',
            'code': errors.BASKET_USAGE_ERROR,
        }, 401)
    if not language_code_is_valid(data['lang']):
        return HttpResponseJSON({
            'status': 'error',
            'desc': 'invalid language',
            'code': errors.BASKET_INVALID_LANGUAGE,
        }, 400)
    if 'name' not in data:
        return HttpResponseJSON({
            'status': 'error',
            'desc': 'name is required',
            'code': errors.BASKET_USAGE_ERROR,
        }, 401)
    if 'country' not in data:
        return HttpResponseJSON({
            'status': 'error',
            'desc': 'country is required',
            'code': errors.BASKET_USAGE_ERROR,
        }, 401)

    try:
        validate_email(data.get('email'))
    except EmailValidationError as e:
        return invalid_email_response(e)

    update_get_involved.delay(
        data['interest_id'],
        data['lang'],
        data['name'],
        data['email'],
        data['country'],
        data.get('format', 'H'),
        data.get('subscribe', False),
        data.get('message', None),
        data.get('source_url', None),
    )
    return HttpResponseJSON({'status': 'ok'})
Пример #7
0
def subscribe(request):
    data = request.POST.dict()
    newsletters = data.get('newsletters', None)
    if not newsletters:
        # request.body causes tests to raise exceptions
        # while request.read() works.
        raw_request = request.read()
        if 'newsletters=' in raw_request:
            # malformed request from FxOS
            # Can't use QueryDict since the string is not url-encoded.
            # It will convert '+' to ' ' for example.
            data = dict(pair.split('=') for pair in raw_request.split('&') if '=' in pair)
            statsd.incr('news.views.subscribe.fxos-workaround')
        else:
            return HttpResponseJSON({
                'status': 'error',
                'desc': 'newsletters is missing',
                'code': errors.BASKET_USAGE_ERROR,
            }, 400)

    if 'email' not in data:
        return HttpResponseJSON({
            'status': 'error',
            'desc': 'email is required',
            'code': errors.BASKET_USAGE_ERROR,
        }, 401)

    email = process_email(data['email'])
    if not email:
        return invalid_email_response()

    data['email'] = email

    if email_is_blocked(data['email']):
        statsd.incr('news.views.subscribe.email_blocked')
        # don't let on there's a problem
        return HttpResponseJSON({'status': 'ok'})

    optin = data.pop('optin', 'N').upper() == 'Y'
    sync = data.pop('sync', 'N').upper() == 'Y'

    if optin and (not request.is_secure() or not has_valid_api_key(request)):
        # for backward compat we just ignore the optin if
        # no valid API key is sent.
        optin = False

    if sync:
        if not request.is_secure():
            return HttpResponseJSON({
                'status': 'error',
                'desc': 'subscribe with sync=Y requires SSL',
                'code': errors.BASKET_SSL_REQUIRED,
            }, 401)
        if not has_valid_api_key(request):
            return HttpResponseJSON({
                'status': 'error',
                'desc': 'Using subscribe with sync=Y, you need to pass a '
                        'valid `api-key` GET or POST parameter or X-api-key header',
                'code': errors.BASKET_AUTH_ERROR,
            }, 401)

    # NOTE this is not a typo; Referrer is misspelled in the HTTP spec
    # https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.36
    if not data.get('source_url') and request.META.get('HTTP_REFERER'):
        # try to get it from referrer
        statsd.incr('news.views.subscribe.use_referrer')
        data['source_url'] = request.META['HTTP_REFERER']

    return update_user_task(request, SUBSCRIBE, data=data, optin=optin, sync=sync)
Пример #8
0
def get_involved(request):
    data = request.POST.dict()
    if 'email' not in data:
        return HttpResponseJSON({
            'status': 'error',
            'desc': 'email is required',
            'code': errors.BASKET_USAGE_ERROR,
        }, 401)
    if email_is_blocked(data['email']):
        # don't let on there's a problem
        return HttpResponseJSON({'status': 'ok'})
    if 'interest_id' not in data:
        return HttpResponseJSON({
            'status': 'error',
            'desc': 'interest_id is required',
            'code': errors.BASKET_USAGE_ERROR,
        }, 401)

    try:
        Interest.objects.get(interest_id=data['interest_id'])
    except Interest.DoesNotExist:
        return HttpResponseJSON({
            'status': 'error',
            'desc': 'invalid interest_id',
            'code': errors.BASKET_USAGE_ERROR,
        }, 401)

    if 'lang' not in data:
        return HttpResponseJSON({
            'status': 'error',
            'desc': 'lang is required',
            'code': errors.BASKET_USAGE_ERROR,
        }, 401)
    if not language_code_is_valid(data['lang']):
        return HttpResponseJSON({
            'status': 'error',
            'desc': 'invalid language',
            'code': errors.BASKET_INVALID_LANGUAGE,
        }, 400)
    if 'name' not in data:
        return HttpResponseJSON({
            'status': 'error',
            'desc': 'name is required',
            'code': errors.BASKET_USAGE_ERROR,
        }, 401)
    if 'country' not in data:
        return HttpResponseJSON({
            'status': 'error',
            'desc': 'country is required',
            'code': errors.BASKET_USAGE_ERROR,
        }, 401)

    email = process_email(data.get('email'))
    if not email:
        return invalid_email_response()

    update_get_involved.delay(
        data['interest_id'],
        data['lang'],
        data['name'],
        email,
        data['country'],
        data.get('format', 'H'),
        data.get('subscribe', False),
        data.get('message', None),
        data.get('source_url', None),
    )
    return HttpResponseJSON({'status': 'ok'})