Implement `Guard` for `Fn`
This commit is contained in:
parent
d551c982b3
commit
a19298beaf
10
src/guard.rs
10
src/guard.rs
|
@ -12,6 +12,16 @@ pub trait Guard {
|
|||
async fn check(&self, ctx: &Context<'_>) -> Result<()>;
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<T> Guard for T
|
||||
where
|
||||
T: Fn(&Context<'_>) -> Result<()> + Send + Sync + 'static,
|
||||
{
|
||||
async fn check(&self, ctx: &Context<'_>) -> Result<()> {
|
||||
self(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
/// An extension trait for `Guard`.
|
||||
pub trait GuardExt: Guard + Sized {
|
||||
/// Perform `and` operator on two rules
|
||||
|
|
|
@ -583,3 +583,46 @@ pub async fn test_guard_on_complex_object_field() {
|
|||
}]
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
pub async fn test_guard_with_fn() {
|
||||
fn is_admin(ctx: &Context<'_>) -> Result<()> {
|
||||
if ctx.data_opt::<Role>() == Some(&Role::Admin) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("Forbidden".into())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(SimpleObject)]
|
||||
struct Query {
|
||||
#[graphql(guard = "is_admin")]
|
||||
value: i32,
|
||||
}
|
||||
|
||||
let schema = Schema::new(Query { value: 10 }, EmptyMutation, EmptySubscription);
|
||||
|
||||
let query = "{ value }";
|
||||
assert_eq!(
|
||||
schema
|
||||
.execute(Request::new(query).data(Role::Admin))
|
||||
.await
|
||||
.data,
|
||||
value!({"value": 10})
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
schema
|
||||
.execute(Request::new(query).data(Role::Guest))
|
||||
.await
|
||||
.into_result()
|
||||
.unwrap_err(),
|
||||
vec![ServerError {
|
||||
message: "Forbidden".to_string(),
|
||||
source: None,
|
||||
locations: vec![Pos { line: 1, column: 3 }],
|
||||
path: vec![PathSegment::Field("value".to_owned())],
|
||||
extensions: None,
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue