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! {
|
resolvers.push(quote! {
|
||||||
if ctx.name.as_str() == #field_name {
|
if ctx.name.as_str() == #field_name {
|
||||||
use #crate_name::OutputValueType;
|
use #crate_name::OutputValueType;
|
||||||
#guard
|
|
||||||
#(#get_params)*
|
#(#get_params)*
|
||||||
|
#guard
|
||||||
let ctx_obj = ctx.with_selection_set(&ctx.selection_set);
|
let ctx_obj = ctx.with_selection_set(&ctx.selection_set);
|
||||||
return OutputValueType::resolve(&#resolve_obj, &ctx_obj, ctx.position()).await;
|
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 {
|
if ctx.name.as_str() == #field_name {
|
||||||
use #crate_name::futures::stream::{StreamExt, TryStreamExt};
|
use #crate_name::futures::stream::{StreamExt, TryStreamExt};
|
||||||
|
|
||||||
#guard
|
|
||||||
|
|
||||||
let field_name = std::sync::Arc::new(ctx.result_name().to_string());
|
|
||||||
#(#get_params)*
|
#(#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 field_selection_set = std::sync::Arc::new(ctx.selection_set.clone());
|
||||||
let schema = schema.clone();
|
let schema = schema.clone();
|
||||||
let pos = ctx.position();
|
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 {
|
if let NestedMeta::Meta(Meta::NameValue(nv)) = attr {
|
||||||
let name = &nv.path;
|
let name = &nv.path;
|
||||||
if let Lit::Str(value) = &nv.lit {
|
if let Lit::Str(value) = &nv.lit {
|
||||||
let expr = syn::parse_str::<Expr>(&value.value())?;
|
let value_str = value.value();
|
||||||
params.push(quote! { #name: #expr.into() });
|
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 {
|
} else {
|
||||||
return Err(Error::new_spanned(
|
return Err(Error::new_spanned(
|
||||||
&nv.lit,
|
&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