Add ability to forward field arguments to guard #59
This commit is contained in:
parent
dc7c8d5280
commit
f24c6fceff
|
@ -387,8 +387,8 @@ pub fn generate(object_args: &args::Object, item_impl: &mut ItemImpl) -> Result<
|
|||
resolvers.push(quote! {
|
||||
if ctx.name.as_str() == #field_name {
|
||||
use #crate_name::OutputValueType;
|
||||
#guard
|
||||
#(#get_params)*
|
||||
#guard
|
||||
let ctx_obj = ctx.with_selection_set(&ctx.selection_set);
|
||||
return OutputValueType::resolve(&#resolve_obj, &ctx_obj, ctx.position()).await;
|
||||
}
|
||||
|
|
|
@ -238,10 +238,9 @@ pub fn generate(object_args: &args::Object, item_impl: &mut ItemImpl) -> Result<
|
|||
if ctx.name.as_str() == #field_name {
|
||||
use #crate_name::futures::stream::{StreamExt, TryStreamExt};
|
||||
|
||||
#guard
|
||||
|
||||
let field_name = std::sync::Arc::new(ctx.result_name().to_string());
|
||||
#(#get_params)*
|
||||
#guard
|
||||
let field_name = std::sync::Arc::new(ctx.result_name().to_string());
|
||||
let field_selection_set = std::sync::Arc::new(ctx.selection_set.clone());
|
||||
let schema = schema.clone();
|
||||
let pos = ctx.position();
|
||||
|
|
|
@ -196,8 +196,14 @@ pub fn parse_guards(crate_name: &TokenStream, args: &MetaList) -> Result<Option<
|
|||
if let NestedMeta::Meta(Meta::NameValue(nv)) = attr {
|
||||
let name = &nv.path;
|
||||
if let Lit::Str(value) = &nv.lit {
|
||||
let expr = syn::parse_str::<Expr>(&value.value())?;
|
||||
params.push(quote! { #name: #expr.into() });
|
||||
let value_str = value.value();
|
||||
if value_str.starts_with('@') {
|
||||
let id = Ident::new(&value_str[1..], value.span());
|
||||
params.push(quote! { #name: &#id });
|
||||
} else {
|
||||
let expr = syn::parse_str::<Expr>(&value_str)?;
|
||||
params.push(quote! { #name: #expr.into() });
|
||||
}
|
||||
} else {
|
||||
return Err(Error::new_spanned(
|
||||
&nv.lit,
|
||||
|
|
|
@ -317,3 +317,61 @@ pub async fn test_multiple_guards() {
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
pub async fn test_guard_forward_arguments() {
|
||||
struct UserGuard<'a> {
|
||||
id: &'a ID,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Guard for UserGuard<'a> {
|
||||
async fn check(&self, ctx: &Context<'_>) -> FieldResult<()> {
|
||||
if ctx.data_opt::<ID>() != Some(self.id) {
|
||||
Err("Forbidden".into())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct QueryRoot;
|
||||
|
||||
#[Object]
|
||||
impl QueryRoot {
|
||||
#[field(guard(UserGuard(id = "@id")))]
|
||||
async fn user(&self, id: ID) -> ID {
|
||||
id
|
||||
}
|
||||
}
|
||||
|
||||
let schema = Schema::new(QueryRoot, EmptyMutation, EmptySubscription);
|
||||
|
||||
let query = r#"{ user(id: "abc") }"#;
|
||||
assert_eq!(
|
||||
QueryBuilder::new(query)
|
||||
.data(ID::from("abc"))
|
||||
.execute(&schema)
|
||||
.await
|
||||
.unwrap()
|
||||
.data,
|
||||
serde_json::json!({"user": "abc"})
|
||||
);
|
||||
|
||||
let query = r#"{ user(id: "abc") }"#;
|
||||
assert_eq!(
|
||||
QueryBuilder::new(query)
|
||||
.data(ID::from("aaa"))
|
||||
.execute(&schema)
|
||||
.await
|
||||
.unwrap_err(),
|
||||
Error::Query {
|
||||
pos: Pos { line: 1, column: 3 },
|
||||
path: Some(serde_json::json!(["user"])),
|
||||
err: QueryError::FieldError {
|
||||
err: "Forbidden".to_string(),
|
||||
extended_error: None,
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user