From 206d45bb31e1afa1fea16d0194c107d302d0a593 Mon Sep 17 00:00:00 2001 From: reivilibre Date: Fri, 17 May 2024 17:22:34 +0100 Subject: [PATCH] Merge the `mas_graphql` crate into the `mas_handlers` crate (#2783) --- Cargo.lock | 26 +-- crates/cli/Cargo.toml | 1 - crates/cli/src/app_state.rs | 6 +- crates/graphql/Cargo.toml | 36 ---- crates/graphql/src/lib.rs | 174 ----------------- crates/handlers/Cargo.toml | 2 +- .../src/bin/graphql-schema.rs} | 2 +- crates/handlers/src/graphql/mod.rs | 175 ++++++++++++++++-- .../src/graphql}/model/browser_sessions.rs | 2 +- .../src/graphql}/model/compat_sessions.rs | 2 +- .../src/graphql}/model/cursor.rs | 0 .../src/graphql}/model/matrix.rs | 0 .../src => handlers/src/graphql}/model/mod.rs | 0 .../src/graphql}/model/node.rs | 0 .../src/graphql}/model/oauth.rs | 2 +- .../src/graphql}/model/site_config.rs | 0 .../src/graphql}/model/upstream_oauth.rs | 2 +- .../src/graphql}/model/users.rs | 2 +- .../src/graphql}/model/viewer/anonymous.rs | 0 .../src/graphql}/model/viewer/mod.rs | 2 +- .../src/graphql}/mutations/browser_session.rs | 2 +- .../src/graphql}/mutations/compat_session.rs | 2 +- .../src/graphql}/mutations/matrix.rs | 2 +- .../src/graphql}/mutations/mod.rs | 0 .../src/graphql}/mutations/oauth2_session.rs | 2 +- .../src/graphql}/mutations/user.rs | 2 +- .../src/graphql}/mutations/user_email.rs | 2 +- .../src => handlers/src/graphql}/query/mod.rs | 4 +- .../src/graphql}/query/session.rs | 2 +- .../src/graphql}/query/upstream_oauth.rs | 2 +- .../src/graphql}/query/viewer.rs | 2 +- .../src => handlers/src/graphql}/state.rs | 2 +- crates/handlers/src/lib.rs | 6 +- crates/handlers/src/test_utils.rs | 11 +- misc/update.sh | 2 +- 35 files changed, 199 insertions(+), 278 deletions(-) delete mode 100644 crates/graphql/Cargo.toml delete mode 100644 crates/graphql/src/lib.rs rename crates/{graphql/src/bin/schema.rs => handlers/src/bin/graphql-schema.rs} (92%) rename crates/{graphql/src => handlers/src/graphql}/model/browser_sessions.rs (99%) rename crates/{graphql/src => handlers/src/graphql}/model/compat_sessions.rs (99%) rename crates/{graphql/src => handlers/src/graphql}/model/cursor.rs (100%) rename crates/{graphql/src => handlers/src/graphql}/model/matrix.rs (100%) rename crates/{graphql/src => handlers/src/graphql}/model/mod.rs (100%) rename crates/{graphql/src => handlers/src/graphql}/model/node.rs (100%) rename crates/{graphql/src => handlers/src/graphql}/model/oauth.rs (99%) rename crates/{graphql/src => handlers/src/graphql}/model/site_config.rs (100%) rename crates/{graphql/src => handlers/src/graphql}/model/upstream_oauth.rs (99%) rename crates/{graphql/src => handlers/src/graphql}/model/users.rs (99%) rename crates/{graphql/src => handlers/src/graphql}/model/viewer/anonymous.rs (100%) rename crates/{graphql/src => handlers/src/graphql}/model/viewer/mod.rs (95%) rename crates/{graphql/src => handlers/src/graphql}/mutations/browser_session.rs (99%) rename crates/{graphql/src => handlers/src/graphql}/mutations/compat_session.rs (99%) rename crates/{graphql/src => handlers/src/graphql}/mutations/matrix.rs (99%) rename crates/{graphql/src => handlers/src/graphql}/mutations/mod.rs (100%) rename crates/{graphql/src => handlers/src/graphql}/mutations/oauth2_session.rs (99%) rename crates/{graphql/src => handlers/src/graphql}/mutations/user.rs (99%) rename crates/{graphql/src => handlers/src/graphql}/mutations/user_email.rs (99%) rename crates/{graphql/src => handlers/src/graphql}/query/mod.rs (99%) rename crates/{graphql/src => handlers/src/graphql}/query/session.rs (99%) rename crates/{graphql/src => handlers/src/graphql}/query/upstream_oauth.rs (99%) rename crates/{graphql/src => handlers/src/graphql}/query/viewer.rs (98%) rename crates/{graphql/src => handlers/src/graphql}/state.rs (98%) diff --git a/Cargo.lock b/Cargo.lock index c8942e48..c22225dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3018,7 +3018,6 @@ dependencies = [ "mas-config", "mas-data-model", "mas-email", - "mas-graphql", "mas-handlers", "mas-http", "mas-i18n", @@ -3125,29 +3124,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "mas-graphql" -version = "0.9.0" -dependencies = [ - "anyhow", - "async-graphql", - "async-trait", - "chrono", - "lettre", - "mas-data-model", - "mas-matrix", - "mas-policy", - "mas-storage", - "oauth2-types", - "serde", - "thiserror", - "tokio", - "tower", - "tracing", - "ulid", - "url", -] - [[package]] name = "mas-handlers" version = "0.9.0" @@ -3155,6 +3131,7 @@ dependencies = [ "anyhow", "argon2", "async-graphql", + "async-trait", "axum", "axum-extra", "axum-macros", @@ -3170,7 +3147,6 @@ dependencies = [ "lettre", "mas-axum-utils", "mas-data-model", - "mas-graphql", "mas-http", "mas-i18n", "mas-iana", diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 67fc0cf6..295b1704 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -57,7 +57,6 @@ sentry-tower = { version = "0.31.8", features = ["http"] } mas-config.workspace = true mas-data-model.workspace = true mas-email.workspace = true -mas-graphql.workspace = true mas-handlers = { workspace = true } mas-http = { workspace = true, features = ["client"] } mas-i18n.workspace = true diff --git a/crates/cli/src/app_state.rs b/crates/cli/src/app_state.rs index a3188f00..fefe889a 100644 --- a/crates/cli/src/app_state.rs +++ b/crates/cli/src/app_state.rs @@ -22,7 +22,7 @@ use ipnetwork::IpNetwork; use mas_data_model::SiteConfig; use mas_handlers::{ passwords::PasswordManager, ActivityTracker, BoundActivityTracker, CookieManager, ErrorWrapper, - HttpClientFactory, MetadataCache, + GraphQLSchema, HttpClientFactory, MetadataCache, }; use mas_i18n::Translator; use mas_keystore::{Encrypter, Keystore}; @@ -50,7 +50,7 @@ pub struct AppState { pub url_builder: UrlBuilder, pub homeserver_connection: SynapseConnection, pub policy_factory: Arc, - pub graphql_schema: mas_graphql::Schema, + pub graphql_schema: GraphQLSchema, pub http_client_factory: HttpClientFactory, pub password_manager: PasswordManager, pub metadata_cache: MetadataCache, @@ -144,7 +144,7 @@ impl FromRef for PgPool { } } -impl FromRef for mas_graphql::Schema { +impl FromRef for GraphQLSchema { fn from_ref(input: &AppState) -> Self { input.graphql_schema.clone() } diff --git a/crates/graphql/Cargo.toml b/crates/graphql/Cargo.toml deleted file mode 100644 index f30b8e2a..00000000 --- a/crates/graphql/Cargo.toml +++ /dev/null @@ -1,36 +0,0 @@ -[package] -name = "mas-graphql" -version.workspace = true -authors.workspace = true -edition.workspace = true -license.workspace = true -homepage.workspace = true -repository.workspace = true -publish = false - -[lints] -workspace = true - -[dependencies] -anyhow.workspace = true -async-graphql.workspace = true -async-trait.workspace = true -chrono.workspace = true -lettre.workspace = true -serde.workspace = true -thiserror.workspace = true -tokio.workspace = true -tracing.workspace = true -tower.workspace = true -ulid.workspace = true -url.workspace = true - -oauth2-types.workspace = true -mas-data-model.workspace = true -mas-matrix.workspace = true -mas-policy.workspace = true -mas-storage.workspace = true - -[[bin]] -name = "schema" -doc = false diff --git a/crates/graphql/src/lib.rs b/crates/graphql/src/lib.rs deleted file mode 100644 index 06485707..00000000 --- a/crates/graphql/src/lib.rs +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright 2022-2023 The Matrix.org Foundation C.I.C. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#![deny(clippy::future_not_send)] -#![allow(clippy::module_name_repetitions, clippy::unused_async)] - -use async_graphql::EmptySubscription; -use mas_data_model::{BrowserSession, Session, User}; -use ulid::Ulid; - -mod model; -mod mutations; -mod query; -mod state; - -pub use self::{ - model::{CreationEvent, Node}, - mutations::Mutation, - query::Query, - state::{BoxState, State}, -}; - -pub type Schema = async_graphql::Schema; -pub type SchemaBuilder = async_graphql::SchemaBuilder; - -#[must_use] -pub fn schema_builder() -> SchemaBuilder { - async_graphql::Schema::build(Query::new(), Mutation::new(), EmptySubscription) - .register_output_type::() - .register_output_type::() -} - -/// The identity of the requester. -#[derive(Debug, Clone, Default, PartialEq, Eq)] -pub enum Requester { - /// The requester presented no authentication information. - #[default] - Anonymous, - - /// The requester is a browser session, stored in a cookie. - BrowserSession(Box), - - /// The requester is a `OAuth2` session, with an access token. - OAuth2Session(Box<(Session, Option)>), -} - -trait OwnerId { - fn owner_id(&self) -> Option; -} - -impl OwnerId for User { - fn owner_id(&self) -> Option { - Some(self.id) - } -} - -impl OwnerId for BrowserSession { - fn owner_id(&self) -> Option { - Some(self.user.id) - } -} - -impl OwnerId for mas_data_model::UserEmail { - fn owner_id(&self) -> Option { - Some(self.user_id) - } -} - -impl OwnerId for Session { - fn owner_id(&self) -> Option { - self.user_id - } -} - -impl OwnerId for mas_data_model::CompatSession { - fn owner_id(&self) -> Option { - Some(self.user_id) - } -} - -impl OwnerId for mas_data_model::UpstreamOAuthLink { - fn owner_id(&self) -> Option { - self.user_id - } -} - -/// A dumb wrapper around a `Ulid` to implement `OwnerId` for it. -pub struct UserId(Ulid); - -impl OwnerId for UserId { - fn owner_id(&self) -> Option { - Some(self.0) - } -} - -impl Requester { - fn browser_session(&self) -> Option<&BrowserSession> { - match self { - Self::BrowserSession(session) => Some(session), - Self::OAuth2Session(_) | Self::Anonymous => None, - } - } - - fn user(&self) -> Option<&User> { - match self { - Self::BrowserSession(session) => Some(&session.user), - Self::OAuth2Session(tuple) => tuple.1.as_ref(), - Self::Anonymous => None, - } - } - - fn oauth2_session(&self) -> Option<&Session> { - match self { - Self::OAuth2Session(tuple) => Some(&tuple.0), - Self::BrowserSession(_) | Self::Anonymous => None, - } - } - - /// Returns true if the requester can access the resource. - fn is_owner_or_admin(&self, resource: &impl OwnerId) -> bool { - // If the requester is an admin, they can do anything. - if self.is_admin() { - return true; - } - - // Otherwise, they must be the owner of the resource. - let Some(owner_id) = resource.owner_id() else { - return false; - }; - - let Some(user) = self.user() else { - return false; - }; - - user.id == owner_id - } - - fn is_admin(&self) -> bool { - match self { - Self::OAuth2Session(tuple) => { - // TODO: is this the right scope? - // This has to be in sync with the policy - tuple.0.scope.contains("urn:mas:admin") - } - Self::BrowserSession(_) | Self::Anonymous => false, - } - } -} - -impl From for Requester { - fn from(session: BrowserSession) -> Self { - Self::BrowserSession(Box::new(session)) - } -} - -impl From> for Requester -where - T: Into, -{ - fn from(session: Option) -> Self { - session.map(Into::into).unwrap_or_default() - } -} diff --git a/crates/handlers/Cargo.toml b/crates/handlers/Cargo.toml index fd7e9a0d..27bbbed2 100644 --- a/crates/handlers/Cargo.toml +++ b/crates/handlers/Cargo.toml @@ -15,6 +15,7 @@ workspace = true # Async runtime tokio.workspace = true futures-util = "0.3.30" +async-trait.workspace = true # Logging and tracing tracing.workspace = true @@ -70,7 +71,6 @@ ulid.workspace = true mas-axum-utils.workspace = true mas-data-model.workspace = true -mas-graphql.workspace = true mas-http.workspace = true mas-i18n.workspace = true mas-iana.workspace = true diff --git a/crates/graphql/src/bin/schema.rs b/crates/handlers/src/bin/graphql-schema.rs similarity index 92% rename from crates/graphql/src/bin/schema.rs rename to crates/handlers/src/bin/graphql-schema.rs index 1ca27c2e..623e59b7 100644 --- a/crates/graphql/src/bin/schema.rs +++ b/crates/handlers/src/bin/graphql-schema.rs @@ -22,6 +22,6 @@ #![warn(clippy::pedantic)] fn main() { - let schema = mas_graphql::schema_builder().finish(); + let schema = mas_handlers::graphql_schema_builder().finish(); println!("{}", schema.sdl()); } diff --git a/crates/handlers/src/graphql/mod.rs b/crates/handlers/src/graphql/mod.rs index acdad738..309af31d 100644 --- a/crates/handlers/src/graphql/mod.rs +++ b/crates/handlers/src/graphql/mod.rs @@ -12,15 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![allow(clippy::module_name_repetitions)] + use std::sync::Arc; use async_graphql::{ extensions::Tracing, http::{playground_source, GraphQLPlaygroundConfig, MultipartOptions}, + EmptySubscription, }; use axum::{ async_trait, - extract::{BodyStream, RawQuery, State}, + extract::{BodyStream, RawQuery, State as AxumState}, http::StatusCode, response::{Html, IntoResponse, Response}, Json, TypedHeader, @@ -31,8 +34,7 @@ use hyper::header::CACHE_CONTROL; use mas_axum_utils::{ cookies::CookieJar, sentry::SentryEventID, FancyError, SessionInfo, SessionInfoExt, }; -use mas_data_model::{SiteConfig, User}; -use mas_graphql::{Requester, Schema}; +use mas_data_model::{BrowserSession, Session, SiteConfig, User}; use mas_matrix::HomeserverConnection; use mas_policy::{InstantiateError, Policy, PolicyFactory}; use mas_storage::{ @@ -44,7 +46,19 @@ use rand::{thread_rng, SeedableRng}; use rand_chacha::ChaChaRng; use sqlx::PgPool; use tracing::{info_span, Instrument}; +use ulid::Ulid; +mod model; +mod mutations; +mod query; +mod state; + +pub use self::state::{BoxState, State}; +use self::{ + model::{CreationEvent, Node}, + mutations::Mutation, + query::Query, +}; use crate::{impl_from_error_for_route, BoundActivityTracker}; #[cfg(test)] @@ -58,7 +72,7 @@ struct GraphQLState { } #[async_trait] -impl mas_graphql::State for GraphQLState { +impl state::State for GraphQLState { async fn repository(&self) -> Result { let repo = PgRepository::from_pool(&self.pool) .await @@ -106,12 +120,9 @@ pub fn schema( homeserver_connection: Arc::new(homeserver_connection), site_config, }; - let state: mas_graphql::BoxState = Box::new(state); + let state: BoxState = Box::new(state); - mas_graphql::schema_builder() - .extension(Tracing) - .data(state) - .finish() + schema_builder().extension(Tracing).data(state).finish() } fn span_for_graphql_request(request: &async_graphql::Request) -> tracing::Span { @@ -261,7 +272,7 @@ async fn get_requester( } pub async fn post( - State(schema): State, + AxumState(schema): AxumState, clock: BoxClock, repo: BoxRepository, activity_tracker: BoundActivityTracker, @@ -302,7 +313,7 @@ pub async fn post( } pub async fn get( - State(schema): State, + AxumState(schema): AxumState, clock: BoxClock, repo: BoxRepository, activity_tracker: BoundActivityTracker, @@ -338,3 +349,145 @@ pub async fn playground() -> impl IntoResponse { GraphQLPlaygroundConfig::new("/graphql").with_setting("request.credentials", "include"), )) } + +pub type Schema = async_graphql::Schema; +pub type SchemaBuilder = async_graphql::SchemaBuilder; + +#[must_use] +pub fn schema_builder() -> SchemaBuilder { + async_graphql::Schema::build(Query::new(), Mutation::new(), EmptySubscription) + .register_output_type::() + .register_output_type::() +} + +/// The identity of the requester. +#[derive(Debug, Clone, Default, PartialEq, Eq)] +pub enum Requester { + /// The requester presented no authentication information. + #[default] + Anonymous, + + /// The requester is a browser session, stored in a cookie. + BrowserSession(Box), + + /// The requester is a `OAuth2` session, with an access token. + OAuth2Session(Box<(Session, Option)>), +} + +trait OwnerId { + fn owner_id(&self) -> Option; +} + +impl OwnerId for User { + fn owner_id(&self) -> Option { + Some(self.id) + } +} + +impl OwnerId for BrowserSession { + fn owner_id(&self) -> Option { + Some(self.user.id) + } +} + +impl OwnerId for mas_data_model::UserEmail { + fn owner_id(&self) -> Option { + Some(self.user_id) + } +} + +impl OwnerId for Session { + fn owner_id(&self) -> Option { + self.user_id + } +} + +impl OwnerId for mas_data_model::CompatSession { + fn owner_id(&self) -> Option { + Some(self.user_id) + } +} + +impl OwnerId for mas_data_model::UpstreamOAuthLink { + fn owner_id(&self) -> Option { + self.user_id + } +} + +/// A dumb wrapper around a `Ulid` to implement `OwnerId` for it. +pub struct UserId(Ulid); + +impl OwnerId for UserId { + fn owner_id(&self) -> Option { + Some(self.0) + } +} + +impl Requester { + fn browser_session(&self) -> Option<&BrowserSession> { + match self { + Self::BrowserSession(session) => Some(session), + Self::OAuth2Session(_) | Self::Anonymous => None, + } + } + + fn user(&self) -> Option<&User> { + match self { + Self::BrowserSession(session) => Some(&session.user), + Self::OAuth2Session(tuple) => tuple.1.as_ref(), + Self::Anonymous => None, + } + } + + fn oauth2_session(&self) -> Option<&Session> { + match self { + Self::OAuth2Session(tuple) => Some(&tuple.0), + Self::BrowserSession(_) | Self::Anonymous => None, + } + } + + /// Returns true if the requester can access the resource. + fn is_owner_or_admin(&self, resource: &impl OwnerId) -> bool { + // If the requester is an admin, they can do anything. + if self.is_admin() { + return true; + } + + // Otherwise, they must be the owner of the resource. + let Some(owner_id) = resource.owner_id() else { + return false; + }; + + let Some(user) = self.user() else { + return false; + }; + + user.id == owner_id + } + + fn is_admin(&self) -> bool { + match self { + Self::OAuth2Session(tuple) => { + // TODO: is this the right scope? + // This has to be in sync with the policy + tuple.0.scope.contains("urn:mas:admin") + } + Self::BrowserSession(_) | Self::Anonymous => false, + } + } +} + +impl From for Requester { + fn from(session: BrowserSession) -> Self { + Self::BrowserSession(Box::new(session)) + } +} + +impl From> for Requester +where + T: Into, +{ + fn from(session: Option) -> Self { + session.map(Into::into).unwrap_or_default() + } +} diff --git a/crates/graphql/src/model/browser_sessions.rs b/crates/handlers/src/graphql/model/browser_sessions.rs similarity index 99% rename from crates/graphql/src/model/browser_sessions.rs rename to crates/handlers/src/graphql/model/browser_sessions.rs index ac02b485..576526c0 100644 --- a/crates/graphql/src/model/browser_sessions.rs +++ b/crates/handlers/src/graphql/model/browser_sessions.rs @@ -26,7 +26,7 @@ use super::{ AppSession, CompatSession, Cursor, NodeCursor, NodeType, OAuth2Session, PreloadedTotalCount, SessionState, User, UserAgent, }; -use crate::state::ContextExt; +use crate::graphql::state::ContextExt; /// A browser session represents a logged in user in a browser. #[derive(Description)] diff --git a/crates/graphql/src/model/compat_sessions.rs b/crates/handlers/src/graphql/model/compat_sessions.rs similarity index 99% rename from crates/graphql/src/model/compat_sessions.rs rename to crates/handlers/src/graphql/model/compat_sessions.rs index 5ce782fc..057bf5c5 100644 --- a/crates/graphql/src/model/compat_sessions.rs +++ b/crates/handlers/src/graphql/model/compat_sessions.rs @@ -19,7 +19,7 @@ use mas_storage::{compat::CompatSessionRepository, user::UserRepository}; use url::Url; use super::{BrowserSession, NodeType, SessionState, User, UserAgent}; -use crate::state::ContextExt; +use crate::graphql::state::ContextExt; /// Lazy-loaded reverse reference. /// diff --git a/crates/graphql/src/model/cursor.rs b/crates/handlers/src/graphql/model/cursor.rs similarity index 100% rename from crates/graphql/src/model/cursor.rs rename to crates/handlers/src/graphql/model/cursor.rs diff --git a/crates/graphql/src/model/matrix.rs b/crates/handlers/src/graphql/model/matrix.rs similarity index 100% rename from crates/graphql/src/model/matrix.rs rename to crates/handlers/src/graphql/model/matrix.rs diff --git a/crates/graphql/src/model/mod.rs b/crates/handlers/src/graphql/model/mod.rs similarity index 100% rename from crates/graphql/src/model/mod.rs rename to crates/handlers/src/graphql/model/mod.rs diff --git a/crates/graphql/src/model/node.rs b/crates/handlers/src/graphql/model/node.rs similarity index 100% rename from crates/graphql/src/model/node.rs rename to crates/handlers/src/graphql/model/node.rs diff --git a/crates/graphql/src/model/oauth.rs b/crates/handlers/src/graphql/model/oauth.rs similarity index 99% rename from crates/graphql/src/model/oauth.rs rename to crates/handlers/src/graphql/model/oauth.rs index 3307e16a..a06d9100 100644 --- a/crates/graphql/src/model/oauth.rs +++ b/crates/handlers/src/graphql/model/oauth.rs @@ -21,7 +21,7 @@ use ulid::Ulid; use url::Url; use super::{BrowserSession, NodeType, SessionState, User, UserAgent}; -use crate::{state::ContextExt, UserId}; +use crate::graphql::{state::ContextExt, UserId}; /// An OAuth 2.0 session represents a client session which used the OAuth APIs /// to login. diff --git a/crates/graphql/src/model/site_config.rs b/crates/handlers/src/graphql/model/site_config.rs similarity index 100% rename from crates/graphql/src/model/site_config.rs rename to crates/handlers/src/graphql/model/site_config.rs diff --git a/crates/graphql/src/model/upstream_oauth.rs b/crates/handlers/src/graphql/model/upstream_oauth.rs similarity index 99% rename from crates/graphql/src/model/upstream_oauth.rs rename to crates/handlers/src/graphql/model/upstream_oauth.rs index cc6771d7..4e25d620 100644 --- a/crates/graphql/src/model/upstream_oauth.rs +++ b/crates/handlers/src/graphql/model/upstream_oauth.rs @@ -18,7 +18,7 @@ use chrono::{DateTime, Utc}; use mas_storage::{upstream_oauth2::UpstreamOAuthProviderRepository, user::UserRepository}; use super::{NodeType, User}; -use crate::state::ContextExt; +use crate::graphql::state::ContextExt; #[derive(Debug, Clone)] pub struct UpstreamOAuth2Provider { diff --git a/crates/graphql/src/model/users.rs b/crates/handlers/src/graphql/model/users.rs similarity index 99% rename from crates/graphql/src/model/users.rs rename to crates/handlers/src/graphql/model/users.rs index 3b4662d5..c60ae7f3 100644 --- a/crates/graphql/src/model/users.rs +++ b/crates/handlers/src/graphql/model/users.rs @@ -34,7 +34,7 @@ use super::{ BrowserSession, CompatSession, Cursor, NodeCursor, NodeType, OAuth2Session, PreloadedTotalCount, SessionState, UpstreamOAuth2Link, }; -use crate::state::ContextExt; +use crate::graphql::state::ContextExt; #[derive(Description)] /// A user is an individual's account. diff --git a/crates/graphql/src/model/viewer/anonymous.rs b/crates/handlers/src/graphql/model/viewer/anonymous.rs similarity index 100% rename from crates/graphql/src/model/viewer/anonymous.rs rename to crates/handlers/src/graphql/model/viewer/anonymous.rs diff --git a/crates/graphql/src/model/viewer/mod.rs b/crates/handlers/src/graphql/model/viewer/mod.rs similarity index 95% rename from crates/graphql/src/model/viewer/mod.rs rename to crates/handlers/src/graphql/model/viewer/mod.rs index c382109e..0a8626c3 100644 --- a/crates/graphql/src/model/viewer/mod.rs +++ b/crates/handlers/src/graphql/model/viewer/mod.rs @@ -14,7 +14,7 @@ use async_graphql::Union; -use crate::model::{BrowserSession, OAuth2Session, User}; +use crate::graphql::model::{BrowserSession, OAuth2Session, User}; mod anonymous; pub use self::anonymous::Anonymous; diff --git a/crates/graphql/src/mutations/browser_session.rs b/crates/handlers/src/graphql/mutations/browser_session.rs similarity index 99% rename from crates/graphql/src/mutations/browser_session.rs rename to crates/handlers/src/graphql/mutations/browser_session.rs index 147de040..76621a4e 100644 --- a/crates/graphql/src/mutations/browser_session.rs +++ b/crates/handlers/src/graphql/mutations/browser_session.rs @@ -15,7 +15,7 @@ use async_graphql::{Context, Enum, InputObject, Object, ID}; use mas_storage::RepositoryAccess; -use crate::{ +use crate::graphql::{ model::{BrowserSession, NodeType}, state::ContextExt, }; diff --git a/crates/graphql/src/mutations/compat_session.rs b/crates/handlers/src/graphql/mutations/compat_session.rs similarity index 99% rename from crates/graphql/src/mutations/compat_session.rs rename to crates/handlers/src/graphql/mutations/compat_session.rs index 38c6cb8a..49c57735 100644 --- a/crates/graphql/src/mutations/compat_session.rs +++ b/crates/handlers/src/graphql/mutations/compat_session.rs @@ -20,7 +20,7 @@ use mas_storage::{ RepositoryAccess, }; -use crate::{ +use crate::graphql::{ model::{CompatSession, NodeType}, state::ContextExt, }; diff --git a/crates/graphql/src/mutations/matrix.rs b/crates/handlers/src/graphql/mutations/matrix.rs similarity index 99% rename from crates/graphql/src/mutations/matrix.rs rename to crates/handlers/src/graphql/mutations/matrix.rs index 839c298a..dd7af4a4 100644 --- a/crates/graphql/src/mutations/matrix.rs +++ b/crates/handlers/src/graphql/mutations/matrix.rs @@ -15,7 +15,7 @@ use anyhow::Context as _; use async_graphql::{Context, Description, Enum, InputObject, Object, ID}; -use crate::{ +use crate::graphql::{ model::{NodeType, User}, state::ContextExt, UserId, diff --git a/crates/graphql/src/mutations/mod.rs b/crates/handlers/src/graphql/mutations/mod.rs similarity index 100% rename from crates/graphql/src/mutations/mod.rs rename to crates/handlers/src/graphql/mutations/mod.rs diff --git a/crates/graphql/src/mutations/oauth2_session.rs b/crates/handlers/src/graphql/mutations/oauth2_session.rs similarity index 99% rename from crates/graphql/src/mutations/oauth2_session.rs rename to crates/handlers/src/graphql/mutations/oauth2_session.rs index c3c7088c..0acc137b 100644 --- a/crates/graphql/src/mutations/oauth2_session.rs +++ b/crates/handlers/src/graphql/mutations/oauth2_session.rs @@ -27,7 +27,7 @@ use mas_storage::{ }; use oauth2_types::scope::Scope; -use crate::{ +use crate::graphql::{ model::{NodeType, OAuth2Session}, state::ContextExt, }; diff --git a/crates/graphql/src/mutations/user.rs b/crates/handlers/src/graphql/mutations/user.rs similarity index 99% rename from crates/graphql/src/mutations/user.rs rename to crates/handlers/src/graphql/mutations/user.rs index c38037c8..c43e3741 100644 --- a/crates/graphql/src/mutations/user.rs +++ b/crates/handlers/src/graphql/mutations/user.rs @@ -20,7 +20,7 @@ use mas_storage::{ }; use tracing::{info, warn}; -use crate::{ +use crate::graphql::{ model::{NodeType, User}, state::ContextExt, UserId, diff --git a/crates/graphql/src/mutations/user_email.rs b/crates/handlers/src/graphql/mutations/user_email.rs similarity index 99% rename from crates/graphql/src/mutations/user_email.rs rename to crates/handlers/src/graphql/mutations/user_email.rs index 456a490c..796d8854 100644 --- a/crates/graphql/src/mutations/user_email.rs +++ b/crates/handlers/src/graphql/mutations/user_email.rs @@ -20,7 +20,7 @@ use mas_storage::{ RepositoryAccess, }; -use crate::{ +use crate::graphql::{ model::{NodeType, User, UserEmail}, state::ContextExt, UserId, diff --git a/crates/graphql/src/query/mod.rs b/crates/handlers/src/graphql/query/mod.rs similarity index 99% rename from crates/graphql/src/query/mod.rs rename to crates/handlers/src/graphql/query/mod.rs index 6e476a2b..8e829c01 100644 --- a/crates/graphql/src/query/mod.rs +++ b/crates/handlers/src/graphql/query/mod.rs @@ -15,7 +15,7 @@ use async_graphql::{Context, MergedObject, Object, ID}; use mas_storage::user::UserRepository; -use crate::{ +use crate::graphql::{ model::{ Anonymous, BrowserSession, CompatSession, Node, NodeType, OAuth2Client, OAuth2Session, SiteConfig, User, UserEmail, @@ -234,7 +234,7 @@ impl BaseQuery { return Ok(Some(Node::Anonymous(Box::new(Anonymous)))); } - if id.as_str() == crate::model::SITE_CONFIG_ID { + if id.as_str() == crate::graphql::model::SITE_CONFIG_ID { return Ok(Some(Node::SiteConfig(Box::new(SiteConfig::new( ctx.state().site_config(), ))))); diff --git a/crates/graphql/src/query/session.rs b/crates/handlers/src/graphql/query/session.rs similarity index 99% rename from crates/graphql/src/query/session.rs rename to crates/handlers/src/graphql/query/session.rs index 1a4d6ed7..19e5f85f 100644 --- a/crates/graphql/src/query/session.rs +++ b/crates/handlers/src/graphql/query/session.rs @@ -21,7 +21,7 @@ use mas_storage::{ }; use oauth2_types::scope::Scope; -use crate::{ +use crate::graphql::{ model::{CompatSession, NodeType, OAuth2Session}, state::ContextExt, UserId, diff --git a/crates/graphql/src/query/upstream_oauth.rs b/crates/handlers/src/graphql/query/upstream_oauth.rs similarity index 99% rename from crates/graphql/src/query/upstream_oauth.rs rename to crates/handlers/src/graphql/query/upstream_oauth.rs index b8a2d750..bfc7dfb6 100644 --- a/crates/graphql/src/query/upstream_oauth.rs +++ b/crates/handlers/src/graphql/query/upstream_oauth.rs @@ -18,7 +18,7 @@ use async_graphql::{ }; use mas_storage::{upstream_oauth2::UpstreamOAuthProviderFilter, Pagination, RepositoryAccess}; -use crate::{ +use crate::graphql::{ model::{ Cursor, NodeCursor, NodeType, PreloadedTotalCount, UpstreamOAuth2Link, UpstreamOAuth2Provider, diff --git a/crates/graphql/src/query/viewer.rs b/crates/handlers/src/graphql/query/viewer.rs similarity index 98% rename from crates/graphql/src/query/viewer.rs rename to crates/handlers/src/graphql/query/viewer.rs index d74675c7..eb273117 100644 --- a/crates/graphql/src/query/viewer.rs +++ b/crates/handlers/src/graphql/query/viewer.rs @@ -14,7 +14,7 @@ use async_graphql::{Context, Object}; -use crate::{ +use crate::graphql::{ model::{Viewer, ViewerSession}, state::ContextExt, Requester, diff --git a/crates/graphql/src/state.rs b/crates/handlers/src/graphql/state.rs similarity index 98% rename from crates/graphql/src/state.rs rename to crates/handlers/src/graphql/state.rs index ab102e16..2caa7670 100644 --- a/crates/graphql/src/state.rs +++ b/crates/handlers/src/graphql/state.rs @@ -17,7 +17,7 @@ use mas_matrix::HomeserverConnection; use mas_policy::Policy; use mas_storage::{BoxClock, BoxRepository, BoxRng, RepositoryError}; -use crate::Requester; +use crate::graphql::Requester; #[async_trait::async_trait] pub trait State { diff --git a/crates/handlers/src/lib.rs b/crates/handlers/src/lib.rs index cc8ccd3d..4652c839 100644 --- a/crates/handlers/src/lib.rs +++ b/crates/handlers/src/lib.rs @@ -90,7 +90,9 @@ pub use mas_axum_utils::{ pub use self::{ activity_tracker::{ActivityTracker, Bound as BoundActivityTracker}, - graphql::schema as graphql_schema, + graphql::{ + schema as graphql_schema, schema_builder as graphql_schema_builder, Schema as GraphQLSchema, + }, preferred_language::PreferredLanguage, upstream_oauth2::cache::MetadataCache, }; @@ -110,7 +112,7 @@ where ::Data: Into, ::Error: std::error::Error + Send + Sync, S: Clone + Send + Sync + 'static, - mas_graphql::Schema: FromRef, + graphql::Schema: FromRef, BoundActivityTracker: FromRequestParts, BoxRepository: FromRequestParts, BoxClock: FromRequestParts, diff --git a/crates/handlers/src/test_utils.rs b/crates/handlers/src/test_utils.rs index ce994f62..5741c7eb 100644 --- a/crates/handlers/src/test_utils.rs +++ b/crates/handlers/src/test_utils.rs @@ -54,6 +54,7 @@ use tower::{Layer, Service, ServiceExt}; use url::Url; use crate::{ + graphql, passwords::{Hasher, PasswordManager}, upstream_oauth2::cache::MetadataCache, ActivityTracker, BoundActivityTracker, @@ -102,7 +103,7 @@ pub(crate) struct TestState { pub url_builder: UrlBuilder, pub homeserver_connection: Arc, pub policy_factory: Arc, - pub graphql_schema: mas_graphql::Schema, + pub graphql_schema: graphql::Schema, pub http_client_factory: HttpClientFactory, pub password_manager: PasswordManager, pub site_config: SiteConfig, @@ -198,9 +199,9 @@ impl TestState { rng: Arc::clone(&rng), clock: Arc::clone(&clock), }; - let state: mas_graphql::BoxState = Box::new(graphql_state); + let state: crate::graphql::BoxState = Box::new(graphql_state); - let graphql_schema = mas_graphql::schema_builder().data(state).finish(); + let graphql_schema = graphql::schema_builder().data(state).finish(); let activity_tracker = ActivityTracker::new(pool.clone(), std::time::Duration::from_secs(1)); @@ -316,7 +317,7 @@ struct TestGraphQLState { } #[async_trait] -impl mas_graphql::State for TestGraphQLState { +impl graphql::State for TestGraphQLState { async fn repository(&self) -> Result { let repo = PgRepository::from_pool(&self.pool) .await @@ -356,7 +357,7 @@ impl FromRef for PgPool { } } -impl FromRef for mas_graphql::Schema { +impl FromRef for graphql::Schema { fn from_ref(input: &TestState) -> Self { input.graphql_schema.clone() } diff --git a/misc/update.sh b/misc/update.sh index 850342fc..0ad0f61b 100644 --- a/misc/update.sh +++ b/misc/update.sh @@ -10,7 +10,7 @@ POLICIES_SCHEMA="${BASE_DIR}/policies/schema/" set -x cargo run -p mas-config > "${CONFIG_SCHEMA}" -cargo run -p mas-graphql > "${GRAPHQL_SCHEMA}" +cargo run -p mas-handlers --bin graphql-schema > "${GRAPHQL_SCHEMA}" cargo run -p mas-i18n-scan -- --update "${BASE_DIR}/templates/" "${BASE_DIR}/translations/en.json" OUT_DIR="${POLICIES_SCHEMA}" cargo run -p mas-policy --features jsonschema