예제 #1
0
    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()
예제 #2
0
    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)
예제 #3
0
    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()
예제 #4
0
    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)
예제 #5
0
    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']))
예제 #6
0
    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']))
예제 #7
0
    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()
예제 #8
0
    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)