def register_by_password(): """注册:第三步:使用密码验证注册""" if request.method == 'POST': if any( map(lambda x: not request.form.get(x, None), ("password", "password2", "jwPassword"))): flash(MSG_EMPTY_PASSWORD) return redirect(url_for("user.register_by_password")) # 密码强度检查 pwd_strength_report = zxcvbn(password=request.form["password"]) if pwd_strength_report['score'] < 2: SimplePassword.new( password=request.form["password"], sid_orig=session[SESSION_STUDENT_TO_REGISTER].sid_orig) flash(MSG_WEAK_PASSWORD) return redirect(url_for("user.register_by_password")) if request.form["password"] != request.form["password2"]: flash(MSG_PWD_DIFFERENT) return redirect(url_for("user.register_by_password")) # captcha if not TencentCaptcha.verify_old(): flash(MSG_INVALID_CAPTCHA) return redirect(url_for("user.register_by_password")) request_id = IdentityVerification.new_register_request( session[SESSION_STUDENT_TO_REGISTER].sid_orig, "password", ID_STATUS_WAIT_VERIFY, password=request.form["password"]) # call everyclass-auth to verify password with tracer.trace('register_by_password'): try: rpc_result = Auth.register_by_password( request_id=str(request_id), student_id=session[SESSION_STUDENT_TO_REGISTER].sid_orig, password=request.form["jwPassword"]) except Exception as e: return handle_exception_with_error_page(e) if rpc_result['acknowledged']: session[SESSION_PWD_VER_REQ_ID] = request_id return render_template('user/passwordRegistrationPending.html', request_id=request_id) else: return render_template('common/error.html', message=MSG_INTERNAL_ERROR) else: # show password registration page if not session.get(SESSION_STUDENT_TO_REGISTER, None): return render_template('common/error.html', message=MSG_VIEW_SCHEDULE_FIRST) return render_template("user/passwordRegistration.html", name=session[SESSION_STUDENT_TO_REGISTER].name)
def email_verification(): """注册:邮箱验证""" if request.method == 'POST': # 设置密码表单提交 if not session.get(SESSION_EMAIL_VER_REQ_ID, None): return render_template("common/error.html", message=MSG_400) req = IdentityVerification.get_request_by_id( session[SESSION_EMAIL_VER_REQ_ID]) if not req: return render_template("common/error.html", message=MSG_TOKEN_INVALID) # 此处不是一定需要验证状态,但是为了保险还是判断一下 if req["status"] != ID_STATUS_TKN_PASSED: return render_template("common/error.html", message=MSG_TOKEN_INVALID) if any( map(lambda x: not request.form.get(x, None), ("password", "password2"))): # check if empty password flash(MSG_EMPTY_PASSWORD) return redirect(url_for("user.email_verification")) if request.form["password"] != request.form["password2"]: flash(MSG_PWD_DIFFERENT) return redirect(url_for("user.email_verification")) sid_orig = req['sid_orig'] # 密码强度检查 pwd_strength_report = zxcvbn(password=request.form["password"]) if pwd_strength_report['score'] < 2: SimplePassword.new(password=request.form["password"], sid_orig=sid_orig) flash(MSG_WEAK_PASSWORD) return redirect(url_for("user.email_verification")) try: User.add_user(sid_orig=sid_orig, password=request.form['password']) except ValueError: flash(MSG_ALREADY_REGISTERED) logger.info( f"User {sid_orig} try to register again by email token. Filtered when posting." ) return redirect(url_for("user.email_verification")) del session[SESSION_EMAIL_VER_REQ_ID] IdentityVerification.set_request_status(str(req["request_id"]), ID_STATUS_PASSWORD_SET) flash(MSG_REGISTER_SUCCESS) # 查询 api-server 获得学生基本信息 try: student = Entity.get_student(sid_orig) except Exception as e: return handle_exception_with_error_page(e) # 登录态写入 session session[SESSION_CURRENT_USER] = StudentSession( sid_orig=student.student_id, sid=student.student_id_encoded, name=student.name) return redirect(url_for("user.main")) else: # 设置密码页面 if not session.get(SESSION_EMAIL_VER_REQ_ID, None): if not request.args.get("token", None): return render_template("common/error.html", message=MSG_400) with tracer.trace('verify_email_token'): try: rpc_result = Auth.verify_email_token( token=request.args.get("token", None)) except Exception as e: return handle_exception_with_error_page(e) if rpc_result.success: session[SESSION_EMAIL_VER_REQ_ID] = rpc_result.request_id IdentityVerification.set_request_status( rpc_result.request_id, ID_STATUS_TKN_PASSED) req = IdentityVerification.get_request_by_id( rpc_result.request_id) student_id = req["sid_orig"] if User.exist(student_id): flash(MSG_ALREADY_REGISTERED) logger.info( f"User {student_id} try to register again by email token. Request filtered." ) return redirect(url_for("main.main")) return render_template('user/emailVerificationProceed.html') else: return render_template("common/error.html", message=MSG_TOKEN_INVALID) else: # have session return render_template('user/emailVerificationProceed.html')
def email_verification(): """注册:邮箱验证""" if request.method == 'POST': # 设置密码表单提交 if not session.get(SESSION_VER_REQ_ID, None): return render_template("common/error.html", message=MSG_400) req = IdentityVerification.get_request_by_id(session[SESSION_VER_REQ_ID]) if not req: return render_template("common/error.html", message=MSG_TOKEN_INVALID) # 由于 SESSION_VER_REQ_ID 在密码验证和邮件验证两个验证方式中共享,当使用密码验证写入了 session 之后,如果马上在邮件验证页面 # POST,并且此处不做请求状态的判断,将会绕过验证过程直接设置密码 if req["status"] != ID_STATUS_TKN_PASSED: return render_template("common/error.html", message=MSG_TOKEN_INVALID) if any(map(lambda x: not request.form.get(x, None), ("password", "password2"))): # check if empty password flash(MSG_EMPTY_PASSWORD) return redirect(url_for("user.email_verification")) if request.form["password"] != request.form["password2"]: flash(MSG_PWD_DIFFERENT) return redirect(url_for("user.email_verification")) sid_orig = req['sid_orig'] # 密码强度检查 pwd_strength_report = zxcvbn(password=request.form["password"]) if pwd_strength_report['score'] < 2: SimplePassword.new(password=request.form["password"], sid_orig=sid_orig) flash(MSG_WEAK_PASSWORD) return redirect(url_for("user.email_verification")) User.add_user(sid_orig=sid_orig, password=request.form['password']) del session[SESSION_VER_REQ_ID] IdentityVerification.set_request_status(str(req["request_id"]), ID_STATUS_PASSWORD_SET) flash(MSG_REGISTER_SUCCESS) # 查询 api-server 获得学生基本信息 try: student = APIServer.get_student(sid_orig) except Exception as e: return handle_exception_with_error_page(e) # 登录态写入 session session[SESSION_CURRENT_USER] = StudentSession(sid_orig=student.student_id, sid=student.student_id_encoded, name=student.name) return redirect(url_for("user.main")) else: # 设置密码页面 if not session.get(SESSION_VER_REQ_ID, None): if not request.args.get("token", None): return render_template("common/error.html", message=MSG_400) with elasticapm.capture_span('verify_email_token'): try: rpc_result = Auth.verify_email_token(token=request.args.get("token", None)) except Exception as e: return handle_exception_with_error_page(e) if rpc_result['success']: session[SESSION_VER_REQ_ID] = rpc_result['request_id'] IdentityVerification.set_request_status(rpc_result['request_id'], ID_STATUS_TKN_PASSED) return render_template('user/emailVerificationProceed.html') else: return render_template("common/error.html", message=MSG_TOKEN_INVALID) else: # have session return render_template('user/emailVerificationProceed.html')