Exemplo n.º 1
0
class RegisterLink(Resource):
    """
    EMail verification.
    Send verify code to user's EMail.
    """
    name = 'register_link'
    code = {}

    @args(require=['email'])
    @email_verify
    def get(self, email):
        """
        Send EMail to certain user.
        One user can only be send once per 30 min.
        :param email: GET params or JSON data.
        :return: Result.
        """
        if not _email_to_sid(email).isdigit():
            return jsonDict(False, '老师的邮箱注册暂未开放(防止对老师形成骚扰),请手动联系我们进行注册。')
        if (code_tuple := RegisterLink.code.get(email, None)) is not None:
            if datetime.now() < code_tuple[1] + timedelta(minutes=1):
                return jsonDict(False, '请1分钟后再试。')
        RegisterLink.code[email] = (vcode := str(uuid.uuid4()), datetime.now())
        try:
            email_sender = EmailSender()
            # TODO Remove the following comment mark in production.
            email_sender.send_msg(f'您的SUSTechFlow注册链接是:https://sustechflow.top/signup?vcode={vcode}', email)
            return jsonDict(True, '发送成功')
        except:
            return jsonDict(False, 'Email发送失败')
Exemplo n.º 2
0
 def put(self, username, password, email, vcode):
     """
     User registration.
     :param username: JSON data.
     :param password: JSON data.
     :param email: JSON data.
     :param vcode: Verify code JSON data.
     :return: Token and username. The token should be attached when request a *auth_required* API.
     """
     if not Verification.verify(email, vcode):
         if not RegisterLink.verify(email, vcode):
             return jsonDict(False, '验证码错误')
     permanent_token = Key.hashpw(password)
     temp_token = session.sign_jwt_token(username)
     db = db_client[db_name]
     if db.User.count_documents({"username": username}) >= 1:
         return jsonDict(False, '用户已存在')
     if db.User.count_documents({"email": email}) >= 1:
         return jsonDict(False, '用户已存在')
     ins_res = db.User.insert_one({
         "username": username,
         "email": email,
         "permanent_token": permanent_token,
         'learnt_course': []
     })
     if not ins_res.acknowledged:
         return jsonDict(False, '无法与数据库通信')
     return jsonDict(True, '注册成功', temp_token=temp_token, username=username)
Exemplo n.º 3
0
class Verification(Resource):
    """
    EMail verification.
    Send verify code to user's EMail.
    """
    name = 'verify'
    code = {}

    @args(require=['email'])
    @email_verify
    def get(self, email):
        """
        Send EMail to certain user.
        One user can only be send once per 30 min.
        :param email: GET params or JSON data.
        :return: Result.
        """
        if (code_tuple := Verification.code.get(email, None)) is not None:
            if datetime.now() < code_tuple[1] + timedelta(minutes=1):
                return jsonDict(False, '请1分钟后再试。')
        Verification.code[email] = (vcode :=
                                    str(int(random.uniform(100000, 999999))),
                                    datetime.now())
        try:
            email_sender = EmailSender()
            # TODO Remove the following comment mark in production.
            email_sender.send_msg(f'你的SUSTechFlow验证码是:{vcode}', email)
            return jsonDict(True, '发送成功')
        except:
            return jsonDict(False, 'Email发送失败')
Exemplo n.º 4
0
def rate_verify(rate):
    required_field = ['likes', 'useful', 'easy']
    if isinstance(rate, dict):
        for field in required_field:
            if rate.get(field) is None:
                return jsonDict(False, '评分数据不完整。')
        rate['ratings'] = 5
        return jsonDict(True, '', rate=rate)
    else:
        return jsonDict(False, 'rate必须是字典类型。')
Exemplo n.º 5
0
 def get(self, username):
     """
     Fetch a user's learnt course.
     :param username: Provided by *auth_required*
     :return: data: [cid] User's learnt course.
     """
     db = db_client[db_name]
     user = db.User.find_one({'username': username})
     if user is not None:
         return jsonDict(True, '', data=user['learnt_course'])
     else:
         return jsonDict(False, '用户不存在')
Exemplo n.º 6
0
 def auth_required_func(self, *args, **kwargs):
     self.parser = reqparse.RequestParser()
     self.parser.add_argument('Authorization', location='headers')
     temp_token = self.parser.parse_args()['Authorization']
     if temp_token is None:
         return jsonDict(False, '认证失败')
     success, username = session.check_jwt_token(temp_token)
     if success:
         kwargs['username'] = username
         return func(self, *args, **kwargs)
     else:
         return jsonDict(False, '认证失败')
Exemplo n.º 7
0
 def get(self, email):
     """
     Send EMail to certain user.
     One user can only be send once per 30 min.
     :param email: GET params or JSON data.
     :return: Result.
     """
     if not _email_to_sid(email).isdigit():
         return jsonDict(False, '老师的邮箱注册暂未开放(防止对老师形成骚扰),请手动联系我们进行注册。')
     if (code_tuple := Verification.code.get(email, None)) is not None:
         if datetime.now() < code_tuple[1] + timedelta(minutes=1):
             return jsonDict(False, '请1分钟后再试。')
Exemplo n.º 8
0
 def post(self, username, cids=None, cid=None):
     """
     Add learnt course(s) for certain user.
     :param username: Provided by *auth_required*
     :param cids: Bulker write to add user's learnt course, JSON list
     :param cid: Insert one learnt course, JSON data.
     :return:
     """
     db = db_client[db_name]
     if cids is not None:
         db.User.update({'username': username}, {'$addToSet': {'learnt_course': {'$each': cids}}})
     if cid is not None:
         db.User.update({'username': username}, {'$addToSet': {'learnt_course': cid}})
     if cid is None and cids is None:
         return jsonDict(False, '你至少需要提供一个参数,cid或者cids')
     return jsonDict(True, '添加成功', data=True)
Exemplo n.º 9
0
 def delete(self, username, cids=None, cid=None):
     """
     Remove learnt course(s) for certain user.
     :param username: Provided by *auth_required*
     :param cids: Bulker remove user's learnt course, JSON list
     :param cid: Remove one learnt course, JSON data.
     :return:
     """
     db = db_client[db_name]
     if cids is not None:
         db.User.update({'username': username}, {'$pull': {'learnt_course': {'$in': cids}}})
     if cid is not None:
         db.User.update({'username': username}, {'$pull': {'learnt_course': cid}})
     if cid is None and cids is None:
         return jsonDict(False, '你至少需要提供一个参数,cid或者cids')
     return jsonDict(True, '删除成功', data=False)
Exemplo n.º 10
0
 def get(self, username):
     """
     Respond the username based on request Authentication.
     :param username: Provided by *auth_required*, see its document.
     :return: username.
     """
     return jsonDict(True, msg='成功', username=username)
Exemplo n.º 11
0
 def get(self, **kwargs):
     """
     Fetch plan info.
     :param kwargs: Any filter you want.
     :return: Just Try.
     """
     db = db_client[db_name]
     return jsonDict(True, '', data=[c for c in db.Plan.find(kwargs)])
Exemplo n.º 12
0
 def get(self, **kwargs):
     """
     Fetch course basic info and their rate.
     :param kwargs: Any filter you want. JSON data.
     :return: Just Try.
     """
     db = db_client[db_name]
     return jsonDict(True, '', data=[c for c in db.Rate.find(kwargs)])
Exemplo n.º 13
0
 def get(self, **kwargs):
     db = db_client[db_name]
     comments = list(db.Comment.find(kwargs))
     for c in comments:
         if c['anonymous']:
             c['commentBy'] = '佚名'
     comments = list(filter(lambda a: a['content'] != '', comments))
     return jsonDict(True, '', data=comments)
Exemplo n.º 14
0
class User(Resource):
    """
    User registration and login.
    """
    name = 'user'

    @auth_required
    def get(self, username):
        """
        Respond the username based on request Authentication.
        :param username: Provided by *auth_required*, see its document.
        :return: username.
        """
        return jsonDict(True, msg='成功', username=username)

    @args(require=['username', 'password'])
    def post(self, username, password):
        """
        User login.
        :param username: Username, JSON data.
        :param password: Password, JSON data.
        :return: Token and username. The token should be attached when request a *auth_required* API.
        """
        db = db_client[db_name]
        if (res := db.User.find_one({'username': username})) is None:
            res = db.User.find_one({'email': username})
        if res is None:
            return jsonDict(False, '用户不存在')
        username = res['username']
        permanent_token = res['permanent_token']
        valid = Key.checkpw(password, permanent_token)
        if not valid:
            return jsonDict(False, '用户名或密码错误')
        else:
            new_temp_token = session.sign_jwt_token(username)
            db.User.find_one_and_update(
                {'username': username},
                {'$set': {
                    'temp_token': new_temp_token
                }})
            return jsonDict(True,
                            '登录成功',
                            temp_token=new_temp_token,
                            username=username)
Exemplo n.º 15
0
 def get(self, email):
     """
     Send EMail to certain user.
     One user can only be send once per 30 min.
     :param email: GET params or JSON data.
     :return: Result.
     """
     if (code_tuple := Verification.code.get(email, None)) is not None:
         if datetime.now() < code_tuple[1] + timedelta(minutes=1):
             return jsonDict(False, '请1分钟后再试。')
Exemplo n.º 16
0
 def post(self, email, vcode):
     """
     Verify whether a verify code is correct.
     :param email: User's email. JSON data.
     :param vcode: Verify code. JSON data.
     :return:
     """
     if (code_tuple := RegisterLink.code.get(email, None)) is not None:
         if vcode == code_tuple[0] and datetime.now() < code_tuple[1] + timedelta(minutes=30):
             return jsonDict(True, '验证成功')
Exemplo n.º 17
0
 def get(self, **kwargs):
     db = db_client[db_name]
     comments = list(db.Comment.find(kwargs))
     for c in comments:
         if c['anonymous']:
             c['commentBy'] = '佚名'
             c['username'] = '******'
         if not c['willing']:
             c['gpa'] = 'flag{奇迹和魔法都是存在的。}'
     comments = list(filter(lambda a: a['content'] != '', comments))
     return jsonDict(True, '', data=comments)
Exemplo n.º 18
0
 def get(self, **kwargs):
     db = db_client[db_name]
     comments = list(db.Comment.find(kwargs))
     data = {
         'likes': [0 for _ in range(11)],
         'useful': [0 for _ in range(11)],
         'easy': [0 for _ in range(11)]
     }
     for c in comments:
         for k, v in c['rate'].items():
             if k == 'ratings':
                 continue
             data[k][int(v * 2)] += 1
     return jsonDict(True, '', data=data)
Exemplo n.º 19
0
 def put(self, **kwargs):
     rate_tuple = rate_verify(kwargs['rate'])
     if rate_tuple['success']:
         kwargs['rate'] = rate_tuple['rate']
         kwargs['helpful'] = 0
         kwargs['year'] = datetime.now().year
         kwargs['month'] = datetime.now().month
         kwargs['day'] = datetime.now().day
         kwargs['commentBy'] = kwargs['username']
         del kwargs['username']
         db = db_client[db_name]
         db.Comment.find_one_and_replace({'cid': kwargs['cid'], 'commentBy': kwargs['commentBy']}, kwargs, upsert=True)
         return jsonDict(True, '评论成功!')
     else:
         return rate_tuple
Exemplo n.º 20
0
 def get(self):
     db = db_client[db_name]
     majors = db.Plan.distinct('major')
     majors = list(filter(lambda c: c is not None and '通识' not in c, majors))
     return jsonDict(True, '', data=majors)
Exemplo n.º 21
0
 def get(self, **kwargs):
     db = db_client[db_name]
     return jsonDict(True, '', data=db.Comment.find_one(kwargs))
Exemplo n.º 22
0
                                    str(int(random.uniform(100000, 999999))),
                                    datetime.now())
        try:
            email_sender = EmailSender()
            # TODO Remove the following comment mark in production.
            email_sender.send_msg(f'你的SUSTechFlow验证码是:{vcode}', email)
            return jsonDict(True, '发送成功')
        except:
            return jsonDict(False, 'Email发送失败')

    @args(require=['email', 'vcode'])
    @email_verify
    def post(self, email, vcode):
        """
        Verify whether a verify code is correct.
        :param email: User's email. JSON data.
        :param vcode: Verify code. JSON data.
        :return:
        """
        if (code_tuple := Verification.code.get(email, None)) is not None:
            if vcode == code_tuple[0] and datetime.now(
            ) < code_tuple[1] + timedelta(minutes=30):
                return jsonDict(True, '验证成功')
        return jsonDict(False, '验证码错误')

    @staticmethod
    def verify(email, vcode):
        if (code_tuple := Verification.code.get(email, None)) is not None:
            return code_tuple[0] == str(vcode)
        return False
Exemplo n.º 23
0
                            username=username)

    @args(require=['username', 'password', 'new_password'])
    def patch(self, username, password, new_password):
        """
        Change user's password. NOT USED AND TESTED YET.
        :param username:
        :param password:
        :param new_password:
        :return:
        """
        db = db_client[db_name]
        if (res := db.User.find_one({'username': username})) is None:
            res = db.User.find_one({'email': username})
        if res is None:
            return jsonDict(False, '用户不存在')
        username = res['username']
        if res is None:
            return jsonDict(False, '用户不存在')
        permanent_token = res['permanent_token']
        valid = Key.checkpw(password, permanent_token)
        if not valid:
            return jsonDict(False, '用户名或密码错误')
        else:
            new_permanent_token = Key.hashpw(new_password)
            db.User.find_one_and_update(
                {'username': username},
                {'$set': {
                    'permanent_token': new_permanent_token
                }})
            return jsonDict(True, '修改成功')
Exemplo n.º 24
0
 def get(self, **kwargs):
     db = db_client[db_name]
     course_info = db.Course.aggregate([
         {
             '$match': kwargs
         },
         {
             '$lookup': {
                 'from': 'Detail',
                 'localField': 'cid',
                 'foreignField': 'cid',
                 'as': 'detail'
             }
         },
         {
             '$lookup': {
                 'from':
                 'Comment',
                 'let': {
                     'course_cid': '$cid'
                 },
                 'pipeline': [
                     {
                         '$match': {
                             '$expr': {
                                 '$eq': ['$cid', '$$course_cid']
                             }
                         }
                     },
                     {
                         '$replaceRoot': {
                             'newRoot': '$rate'
                         }
                     },
                 ],
                 'as':
                 "rate"
             }
         },
         {
             '$project': {
                 'rate': {
                     '$concatArrays': [[{
                         'ratings': 0,
                         'likes': 0,
                         'useful': 0,
                         'easy': 0
                     }], '$rate']
                 },
                 'cid': '$cid',
                 'name': '$name',
                 'faculty': '$faculty',
                 'detail': '$detail',
                 'taughtBy': '$taughtBy'
             }
         },
         {
             '$lookup': {
                 'from':
                 'Plan',
                 'let': {
                     'course_cid': '$cid'
                 },
                 'pipeline': [{
                     '$match': {
                         '$expr': {
                             '$eq': ['$cid', '$$course_cid']
                         }
                     }
                 }, {
                     '$group': {
                         '_id': '$grade',
                         'grade': {
                             '$first': '$grade'
                         },
                         'gradePlan': {
                             '$addToSet': {
                                 'optionalType': '$optionalType',
                                 'faculty': '$faculty',
                                 'major': '$major',
                                 'category': '$category',
                             }
                         },
                     }
                 }, {
                     '$unwind': '$gradePlan'
                 }],
                 'as':
                 'plan'
             }
         },
         {
             '$unwind': '$detail'
         },
         {
             '$group': {
                 '_id': '$cid',
                 'cid': {
                     '$first': '$cid'
                 },
                 'name': {
                     '$first': '$name'
                 },
                 'taughtBy': {
                     '$addToSet': '$taughtBy'
                 },
                 'detail': {
                     '$first': '$detail'
                 },
                 'ratings': {
                     '$first': {
                         '$sum': '$rate.ratings'
                     }
                 },
                 'likes': {
                     '$first': {
                         '$sum': '$rate.likes'
                     }
                 },
                 'useful': {
                     '$first': {
                         '$sum': '$rate.useful'
                     }
                 },
                 'easy': {
                     '$first': {
                         '$sum': '$rate.easy'
                     }
                 },
                 'plan': {
                     '$first': '$plan'
                 }
             }
         },
     ])
     return jsonDict(True, '', data=[c for c in course_info][0])