def get(self): """ 得到全部用户 """ self.current_user = self.get_current_user() if not self.current_user: return self.send_error(errors.need_login) fields = base_fields + list(u.authority_map.keys()) try: self.update_login() cond = {} if u.ACCESS_MANAGER in self.authority else dict( id=self.current_user.id) users = self.db.user.find(cond) users = [ self.fetch2obj(r, u.User, fetch_authority, fields=fields) for r in users ] users.sort(key=lambda a: a.name) users = self.convert_for_send(users, trim=trim_user) self.add_op_log('get_users', context='取到 %d 个用户' % len(users)) except DbError as e: return self.send_db_error(e) response = dict(items=users, authority=self.authority, time=errors.get_date_time()) self.send_response(response)
def check_info(self, user): if not user: return self.send_error(errors.incomplete) if not user.email: return self.send_error(errors.need_email) if not user.name: return self.send_error(errors.incomplete, reason='姓名') if not user.password: return self.send_error(errors.need_password) user.email = user.email.lower() if not re_email.match(user.email): return self.send_error(errors.invalid_email) if not re_password.match(user.password) or re.match( r'^(\d+|[A-Z]+|[a-z]+)$', user.password): return self.send_error(errors.invalid_psw_format) if not re_name.match(unicode_type(user.name)): return self.send_error(errors.invalid_name, reason=user.name) user.id = errors.gen_id(user.email, 'user') user.create_time = errors.get_date_time() self.authority = user.authority = '' return True
def add_op_log(self, op_type, file_id=None, context=None): logging.info('%s,file_id=%s,context=%s' % (op_type, file_id, context)) self.db.log.insert_one(dict(type=op_type, user_id=self.current_user and self.current_user.id, file_id=file_id or None, context=context and context[:80], create_time=errors.get_date_time(), ip=self.get_ip()))
def remove_login_fails(self, email): self.db.log.delete_many({ 'type': 'login-fail', 'create_time': { '$gt': errors.get_date_time(diff_seconds=-3600) }, 'context': email })
def post(self): """ 登录 """ user = self.get_body_obj(u.User) email = user.email password = user.password if not email: return self.send_error(errors.need_email) if not password: return self.send_error(errors.need_password) email = email.lower() if not re_email.match(email): return self.send_error(errors.invalid_email) fields = base_fields + ['password'] + list(u.authority_map.keys()) try: # 检查是否多次登录失败 login_fail = { 'type': 'login-fail', 'create_time': { '$gt': errors.get_date_time(diff_seconds=-1800) }, 'context': email } times = self.db.log.count_documents(login_fail) if times >= 20: return self.send_error(errors.unauthorized, reason='请半小时后重试,或者申请重置密码') login_fail['create_time']['$gt'] = errors.get_date_time( diff_seconds=-60) times = self.db.log.count_documents(login_fail) if times >= 5: return self.send_error(errors.unauthorized, reason='请一分钟后重试') # 尝试登录,成功后清除登录失败记录,设置为当前用户 user = self.fetch2obj(self.db.user.find_one(dict(email=email)), u.User, fetch_authority, fields=fields) if not user: self.add_op_log('login-no', context=email) return self.send_error(errors.no_user, reason=email) if user.password != errors.gen_id(password): self.add_op_log('login-fail', context=email) return self.send_error(errors.invalid_password) self.current_user = user self.add_op_log('login-ok', context=email + ': ' + user.name) ResetPasswordApi.remove_login_fails(self, email) user.login_md5 = errors.gen_id(user.authority) except DbError as e: return self.send_db_error(e) user.__dict__.pop('old_password', 0) user.__dict__.pop('password', 0) user.__dict__.pop('last_time', 0) self.authority = user.authority self.set_secure_cookie('user', json_encode(self.convert2dict(user))) logging.info('login id=%s, name=%s, email=%s, auth=%s' % (user.id, user.name, user.email, user.authority)) self.send_response(user, trim=trim_user)