Esempio n. 1
0
    def get_service_by_uuid(self, service_uuid):
        with session_scope() as session:
            service = session.query(Service).filter(Service.uuid == service_uuid,
                                                    Service.status != Service.STATUS.DELETED).first()
            if service is None:
                raise exception.api.NotFound('套餐不存在')

            if service.user_uuid != self.user_uuid:
                raise exception.api.Forbidden('无权查看其他用户的套餐信息')

            template = session.query(ServiceTemplate) \
                .filter(ServiceTemplate.uuid == service.template_uuid).first()
            service_dict = service.to_dict()
            service_dict['title'] = template.title
            service_dict['price'] = float(template.price)

            result = ApiResult('获取学术服务详情成功', payload={
                'service': service_dict
            })
            return make_response(result.to_response())
    def get(self):
        role_id = self.get_data('role_id')
        return_all_permissions = self.get_data('all_permissions')

        with session_scope() as db_session:
            if not permission.toolkit.check_manage_role_permission(
                    db_session, self.user_id):
                raise exception.api.Forbidden('当前用户无权进行角色权限管理')

            all_permission_list = None
            if return_all_permissions:
                all_permission_list = []
                all_permissions = db_session.query(Permission).all()
                for p in all_permissions:
                    all_permission_list.append(to_dict(p))

            data = None
            if self.valid_data(role_id):
                role = db_session.query(Role).filter(
                    Role.id == role_id).first()

                permissions = db_session.query(Permission) \
                    .filter(Role.id == RolePermission.role_id) \
                    .filter(RolePermission.permission_id == Permission.id) \
                    .filter(Role.id == role_id)
                permission_list = []
                for p in permissions:
                    permission_list.append(to_dict(p))
                data = {
                    'role_id': role_id,
                    'role_name': role.name,
                    'role_label': role.label,
                    'role_description': role.description,
                    'permissions': permission_list
                }

        payload = data if data is not None else {}
        if all_permission_list is not None:
            payload['all_permissions'] = all_permission_list
        result = ApiResult('获取权限信息成功', payload=payload)
        return make_response(result.to_response())
Esempio n. 3
0
    def get(self):
        with session_scope() as session:
            template_list = []
            query = self.derive_query_for_get_method(session, ServiceTemplate) \
                .filter(ServiceTemplate.status != ServiceTemplate.STATUS.DELETED)
            page, page_size, offset, max_page = self.derive_page_parameter(
                query.count())
            templates = query.limit(page_size).offset(offset).all()
            for template in templates:  # type: ServiceTemplate
                # template_dict = template.to_dict()
                # template_list.append(template_dict)
                template_list.append(template.to_dict())

            result = ApiResult('获取学术服务信息成功',
                               payload={
                                   'templates': template_list,
                                   'page': page,
                                   'page_size': page_size,
                                   'max_page': max_page,
                               })
            return result.to_response()
Esempio n. 4
0
    def delete(self):
        # TODO 软删除
        role_id = self.get_data('id')
        if not self.valid_data(role_id):
            role_id = self.get_post_data('id',
                                         require=True,
                                         error_message='所需删除的角色id不能为空')

        with session_scope() as session:

            if not permission.toolkit.check_manage_role_permission(
                    session, self.user_id):
                raise exception.api.Forbidden('当前用户无法管理角色')

            # 判断是否有user的角色是待删除角色
            users = session.query(User) \
                .filter(UserRole.user_id == User.id) \
                .filter(UserRole.role_id == Role.id) \
                .filter(Role.id == role_id).all()

            if users is not None and len(users) > 0:
                raise exception.api.InvalidRequest(
                    '当前还有{}位用户的角色为待删除角色,故无法删除该角色'.format(users))

            # 从role表删除记录
            role = session.query(Role).filter_by(id=role_id).first()
            if role is None:
                raise exception.api.NotFound('需要删除的角色不存在')
            session.delete(role)

            # 从role_permission表删除记录
            role_permissions = session.query(RolePermission) \
                .filter(Role.id == role_id) \
                .filter(Role.id == RolePermission.role_id).all()
            for role_permission in role_permissions:
                session.delete(role_permission)

        result = ApiResult('删除角色成功')
        return make_response(result.to_response())
Esempio n. 5
0
    def patch(self):
        target_user_id = self.get_post_data('user_id',
                                            require=True,
                                            error_message='缺少user_id字段')
        role_id = self.get_post_data('role_id',
                                     require=True,
                                     error_message='缺少role_id字段')

        with session_scope() as db_session:
            if not permission.toolkit.check_manage_role_permission(
                    db_session, self.user_id):
                raise exception.api.Forbidden('当前用户无法管理用户角色')

            user_role = db_session.query(UserRole) \
                .filter(User.id == UserRole.user_id) \
                .filter(UserRole.role_id == Role.id) \
                .filter(User.id == target_user_id).first()

            user_role.role_id = role_id

        result = ApiResult('修改用户角色成功')
        return make_response(result.to_response())
Esempio n. 6
0
    def get(self):
        user_uuid = self.get_data('uuid')
        if self.valid_data(user_uuid):
            return self.get_single_user(user_uuid)

        with session_scope() as session:
            user_list = []
            query = self.derive_query_for_get_method(session, User) \
                .filter(User.status != User.STATUS.DELETED)
            record_count = query.count()
            page, page_size, offset, max_page = self.derive_page_parameter(
                record_count)
            users = query.offset(offset).limit(page_size).all()
            for user in users:  # type: User
                user_object = user.to_dict()

                user_login_log = session.query(UserLoginLog).filter(
                    UserLoginLog.user_uuid == user.uuid, UserLoginLog.status ==
                    UserLoginLog.STATUS.ACTIVATED.value).order_by(
                        UserLoginLog.created_at.desc()).first(
                        )  # type: UserLoginLog
                if user_login_log is None:
                    user_object['last_login_at'] = user.created_at.isoformat()
                else:
                    user_object[
                        'last_login_at'] = user_login_log.created_at.isoformat(
                        )

                user_list.append(user_object)

            result = ApiResult('获取用户信息成功',
                               payload={
                                   'users': user_list,
                                   'page': page,
                                   'page_size': page_size,
                                   'max_page': max_page,
                                   'total': record_count,
                               })
            return result.to_response()
Esempio n. 7
0
    def get_event_detail(self, event_uuid):
        with session_scope() as session:
            event = session.query(Event).filter(
                Event.uuid == event_uuid).first()
            if event is None:
                raise exception.api.NotFound('公告不存在')

            data = event.to_dict()
            data['content'] = data['content'].replace(
                '{{ image }}', configs.URL_OF_BLOG_IMAGE)

            html_version = self.get_data('html')
            if html_version:
                html_content = markdown2.markdown(
                    event.content,
                    extras=['fenced-code-blocks', 'tables', 'toc'])
                html_content = html_content.replace('{{ image }}',
                                                    configs.URL_OF_BLOG_IMAGE)
                data['html'] = html_content

            result = ApiResult('获取公告成功', payload={'event': data})
            return result.to_response()
    def get(self):
        user_uuid = self.get_data('user_uuid')
        if self.valid_data(user_uuid):
            return self.get_single_account(user_uuid)

        with session_scope() as session:
            account_list = []
            query = self.derive_query_for_get_method(session, ScholarPaymentAccount) \
                .filter(ScholarPaymentAccount.status != ScholarPaymentAccount.STATUS.DELETED.value)
            page, page_size, offset, max_page = self.derive_page_parameter(
                query.count())
            accounts = query.offset(offset).limit(page_size).all()
            for account in accounts:  # type: ScholarPaymentAccount
                account_list.append(account.to_dict())

            result = ApiResult('获取学术积分账户信息成功',
                               payload={
                                   'accounts': account_list,
                                   'page': page,
                                   'page_size': page_size,
                                   'max_page': max_page,
                               })
            return result.to_response()
    def get(self):
        cache_key = 'api-today-in-history-{}'.format(
            datetime.now().strftime('%Y-%m-%d'))
        today_in_history_json_str = cache.get(cache_key)
        if not self.valid_data(today_in_history_json_str):
            api_url = 'http://www.ipip5.com/today/api.php'
            params = {'type': 'json'}
            response = requests.get(api_url, params=params, verify=False)
            if response.ok:
                today_in_history_json_str = response.text
                cache.set(cache_key, today_in_history_json_str)
            else:
                raise exception.api.ServiceUnavailable('获取历史上的今天数据失败')

        try:
            payload = json.loads(today_in_history_json_str)
        except:
            cache.delete(cache_key)
            raise exception.api.ServiceUnavailable(
                '获取历史上的今天数据失败,数据源返回的数据异常,请稍后再试')

        result = ApiResult('获取历史上的今天数据成功', payload=payload)
        return result.to_response()
Esempio n. 10
0
    def get_single_user(self, user_uuid):
        with session_scope() as session:
            user = session.query(User) \
                .filter(User.uuid == user_uuid,
                        User.status != User.STATUS.DELETED).first()  # type: User

            if user is None:
                raise exception.api.NotFound('用户不存在')

            user_object = user.to_dict()

            user_login_log = session.query(UserLoginLog).filter(
                UserLoginLog.user_uuid == user.uuid,
                UserLoginLog.status == UserLoginLog.STATUS.ACTIVATED.value
            ).order_by(
                UserLoginLog.created_at.desc()).first()  # type: UserLoginLog
            if user_login_log is None:
                user_object['last_login_at'] = user.created_at.isoformat()
            else:
                user_object[
                    'last_login_at'] = user_login_log.created_at.isoformat()

            result = ApiResult('获取用户信息成功', payload={'user': user_object})
            return result.to_response()
Esempio n. 11
0
    def get_recommendation_template(self):
        size = self.get_data('size')
        try:
            size = int(size)
        except ValueError:
            size = 3

        with session_scope() as session:
            monthly_templates = session.query(ServiceTemplate) \
                .filter(ServiceTemplate.type == ServiceTemplate.TYPE.MONTHLY,
                        ServiceTemplate.status == ServiceTemplate.STATUS.VALID) \
                .order_by(ServiceTemplate.created_at.desc()).limit(size).all()

            data_templates = session.query(ServiceTemplate) \
                .filter(ServiceTemplate.type == ServiceTemplate.TYPE.DATA,
                        ServiceTemplate.status == ServiceTemplate.STATUS.VALID) \
                .order_by(ServiceTemplate.created_at.desc()).limit(size).all()

            result = ApiResult(
                '获取服务模板信息成功', 200, {
                    'monthly_services': self.models_to_list(monthly_templates),
                    'data_services': self.models_to_list(data_templates),
                })
            return result.to_response()
Esempio n. 12
0
    def generate_renew_order(self, service_uuid: str):
        """
        生成续费订单

        :param service_uuid:
        :return:
        """
        with session_scope() as session:
            service = session.query(Service).filter(
                Service.uuid == service_uuid, Service.status !=
                Service.STATUS.DELETED).first()  # type: Service
            if service is None:
                raise exception.api.NotFound('学术服务不存在,无法续费')
            if service.status == Service.STATUS.INVALID:
                raise exception.api.InvalidRequest('由于学术服务长时间没有续费,已被系统回收,无法续费')
            if service.type == Service.TYPE.MONTHLY:
                raise exception.api.InvalidRequest(
                    '包月学术服务无法手动续费,请在每月的账单日支付系统自动生成的续费账单即可完成续费')
            if service.usage / service.package < 0.8:
                raise exception.api.Forbidden('剩余流量大于总流量的20%,暂无法续费')

            conflict, snapshot = trade_order.toolkit.check_is_order_conflict(
                session,
                service.user_uuid,
                service_uuid=service.uuid,
            )
            if conflict:
                raise exception.api.Conflict('有尚未支付的『{}』的订单,请勿重复下单'.format(
                    snapshot.title))

            service_template = session.query(ServiceTemplate) \
                .filter(ServiceTemplate.uuid == service.template_uuid,
                        ServiceTemplate.status != ServiceTemplate.STATUS.DELETED).first()  # type: ServiceTemplate
            if service_template is None:
                raise exception.api.NotFound('套餐不存在,无法办理')
            if service_template.status == ServiceTemplate.STATUS.SUSPEND:
                raise exception.api.ServiceUnavailable('该套餐已下架,无法办理')

            total_payment = service_template.price

            order = TradeOrder(user_uuid=service.user_uuid,
                               order_type=TradeOrder.TYPE.CONSUME.value,
                               amount=total_payment,
                               description='续费学术服务,服务UUID:{}'.format(
                                   service.uuid))
            session.add(order)
            session.flush()

            snapshot = SubscribeServiceSnapshot(
                trade_order_uuid=order.uuid,
                user_uuid=service.user_uuid,
                service_password=service.password,
                auto_renew=service.auto_renew,
                service_template_uuid=service.template_uuid,
                service_type=service.type,
                title=service_template.title,
                subtitle=service_template.subtitle,
                description=service_template.description,
                package=service_template.package,
                price=service_template.price,
                initialization_fee=service_template.initialization_fee)
            session.add(snapshot)

            relationship = ServiceTradeOrder(
                service_uuid=service.uuid,
                trade_order_uuid=order.uuid,
            )
            session.add(relationship)

            result = ApiResult('订单创建成功', 201, {
                'uuid': order.uuid,
            })
            return result.to_response()
Esempio n. 13
0
    def pay_order_by_scholar_payment_system(trade_order_uuid):
        scholar_payment_system.toolkit.pay_order(trade_order_uuid)

        result = ApiResult('支付订单的请求已收到,正在后台支付', 200)
        return result.to_response()
Esempio n. 14
0
    def post(self):
        username = self.get_post_data('username',
                                      require=True,
                                      error_message='请输入用户名或邮箱')
        password = self.get_post_data('password',
                                      require=True,
                                      error_message='请输入密码')

        with session_scope() as session:
            user = session.query(User) \
                .filter(User.username == username, User.status != User.STATUS.DELETED).first()  # type:User
            if user is None:
                user = session.query(User).filter(
                    User.email == username,
                    User.status != User.STATUS.DELETED).first()
                if user is None:
                    raise exception.api.NotFound('用户不存在')

            hashed_password = authorization.toolkit.hash_plaintext(password)

            if user.password != hashed_password:
                sha1 = hashlib.sha1()
                sha1.update(password.encode('utf-8'))
                legacy_password = sha1.hexdigest()

                sha1 = hashlib.sha1()
                sha1.update(configs.SHA1_SALT.encode('utf-8'))
                sha1.update(b':')
                sha1.update(legacy_password.encode('utf-8'))
                legacy_hash_password = sha1.hexdigest()

                if user.password != legacy_hash_password:
                    raise exception.api.InvalidRequest('密码错误,请重试')
                else:
                    user.password = hashed_password

            if user.status == User.STATUS.SUSPENDED:
                raise exception.api.Forbidden('用户已申请停用账号,如需恢复使用,请联系管理员')

            if not permission.toolkit.check_login_permission(
                    session, user.uuid):
                user_role = session.query(UserRole).filter(
                    UserRole.user_uuid == user.uuid).first()  # type: UserRole
                if user_role is None:
                    role = session.query(Role).filter(
                        Role.name == Role.BuiltInRole.REGISTRATION_USER.value.
                        name).first()  # type: Role
                    user_role = UserRole(user.uuid, role.uuid)
                    session.add(user_role)
                    session.commit()

                role = session.query(Role).filter(
                    Role.uuid == user_role.role_uuid).first()  # type: Role

                if role is not None and role.name == Role.BuiltInRole.BAN_LIST.value.name:
                    raise exception.api.Forbidden('该用户已被拉黑,请联系管理员进行申诉')

            login_log = UserLoginLog(user_uuid=user.uuid,
                                     ip=request.remote_addr)
            session.add(login_log)

            result = ApiResult('登录成功',
                               payload={
                                   'jwt':
                                   authorization.toolkit.derive_jwt_token(
                                       user_id=user.id, user_uuid=user.uuid)
                               })
            return result.to_response()
Esempio n. 15
0
    def post(self):
        re_email = re.compile(
            r'^[a-z0-9\.\-\_]+\@[a-z0-9\-\_]+(\.[a-z0-9\-\_]+){1,4}$')

        username = self.get_post_data('username',
                                      require=True,
                                      error_message='请输入用户名')
        email = self.get_post_data('email',
                                   require=True,
                                   error_message='请输入邮箱')
        if not re_email.match(email):
            raise exception.api.InvalidRequest('请输入正确的邮箱')
        password = self.get_post_data('password',
                                      require=True,
                                      error_message='请输入密码')
        code = self.get_post_data('invitation_code',
                                  require=True,
                                  error_message='请输入邀请码')

        with session_scope() as session:
            user = session.query(User).filter(
                User.username == username,
                User.status != User.STATUS.DELETED).first()
            if user is not None:
                raise exception.api.Conflict('用户名已被注册')
            user = session.query(User).filter(
                User.email == email, ~User.status.in_(
                    [User.STATUS.DELETED, User.STATUS.INACTIVATED])).first()
            if user is not None:
                return exception.api.Conflict('邮箱已被注册')

            invitation_code = session.query(InvitationCode) \
                .filter(InvitationCode.code == code).first()  # type:InvitationCode
            if invitation_code is None:
                raise exception.api.NotFound('邀请码不存在')
            elif invitation_code.status != 1:
                raise exception.api.Conflict('邀请码已被使用')

            # 将记录写入user表
            hashed_password = authorization.toolkit.hash_plaintext(password)
            user = User(username=username.strip(),
                        email=email,
                        password=hashed_password)  # type: User

            session.add(user)
            session.flush()

            # 进行角色关联
            role = session.query(Role).filter(
                Role.name == Role.BuiltInRole.REGISTRATION_USER.value.name,
                Role.status == Role.Status.VALID.value).first()  # type: Role
            user_role = UserRole(user_uuid=user.uuid, role_uuid=role.uuid)
            session.add(user_role)

            # 将记录写入invitation_code表
            invitation_code.status = 2
            invitation_code.invitee_uuid = user.uuid
            invitation_code.invited_at = datetime.now()

            # 创建学术积分账户
            scholar_payment_account = ScholarPaymentAccount(
                user_uuid=user.uuid,
                balance=0,
            )
            session.add(scholar_payment_account)

            self.send_activation_email(user)

            result = ApiResult('注册成功',
                               status=201,
                               payload={
                                   'jwt':
                                   authorization.toolkit.derive_jwt_token(
                                       user_id=user.id, user_uuid=user.uuid)
                               })
            return result.to_response()