def login(handler, username, password=None, oath_code=None, check_bind_oath=False): sys_cfg = tp_cfg().sys msg = '' current_unix_time = int(time.mktime(datetime.datetime.now().timetuple())) # log.e('current:',current_unix_time,'validfrom:', user_info['valid_from']) err, user_info = get_by_username(username) if err != TPE_OK: return err, None, msg if user_info.privilege == 0: # 尚未为此用户设置角色 msg = '登录失败,用户尚未分配权限' return TPE_PRIVILEGE, None, msg if check_bind_oath and len(user_info['oath_secret']) != 0: return TPE_OATH_ALREADY_BIND, None, msg if user_info['state'] == TP_STATE_LOCKED: # 用户已经被锁定,如果系统配置为一定时间后自动解锁,则更新一下用户信息 if sys_cfg.login.lock_timeout != 0: if tp_timestamp_sec( ) - user_info.lock_time > sys_cfg.login.lock_timeout * 60: user_info.fail_count = 0 user_info.state = TP_STATE_NORMAL if user_info['state'] == TP_STATE_LOCKED: msg = '登录失败,用户已被临时锁定' syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_LOCKED, msg) return TPE_USER_LOCKED, None, msg elif user_info['state'] == TP_STATE_DISABLED: msg = '登录失败,用户已被禁用' syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_DISABLED, msg) return TPE_USER_DISABLED, None, msg elif user_info['state'] != TP_STATE_NORMAL: msg = '登录失败,用户状态异常' syslog.sys_log(user_info, handler.request.remote_ip, TPE_FAILED, msg) return TPE_FAILED, None, msg elif current_unix_time < user_info['valid_from'] or ( current_unix_time > user_info['valid_to'] and user_info['valid_to'] != 0): msg = '登录失败,用户已过期' syslog.sys_log(user_info, handler.request.remote_ip, TPE_FAILED, msg) return TPE_FAILED, None, msg err_msg = '' if password is not None: if user_info['type'] == TpUserType.LOCAL: # 如果系统配置了密码有效期,则检查用户的密码是否失效 if sys_cfg.password.timeout != 0: _time_now = tp_timestamp_sec() if user_info['last_chpass'] + (sys_cfg.password.timeout * 60 * 60 * 24) < _time_now: msg = '登录失败,用户密码已过期' syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, msg) return TPE_EXPIRED, None, msg if not tp_password_verify(password, user_info['password']): err, is_locked = update_fail_count(handler, user_info) if is_locked: err_msg = ',用户已被临时锁定' msg = '登录失败,密码错误{}'.format(err_msg) syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, msg) return TPE_USER_AUTH, None, msg elif user_info['type'] == TP_USER_TYPE_LDAP: try: if len(tp_cfg().sys_ldap_password) == 0: msg = 'LDAP尚未配置' syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, msg) return TPE_USER_AUTH, None, msg else: _ldap_password = tp_cfg().sys_ldap_password _ldap_server = tp_cfg().sys.ldap.server _ldap_port = tp_cfg().sys.ldap.port _ldap_base_dn = tp_cfg().sys.ldap.base_dn except: msg = 'LDAP尚未正确配置' syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, msg) return TPE_USER_AUTH, None, msg try: ldap = Ldap(_ldap_server, _ldap_port, _ldap_base_dn) ret, err_msg = ldap.valid_user(user_info['ldap_dn'], password) if ret != TPE_OK: if ret == TPE_USER_AUTH: err, is_locked = update_fail_count(handler, user_info) if is_locked: err_msg = ',用户已被临时锁定' msg = 'LDAP用户验证失败{}'.format(err_msg) syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, msg) return TPE_USER_AUTH, None, msg else: msg = 'LDAP用户登录失败,{}'.format(err_msg) syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, msg) return TPE_USER_AUTH, None, msg except: msg = 'LDAP用户登录失败,发生内部错误' syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, msg) return TPE_USER_AUTH, None, msg else: msg = '登录失败,系统内部错误' syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, msg) return TPE_USER_AUTH, None, msg if oath_code is not None: # use oath if len(user_info['oath_secret']) == 0: return TPE_OATH_MISMATCH, None, msg if not tp_oath_verify_code(user_info['oath_secret'], oath_code): err, is_locked = update_fail_count(handler, user_info) if is_locked: err_msg = ',用户已被临时锁定!' msg = '登录失败,身份验证器动态验证码错误{}'.format(err_msg) syslog.sys_log(user_info, handler.request.remote_ip, TPE_OATH_MISMATCH, msg) return TPE_OATH_MISMATCH, None, msg del user_info['password'] del user_info['oath_secret'] if len(user_info['surname']) == 0: user_info['surname'] = user_info['username'] return TPE_OK, user_info, msg
def post(self): args = self.get_argument('args', None) if args is None: return self.write_json(TPE_PARAM) try: args = json.loads(args) except: return self.write_json(TPE_JSON_FORMAT) try: mode = int(args['mode']) except: return self.write_json(TPE_PARAM) password = '' if mode == 1: # 管理员直接在后台给用户发送密码重置邮件 err = self.check_privilege(TP_PRIVILEGE_USER_CREATE) if err != TPE_OK: return self.write_json(err) try: user_id = int(args['id']) except: return self.write_json(TPE_PARAM) elif mode == 2: # 管理员直接在后台为用户重置密码 err = self.check_privilege(TP_PRIVILEGE_USER_CREATE) if err != TPE_OK: return self.write_json(err) try: user_id = int(args['id']) password = args['password'] except: return self.write_json(TPE_PARAM) elif mode == 3: # 用户自行找回密码,需要填写用户名、邮箱、验证码 try: username = args['username'] email = args['email'] captcha = args['captcha'] except: return self.write_json(TPE_PARAM) code = self.get_session('captcha') if code is None: return self.write_json(TPE_CAPTCHA_EXPIRED, '验证码已失效') if code.lower() != captcha.lower(): return self.write_json(TPE_CAPTCHA_MISMATCH, '验证码错误') self.del_session('captcha') err, user_info = user.get_by_username(username) if err != TPE_OK: return self.write_json(err) if user_info.email != email: return self.write_json(TPE_NOT_EXISTS) user_id = user_info.id elif mode == 4: # 用户通过密码重置邮件中的链接(有token验证),在页面上设置新密码,需要提供token、新密码 try: token = args['token'] password = args['password'] except: return self.write_json(TPE_PARAM) err, user_id = user.check_reset_token(token) if err != TPE_OK: return self.write_json(err) elif mode == 5: # 用户输入当前密码和新密码进行设置 try: current_password = args['current_password'] password = args['password'] except: return self.write_json(TPE_PARAM) err, user_info = user.get_by_username( self.get_current_user()['username']) if err != TPE_OK: return self.write_json(err) if not tp_password_verify(current_password, user_info['password']): return self.write_json(TPE_USER_AUTH) user_id = user_info['id'] elif mode == 6: # 用户密码过期,在登录前进行修改 try: username = args['username'] current_password = args['password'] password = args['new_password'] captcha = args['captcha'] except: return self.write_json(TPE_PARAM) code = self.get_session('captcha') if code is None: return self.write_json(TPE_CAPTCHA_EXPIRED, '验证码已失效') if code.lower() != captcha.lower(): return self.write_json(TPE_CAPTCHA_MISMATCH, '验证码错误') self.del_session('captcha') err, user_info = user.get_by_username(username) if err != TPE_OK: return self.write_json(err) # xxx 如果是密码过期而在登录前修改密码,需要额外判断用户是否已经被锁定 # 如果用户被禁用或锁定,在登录时会被拒绝,因此此处仍然允许其修改密码 # if user_info['state'] != TP_STATE_NORMAL: # if user_info['state'] == TP_STATE_LOCKED: # return self.write_json(TPE_USER_LOCKED) # elif user_info['state'] == TP_STATE_DISABLED: # return self.write_json(TPE_USER_DISABLED) # else: # return self.write_json(TPE_FAILED) if not tp_password_verify(current_password, user_info['password']): return self.write_json(TPE_USER_AUTH) user_id = user_info['id'] else: return self.write_json(TPE_PARAM) if user_id == 0: return self.write_json(TPE_PARAM) if mode == 1 or mode == 3: err, email, token = user.generate_reset_password_token( self, user_id) # generate an URL for reset password, valid in 24hr. reset_url = '{}://{}/user/reset-password?token={}'.format( self.request.protocol, self.request.host, token) err, msg = yield mail.tp_send_mail( email, 'Teleport用户,您好!\n\n请访问以下链接以重设您的teleport登录密码。此链接将于本邮件寄出24小时之后失效。\n' '访问此链接,将会为您打开密码重置页面,然后您可以设定新密码。\n\n' '如果您并没有做重设密码的操作,请忽略本邮件,请及时联系您的系统管理员!\n\n' '{reset_url}\n\n\n\n' '[本邮件由teleport系统自动发出,请勿回复]' '\n\n' ''.format(reset_url=reset_url), subject='密码重置确认函') return self.write_json(err, msg) elif mode == 2 or mode == 4 or mode == 5 or mode == 6: if len(password) == 0: return self.write_json(TPE_PARAM) # 根据需要进行弱密码检测 if tp_cfg().sys.password.force_strong: if not tp_check_strong_password(password): return self.write_json( TPE_FAILED, '密码强度太弱!强密码需要至少8个英文字符,必须包含大写字母、小写字母和数字。') password = tp_password_generate_secret(password) err = user.set_password(self, mode, user_id, password) if mode == 4 and err == TPE_OK: user.remove_reset_token(token) # 非用户自行修改密码的情况,都默认重置身份认证 if not (mode == 5 or mode == 6) and err == TPE_OK: # print("reset oath secret") user.update_oath_secret(self, user_id, '') self.write_json(err) else: self.write_json(TPE_PARAM)
def login(handler, username, password=None, oath_code=None, check_bind_oath=False): sys_cfg = tp_cfg().sys err, user_info = get_by_username(username) if err != TPE_OK: # if err == TPE_NOT_EXISTS: # syslog.sys_log({'username': username, 'surname': username}, handler.request.remote_ip, TPE_NOT_EXISTS, # '用户身份验证失败,用户`{}`不存在'.format(username)) return err, None if user_info.privilege == 0: # 尚未为此用户设置角色 return TPE_PRIVILEGE, None if check_bind_oath and len(user_info['oath_secret']) != 0: return TPE_OATH_ALREADY_BIND, None if user_info['state'] == TP_STATE_LOCKED: # 用户已经被锁定,如果系统配置为一定时间后自动解锁,则更新一下用户信息 if sys_cfg.login.lock_timeout != 0: if tp_timestamp_utc_now( ) - user_info.lock_time > sys_cfg.login.lock_timeout * 60: user_info.fail_count = 0 user_info.state = TP_STATE_NORMAL if user_info['state'] == TP_STATE_LOCKED: syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_LOCKED, '登录失败,用户已被临时锁定') return TPE_USER_LOCKED, None elif user_info['state'] == TP_STATE_DISABLED: syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_DISABLED, '登录失败,用户已被禁用') return TPE_USER_DISABLED, None elif user_info['state'] != TP_STATE_NORMAL: syslog.sys_log(user_info, handler.request.remote_ip, TPE_FAILED, '登录失败,用户状态异常') return TPE_FAILED, None err_msg = '' if password is not None: if user_info['type'] == TP_USER_TYPE_LOCAL: # 如果系统配置了密码有效期,则检查用户的密码是否失效 if sys_cfg.password.timeout != 0: _time_now = tp_timestamp_utc_now() if user_info['last_chpass'] + (sys_cfg.password.timeout * 60 * 60 * 24) < _time_now: syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, '登录失败,用户密码已过期') return TPE_USER_AUTH, None if not tp_password_verify(password, user_info['password']): err, is_locked = update_fail_count(handler, user_info) if is_locked: err_msg = ',用户已被临时锁定' syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, '登录失败,密码错误{}'.format(err_msg)) return TPE_USER_AUTH, None elif user_info['type'] == TP_USER_TYPE_LDAP: try: if len(tp_cfg().sys_ldap_password) == 0: syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP未能正确配置,需要管理员密码') return TPE_USER_AUTH, None else: _ldap_password = tp_cfg().sys_ldap_password _ldap_server = tp_cfg().sys.ldap.server _ldap_port = tp_cfg().sys.ldap.port _ldap_base_dn = tp_cfg().sys.ldap.base_dn except: syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP未能正确配置') return TPE_USER_AUTH, None try: ldap = Ldap(_ldap_server, _ldap_port, _ldap_base_dn) ret, err_msg = ldap.valid_user(user_info['ldap_dn'], password) if ret != TPE_OK: if ret == TPE_USER_AUTH: err, is_locked = update_fail_count(handler, user_info) if is_locked: err_msg = ',用户已被临时锁定' syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP用户登录失败,密码错误{}'.format(err_msg)) return TPE_USER_AUTH, None else: syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP用户登录失败,{}'.format(err_msg)) return TPE_USER_AUTH, None except: syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP用户登录失败,发生内部错误') return TPE_USER_AUTH, None else: syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, '登录失败,系统内部错误') return TPE_USER_AUTH, None if oath_code is not None: # use oath if len(user_info['oath_secret']) == 0: return TPE_OATH_MISMATCH, None if not tp_oath_verify_code(user_info['oath_secret'], oath_code): err, is_locked = update_fail_count(handler, user_info) if is_locked: err_msg = ',用户已被临时锁定!' syslog.sys_log(user_info, handler.request.remote_ip, TPE_OATH_MISMATCH, "登录失败,身份验证器动态验证码错误{}".format(err_msg)) return TPE_OATH_MISMATCH, None del user_info['password'] del user_info['oath_secret'] if len(user_info['surname']) == 0: user_info['surname'] = user_info['username'] return TPE_OK, user_info
def post(self): args = self.get_argument('args', None) if args is None: return self.write_json(TPE_PARAM) try: args = json.loads(args) except: return self.write_json(TPE_JSON_FORMAT) try: mode = int(args['mode']) except: return self.write_json(TPE_PARAM) password = '' if mode == 1: # 管理员直接在后台给用户发送密码重置邮件 err = self.check_privilege(TP_PRIVILEGE_USER_CREATE) if err != TPE_OK: return self.write_json(err) try: user_id = int(args['id']) except: return self.write_json(TPE_PARAM) elif mode == 2: # 管理员直接在后台为用户重置密码 err = self.check_privilege(TP_PRIVILEGE_USER_CREATE) if err != TPE_OK: return self.write_json(err) try: user_id = int(args['id']) password = args['password'] except: return self.write_json(TPE_PARAM) elif mode == 3: # 用户自行找回密码,需要填写用户名、邮箱、验证码 try: username = args['username'] email = args['email'] captcha = args['captcha'] except: return self.write_json(TPE_PARAM) code = self.get_session('captcha') if code is None: return self.write_json(TPE_CAPTCHA_EXPIRED, '验证码已失效') if code.lower() != captcha.lower(): return self.write_json(TPE_CAPTCHA_MISMATCH, '验证码错误') self.del_session('captcha') err, user_info = user.get_by_username(username) if err != TPE_OK: return self.write_json(err) if user_info.email != email: return self.write_json(TPE_NOT_EXISTS) user_id = user_info.id elif mode == 4: # 用户通过密码重置邮件中的链接(有token验证),在页面上设置新密码,需要提供token、新密码 try: token = args['token'] password = args['password'] except: return self.write_json(TPE_PARAM) err, user_id = user.check_reset_token(token) if err != TPE_OK: return self.write_json(err) elif mode == 5: # 用户输入当前密码和新密码进行设置 try: current_password = args['current_password'] password = args['password'] except: return self.write_json(TPE_PARAM) err, user_info = user.get_by_username(self.get_current_user()['username']) if err != TPE_OK: return self.write_json(err) if not tp_password_verify(current_password, user_info['password']): return self.write_json(TPE_USER_AUTH) user_id = user_info['id'] else: return self.write_json(TPE_PARAM) if user_id == 0: return self.write_json(TPE_PARAM) if mode == 1 or mode == 3: err, email, token = user.generate_reset_password_token(self, user_id) # generate an URL for reset password, valid in 24hr. reset_url = '{}://{}/user/reset-password?token={}'.format(self.request.protocol, self.request.host, token) err, msg = yield mail.tp_send_mail( email, 'Teleport用户,您好!\n\n请访问以下链接以重设您的teleport登录密码。此链接将于本邮件寄出24小时之后失效。\n' '访问此链接,将会为您打开密码重置页面,然后您可以设定新密码。\n\n' '如果您并没有做重设密码的操作,请忽略本邮件,请及时联系您的系统管理员!\n\n' '{reset_url}\n\n\n\n' '[本邮件由teleport系统自动发出,请勿回复]' '\n\n' ''.format(reset_url=reset_url), subject='密码重置确认函' ) return self.write_json(err, msg) elif mode == 2 or mode == 4 or mode == 5: if len(password) == 0: return self.write_json(TPE_PARAM) # 根据需要进行弱密码检测 if tp_cfg().sys.password.force_strong: if not tp_check_strong_password(password): return self.write_json(TPE_FAILED, '密码强度太弱!强密码需要至少8个英文字符,必须包含大写字母、小写字母和数字。') password = tp_password_generate_secret(password) err = user.set_password(self, user_id, password) if mode == 4 and err == TPE_OK: user.remove_reset_token(token) # 非用户自行修改密码的情况,都默认重置身份认证 if mode != 5 and err == TPE_OK: print("reset oath secret") user.update_oath_secret(self, user_id, '') self.write_json(err) else: self.write_json(TPE_PARAM)
def login(handler, username, password=None, oath_code=None, check_bind_oath=False): sys_cfg = tp_cfg().sys err, user_info = get_by_username(username) if err != TPE_OK: # if err == TPE_NOT_EXISTS: # syslog.sys_log({'username': username, 'surname': username}, handler.request.remote_ip, TPE_NOT_EXISTS, # '用户身份验证失败,用户`{}`不存在'.format(username)) return err, None if user_info.privilege == 0: # 尚未为此用户设置角色 return TPE_PRIVILEGE, None if check_bind_oath and len(user_info['oath_secret']) != 0: return TPE_OATH_ALREADY_BIND, None if user_info['state'] == TP_STATE_LOCKED: # 用户已经被锁定,如果系统配置为一定时间后自动解锁,则更新一下用户信息 if sys_cfg.login.lock_timeout != 0: if tp_timestamp_utc_now() - user_info.lock_time > sys_cfg.login.lock_timeout * 60: user_info.fail_count = 0 user_info.state = TP_STATE_NORMAL if user_info['state'] == TP_STATE_LOCKED: syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_LOCKED, '登录失败,用户已被临时锁定') return TPE_USER_LOCKED, None elif user_info['state'] == TP_STATE_DISABLED: syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_DISABLED, '登录失败,用户已被禁用') return TPE_USER_DISABLED, None elif user_info['state'] != TP_STATE_NORMAL: syslog.sys_log(user_info, handler.request.remote_ip, TPE_FAILED, '登录失败,用户状态异常') return TPE_FAILED, None err_msg = '' if password is not None: if user_info['type'] == TP_USER_TYPE_LOCAL: # 如果系统配置了密码有效期,则检查用户的密码是否失效 if sys_cfg.password.timeout != 0: _time_now = tp_timestamp_utc_now() if user_info['last_chpass'] + (sys_cfg.password.timeout * 60 * 60 * 24) < _time_now: syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, '登录失败,用户密码已过期') return TPE_USER_AUTH, None if not tp_password_verify(password, user_info['password']): err, is_locked = update_fail_count(handler, user_info) if is_locked: err_msg = ',用户已被临时锁定' syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, '登录失败,密码错误{}'.format(err_msg)) return TPE_USER_AUTH, None elif user_info['type'] == TP_USER_TYPE_LDAP: try: if len(tp_cfg().sys_ldap_password) == 0: syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP未能正确配置,需要管理员密码') return TPE_USER_AUTH, None else: _ldap_password = tp_cfg().sys_ldap_password _ldap_server = tp_cfg().sys.ldap.server _ldap_port = tp_cfg().sys.ldap.port _ldap_base_dn = tp_cfg().sys.ldap.base_dn except: syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP未能正确配置') return TPE_USER_AUTH, None try: ldap = Ldap(_ldap_server, _ldap_port, _ldap_base_dn) ret, err_msg = ldap.valid_user(user_info['ldap_dn'], password) if ret != TPE_OK: if ret == TPE_USER_AUTH: err, is_locked = update_fail_count(handler, user_info) if is_locked: err_msg = ',用户已被临时锁定' syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP用户登录失败,密码错误{}'.format(err_msg)) return TPE_USER_AUTH, None else: syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP用户登录失败,{}'.format(err_msg)) return TPE_USER_AUTH, None except: syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, 'LDAP用户登录失败,发生内部错误') return TPE_USER_AUTH, None else: syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, '登录失败,系统内部错误') return TPE_USER_AUTH, None if oath_code is not None: # use oath if len(user_info['oath_secret']) == 0: return TPE_OATH_MISMATCH, None if not tp_oath_verify_code(user_info['oath_secret'], oath_code): err, is_locked = update_fail_count(handler, user_info) if is_locked: err_msg = ',用户已被临时锁定!' syslog.sys_log(user_info, handler.request.remote_ip, TPE_OATH_MISMATCH, "登录失败,身份验证器动态验证码错误{}".format(err_msg)) return TPE_OATH_MISMATCH, None del user_info['password'] del user_info['oath_secret'] if len(user_info['surname']) == 0: user_info['surname'] = user_info['username'] return TPE_OK, user_info
def post(self): args = self.get_argument('args', None) if args is None: return self.write_json(TPE_PARAM) try: args = json.loads(args) except: return self.write_json(TPE_JSON_FORMAT) try: mode = int(args['mode']) except: return self.write_json(TPE_PARAM) password = '' if mode == 1: # 管理员直接在后台给用户发送密码重置邮件 err = self.check_privilege(TP_PRIVILEGE_USER_CREATE) if err != TPE_OK: return self.write_json(err) try: user_id = int(args['id']) except: return self.write_json(TPE_PARAM) elif mode == 2: # 管理员直接在后台为用户重置密码 err = self.check_privilege(TP_PRIVILEGE_USER_CREATE) if err != TPE_OK: return self.write_json(err) try: user_id = int(args['id']) password = args['password'] except: return self.write_json(TPE_PARAM) elif mode == 3: # 用户自行找回密码,需要填写用户名、邮箱、验证码 try: username = args['username'] email = args['email'] captcha = args['captcha'] except: return self.write_json(TPE_PARAM) code = self.get_session('captcha') if code is None: return self.write_json(TPE_CAPTCHA_EXPIRED, '验证码已失效') if code.lower() != captcha.lower(): return self.write_json(TPE_CAPTCHA_MISMATCH, '验证码错误') self.del_session('captcha') err, user_info = user.get_by_username(username) if err != TPE_OK: return self.write_json(err) if user_info.email != email: return self.write_json(TPE_NOT_EXISTS) user_id = user_info.id elif mode == 4: # 用户通过密码重置邮件中的链接(有token验证),在页面上设置新密码,需要提供token、新密码 try: token = args['token'] password = args['password'] except: return self.write_json(TPE_PARAM) err, user_id = user.check_reset_token(token) if err != TPE_OK: return self.write_json(err) elif mode == 5: # 用户输入当前密码和新密码进行设置 try: current_password = args['current_password'] password = args['password'] except: return self.write_json(TPE_PARAM) err, user_info = user.get_by_username( self.get_current_user()['username']) if err != TPE_OK: return self.write_json(err) if not tp_password_verify(current_password, user_info['password']): return self.write_json(TPE_USER_AUTH) user_id = user_info['id'] else: return self.write_json(TPE_PARAM) if user_id == 0: return self.write_json(TPE_PARAM) if mode == 1 or mode == 3: err, email, token = user.generate_reset_password_token( self, user_id) # 生成一个密码重置链接,24小时有效 # token = tp_generate_random(16) reset_url = '{}://{}/user/reset-password?token={}'.format( self.request.protocol, self.request.host, token) # reset_url = 'http://127.0.0.1/user/validate-password-reset-token?token=G66LXH0EOJ47OXTH7O5KBQ0PHXRSBXBVVFALI6JBJ8HNWUALWI35QECPJ8UV8DEQ' err, msg = yield mail.tp_send_mail( email, 'Teleport用户,您好!\n\n请访问以下链接以重设您的teleport登录密码。此链接将于本邮件寄出24小时之后失效。\n' '访问此链接,将会为您打开密码重置页面,然后您可以设定新密码。\n\n' '如果您并没有做重设密码的操作,请忽略本邮件,请及时联系您的系统管理员!\n\n' '{reset_url}\n\n\n\n' '[本邮件由teleport系统自动发出,请勿回复]' '\n\n' ''.format(reset_url=reset_url), subject='密码重置确认函') return self.write_json(err, msg) elif mode == 2 or mode == 4 or mode == 5: if len(password) == 0: return self.write_json(TPE_PARAM) # 根据需要进行弱密码检测 if tp_cfg().sys.password.force_strong: if not tp_check_strong_password(password): return self.write_json( TPE_FAILED, '密码强度太弱!强密码需要至少8个英文字符,必须包含大写字母、小写字母和数字。') password = tp_password_generate_secret(password) err = user.set_password(self, user_id, password) if mode == 4 and err == TPE_OK: user.remove_reset_token(token) self.write_json(err) else: self.write_json(TPE_PARAM)
def login(handler, username, password=None, oath_code=None, check_bind_oath=False): sys_cfg = tp_cfg().sys err, user_info = get_by_username(username) if err != TPE_OK: # if err == TPE_NOT_EXISTS: # syslog.sys_log({'username': username, 'surname': username}, handler.request.remote_ip, TPE_NOT_EXISTS, '用户身份验证失败,用户`{}`不存在'.format(username)) return err, None if user_info.privilege == 0: # 尚未为此用户设置角色 return TPE_PRIVILEGE, None if check_bind_oath == True and len(user_info['oath_secret']) != 0: return TPE_OATH_ALREADY_BIND, None if user_info['state'] == TP_STATE_LOCKED: # 用户已经被锁定,如果系统配置为一定时间后自动解锁,则更新一下用户信息 if sys_cfg.login.lock_timeout != 0: if tp_timestamp_utc_now( ) - user_info.lock_time > sys_cfg.login.lock_timeout * 60: user_info.fail_count = 0 user_info.state = TP_STATE_NORMAL if user_info['state'] == TP_STATE_LOCKED: syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_LOCKED, '登录失败,用户已被临时锁定') return TPE_USER_LOCKED, None elif user_info['state'] == TP_STATE_DISABLED: syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_DISABLED, '登录失败,用户已被禁用') return TPE_USER_DISABLED, None elif user_info['state'] != TP_STATE_NORMAL: syslog.sys_log(user_info, handler.request.remote_ip, TPE_FAILED, '登录失败,用户状态异常') return TPE_FAILED, None err_msg = '' if password is not None: # 如果系统配置了密码有效期,则检查用户的密码是否失效 if sys_cfg.password.timeout != 0: pass if not tp_password_verify(password, user_info['password']): err, is_locked = update_fail_count(handler, user_info) if is_locked: err_msg = ',用户已被临时锁定' syslog.sys_log(user_info, handler.request.remote_ip, TPE_USER_AUTH, '登录失败,密码错误{}'.format(err_msg)) return TPE_USER_AUTH, None if oath_code is not None: # use oath if len(user_info['oath_secret']) == 0: return TPE_OATH_MISMATCH, None if not tp_oath_verify_code(user_info['oath_secret'], oath_code): err, is_locked = update_fail_count(handler, user_info) if is_locked: err_msg = ',用户已被临时锁定!' syslog.sys_log(user_info, handler.request.remote_ip, TPE_OATH_MISMATCH, "登录失败,身份验证器动态验证码错误{}".format(err_msg)) return TPE_OATH_MISMATCH, None del user_info['password'] del user_info['oath_secret'] if len(user_info['surname']) == 0: user_info['surname'] = user_info['username'] return TPE_OK, user_info