Ejemplo n.º 1
0
def memberid_sms(request):
    """This membership service tries to send a membership receipt by SMS to the given phone number.
    Note that a lot of phone number entries in Focus are bogus (email, date of birth, or poorly
    formatted) and some are also foreign, which is allowed for now. We are currently relying on the
    SMS service to fail if a bogus number happens to fall through."""
    if 'phone_mobile' not in request.POST:
        raise PermissionDenied

    request_count = memberid_sms_count(request.META['REMOTE_ADDR'])
    if request_count > 10 and request.META['REMOTE_ADDR'] not in settings.SMS_RESTRICTION_WHITELIST:
        return HttpResponse(json.dumps({'status': 'too_high_frequency'}))

    users = lookup_users_by_phone(request.POST['phone_mobile'])
    if len(users) == 0:
        return HttpResponse(json.dumps({'status': 'no_match'}))
    elif len(users) == 1:
        user = users[0]
        # Delete the user cache in case the number was recently updated; the cache may differ from
        # our raw lookup above
        user.clear_cache()
        return HttpResponse(json.dumps(send_sms_receipt(request, user)))
    else:
        # Multiple matches. This is typically a number related to members of a single family. This
        # is fine, since the receipt will include all family members, regardless of who it's sent
        # to. However, if that's not the case, we need to send one SMS for each matched but
        # unrelated user.
        recipients = []
        for user in users:
            # If this user is not in the family of any other recipients, add them to the recipient
            # list
            if not any([r.has_family() and user in r.family.all_members() for r in recipients]):
                recipients.append(user)

        statuses = []
        for user in recipients:
            # Delete the user cache in case the number was recently updated; the cache may differ
            # from our raw lookup above
            user.clear_cache()
            statuses.append(send_sms_receipt(request, user)['status'])

        if all([s == 'ok' for s in statuses]):
            return HttpResponse(json.dumps({'status': 'ok'}))
        else:
            return HttpResponse(json.dumps({'status': 'service_fail'}))
Ejemplo n.º 2
0
def memberid_sms(request):
    request_count = memberid_sms_count(request.META['REMOTE_ADDR'])
    if request_count > 10:
        return HttpResponse(json.dumps({'status': 'too_high_frequency'}))

    if request.user.get_phone_mobile() == '':
        # This shouldn't happen (it's checked client-side first) - but handle it anyway, just in case
        return HttpResponse(json.dumps({
            'status': 'missing_number'
        }))
    return HttpResponse(json.dumps(send_sms_receipt(request, request.user)))
Ejemplo n.º 3
0
def memberid_sms(request, user_id):
    try:
        user = User.get_users(include_pending=True).get(id=user_id)
        if user.get_phone_mobile() == '':
            # This shouldn't happen, but handle it just in case
            return HttpResponse(json.dumps({
                'status': 'missing_number'
            }))
        return HttpResponse(json.dumps(send_sms_receipt(request, user)))
    except User.DoesNotExist:
        return HttpResponse()
Ejemplo n.º 4
0
def memberid_sms(request):
    """This is a membership service that lets you get your memberid by providing your phone number.
    Note that a lot of phone number entries in Focus are bogus (email, date of birth, or
    poorly formatted) and some are also foreign, which we allow for now.
    We are currently relying on the SMS service to fail if a bogus number
    happens to fall through."""

    # Robots etc, just redirect them
    if not 'phone_mobile' in request.POST:
        return redirect('membership.views.service')

    # Start recording this request - details will be filled underway
    sms_request = SMSServiceRequest()
    sms_request.phone_number_input = request.POST['phone_mobile']
    sms_request.ip = request.META['REMOTE_ADDR']
    if request.user.is_authenticated():
        sms_request.user = request.user

    sms_request.count = memberid_sms_count(request.META['REMOTE_ADDR'])
    if sms_request.count > 10 and request.META['REMOTE_ADDR'] not in settings.SMS_RESTRICTION_WHITELIST:
        sms_request.blocked = True
        sms_request.save()
        return HttpResponse(json.dumps({'status': 'too_high_frequency'}))

    users = lookup_users_by_phone(request.POST['phone_mobile'])
    if len(users) == 0:
        sms_request.save()
        return HttpResponse(json.dumps({'status': 'no_match'}))
    elif len(users) == 1:
        user = users[0]
    elif len(users) > 1:
        # Usually, this will be because household members have the same number as their parents.
        # Check if any of these are related, and in that case, use the parent.
        user = None
        for user_to_check in users:
            if user_to_check.is_household_member() and \
                    user_to_check.get_parent() is not None and \
                    user_to_check.get_parent() in users:
                # Ah, this parent is in the result set - probably the one we want, use it
                user = user_to_check.get_parent()
                break
        if user is None:
            # Multiple hits, and they are not related. What do? Pick a random hit for now.
            user = users[0]
    else:
        raise Exception("A negative number of actors resulted from raw query. This is very strange, please investigate immediately.")

    sms_request.memberid = user.memberid
    sms_request.save()

    # Delete the actor cache in case the number was recently updated; the cache may differ from our raw lookup above
    user.get_actor().clear_cache()
    return HttpResponse(json.dumps(send_sms_receipt(request, user)))
Ejemplo n.º 5
0
def memberid_sms_userpage(request):
    # Requests from the userpage
    user = request.user

    sms_request = SMSServiceRequest(
        phone_number_input=None,
        ip=request.META['REMOTE_ADDR'],
        user=request.user,
        memberid=user.memberid
    )

    sms_request.count = memberid_sms_count(request.META['REMOTE_ADDR'])
    if sms_request.count > 10:
        sms_request.blocked = True
        sms_request.save()
        return HttpResponse(json.dumps({'status': 'too_high_frequency'}))

    if user.get_phone_mobile() == '':
        # This shouldn't happen (it's checked client-side first) - but handle it anyway, just in case
        return HttpResponse(json.dumps({
            'status': 'missing_number'
        }))
    sms_request.save()
    return HttpResponse(json.dumps(send_sms_receipt(request, user)))
Ejemplo n.º 6
0
def memberid(request, version, format):
    librato.increment('sherpa.api.tailored.medlemsnummer.request')

    if request.method != 'GET':
        librato.increment('sherpa.api.tailored.medlemsnummer.response.400')
        raise BadRequest(
            "Unsupported HTTP verb '%s'" % request.method,
            code=error_codes.UNSUPPORTED_HTTP_VERB,
            http_code=400
        )

    require_focus(request)

    if 'mobilnummer' not in request.GET:
        librato.increment('sherpa.api.tailored.medlemsnummer.response.400')
        raise BadRequest(
            "Missing required 'mobilnummer' parameter",
            code=error_codes.MISSING_REQUIRED_PARAMETER,
            http_code=400
        )

    phone_number = request.GET['mobilnummer'].strip()
    users = lookup_users_by_phone(phone_number)

    # Send the recipient an SMS
    if len(users) == 0:
        librato.increment('sherpa.api.tailored.medlemsnummer.response.404')
        raise BadRequest(
            "A member with phone number '%s' wasn't found." % phone_number,
            code=error_codes.RESOURCE_NOT_FOUND,
            http_code=404
        )
    elif len(users) == 1:
        user = users[0]
    elif len(users) > 1:
        # Usually, this will be because household members have the same number as their parents.
        # Check if any of these are related, and in that case, use the parent.
        user = None
        for user_to_check in users:
            if user_to_check.is_related_member() and \
                    user_to_check.get_parent() is not None and \
                    user_to_check.get_parent() in users:
                # Ah, this parent is in the result set - probably the one we want, use it
                user = user_to_check.get_parent()
                break
        if user is None:
            # Multiple hits, and they are not related. What do? Pick a random hit for now.
            user = users[0]

    # Delete the user cache in case the number was recently updated; the cache may differ from our raw lookup above
    user.clear_cache()
    result = send_sms_receipt(request, user)
    if result['status'] == 'ok':
        librato.increment('sherpa.api.tailored.medlemsnummer.response.200')
        return HttpResponse(json.dumps({
            'status': 'ok',
            'message': 'An SMS was successfully sent to the member with the given phone number.',
        }))
    elif result['status'] == 'service_fail':
        librato.increment('sherpa.api.tailored.medlemsnummer.response.500')
        raise BadRequest(
            "There is a problem with our SMS gateway and we were unable to send the SMS.",
            code=error_codes.SMS_GATEWAY_ERROR,
            http_code=500
        )
    else:
        # Might happen if we add a new status code to the send_sms_receipt function and forget to account for it here
        logger.error(
            "Unknown SMS return status code '%s'" % result['status'],
            extra={'request': request}
        )
        librato.increment('sherpa.api.tailored.medlemsnummer.response.500')
        raise BadRequest(
            "An internal error occurred while trying to send the SMS. This error has been logged and we'll get it fixed asap.",
            code=error_codes.INTERNAL_ERROR,
            http_code=500
        )