Created
December 26, 2021 01:30
-
-
Save oscartbeaumont/6341b14282d6fff7f6849c62a6573128 to your computer and use it in GitHub Desktop.
Async GraphQL Field Guard on Complex Object Not Working
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "async-graphql-example" | |
version = "0.1.0" | |
authors = ["Oscar Beaumont <[email protected]>"] | |
edition = "2018" | |
[dependencies] | |
async-graphql = "3.0.17" | |
actix-web = "4.0.0-beta.14" | |
async-graphql-actix-web = "3.0.17" | |
async-trait = "0.1.52" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use actix_web::guard; | |
use actix_web::web::Data; | |
use actix_web::{web, App, HttpResponse, HttpServer, Responder}; | |
use async_graphql::http::{playground_source, GraphQLPlaygroundConfig}; | |
use async_graphql::{ | |
ComplexObject, Context, EmptyMutation, EmptySubscription, Error, Guard, Object, SimpleObject, | |
}; | |
use async_graphql_actix_web::{GraphQLRequest, GraphQLResponse}; | |
#[derive(Eq, PartialEq, Copy, Clone)] | |
enum Role { | |
Admin, | |
Guest, | |
} | |
struct RoleGuard { | |
role: Role, | |
} | |
impl RoleGuard { | |
fn new(role: Role) -> Self { | |
Self { role } | |
} | |
} | |
#[async_trait::async_trait] | |
impl Guard for RoleGuard { | |
async fn check(&self, ctx: &Context<'_>) -> Result<(), Error> { | |
if ctx.data_opt::<Role>() == Some(&self.role) { | |
Ok(()) | |
} else { | |
Err("Forbidden".into()) | |
} | |
} | |
} | |
#[derive(SimpleObject)] | |
#[graphql(complex)] | |
pub struct Test { | |
pub name: String, | |
} | |
#[ComplexObject] | |
impl Test { | |
#[graphql(guard = "RoleGuard::new(Role::Admin)")] // This line is what is causing the code to not compile | |
async fn test(&self) -> String { | |
"Hello World".into() | |
} | |
} | |
pub struct QueryRoot; | |
#[Object] | |
impl QueryRoot { | |
#[graphql(guard = "RoleGuard::new(Role::Admin)")] | |
async fn test(&self) -> Test { | |
Test { | |
name: "Oscar".into(), | |
} | |
} | |
} | |
pub type Schema = async_graphql::Schema<QueryRoot, EmptyMutation, EmptySubscription>; | |
pub async fn handler(schema: web::Data<Schema>, req: GraphQLRequest) -> GraphQLResponse { | |
schema.execute(req.into_inner()).await.into() | |
} | |
pub async fn playground() -> impl Responder { | |
HttpResponse::Ok() | |
.content_type("text/html; charset=utf-8") | |
.body(playground_source(GraphQLPlaygroundConfig::new("/"))) | |
} | |
#[actix_web::main] | |
async fn main() -> std::io::Result<()> { | |
let schema = Schema::build(QueryRoot, EmptyMutation, EmptySubscription).finish(); | |
println!("Listening http://localhost:8080/ ..."); | |
HttpServer::new(move || { | |
App::new() | |
.app_data(Data::new(schema.clone())) | |
.service(web::resource("/").guard(guard::Post()).to(handler)) | |
.service(web::resource("/").guard(guard::Get()).to(playground)) | |
}) | |
.bind(("0.0.0.0", 8080))? | |
.run() | |
.await | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment