def post(self): """ @api {post} /api/user/password/reset 重置密码 @apiName UserResetPasswordHandler @apiGroup User @apiParam {String} mobile @apiParam {String} old_password @apiParam {String} new_password @apiParam {String} auth_code 验证码 @apiUse Success """ with catch(self): args = ['mobile', 'new_password', 'auth_code'] self.guarantee(*args) self.strip(*args) validate_mobile(self.params['mobile']) validate_auth_code(self.params['auth_code']) validate_user_password(self.params['new_password']) mobile, auth_code = self.params['mobile'], self.params['auth_code'] is_ok = yield self.check(mobile, auth_code) if not is_ok: return old_password = self.params.get('old_password', '') if old_password: old_password = old_password.encode('utf-8') hashed = yield self.user_service.select( fields='password', conds={'mobile': self.params['mobile']}, ct=False, ut=False, one=True) result = bcrypt.checkpw(old_password, hashed['password'].encode('utf-8')) if not result: self.error(status=ERR_TIP['password_error']['sts'], message=ERR_TIP['password_error']['msg']) return hashed = bcrypt.hashpw(self.params['new_password'].encode('utf-8'), bcrypt.gensalt()) p_strength = password_strength(self.params['new_password']) yield self.user_service.update( sets={ 'password': hashed, 'password_strength': p_strength }, conds={'mobile': self.params['mobile']}) yield self.make_session(self.params['mobile']) self.clean() self.success()
def post(self): """ @api {post} /api/user/register 用户注册 @apiName UserRegisterHandler @apiGroup User @apiParam {Number} mobile 手机号码 @apiParam {String} auth_code 验证码 @apiParam {String} password 密码 @apiSuccessExample {json} Success-Response: HTTP/1.1 200 ok { "status": int, "message": str, "data": { "token": 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MTI1NTAyMTMsImlhdCI6MTUxMTk0NTQxMywic3ViIjoxfQ.CmyWtufHH5jte3xFjvUPhiu_T2pv57qX6jxHyqju7Og' } } """ with catch(self): args = ['mobile', 'auth_code', 'password'] self.guarantee(*args) self.strip(*args) validate_mobile(self.params['mobile']) validate_auth_code(self.params['auth_code']) validate_user_password(self.params['password']) data = yield self.user_service.select( fields='id', conds={'mobile': self.params['mobile']}, ct=False, ut=False, one=True) if data: self.error(status=ERR_TIP['mobile_has_exist']['sts'], message=ERR_TIP['mobile_has_exist']['msg']) return mobile, auth_code = self.params['mobile'], self.params['auth_code'] is_ok = yield self.check(mobile, auth_code) if not is_ok: return arg = { 'mobile': mobile, 'password_strength': password_strength(self.params['password']) } yield self.user_service.add(params=arg) result = yield self.make_session(self.params['mobile'], set_token=True) self.clean() result['user'] = arg self.success(result)
def post(self): """ @api {post} /api/company/update 更新公司 @apiName CompanyUpdateHandler @apiGroup Company @apiUse cidHeader @apiParam {Number} cid 公司id @apiParam {String} name 公司名称 @apiParam {String} contact 联系人 @apiParam {String} mobile 联系方式 @apiParam {String} image_url 企业logo @apiUse Success """ with catch(self): # 参数认证 self.guarantee('cid', 'name', 'contact', 'mobile') validate_mobile(self.params['mobile']) # 公司名字是否存在 data = yield self.company_service.select(fields='id, name', ut=False, ct=False) names = [i['name'] for i in data if i['id'] != self.params['cid']] if self.params['name'] in names: err_key = 'company_name_repeat' self.error(status=ERR_TIP[err_key]['sts'], message=ERR_TIP[err_key]['msg']) return # 更新数据 old = {} for i in data: if i['id'] == self.params['cid']: old = i yield self.company_service.update( sets={ 'name': self.params['name'], 'contact': self.params['contact'], 'mobile': self.params['mobile'], 'image_url': settings['qiniu_header_bucket_url'] + self.params['image_url'] }, conds={'id': self.params['cid']}, ) # 修改名称才通知 if self.params['name'] != old['name']: employee = yield self.company_employee_service.get_employee_list(self.params['cid'], status=[APPLICATION_STATUS['accept'], APPLICATION_STATUS['founder']]) yield self.message_service.notify_change({ 'owners': employee, 'cid': self.params['cid'], 'old_name': old['name'], 'new_name': self.params['name'], 'admin_name': self.get_current_name(), }) self.success()
def post(self): """ @api {post} /api/company/new 创建公司 @apiName CompanyNewHandler @apiGroup Company @apiParam {String} name 公司名称 @apiParam {String} contact 联系人 @apiParam {String} mobile 联系方式 @apiErrorExample {json} Error-Response: HTTP/1.1 400 { "status": 10000/10001, "message": 公司已存在/公司已存在并且是员工, "data": {} } """ with catch(self): # 参数认证 self.guarantee('name', 'contact', 'mobile') validate_mobile(self.params['mobile']) # 公司是否存在/是否已经公司员工 company_info = yield self.company_service.select({'name': self.params['name']}, one=True) if company_info: err_key = 'company_exists' employee_info = yield self.company_employee_service.select({'cid': company_info['id'], 'uid': self.current_user['id']}) if employee_info: err_key = 'is_employee' self.error(status=ERR_TIP[err_key]['sts'], message=ERR_TIP[err_key]['msg']) return # 创建公司 self.params.pop('cid', None) self.params.pop('token', None) info = yield self.company_service.add(self.params) yield self.company_employee_service.add(dict(cid=info['id'], uid=self.current_user['id'], status=APPLICATION_STATUS['founder'], is_admin=1)) data = { 'cid': info['id'] } # 生成默认邀请条件 arg = {'cid': info['id'], 'setting': DEFAULT_ENTRY_SETTING, 'code': self.company_entry_setting_service.create_code(info['id'])} yield self.company_entry_setting_service.add(arg) self.success(data)
def post(self): """ @api {post} /api/user/login 验证码登陆 @apiName UserLoginHandler @apiGroup User @apiParam {String} mobile @apiParam {String} auth_code @apiUse Login """ with catch(self): # 参数认证 args = ['mobile', 'auth_code'] self.guarantee(*args) self.strip(*args) validate_mobile(self.params['mobile']) validate_auth_code(self.params['auth_code']) mobile, auth_code = self.params['mobile'], self.params['auth_code'] is_ok = yield self.check(mobile, auth_code) if not is_ok: return result = yield self.make_session(self.params['mobile'], set_token=True) cid = self.redis.hget(LOGOUT_CID, self.params['mobile']) result['cid'] = int(cid) if cid else 0 self.clean() user = yield self.user_service.select({'mobile': mobile}, one=True) result['user'] = user if not user['password']: user.pop('password', None) self.error(status=ERR_TIP['no_registered_jump']['sts'], message=ERR_TIP['no_registered_jump']['msg'], data=result) return user.pop('password', None) self.success(result) self.log.stats('AuthcodeLogin, IP: {}, Mobile: {}'.format( self.request.headers.get("X-Real-IP") or self.request.remote_ip, self.params['mobile']))
def post(self): """ @api {post} /api/user/login/password 密码登录 @apiName PasswordLoginHandler @apiGroup User @apiParam {String} mobile 手机号码 @apiParam {String} password 密码 @apiUse Login """ with catch(self): args = ['mobile', 'password'] self.guarantee(*args) self.strip(*args) validate_mobile(self.params['mobile']) validate_user_password(self.params['password']) password = self.params['password'].encode('utf-8') data = yield self.user_service.select( {'mobile': self.params['mobile']}, one=True) if not data: self.error(status=ERR_TIP['no_registered']['sts'], message=ERR_TIP['no_registered']['msg']) return hashed = data['password'].encode('utf-8') if hashed and bcrypt.checkpw(password, hashed): result = yield self.make_session(self.params['mobile'], set_token=True) cid = self.redis.hget(LOGOUT_CID, self.params['mobile']) result['cid'] = int(cid) if cid else 0 data.pop('password', None) result['user'] = data self.success(result) else: self.error(status=ERR_TIP['password_error']['sts'], message=ERR_TIP['password_error']['msg']) self.log.stats('PasswordLogin, IP: {}, Mobile: {}'.format( self.request.headers.get("X-Real-IP") or self.request.remote_ip, self.params['mobile']))
def post(self): """ @api {post} /api/company/application 员工申请提交 @apiName CompanyApplicationPostHandler @apiGroup Company @apiParam {String} code @apiParam {String} mobile @apiParam {String} name 可选 @apiParam {String} id_card 暂时移除 @apiUse Success """ with catch(self): self.guarantee('mobile') validate_mobile(self.params['mobile']) # 检验code info = yield self.company_service.fetch_with_code(self.params['code']) if not info: self.error('code不合法') return for f in info['setting'].split(','): # 临时屏蔽身份证 if f == 'id_card': continue self.guarantee(f) # 刷新用户数据 sets = {} if self.params.get('name'): sets['name'] = self.params['name'] # if self.params.get('id_card'): # validate_id_card(self.params['id_card']) # sets['id_card'] = self.params['id_card'] if sets: yield self.user_service.update(sets=sets, conds={'id': self.current_user['id']}) yield self.make_session(self.params['mobile']) # 加入员工 app_data = { 'cid': info['cid'], 'uid': self.current_user['id'] } yield self.company_employee_service.add_employee(app_data) # 组装通知的消息内容 admin_data = { 'content': MSG['application']['admin'].format(name=self.params.get('name', ''), mobile=self.params['mobile'], company_name=info['company_name']), 'mode': MSG_MODE['application'], 'sub_mode': MSG_SUB_MODE['verify'], 'tip': '{}:{}'.format(info.get('cid', ''), self.params['code']) } # 给公司管理员发送消息 admin = yield self.company_employee_service.select(fields='uid', conds={'cid': info['cid'], 'is_admin': 1}) # 给具有审核员工权限的人发送消息,若没有存在审核权限的用户会返回一个空tuple,为防止报错,下面做一次转换 has_send = [] audit = yield self.user_permission_service.select({'cid': info['cid'], 'pid': RIGHT['audit_employee']}) for i in admin + list(audit): if i['uid'] not in has_send: has_send.append(i['uid']) admin_data['owner'] = i['uid'] yield self.message_service.add(admin_data) self.success()
def post(self): """ @api {post} /api/user/sms 发送手机验证码 @apiName UserSMSHandler @apiGroup User @apiParam {String} mobile @apiParam {String} geetest_challenge @apiParam {String} geetest_validate @apiParam {String} geetest_seccode @apiSuccessExample {json} Success-Response: HTTP/1.1 200 ok { "sms_count": int } """ with catch(self): mobile = self.params['mobile'] # 参数认证 validate_mobile(mobile) # 检查手机一分钟只能发送一次锁 sms_frequence_lock = SMS_FREQUENCE_LOCK.format(mobile=mobile) has_lock = self.redis.get(sms_frequence_lock) if has_lock: self.error(status=ERR_TIP['sms_too_frequency']['sts'], message=ERR_TIP['sms_too_frequency']['msg']) return sms_sent_count_key = SMS_SENT_COUNT.format(mobile=mobile) sms_sent_count = self.get_sms_count(mobile) data = { 'sms_count': sms_sent_count, } if sms_sent_count >= SMS_SENT_COUNT_LIMIT: self.error(status=ERR_TIP['sms_over_limit']['sts'], message=ERR_TIP['sms_over_limit']['msg'], data=data) return if sms_sent_count >= SMS_NEED_GEETEST_COUNT: challenge = self.params.get('geetest_challenge', '') if not challenge: self.error(status=ERR_TIP['sms_over_three']['sts'], message=ERR_TIP['sms_over_three']['msg'], data=data) return valid = yield self.validate_captcha( challenge=self.params['geetest_challenge'], seccode=self.params['geetest_seccode'], validate=self.params['geetest_validate']) if not valid: self.error(status=ERR_TIP['fail_in_geetest']['sts'], message=ERR_TIP['sms_over_three']['msg']) return # 发送短信验证码 auth_code = gen_random_code() self.redis.setex(sms_frequence_lock, SMS_FREQUENCE_LOCK_TIMEOUT, '1') result = yield self.sms_service.send(mobile, auth_code) if result.get('err'): self.error(result.get('err')) return # 增加手机发送次数 if sms_sent_count == 0: self.redis.setex(sms_sent_count_key, SMS_SENT_COUNT_LIMIT_TIMEOUT, '1') else: self.redis.incr(sms_sent_count_key) # 设置验证码有效期 self.redis.setex(AUTH_CODE.format(mobile=mobile), SMS_EXISTS_TIME, auth_code) self.log.info('mobile: {mobile}, auth_code: {auth_code}'.format( mobile=mobile, auth_code=auth_code)) data['sms_count'] = sms_sent_count + 1 self.success(data)