Ejemplo n.º 1
0
    def post(self, request):
        post_vars = request.DATA
        if 'phone' not in post_vars or not post_vars['phone']:
            raise error.Error(error.MISSING_PARAMETER, u'缺少参数phone')
        phone_number = post_vars['phone']
        if not PHONE_NUMBER_RE.match(phone_number):
            raise error.Error(error.PHONE_NUMBER_FORMAT_ERROR, u'手机号格式错误')
        if 'authtoken' not in post_vars or not post_vars['authtoken']:
            raise error.Error(error.MISSING_PARAMETER, u'缺少参数authtoken')
        authtoken = decode(post_vars['authtoken'])
        tokens = authtoken.split('#')
        if not authtoken or (len(tokens) != 3):
            raise error.Error(error.AUTHTOKEN_FORMAT_ERROR, u'authtoken格式错误')
        t_phone_number, t_uuid, t_timestamp = tokens
        if phone_number != t_phone_number:
            logging.error('api请求手机号:{} token手机号:{}, 可能盗用短信接口'.format(phone_number, t_phone_number))
            raise error.Error(error.AUTHTOKEN_FORMAT_ERROR, u'authtoken错误')
        if SMSValidate.objects.filter(token=authtoken).exists():
            raise error.Error(error.AUTHTOKEN_OUT_OF_DATE, u'authtoken过期')

        if 'check_phone_type' not in post_vars or not post_vars['check_phone_type']:
            # raise error.Error(error.MISSING_PARAMETER, u'缺少参数check_phone_type)  # blocked for another field check_phone_type  check
            pass
        else:
            check_phone_type = post_vars.get('check_phone_type')
            exist = UserProfile.objects.filter(phone_number=phone_number).exists()

            if check_phone_type == '1':  # register
                if exist:
                    raise error.Error(error.PHONE_NUMBER_EXIST, u'该手机已被注册或绑定')
            elif check_phone_type == '2':  # forget
                if not exist:
                    raise error.Error(error.PHONE_NUMBER_DONT_EXIST, u'该手机号尚未注册')
            elif check_phone_type == '3':  # bind
                if exist:
                    raise error.Error(error.PHONE_ALREADY_BIND, u'该手机号已经被绑定过了喔')
            else:  # unsupported type
                raise error.Error(error.INVALID_PARAMETER, u'参数错误:check_phone_type({})'.format(check_phone_type))

        if 'check_phone_type' not in post_vars:  # need to keep it for old app client
            check_phone_registed = post_vars.get('check_phone_registed')
            if check_phone_registed == '1' or check_phone_registed == 'true':
                if UserProfile.objects.filter(phone_number=phone_number).exists():
                    raise error.Error(error.PHONE_NUMBER_EXIST, u'该手机已被注册或绑定')

        sms_list = SMSValidate.objects.filter(status=SMS_WAIT_TO_CHECK, phone_number=phone_number).order_by('-created_at')
        # 防止用户恶意注册
        if sms_list.exists():
            sms_obj = sms_list[0]
            if sms_obj.is_too_frequently():
                raise error.Error(error.SMS_TOO_FREQUENTLY, SMSValidate.STATUS[SMS_TOO_FREQUENTLY])
        obj = SMSValidate.new(phone_number, token=authtoken)
        resp = sms_send(phone_number, obj.validate)
        sms_response = json.loads(resp)
        # 状态码0为成功
        # http://www.yunpian.com/api/retcode.html
        if sms_response['code']:
            raise error.Error(error.SMS_SEND_FAILED, u'验证码发送失败')
        logging.info('api.sms.validate.send phone [{}] result [{}]'.format(phone_number, resp))
        return Response(status=status.HTTP_204_NO_CONTENT)
Ejemplo n.º 2
0
def send_sms_validate(request):
    '''
    发送短信验证码,当用户连发三次并且验证不通过(或者根本没验证),要求输入验证码
    '''
    phone_number = request.POST.get('phone_number')
    js = {'success': False, 'messages': {}}
    if not phone_number:
        js['messages']['phone_number'] = u'手机号不能为空'
        return JsonResponse(js)

    if SMSValidateCheckFailures.is_phone_locked_out(phone_number):
        captcha = request.POST.get('captcha', '')
        verify = request.session.get('sms_verify', '')
        request.session['sms_verify'] = '!'
        if not captcha or verify.lower() != captcha.lower():
            logging.info(
                "sms captcha image error, session verify: %s, user captcha: %s", verify, captcha)
            js['validation'] = True
            js['sms_validate_image'] = reverse('sms_validate_image')
            js['messages']['captcha'] = u'验证码错误'
            return JsonResponse(js)

    # 防止恶意注册, 次数限制
    SMSValidateCheckFailures.increment_lockout_counter(phone_number)

    sms_list = SMSValidate.objects.filter(status=SMS_WAIT_TO_CHECK, phone_number=phone_number).order_by('-created_at')
    # 防止用户恶意注册
    if sms_list.exists():
        sms_obj = sms_list[0]
        if sms_obj.is_too_frequently():
            js['messages']['validate'] = SMSValidate.STATUS[SMS_TOO_FREQUENTLY]
            return JsonResponse(js)

    obj = SMSValidate.new(phone_number)
    resp = sms_send(phone_number, obj.validate)
    sms_response = json.loads(resp)
    # 状态码0为成功
    # http://www.yunpian.com/api/retcode.html

    if not sms_response['code']:
        js = {'success': True}
    else:
        js['messages']['validate'] = SMSValidate.STATUS[SMS_SEND_FAILED]

    logging.info('sms.validate.send phone [{}] result [{}]'.format(phone_number, resp))
    return JsonResponse(js)
Ejemplo n.º 3
0
 def test_sms_send(self):
     with patch('social_oauth.api.yunpian_sms_send') as mock_yunpian_sms_send:
         mock_yunpian_sms_send.return_value = self.mock_yunpian_response_value
         response = sms_send(self.phone_number, self.code)
         self.assertEqual(response, self.mock_yunpian_response_value)