def misc_feedback(): res = dict(msg=None, success=False) if request.method == "POST": point = request.form.get("point") content = request.form.get("content") email = request.form.get("email") check = True if point and content: if email: if not email_check(email): check = False res.update(msg="Bad mailbox format") else: check = False res.update(msg="There are invalid parameters") if check: # 初始化邮箱发送服务 sendmail = SendMail() result = sendmail.SendMessage( to_addr=SYSTEM["EMAIL"], subject=u"SaintIC Passport 用户反馈: %s" % point, formatType="html", message=u"用户预留邮箱:%s<br/>用户反馈内容:<br/>%s" % (email, content)) res.update(result) return jsonify(dfr(res))
def signUp(): if request.method == 'POST': res = dict(msg=None, code=1, nextUrl=url_for('.signUp')) if vaptcha.validate: account = request.form.get("account") vcode = request.form.get("vcode") password = request.form.get("password") repassword = request.form.get("repassword") auth = Authentication(g.mysql, g.redis) result = auth.signUp(account=account, vcode=vcode, password=password, repassword=repassword, register_ip=g.ip) #注册欢迎消息 FastPushMessage( result, "欢迎您的加入!%s使用中有任何问题,都可以反馈哦。" % ("" if email_check(account) else "您使用手机注册,已经完成实名认证!", )) if result["success"]: res.update(code=0, nextUrl=url_for('.signIn')) else: res.update(msg=result["msg"]) else: res.update(msg="Man-machine verification failed") print res return jsonify(dfr(res)) return render_template("auth/signUp.html", vaptcha=vaptcha.getChallenge)
def signIn(self, account, password): """登录接口,面向前端 参数: @param account str: 注册时的账号,邮箱/手机号 @param password str: 密码 流程: 1. 判断账号类型,仅支持邮箱、手机号两种本地账号。 2. 校验账号(是否合法、启用状态等)。 3. 校验密码(是否合格、正确)。 """ res = dict(msg=None, success=False) # NO.1 检查账号类型 if email_check(account): # 账号类型:邮箱 identity_type = 2 # NO.2 检查账号 if password and 6 <= len(password) < 30: sql = "SELECT uid,certificate FROM user_auth WHERE identity_type={} AND identifier=%s AND status=1".format(identity_type) try: data = self.db.get(sql, account) except Exception, e: logger.error(e, exc_info=True) res.update(msg="System is abnormal") else: if data and isinstance(data, dict): uid = data["uid"] certificate = data["certificate"] if check_password_hash(certificate, password): res.update(success=True, uid=uid, identity_type=identity_type) else: res.update(msg="Wrong password") else: res.update(msg="Invalid account: does not exist or has been disabled") else: res.update(msg="Invalid password: length unqualified")
def misc_sendVcode(): """发送验证码:邮箱、手机""" res = dict(msg=None, success=False) account = request.form.get("account") scene = request.form.get("scene") or request.args.get("scene") or "signUp" scenemap = dict(signUp=u"注册", bindLauth=u"绑定本地化账号", forgot=u"忘记密码") if email_check(account): # 生成验证码,校验的话,libs.auth.Authentication类中`__check_sendVcode`方法 email = account key = "passport:vcode:{}:{}".format(scene, email) try: hasKey = g.redis.exists(key) except Exception, e: logger.error(e, exc_info=True) res.update(msg="System is abnormal") else: if hasKey: res.update(msg="Have sent the verification code, please check the mailbox") else: # 初始化邮箱发送服务 sendmail = SendMail() vcode = generate_verification_code() result = sendmail.SendMessage(to_addr=email, subject=u"SaintIC Passport %s 验证码" %scenemap[scene], formatType="html", message=email_tpl % (email, scenemap[scene], vcode)) if result["success"]: try: g.redis.set(key, vcode) g.redis.expire(key, 300) except Exception, e: logger.error(e, exc_info=True) res.update(msg="System is abnormal") else: res.update(msg="Sent verification code, valid for 300 seconds", success=True) else:
def __check_sendEmailVcode(self, email, vcode, scene="signUp"): """校验发送给邮箱的验证码 @param email str: 邮箱账号 @param vcode str: 验证码 @param scene str: 校验场景 signUp-注册 signIn-登录 forgot-忘记密码 """ if email_check(email) and vcode and scene in ("signUp", "signIn", "forgot"): key = "passport:{}:vcode:{}".format(scene, email) return self.rc.get(key) == vcode return False
def __check_hasEmail(self, email): """检查是否存在邮箱账号""" if email_check(email): sql = "SELECT uid FROM user_auth WHERE identity_type=%s AND identifier=%s" try: data = self.db.get(sql, 2, email) except Exception, e: logger.warn(e, exc_info=True) else: logger.debug(data) if data and isinstance(data, dict): return "uid" in data
def __check_sendVcode(self, account, vcode, scene="signUp"): """校验发送的验证码 @param account str: 邮箱或手机号 @param vcode str: 验证码 @param scene str: 校验场景 signUp-注册 bindLauth-绑定本地账号 forgot-忘记密码 """ if email_check(account) or phone_check(account): if vcode and len(vcode) == 6 and scene in ("signUp", "bindLauth", "forgot"): key = "passport:vcode:{}:{}".format(scene, account) return self.rc.get(key) == vcode return False
def signUp(self, account, vcode, password, repassword, register_ip): """注册接口,面向前端 参数: @param account str: 注册的账号,邮箱/手机号 @param vcode str: 使用手机或邮箱的验证码 @param password str: 密码 @param repassword str: 重复密码 @param register_ip str: 注册IP地址 流程: 1. 判断账号类型,仅支持邮箱、手机号两种本地账号。 2. 校验密码、验证码是否合格、正确。 3. 密码、验证码通过后,当为邮箱时,校验邮箱是否存在;当为手机时,校验手机是否存在。 4. 生成guid,注册并响应事务结果。 """ res = dict(msg=None, success=False) # NO.1 检查账号类型 if email_check(account): # 账号类型:邮箱 # NO.2 检查密码、验证码 if password and repassword and password == repassword and 6 <= len( password) <= 30: certificate = generate_password_hash(password) if vcode and len(vcode) == 6 and self.__check_sendEmailVcode( account, vcode, scene="signUp"): # NO.3 检查账号是否存在 if self.__check_hasEmail(account): res.update(msg="Email already exists") else: guid = gen_uniqueId() upts = self.__signUp_transacion( guid=guid, identifier=account, identity_type=2, certificate=certificate, verified=1, register_ip=register_ip) res.update(upts) else: res.update(msg="Invalid verification code") else: res.update( msg= "Invalid password: Inconsistent password or length failed twice" ) elif phone_check(account): # 账号类型:手机 res.update(msg="Not support phone number registration") else: # 账号类型:非法,拒绝 res.update(msg="Invalid account") logger.info(res) return res
def __check_hasEmail(self, email, getUid=False): """检查是否存在邮箱账号,不检测账号状态""" if email_check(email): sql = "SELECT uid FROM user_auth WHERE identity_type=2 AND identifier=%s" try: data = self.db.get(sql, email) except Exception, e: logger.warn(e, exc_info=True) else: logger.debug(data) if data and isinstance(data, dict): success = "uid" in data return data["uid"] if success and getUid else success
def __createSuperuser(email, password): ''' begin的方式使用事务注册账号, 参数: @param email str: 管理员邮箱 @param password str: 账号密码 流程: 1、写入`user_auth`表 2、写入`user_profile`表 返回字典: success bool 表示注册是否成功; msg str 表示提示信息。 ''' res = dict(success=False, msg=None) # 校验 if email_check(email) and 6 <= len(password) <= 30: guid = gen_uniqueId() ctime = get_current_timestamp() try: mysql._db.begin() try: mysql.insert( "INSERT INTO user_auth (uid, identity_type, identifier, certificate, verified, status, ctime) VALUES (%s, %s, %s, %s, %s, %s, %s)", guid, 2, email, generate_password_hash(password), 1, 1, ctime) except IntegrityError: res.update(msg="Account already exists") raise except Exception, e: res.update(msg="System is abnormal") raise else: try: mysql.insert( "INSERT INTO user_profile (uid, register_source, ctime, is_admin) VALUES (%s, %s, %s, %s)", guid, 2, ctime, 1) except: raise mysql._db.commit()
def forgot(self, account, vcode, password): """忘记密码接口 参数: @param account str: 注册时的账号,邮箱/手机号 @param vcode str: 验证码 @param password str: 新设置的密码 流程: 1. 判断账号类型,仅支持邮箱、手机号两种本地账号。 2. 校验账号是否存在。 3. 校验验证码。 4. 以上3步验证通过重置uid所有类型密码 """ res = dict(msg=None, success=False) # NO.1 检查账号类型 if email_check(account): # NO.2 检查账号 uid = self.__check_hasEmail(account, getUid=True) if uid: # NO.3 检查验证码 if vcode and len(vcode) == 6 and self.__check_sendVcode( account, vcode, "forgot"): # NO.4 重置密码 if password and 6 <= len(password) <= 30: certificate = generate_password_hash(password) try: sql = "UPDATE user_auth SET certificate=%s WHERE identity_type in (1,2) AND uid=%s" data = self.db.update(sql, certificate, uid) except Exception, e: logger.error(e, exc_info=True) res.update(msg="System is abnormal") else: res.update(success=True) else: res.update(msg="Invalid password: length unqualified") else: res.update(msg="Invalid verification code") else: res.update(msg="Invalid account")
def misc_sendVcode(): """发送验证码:邮箱、手机""" res = dict(msg=None, success=False) account = request.form.get("account") if email_check(account): email = account key = "passport:signUp:vcode:{}".format(email) try: hasKey = g.redis.exists(key) except Exception, e: logger.error(e, exc_info=True) res.update(msg="System is abnormal") else: if hasKey: res.update( msg= "Have sent the verification code, please check the mailbox" ) else: vcode = generate_verification_code() result = sendmail.SendMessage(to_addr=email, subject=u"Passport邮箱注册验证码", formatType="html", message=email_tpl % (email, u"注册", vcode)) if result["success"]: try: g.redis.set(key, vcode) g.redis.expire(key, 300) except Exception, e: logger.error(e, exc_info=True) res.update(msg="System is abnormal") else: res.update( msg="Sent verification code, valid for 300 seconds", success=True) else:
res.update(msg="Registration failed") else: res.update(msg="Check failed") cli_logger.info(res) return res try: printcolor("请根据提示输入信息以创建管理员用户", "red") email = raw_input("请输入管理员邮箱账号:") password = getpass.getpass("请输入管理员账号密码:") repasswd = getpass.getpass("请确认管理员账号密码:") except KeyboardInterrupt: sys.stdout.write('\n') exit(1) else: if not email_check(email): printcolor("请输入正确的邮箱", "yellow") else: if password != repasswd: printcolor("两次密码不一致", "yellow") else: res = dfr(__createSuperuser(email, password), "zh-CN") if res["success"] is True: printcolor( "管理员注册成功,账号是<%s>,密码是<%s>,请妥善保管!" % (email, password), "green") else: printcolor(res["msg"], "yellow") if __name__ == "__main__":
def bindLauth(self, uid, account, vcode, password): """绑定本地化账号,需要密码做校验或重置 参数: @param account str: 注册时的账号,邮箱/手机号 @param vcode str: 验证码 @param password str: 密码 流程: 1. 检查参数是否合法 2. 检查账号类型、验证码 3. 检查用户是否有本地化账号 3.1 无本地化账号时,需要password参数生成密码,并且插入数据; 3.2 有本地化账号时,需要校验password是否匹配,匹配后: 3.3 如果账号类型已经绑定,则修改,否则插入 """ res = dict(msg=None, success=False, show_realname_tip=False) # NO.1 if uid and len(uid) == 22 and account and vcode and len( vcode) == 6 and password and 6 <= len(password) <= 30: # NO.2 if email_check(account) or phone_check(account): if self.__check_sendVcode(account, vcode, "bindLauth"): # NO.3 user_its = self.__list_identity_type(uid) identity_type = 1 if phone_check(account) else 2 # `绑定邮箱或手机`函数 def bindEmailOrPhone(): res = dict(success=False) sql = "INSERT INTO user_auth (uid, identity_type, identifier, certificate, verified, status, ctime) VALUES (%s, %s, %s, %s, %s, %s, %s)" try: self.db.insert(sql, uid, identity_type, account, generate_password_hash(password), 1, 1, get_current_timestamp()) except IntegrityError: res.update(msg="Account already bind") except Exception, e: logger.error(e, exc_info=True) res.update(msg="System is abnormal") else: res.update(success=True) if res["success"] and identity_type == 1: # 只有第一次绑定手机成功时设置为实名用户 res.update(show_realname_tip=True) return res # 用户的所有账号类型中包含1或2即存在本地化账号 if 1 in user_its or 2 in user_its: # NO3.2 有本地化账号 if self.__checkUserPassword(uid, password): # NO3.3 if identity_type in user_its: # 修改邮箱或手机 sql = "UPDATE user_auth SET identifier=%s,mtime=%s WHERE identity_type=%s AND uid=%s" try: self.db.update(sql, account, get_current_timestamp(), identity_type, uid) except IntegrityError: res.update(msg="Account already bind") except Exception, e: logger.error(e, exc_info=True) res.update(msg="System is abnormal") else: res.update(success=True) else: # 绑定邮箱或手机 res.update(bindEmailOrPhone()) else: res.update(msg="Wrong password") else: # NO3.1 无本地化账号, 绑定邮箱或手机 res.update(bindEmailOrPhone())