Move context to new file, add to context if user is authentified
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
b20fb5f079
commit
05ca82c4e1
@ -18,8 +18,8 @@ pub struct APVariables {
|
|||||||
impl APVariables {
|
impl APVariables {
|
||||||
pub async fn check_session(
|
pub async fn check_session(
|
||||||
&self,
|
&self,
|
||||||
session_id: String,
|
session_id: &str,
|
||||||
user_id: String,
|
user_id: &str,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
let client = reqwest::Client::new();
|
let client = reqwest::Client::new();
|
||||||
let url = format!("{}/users/{}/sessions", self.endpoint, user_id);
|
let url = format!("{}/users/{}/sessions", self.endpoint, user_id);
|
||||||
|
@ -29,7 +29,7 @@ macro_rules! find_element {
|
|||||||
|
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Database {
|
pub struct Database {
|
||||||
conn: Pool<ConnectionManager<PgConnection>>,
|
conn: Pool<ConnectionManager<PgConnection>>,
|
||||||
}
|
}
|
||||||
|
49
src/graphql/context.rs
Normal file
49
src/graphql/context.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
use crate::appwrite::APVariables;
|
||||||
|
use crate::db::Database;
|
||||||
|
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone)]
|
||||||
|
pub struct Context {
|
||||||
|
pub db: Database,
|
||||||
|
pub appwrite: APVariables,
|
||||||
|
pub user_auth: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Context {
|
||||||
|
/// HTTP header for a user's session
|
||||||
|
///
|
||||||
|
/// This header `Authorization` must be a single string in the
|
||||||
|
/// form `userId;userSessionId` with `userId` and `userSessionId`
|
||||||
|
/// being variables given by Appwrite to users that are logged in.
|
||||||
|
pub async fn user_auth<'r>(&self, auth_token: Option<&'r str>) -> bool {
|
||||||
|
if let Some(token) = auth_token {
|
||||||
|
let key = token.split(';').collect::<Vec<_>>();
|
||||||
|
if key.len() == 2 {
|
||||||
|
let user_id = key[0];
|
||||||
|
let session_id = key[1];
|
||||||
|
match self.appwrite.check_session(session_id, user_id).await {
|
||||||
|
Ok(val) => val,
|
||||||
|
Err(e) => {
|
||||||
|
info!("Error checking user session: {:?}", e);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
info!("Invalid session key: {}", token);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn attach_auth<'r>(&self, auth_token: Option<&'r str>) -> Self {
|
||||||
|
let mut res = self.clone();
|
||||||
|
res.user_auth = self.user_auth(auth_token).await;
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl juniper::Context for Context {}
|
@ -1,31 +1,50 @@
|
|||||||
|
use rocket::request::{FromRequest, Outcome, Request};
|
||||||
use rocket::response::content::RawHtml;
|
use rocket::response::content::RawHtml;
|
||||||
use rocket::State;
|
use rocket::State;
|
||||||
|
|
||||||
|
use tracing::debug;
|
||||||
|
|
||||||
use juniper::EmptySubscription;
|
use juniper::EmptySubscription;
|
||||||
use juniper_rocket::{GraphQLRequest, GraphQLResponse};
|
use juniper_rocket::{GraphQLRequest, GraphQLResponse};
|
||||||
|
|
||||||
use crate::appwrite::APVariables;
|
pub mod context;
|
||||||
use crate::db::Database;
|
pub use context::Context;
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
|
||||||
pub struct Context {
|
|
||||||
pub db: Database,
|
|
||||||
pub appwrite: APVariables,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl juniper::Context for Context {}
|
|
||||||
|
|
||||||
mod query;
|
|
||||||
use query::Query;
|
|
||||||
|
|
||||||
mod mutation;
|
mod mutation;
|
||||||
use mutation::Mutation;
|
mod query;
|
||||||
|
|
||||||
type Schema =
|
#[derive(Copy, Clone, Debug)]
|
||||||
juniper::RootNode<'static, Query, Mutation, EmptySubscription<Context>>;
|
pub struct UserAuth<'r>(Option<&'r str>);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum UserAuthError {}
|
||||||
|
|
||||||
|
#[rocket::async_trait]
|
||||||
|
impl<'r> FromRequest<'r> for UserAuth<'r> {
|
||||||
|
type Error = UserAuthError;
|
||||||
|
async fn from_request(
|
||||||
|
request: &'r Request<'_>,
|
||||||
|
) -> Outcome<Self, Self::Error> {
|
||||||
|
match request.headers().get_one("Authorization") {
|
||||||
|
None => Outcome::Success(UserAuth(None)),
|
||||||
|
Some(key) => Outcome::Success(UserAuth(Some(key))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Schema = juniper::RootNode<
|
||||||
|
'static,
|
||||||
|
query::Query,
|
||||||
|
mutation::Mutation,
|
||||||
|
EmptySubscription<Context>,
|
||||||
|
>;
|
||||||
|
|
||||||
pub fn create_schema() -> Schema {
|
pub fn create_schema() -> Schema {
|
||||||
Schema::new(Query {}, Mutation {}, EmptySubscription::default())
|
Schema::new(
|
||||||
|
query::Query {},
|
||||||
|
mutation::Mutation {},
|
||||||
|
EmptySubscription::default(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rocket::get("/")]
|
#[rocket::get("/")]
|
||||||
@ -37,18 +56,26 @@ pub fn graphiql() -> RawHtml<String> {
|
|||||||
#[rocket::get("/graphql?<request>")]
|
#[rocket::get("/graphql?<request>")]
|
||||||
pub async fn get_graphql_handler(
|
pub async fn get_graphql_handler(
|
||||||
context: &State<Context>,
|
context: &State<Context>,
|
||||||
|
user_auth: UserAuth<'_>,
|
||||||
request: GraphQLRequest,
|
request: GraphQLRequest,
|
||||||
schema: &State<Schema>,
|
schema: &State<Schema>,
|
||||||
) -> GraphQLResponse {
|
) -> GraphQLResponse {
|
||||||
request.execute(schema, context).await
|
debug!("Current context: {:?}", context);
|
||||||
|
request
|
||||||
|
.execute(schema, &(*context).attach_auth(user_auth.0).await)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::needless_pass_by_value)]
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
#[rocket::post("/graphql", data = "<request>")]
|
#[rocket::post("/graphql", data = "<request>")]
|
||||||
pub async fn post_graphql_handler(
|
pub async fn post_graphql_handler(
|
||||||
context: &State<Context>,
|
context: &State<Context>,
|
||||||
|
user_auth: UserAuth<'_>,
|
||||||
request: GraphQLRequest,
|
request: GraphQLRequest,
|
||||||
schema: &State<Schema>,
|
schema: &State<Schema>,
|
||||||
) -> GraphQLResponse {
|
) -> GraphQLResponse {
|
||||||
request.execute(schema, context).await
|
debug!("Current context: {:?}", context);
|
||||||
|
request
|
||||||
|
.execute(schema, &(*context).attach_auth(user_auth.0).await)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user