from flask import Blueprint, g, request, session from everyclass.server.user import exceptions from everyclass.server.user import service as user_service from everyclass.server.utils import generate_success_response, generate_error_response, api_helpers from everyclass.server.utils.api_helpers import login_required from everyclass.server.utils.encryption import decrypt, RTYPE_STUDENT from everyclass.server.utils.web_consts import SESSION_EMAIL_VER_REQ_ID user_api_bp = Blueprint('api_user', __name__) @user_api_bp.route('/_login', methods=["POST"]) def login(): """登录并获得token 可能的错误码: 4000 用户名或密码错误 4100 用户不存在 4101 密码错误 """ username = request.form.get("username") password = request.form.get("password") if not username: return generate_error_response(None, api_helpers.STATUS_CODE_INVALID_REQUEST, "请填写用户名") if not password: return generate_error_response(None, api_helpers.STATUS_CODE_INVALID_REQUEST, "请填写密码") if not user_service.check_password(username, password): raise exceptions.WrongPassword return generate_success_response({"token": user_service.issue_token(username)}) @user_api_bp.route('/_register_by_email') def register_by_email(): """通过邮箱验证注册 错误码: 4000 用户名未填写 4102 已经注册过了 5000 内部错误 todo:加限流 """ identifier = request.args.get("identifier") if not identifier: return generate_error_response(None, api_helpers.STATUS_CODE_INVALID_REQUEST, "请填写用户名") user_service.register_by_email(identifier) return generate_success_response(None) @user_api_bp.route('/_email_verification_check') def email_verification_check(): """验证邮箱token 错误码: 4000 token缺失 4102 用户已存在,token无效 4103 token无效 """ # todo 这里发出去的邮箱里面的链接还是网页版的,要换一下 email_token = request.args.get("token") if not email_token: return generate_error_response(None, api_helpers.STATUS_CODE_INVALID_REQUEST, "token参数缺失") request_id = user_service.register_by_email_token_check(email_token) session[SESSION_EMAIL_VER_REQ_ID] = request_id return generate_success_response(None) @user_api_bp.route('/_email_verification_set_password', methods=['POST']) def email_verification(): """邮件验证-设置密码 错误码: 4104 验证请求不存在(内部异常) 4105 当前VerificationRequest的状态并非STATUS_TKN_PASSED(排除网络卡了导致客户端没收到响应其实已经注册成功的情况) 4106 密码过弱 """ request_id = session.get(SESSION_EMAIL_VER_REQ_ID, None) if not request_id: return generate_error_response(None, api_helpers.STATUS_CODE_INVALID_REQUEST, "无效请求,请重新点击邮件中的链接") password = request.form.get("password") if not password: return generate_error_response(None, api_helpers.STATUS_CODE_INVALID_REQUEST, "请输入密码") username = user_service.register_by_email_set_password(request_id, password) return generate_success_response({"token": user_service.issue_token(username)}) @user_api_bp.route('/grants/_apply') @login_required def apply_grant(): to_user_id_encoded = request.args.get('to_user_id') if not to_user_id_encoded: return generate_error_response(None, api_helpers.STATUS_CODE_INVALID_REQUEST, "mising to_user_id") to_uid = decrypt(to_user_id_encoded, resource_type=RTYPE_STUDENT)[1] user_service.new_grant_request(g.user_id, to_uid) return generate_success_response(None) @user_api_bp.route('/grants/_my_pending') @login_required def my_pending_grants(): return generate_success_response(user_service.get_pending_requests(g.user_id)) @user_api_bp.route('/grants/<int:grant_id>/_approve') @login_required def accept_grant(grant_id: int): action = request.args.get('action') if not action: return generate_error_response(None, api_helpers.STATUS_CODE_INVALID_REQUEST, "action not found") if action == 'accept': return generate_success_response(user_service.accept_grant(grant_id, g.user_id)) elif action == 'reject': return generate_success_response(user_service.reject_grant(grant_id, g.user_id)) else: return generate_error_response(None, api_helpers.STATUS_CODE_INVALID_REQUEST, "invalid action")