Пример #1
0
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})
Пример #2
0
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})
Пример #3
0
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})
Пример #4
0
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))