def verify_email_token(): """ 从用户输入的code判断,该用户是否有注册资格 期望格式: { "email_token": "123456" } """ email_token = request.json.get('email_token') user_info = redis_client.get("auth:email_token:%s" % email_token) if not user_info: logger.info('No user information for email token %s' % email_token) return jsonify({'success': False}) # 通过user_inf_by_token取到的数据格式为request_id:username user_info = bytes.decode(user_info).split(':') request_id, username = user_info logger.info('User %s email verification success' % username) if not check_if_request_id_exist(request_id): insert_email_account(request_id, username, email_token) redis_client.set("auth:request_status:%s" % request_id, Message.IDENTIFYING_SUCCESS, ex=86400) # valid for 1 day return jsonify({'success': True, 'request_id': request_id})
def register_by_email(): """ 通过学校邮箱验证的方式进行用户注册 期望格式: { "request_id": "123", "student_id": "3901160413" } """ request_id = request.json.get("request_id") student_id = request.json.get("student_id") username = student_id user_queue = RedisQueue("everyclass") user_queue.put({ "request_id": request_id, "username": username, "method": "email" }) redis_client.set("auth:request_status:" + request_id, Message.WAITING) logger.info('New request: %s wants to verify by email' % username) return jsonify({"acknowledged": True})
def register_by_password(): """ 通过教务系统的账户密码验证进行用户注册 期望格式: { "request_id":"54e9a329-fac0-4df3-b747-e01fd5396581", "student_id": "3901160413", "password": "" } """ request_id = request.json.get('request_id') username = request.json.get('student_id') password = request.json.get('password') user_queue = RedisQueue('everyclass') user_queue.put({ "request_id": request_id, "username": username, "password": password, "method": "password" }) redis_client.set("auth:request_status:" + request_id, Message.WAITING) logger.info('New request: %s wants to verify by password' % username) return jsonify({"acknowledged": True})
def get_result(): """ 根据 request_id 获取服务器验证结果 期望格式: { "request_id":"123" } """ request_id = str(request.json.get('request_id')) message = redis_client.get("auth:request_status:" + request_id) if not message: logger.info( 'Try to query status for a non-exist request_id: {}'.format( request_id)) return jsonify({ 'success': False, 'message': Message.INVALID_REQUEST_ID }) message = message.decode() return jsonify({ "success": True if message == Message.IDENTIFYING_SUCCESS else False, "message": message })
def handle_email_register_request(request_id: str, username: str): """ 处理redis队列中的通过邮箱验证的请求 :param request_id: str, 请求 ID :param username: str, 学号 """ from everyclass.auth import logger logger.info( "Start new thread to process handle_email_register_request, request_id: {request_id}, username: {username}" ) if check_if_request_id_exist(request_id): logger.warning("request_id reuses as primary key. Rejected.") return False, Message.INTERNAL_ERROR if check_if_have_registered(username): logger.warn("User %s try to register for a second time. " % username) email = username + "@csu.edu.cn" token = str(uuid.uuid1()) send_email(email, token) redis_client.set("auth:request_status:%s" % request_id, Message.SEND_EMAIL_SUCCESS, ex=86400) request_info = "%s:%s" % (request_id, username) redis_client.set("auth:email_token:%s" % token, request_info, ex=86400) return True, Message.SUCCESS
def send_email(email, token): """ 给指定账号发送含有指定token的邮件 :param email: str,需要发送的邮箱账号 :param token: str,需要给该邮箱账号发送的token """ from everyclass.auth import logger logger.info("Sending email to {}".format(email)) sender = config.EMAIL['SENDER'] receivers = email # message = MIMEText(token, 'html', 'utf-8') message = MIMEMultipart('related') message['From'] = _format_address("每课 <*****@*****.**>") message['To'] = _format_address("每课用户 <%s>" % email) message['Subject'] = Header('每课@CSU 学生身份验证', charset='utf-8').encode() message_alternative = MIMEMultipart('alternative') message.attach(message_alternative) with open('everyclass/auth/static/everyclass_email.html', 'r', encoding='utf-8') as email_html, open( 'everyclass/auth/static/everyclass_icon.png', 'rb') as logo_file: original_text = email_html.read() text = original_text.format(config.SERVER_BASE_URL, token) email_html.close() message_alternative.attach(MIMEText(text, 'html', 'utf-8')) # 指定图片为当前目录 message_image = MIMEImage(logo_file.read()) # 定义图片 ID,在 HTML 文本中引用 message_image.add_header('Content-ID', '<image1>') message.attach(message_image) smtp_obj = smtplib.SMTP(host=config.EMAIL['HOST'], port=config.EMAIL['PORT']) smtp_obj.connect(host=config.EMAIL['HOST'], port=config.EMAIL['PORT']) # SMTP 端口号 smtp_obj.ehlo() smtp_obj.starttls() smtp_obj.login(config.EMAIL['USERNAME'], config.EMAIL['PASSWORD']) smtp_obj.sendmail(sender, receivers, message.as_string()) smtp_obj.quit() logger.info("Email sent to {} with token {}".format(email, token))