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())
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()
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())
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())
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()
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()
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()
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()
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()
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()
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()
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()