def main(): user = Account.get_by_alias(EMAIL) if not user: user = register_without_confirm(EMAIL, 'testtest', ACCOUNT_REG_TYPE.EMAIL) bcolors.run(repr(user), key='zhiwang') # 绑定身份证和手机 user.add_alias(MOBILE_PHONE, ACCOUNT_REG_TYPE.MOBILE) identity = Identity.save(user.id_, PERSON_NAME, PERSON_RICN) bcolors.run(repr(identity), key='zhiwang') # 绑定指旺帐号 ZhiwangAccount.bind(user.id_, ZHIWANG_TOKEN) bcolors.run(repr(ZhiwangAccount.get_by_local(user.id_)), key='zhiwang') # 绑定银行卡 bankcards = BankCardManager(user.id_) with patch('core.models.profile.bankcard.DEBUG', True): bankcard = bankcards.create_or_update( mobile_phone=user.mobile, card_number=BANKCARD_NO, bank_id=BANKCARD_BANK, city_id=BANKCARD_DIVISION[:4] + u'00', province_id=BANKCARD_DIVISION[:2] + u'0000', local_bank_name=u'') bcolors.run(repr(bankcard), key='zhiwang') bcolors.run('success: %s' % EMAIL, key='zhiwang')
def test_forgot_password_for_email_account(self): # as email can't be used to register any more, we use the # auto - generated [email protected] for test email = '*****@*****.**' browser = self.browser browser.visit(self.url_for('accounts.password.forgot')) browser.find_by_css('input[name="alias"]').fill(email) self._submit() assert browser.is_element_present_by_css('a.js-btn-resend-forgot') # 获取邮箱更改密码的url地址 user = Account.get_by_alias(email) result = db.execute('select verify_code from user_verify ' 'where user_id=%s and code_type=%s', (user.id, VERIFY_CODE_TYPE.FORGOT_PASSWORD_EMAIL)) browser.visit(self.url_for( 'accounts.password.reset_for_mail_user', user_id=user.id_, code=str(result[0][0]), _external=True)) assert browser.is_element_present_by_css('a.confirm-password-submit') browser.find_by_css('input[name="new-password"]').fill('testtest') browser.find_by_css('input[name="confirmed-password"]').fill('testtest') browser.find_by_css('a.confirm-password-submit').click() assert browser.is_element_present_by_css('.verification-box') assert browser.is_text_present('密码修改成功')
def token_dump(user_alias, workdir=None): """Dumps API token from database.""" account = Account.get_by_alias(user_alias) if not account: return bcolors.fail('user %r not found' % user_alias) workdir = os.path.expanduser(workdir or '~/.guihua') if not os.path.exists(workdir): os.makedirs(workdir) yixin_account = YixinAccount.get_by_local(account.id_) if not yixin_account: return bcolors.fail('%r need to bind yixin account' % user_alias) jsonfile_location = os.path.join(workdir, 'solar-yixin-token.json') if os.path.exists(jsonfile_location): with open(jsonfile_location) as jsonfile: data = json.load(jsonfile) if not isinstance(data, dict): return bcolors.fail('unexpected data') else: data = {} data[user_alias] = { 'user_alias': user_alias, 'yixin_account': yixin_account.p2p_account, 'yixin_token': yixin_account.p2p_token, } with open(jsonfile_location, 'w') as jsonfile: json.dump(data, jsonfile, indent=4) bcolors.success('success: %s %s' % (user_alias, yixin_account.p2p_account))
def validate_reset_password_asker(alias): if not alias: raise AccountAliasValidationError() reg_type = get_reg_type_from_alias(alias) if reg_type == ACCOUNT_REG_TYPE.EMAIL: if validate_email(alias) != errors.err_ok: raise UnsupportedAliasError() if alias.strip().endswith(INSECURE_EMAIL_DOMAINS): raise InsecureEmailError() elif reg_type == ACCOUNT_REG_TYPE.MOBILE: if validate_phone(alias) != errors.err_ok: raise UnsupportedAliasError() else: raise UnsupportedAliasError() user = Account.get_by_alias(alias) if not user: raise AccountNotFoundError() if user.status != ACCOUNT_STATUS.NORMAL: raise AccountInactiveError() return reg_type
def reset_mobile_user_password(): ''' /j/account/reset_mobile_user_password ''' # 校验手机号是否对应已存在的用户 mobile = request.form.get('mobile') user = Account.get_by_alias(mobile) if not user: return jsonify(r=False, error=u'该手机号尚未注册好规划') # 校验验证码是否正确 code = request.form.get('code') try: v = Verify.validate(user.id_, code, VERIFY_CODE_TYPE.FORGOT_PASSWORD_MOBILE) v.delete() except VerifyCodeException as e: return jsonify(r=False, error=unicode(e)) # 校验密码是否合法一致 new_password = request.form.get('new_password') confirmed_password = request.form.get('confirmed_password') try: reset_password(user, new_password, confirmed_password) except PasswordValidationError as e: return jsonify(r=False, error=unicode(e)) else: return jsonify(r=True)
def register_mobile(self, user_mobile=None, user_password=None, user_nickname=None): self.browser.visit(self.url_for('accounts.login.login')) self.browser.find_by_css('.js-to-register').click() assert self.browser.is_element_visible_by_css('.btn-register-submit') mobile = user_mobile or '159%08d' % random.randint(1, 99999999) password = user_password or 'haoguihua123' assert self.browser.is_element_visible_by_css('.captcha-img') session = self.peep_session() captcha_code = digits_captcha.get(session['cap_secret']) self.browser.fill('mobile', mobile) self.browser.fill('captcha', captcha_code) self.browser.find_by_css('.captcha.btn').click() time.sleep(1) button_text = self.browser.find_by_css('.captcha.btn').text assert button_text.endswith(u'后重新发送') # 获取手机注册验证码 user = Account.get_by_alias(mobile) result = db.execute( 'select verify_code from user_verify ' 'where user_id=%s and code_type=%s', (user.id_, VERIFY_CODE_TYPE.REG_MOBILE)) self.browser.fill('verify_code', str(result[0][0])) self.browser.find_by_css('#reg-password').fill(password) self.browser.find_by_css('.btn-register-submit').click() return mobile, password
def j_forgot_password(): if g.user: return jsonify(r=False), 403 error = '' if request.method == 'POST': # TODO 设置依据IP可能会有校园网访问的问题 l = Limit.get(LIMIT.FORGOT_PASSWORD % request.remote_addr) if l.is_limited(): abort(429) l.touch() alias = request.form.get('alias') try: alias_type = validate_reset_password_asker(alias) user = Account.get_by_alias(alias) except AccountAliasValidationError as e: error = unicode(e) else: if alias_type == ACCOUNT_REG_TYPE.EMAIL: send_reset_password_mail(user) return jsonify(r=True, type='email', alias=alias) elif alias_type == ACCOUNT_REG_TYPE.MOBILE: return jsonify(r=True, type='mobile', alias=alias) return jsonify(r=False, error=error)
def reset_password(): """重置密码(发送短信验证码) 要使用本接口, 客户端必须有权以 ``user_info`` 作为 scope. :request: :class:`.ResetPasswordSchema` :response: :class:`.UserSchema` :reqheader X-Client-ID: OAuth 2.0 Client ID :reqheader X-Client-Secret: OAuth 2.0 Client Secret :status 403: 账号不存在 :status 200: 已发出验证码 """ reset_password_schema = ResetPasswordSchema(strict=True) user_schema = UserSchema(strict=True) result = reset_password_schema.load(request.get_json(force=True)) mobile_phone = result.data['mobile_phone'] sms_limiter.raise_for_exceeded( key=mobile_phone, message='{granularity}内只能发送{amount}次验证码,请稍后再试') user = Account.get_by_alias(mobile_phone) if user: sms = ShortMessage.create(mobile_phone, forgot_password_sms, user_id=user.id_) sms.send() sms_limiter.hit(key=mobile_phone) return jsonify(success=True, data=user_schema.dump(user).data) else: abort(403, u'账号不存在')
def forgot(): error = '' alias = '' if request.method == 'POST': # TODO 设置依据IP可能会有校园网访问的问题 l = Limit.get(LIMIT.FORGOT_PASSWORD % request.remote_addr) if l.is_limited(): abort(429) l.touch() alias = request.form.get('alias') try: alias_type = validate_reset_password_asker(alias) user = Account.get_by_alias(alias) except AccountAliasValidationError as e: error = unicode(e) else: if alias_type == ACCOUNT_REG_TYPE.EMAIL: send_reset_password_mail(user) return render_template( 'accounts/forgot_password_mail_sent.html', alias=alias) elif alias_type == ACCOUNT_REG_TYPE.MOBILE: return render_template( 'accounts/reset_mobile_user_password.html', mobile=alias) return render_template('accounts/forgot_password.html', alias=alias, error=error)
def validate_mobile(self, field): if errors.err_ok != validate_phone(field.data): raise validators.StopValidation(message=u'手机号错误') user = Account.get_by_alias(field.data) if user and not user.need_verify(): raise validators.StopValidation(message=u'手机号已被注册 试试直接登录吧')
def test_forgot_password_for_mobile_account(self): # register first mobile, password = self.register_mobile() # logout then self.logout() # get verify code for 1th try browser = self.browser browser.visit(self.url_for('accounts.password.forgot')) browser.find_by_css('input[name="alias"]').fill(mobile) self._submit() assert browser.is_element_present_by_css('a.js-btn-getcode') browser.find_by_css('a.js-btn-getcode').click() time.sleep(1) # 获取手机验证码 user = Account.get_by_alias(mobile) result = db.execute('select verify_code from user_verify ' 'where user_id=%s and code_type=%s', (user.id, VERIFY_CODE_TYPE.FORGOT_PASSWORD_MOBILE)) browser.find_by_css('input[name="code"]').fill(str(result[0][0])) browser.find_by_css('input[name="new-password"]').fill('testtest1234') browser.find_by_css('input[name="password"]').fill('testtest1234') browser.find_by_css('a.confirm-password-submit').click() assert browser.is_element_present_by_css('.verification-box') assert browser.is_text_present('密码修改成功')
def main(): user = Account.get_by_alias(EMAIL) ZhiwangAccount.unbind(user.id_) try: register_zhiwang_account(user.id_) zhiwang_account = ZhiwangAccount.get_by_local(user.id_) except (MismatchUserError, RepeatlyRegisterError) as e: bcolors.fail(e.args[0], key='zhiwang_code') return bcolors.run('The new zhiwang code is %s' % zhiwang_account.zhiwang_id, key='zhiwang_code') with open(ADD_ZHIWANG_FILE, 'r') as f: source = RE_ZHIWANG_CODE.sub( "ZHIWANG_TOKEN = u'%s'" % zhiwang_account.zhiwang_id.encode('ascii'), f.read()) with open(ADD_ZHIWANG_FILE, 'w') as f: f.write(source) bcolors.run('%s is changed. PLEASE COMMIT IT AND OPEN A MERGE REQUEST.' % ADD_ZHIWANG_FILE, key='zhiwang_code') if '--commit' in sys.argv: subprocess.check_call( ['git', 'commit', '-m', COMMIT_MSG, '--', ADD_ZHIWANG_FILE])
def _register_user(alias, password, reg_type, status): user = Account.get_by_alias(alias) salt = randbytes(4) passwd_hash = pwd_hash(salt, password) if user and user.need_verify(): user.change_passwd_hash(salt, passwd_hash) return Account.get_by_alias(alias) elif user: return return Account.add(alias, passwd_hash, salt, generate_nickname(alias, reg_type), reg_type, status=status)
def validate_verify_code(self, field): user = Account.get_by_alias(self.mobile.data) if user: try: v = Verify.validate(user.id_, field.data, VERIFY_CODE_TYPE.REG_MOBILE) v.delete() except VerifyCodeException as e: raise validators.ValidationError(unicode(e))
def test_get_account_by_alias(self): email = '*****@*****.**' account = self.add_account(email=email) self.assertEqual(account.email, email) old_account = account account = Account.get_by_alias(email) self.assertEqual(account.id, old_account.id) self.assertEqual(account.email, email) mobile = '13212345678' email_account = Account.get_by_alias(email) account.add_alias(mobile) mobile_account = Account.get_by_alias(mobile) self.assertEqual(account.id, mobile_account.id) self.assertEqual(account.id, email_account.id) self.assertEqual(mobile_account.email, email) self.assertEqual(email_account.mobile, mobile)
def test_channel_register(self): self.browser.visit(self.url_for('home.home', ch='west')) mobile, password = self.register_mobile() time.sleep(2) user = Account.get_by_alias(mobile) assert user.mobile == mobile assert user.channel.name == u'西方记者' assert user.channel.tag == u'west'
def register(): mobile = request.form.get('mobile') error = validate_phone(mobile) code = request.cookies.get(INVITER_KEY) if error != errors.err_ok: return redirect(url_for('.invite', inviter=code)) user = Account.get_by_alias(mobile) if user and not user.need_verify(): return redirect(url_for('.login', inviter=code)) return render_template('invite/register.html', mobile=mobile)
def pre_bind(mobile, is_send_sms=True): user = Account.get_by_alias(mobile) if validate_phone(mobile) != errors.err_ok: raise BindError(u'非法的手机号') if user and user.is_normal_account(): raise BindError(u'手机号已被使用') request_bind(g.user.id, mobile, is_send_sms) return True
def validate_mobile(self, field): mobile = field.data error = validate_phone(mobile) if error != errors.err_ok: raise validators.ValidationError(u'无效的手机号码') ip_limiter.raise_for_exceeded( key=request.remote_addr, message=u'{granularity}内只能发起{amount}次注册,请稍后再试') if not Account.get_by_alias(mobile): raise validators.ValidationError(u'修改手机号后请重新获取验证码') ip_limiter.hit(request.remote_addr)
def index(): form = ReserveForm() if request.method == 'POST': if form.validate_on_submit(): mobile = form.data['mobile'] user = Account.get_by_alias(mobile) if user: return redirect(url_for('.login', mobile=mobile)) else: sms = ShortMessage.create(mobile, women_day_2016_register_sms) sms.send(provider=YIMEI_AD) return redirect(url_for('.register', mobile=mobile)) return render_template('activity/beauty38/index.html')
def test_remove_account_alias(self): email = '*****@*****.**' mobile = '13211111111' account = self.add_account(email=email) account.add_alias(mobile) # remove an alias whose type is not in reg type result1 = account.remove_alias(ACCOUNT_REG_TYPE.WEIXIN_OPENID) # remove an alias that alias doesn't match the type result2 = account.remove_alias(ACCOUNT_REG_TYPE.MOBILE, '*****@*****.**') # remove an alias that is not in reg alias result3 = account.remove_alias(ACCOUNT_REG_TYPE.MOBILE, '13222222222') # remove an removable alias result4 = account.remove_alias(ACCOUNT_REG_TYPE.EMAIL) self.assertFalse(result1) self.assertFalse(result2) self.assertFalse(result3) self.assertTrue(result4) email_account = Account.get_by_alias(email) assert email_account is None # remove the last alias result5 = account.remove_alias(ACCOUNT_REG_TYPE.MOBILE) self.assertFalse(result5) account = Account.get_by_alias(mobile) assert account is not None # remove mobile when email has been deleted account.add_alias('WX-12nfkl1h3nslk23n', ACCOUNT_REG_TYPE.WEIXIN_OPENID) result6 = account.remove_alias(ACCOUNT_REG_TYPE.MOBILE) self.assertFalse(result6) account = Account.get_by_alias(mobile) assert account is not None
def main(): user = Account.get_by_alias(EMAIL) if not user: bcolors.fail('%s is not found' % EMAIL, key='firewood') flow = FirewoodWorkflow(user.id_) transaction = firewood.create_transaction(flow.account_uid, AMOUNT, TAGS) transaction_uid = uuid.UUID(transaction.json()['uid']) transaction = firewood.confirm_transaction(flow.account_uid, transaction_uid) transaction_uri = transaction.json()['_links']['self'] bcolors.run('%s +100.00' % transaction_uri, key='firewood')
def reserve_spring_gift(mobile_phone): """预约体验金.""" # 给老用户派发礼包 is_new = SpringGift.get_id_by_mobile_phone(mobile_phone) is None user = Account.get_by_alias(mobile_phone) # 给新老用户预约体验金 gift = SpringGift.add(mobile_phone) # 为老用户发放礼包并创建通知 if gift and is_new and user: distribute_welfare_gift(user, spring_2016_package) notify_spring_gift(user, gift) return gift
def request_reset_mobile_user_password_verify(): mobile = request.form.get('mobile') l = Limit.get(LIMIT.MOBILE_REG % mobile, timeout=60 * 60, limit=10) if l.is_limited(): return jsonify(r=False, error=u'发送短信过于频繁,请您稍后再试') l.touch() user = Account.get_by_alias(mobile) if not user: return jsonify(r=False, error=u'该手机号尚未注册好规划') sms = ShortMessage.create(user.mobile, forgot_password_sms, user_id=user.id_) sms.send() return jsonify(r=True)
def christmas_gift(): form = GameResultForm() form.raise_for_validation() mobile = form.mobile_phone.data try: gift = ChristmasGift.add(mobile, form.rank.data) except GiftAwaredError as e: return jsonify(error=unicode(e)), 405 user = Account.get_by_alias(mobile) if user and user.is_normal_account(): # 手机号对应用户是激活用户则直接派发礼包,否则等待用户注册触发 gift.award() return '', 204
def register_mobile(): register = RegisterForm() if register.validate(): user = Account.get_by_alias(register.mobile.data) error = confirm_register(user.id) if error == errors.err_ok: user = login_user(user, remember=True) initial_new_user(user.id_, register.password.data) log_register_source(user.id, request) invitation_register_completed(request, Account.get(user.id_)) if user: return '', 204 else: return jsonify(errors=[{'message': u'手机号注册失败,T_T'}]), 403 else: return jsonify(errors=[{'message': login_err_msg_dict[error]}]), 400 return jsonify(errors=register.failure), 400
def _confirm_bind(uid, mobile): user = Account.get_by_alias(mobile) # handle the unverified mobile account firstly if user: if user.need_verify(): o_uid = user.id user.update_status(ACCOUNT_STATUS.FAILED) user = Account.get(o_uid) is_alias_removed = user.remove_alias(ACCOUNT_REG_TYPE.MOBILE, mobile) if not is_alias_removed: raise BindError(u'手机号绑定失败,请联系客服处理') # handle current user secondly user = Account.get(uid) try: user.add_alias(mobile) except AliasException: raise BindError(u'手机号绑定失败,请联系客服处理') return user
def generate_fake_transactions(): user = Account.get_by_alias('*****@*****.**') if not user: return with patch('core.models.profile.bankcard.DEBUG', True): b1 = BankCard.add( user_id=user.id_, mobile_phone='13800138000', card_number='6222000000000009', bank_id='4', # 建设银行 city_id='110100', # 朝阳 province_id='110000', # 北京 local_bank_name='西夏支行', is_default=True) b2 = BankCard.add( user_id=user.id_, mobile_phone='13800138000', card_number='6222000000010008', bank_id='10002', # 中信银行 city_id='110100', # 朝阳 province_id='110000', # 北京 local_bank_name='天龙寺支行', is_default=True) bcolors.run(repr(b1), key='wallet') bcolors.run(repr(b2), key='wallet') wallet_account = WalletAccount.get_or_add(user, zhongshan) t1 = WalletTransaction.add( wallet_account, b1, decimal.Decimal('40'), WalletTransaction.Type.purchase, uuid.uuid4().hex, WalletTransaction.Status.failure) t2 = WalletTransaction.add( wallet_account, b1, decimal.Decimal('42'), WalletTransaction.Type.purchase, uuid.uuid4().hex, WalletTransaction.Status.success) t3 = WalletTransaction.add( wallet_account, b2, decimal.Decimal('10'), WalletTransaction.Type.redeeming, uuid.uuid4().hex, WalletTransaction.Status.success) bcolors.run(repr(t1), key='wallet') bcolors.run(repr(t2), key='wallet') bcolors.run(repr(t3), key='wallet')
def login(alias, password, remember): # TODO deprecate this user = Account.get_by_alias(alias) if not user: return errors.err_no_such_user if user.status == ACCOUNT_STATUS.NEED_VERIFY: if ACCOUNT_REG_TYPE.MOBILE in user.reg_type: return errors.err_invalid_mobile_user_status if ACCOUNT_REG_TYPE.EMAIL in user.reg_type: return errors.err_invalid_mail_user_status else: return errors.err_invalid_user_status if not user.is_normal_account(): return if not user.verify_password(password): return errors.err_wrong_password user = login_user(user, remember) return errors.err_ok
def orders(user_alias): """Lists all orders of specific user.""" user = Account.get_by_alias(user_alias) if not user: bcolors.fail('user not found') return profile = HoardProfile.get(user.id) if not profile: bcolors.fail('profile not initialized') return for order, _, status in profile.orders(): data = [ order.id_, order.creation_time, round(order.order_amount, 2), order.service.p2pservice_name, status, ] print(u'\t'.join(map(unicode, data)))