diff --git a/src/graphql/queries/blog.rs b/src/graphql/queries/blog.rs index ad8c516..4802c3a 100644 --- a/src/graphql/queries/blog.rs +++ b/src/graphql/queries/blog.rs @@ -1,5 +1,6 @@ +use crate::auth::get_auth_user; use crate::graphql::types::{blog::*, PaginatedResult, PaginationInput}; -use crate::services::blog_service::BlogService; +use crate::services::{blog_service::BlogService, casbin_service::CasbinService}; use async_graphql::{Context, Error as GraphQLError, Object, Result}; use uuid::Uuid; @@ -16,8 +17,49 @@ impl BlogQuery { pagination: Option, ) -> Result> { let blog_service = ctx.data::()?; + + // 检查用户权限 + let mut updated_filter = filter.unwrap_or(BlogFilterInput { + title: None, + slug: None, + category_id: None, + status: None, + is_featured: None, + is_active: None, + tag_ids: None, + search: None, + date_from: None, + date_to: None, + }); + + // 尝试获取用户信息和权限检查 + match get_auth_user(ctx).await { + Ok(user) => { + // 用户已认证,检查是否有读取 blogs 的权限 + let casbin_service = ctx.data::()?; + let has_permission = casbin_service + .can_read(&user.id.to_string(), "blogs") + .await + .unwrap_or(false); + + // 如果没有权限,则只返回非 draft 状态的博客 + if !has_permission { + // 如果过滤器中没有设置状态,或者状态包含 draft,则排除 draft 状态 + if updated_filter.status.is_none() || updated_filter.status.as_ref() == Some(&"draft".to_string()) { + updated_filter.status = Some("published".to_string()); + } + } + } + Err(_) => { + // 用户未认证,只返回已发布的博客 + if updated_filter.status.is_none() || updated_filter.status.as_ref() == Some(&"draft".to_string()) { + updated_filter.status = Some("published".to_string()); + } + } + } + let result = blog_service - .get_blogs(filter, sort, pagination) + .get_blogs(Some(updated_filter), sort, pagination) .await .map_err(|e| GraphQLError::new(e.to_string()))?; @@ -37,6 +79,27 @@ impl BlogQuery { .get_blog_by_id(id) .await .map_err(|e| GraphQLError::new(e.to_string()))?; + + // 权限检查:如果是 draft 状态,需要验证用户权限 + if blog.status == "draft" { + match get_auth_user(ctx).await { + Ok(user) => { + let casbin_service = ctx.data::()?; + let has_permission = casbin_service + .can_read(&user.id.to_string(), "blogs") + .await + .unwrap_or(false); + + if !has_permission { + return Err(GraphQLError::new("Insufficient permissions to access draft content")); + } + } + Err(_) => { + return Err(GraphQLError::new("Authentication required to access draft content")); + } + } + } + Ok(blog.into()) } @@ -47,6 +110,27 @@ impl BlogQuery { .get_blog_by_slug(&slug) .await .map_err(|e| GraphQLError::new(e.to_string()))?; + + // 权限检查:如果是 draft 状态,需要验证用户权限 + if blog.status == "draft" { + match get_auth_user(ctx).await { + Ok(user) => { + let casbin_service = ctx.data::()?; + let has_permission = casbin_service + .can_read(&user.id.to_string(), "blogs") + .await + .unwrap_or(false); + + if !has_permission { + return Err(GraphQLError::new("Insufficient permissions to access draft content")); + } + } + Err(_) => { + return Err(GraphQLError::new("Authentication required to access draft content")); + } + } + } + Ok(blog.into()) } @@ -56,6 +140,26 @@ impl BlogQuery { .get_blog_detail(id) .await .map_err(|e| GraphQLError::new(e.to_string()))?; + + // 权限检查:如果是 draft 状态,需要验证用户权限 + if detail.blog.status == "draft" { + match get_auth_user(ctx).await { + Ok(user) => { + let casbin_service = ctx.data::()?; + let has_permission = casbin_service + .can_read(&user.id.to_string(), "blogs") + .await + .unwrap_or(false); + + if !has_permission { + return Err(GraphQLError::new("Insufficient permissions to access draft content")); + } + } + Err(_) => { + return Err(GraphQLError::new("Authentication required to access draft content")); + } + } + } // 手动转换 BlogDetail,因为它包含嵌套结构 Ok(BlogDetail {