1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-07-29 22:01:14 +03:00

Move storage module to its own crate

This commit is contained in:
Quentin Gliech
2021-12-17 12:15:07 +01:00
parent 584294538b
commit ceb17d3646
46 changed files with 116 additions and 71 deletions

22
Cargo.lock generated
View File

@ -1513,6 +1513,7 @@ dependencies = [
"indoc",
"mas-config",
"mas-core",
"mas-storage",
"mas-templates",
"opentelemetry",
"opentelemetry-http",
@ -1584,6 +1585,7 @@ dependencies = [
"mas-config",
"mas-data-model",
"mas-static-files",
"mas-storage",
"mas-templates",
"mime",
"oauth2-types",
@ -1628,6 +1630,26 @@ dependencies = [
"warp",
]
[[package]]
name = "mas-storage"
version = "0.1.0"
dependencies = [
"anyhow",
"argon2",
"chrono",
"mas-data-model",
"oauth2-types",
"password-hash",
"rand",
"serde",
"sqlx",
"thiserror",
"tokio",
"tracing",
"url",
"warp",
]
[[package]]
name = "mas-templates"
version = "0.1.0"

View File

@ -34,6 +34,7 @@ opentelemetry-zipkin = { version = "0.14.0", features = ["reqwest-client", "reqw
mas-config = { path = "../config" }
mas-core = { path = "../core" }
mas-templates = { path = "../templates" }
mas-storage = { path = "../storage" }
watchman_client = "0.7.1"
[dev-dependencies]

View File

@ -15,7 +15,7 @@
use anyhow::Context;
use clap::Parser;
use mas_config::DatabaseConfig;
use mas_core::storage::MIGRATOR;
use mas_storage::MIGRATOR;
use super::RootCommand;

View File

@ -15,7 +15,7 @@
use argon2::Argon2;
use clap::Parser;
use mas_config::DatabaseConfig;
use mas_core::storage::register_user;
use mas_storage::user::register_user;
use tracing::{info, warn};
use super::RootCommand;

View File

@ -22,10 +22,8 @@ use clap::Parser;
use futures::{future::TryFutureExt, stream::TryStreamExt};
use hyper::{header, Server, Version};
use mas_config::RootConfig;
use mas_core::{
storage::MIGRATOR,
tasks::{self, TaskQueue},
};
use mas_core::tasks::{self, TaskQueue};
use mas_storage::MIGRATOR;
use mas_templates::Templates;
use opentelemetry_http::HeaderExtractor;
use tower::{make::Shared, ServiceBuilder};

View File

@ -67,6 +67,7 @@ mas-config = { path = "../config" }
mas-data-model = { path = "../data-model" }
mas-templates = { path = "../templates" }
mas-static-files = { path = "../static-files" }
mas-storage = { path = "../storage" }
[dev-dependencies]
indoc = "1.0.3"

View File

@ -17,6 +17,10 @@
use headers::{authorization::Bearer, Authorization};
use hyper::StatusCode;
use mas_data_model::{AccessToken, Session};
use mas_storage::{
oauth2::access_token::{lookup_active_access_token, AccessTokenLookupError},
PostgresqlBackend,
};
use sqlx::{pool::PoolConnection, PgPool, Postgres};
use thiserror::Error;
use warp::{
@ -31,10 +35,6 @@ use super::{
};
use crate::{
errors::wrapped_error,
storage::{
oauth2::access_token::{lookup_active_access_token, AccessTokenLookupError},
PostgresqlBackend,
},
tokens::{TokenFormatError, TokenType},
};

View File

@ -16,6 +16,10 @@
use mas_config::CookiesConfig;
use mas_data_model::BrowserSession;
use mas_storage::{
user::{lookup_active_session, ActiveSessionLookupError},
PostgresqlBackend,
};
use serde::{Deserialize, Serialize};
use sqlx::{pool::PoolConnection, Executor, PgPool, Postgres};
use thiserror::Error;
@ -30,7 +34,6 @@ use super::{
database::connection,
none_on_error,
};
use crate::storage::{lookup_active_session, user::ActiveSessionLookupError, PostgresqlBackend};
/// The session is missing or failed to load
#[derive(Error, Debug)]

View File

@ -25,6 +25,16 @@ use mas_data_model::{
Authentication, AuthorizationCode, AuthorizationGrant, AuthorizationGrantStage, BrowserSession,
Pkce, StorageBackend,
};
use mas_storage::{
oauth2::{
access_token::add_access_token,
authorization_grant::{
derive_session, fulfill_grant, get_grant_by_id, new_authorization_grant,
},
refresh_token::add_refresh_token,
},
PostgresqlBackend,
};
use mas_templates::{FormPostContext, Templates};
use oauth2_types::{
errors::{
@ -58,16 +68,6 @@ use crate::{
with_templates,
},
handlers::views::{LoginRequest, PostAuthAction, ReauthRequest},
storage::{
oauth2::{
access_token::add_access_token,
authorization_grant::{
derive_session, fulfill_grant, get_grant_by_id, new_authorization_grant,
},
refresh_token::add_refresh_token,
},
PostgresqlBackend,
},
tokens::{AccessToken, RefreshToken},
};

View File

@ -14,6 +14,9 @@
use hyper::Method;
use mas_config::{OAuth2ClientConfig, OAuth2Config};
use mas_storage::oauth2::{
access_token::lookup_active_access_token, refresh_token::lookup_active_refresh_token,
};
use oauth2_types::requests::{
ClientAuthenticationMethod, IntrospectionRequest, IntrospectionResponse, TokenTypeHint,
};
@ -24,9 +27,6 @@ use warp::{Filter, Rejection, Reply};
use crate::{
errors::WrapError,
filters::{client::client_authentication, cors::cors, database::connection},
storage::oauth2::{
access_token::lookup_active_access_token, refresh_token::lookup_active_refresh_token,
},
tokens::{self, TokenType},
};

View File

@ -20,6 +20,14 @@ use hyper::{Method, StatusCode};
use jwt_compact::{Claims, Header, TimeOptions};
use mas_config::{KeySet, OAuth2ClientConfig, OAuth2Config};
use mas_data_model::AuthorizationGrantStage;
use mas_storage::{
oauth2::{
access_token::{add_access_token, revoke_access_token},
authorization_grant::{exchange_grant, lookup_grant_by_code},
refresh_token::{add_refresh_token, lookup_active_refresh_token, replace_refresh_token},
},
DatabaseInconsistencyError,
};
use oauth2_types::{
errors::{InvalidGrant, InvalidRequest, OAuth2Error, OAuth2ErrorCode, UnauthorizedClient},
requests::{
@ -45,16 +53,6 @@ use crate::{
errors::WrapError,
filters::{client::client_authentication, cors::cors, database::connection, with_keys},
reply::with_typed_header,
storage::{
oauth2::{
access_token::{add_access_token, revoke_access_token},
authorization_grant::{exchange_grant, lookup_grant_by_code},
refresh_token::{
add_refresh_token, lookup_active_refresh_token, replace_refresh_token,
},
},
DatabaseInconsistencyError,
},
tokens::{AccessToken, RefreshToken},
};

View File

@ -15,16 +15,14 @@
use hyper::Method;
use mas_config::OAuth2Config;
use mas_data_model::{AccessToken, Session};
use mas_storage::PostgresqlBackend;
use serde::Serialize;
use sqlx::PgPool;
use warp::{Filter, Rejection, Reply};
use crate::{
filters::{
use crate::filters::{
authenticate::{authentication, recover_unauthorized},
cors::cors,
},
storage::PostgresqlBackend,
};
#[derive(Serialize)]

View File

@ -15,6 +15,10 @@
use argon2::Argon2;
use mas_config::{CookiesConfig, CsrfConfig};
use mas_data_model::BrowserSession;
use mas_storage::{
user::{authenticate_session, count_active_sessions, set_password},
PostgresqlBackend,
};
use mas_templates::{AccountContext, TemplateContext, Templates};
use serde::Deserialize;
use sqlx::{pool::PoolConnection, PgExecutor, PgPool, Postgres, Transaction};
@ -29,10 +33,6 @@ use crate::{
session::session,
with_templates, CsrfToken,
},
storage::{
user::{authenticate_session, count_active_sessions, set_password},
PostgresqlBackend,
},
};
pub(super) fn filter(

View File

@ -14,19 +14,17 @@
use mas_config::{CookiesConfig, CsrfConfig, OAuth2Config};
use mas_data_model::BrowserSession;
use mas_storage::PostgresqlBackend;
use mas_templates::{IndexContext, TemplateContext, Templates};
use sqlx::PgPool;
use url::Url;
use warp::{reply::html, Filter, Rejection, Reply};
use crate::{
filters::{
use crate::filters::{
cookies::{encrypted_cookie_saver, EncryptedCookieSaver},
csrf::updated_csrf_token,
session::optional_session,
with_templates, CsrfToken,
},
storage::PostgresqlBackend,
};
pub(super) fn filter(

View File

@ -15,6 +15,7 @@
use hyper::http::uri::{Parts, PathAndQuery, Uri};
use mas_config::{CookiesConfig, CsrfConfig};
use mas_data_model::{errors::WrapFormError, BrowserSession, StorageBackend};
use mas_storage::{user::login, PostgresqlBackend};
use mas_templates::{LoginContext, LoginFormField, TemplateContext, Templates};
use serde::Deserialize;
use sqlx::{pool::PoolConnection, PgPool, Postgres};
@ -30,7 +31,6 @@ use crate::{
session::{optional_session, SessionCookie},
with_templates, CsrfToken,
},
storage::{login, PostgresqlBackend},
};
#[derive(Deserialize)]
@ -155,7 +155,7 @@ async fn post(
form: LoginForm,
query: LoginRequest<PostgresqlBackend>,
) -> Result<Box<dyn Reply>, Rejection> {
use crate::storage::user::LoginError;
use mas_storage::user::LoginError;
// TODO: recover
match login(&mut conn, &form.username, form.password).await {
Ok(session_info) => {

View File

@ -14,13 +14,13 @@
use mas_config::CookiesConfig;
use mas_data_model::BrowserSession;
use mas_storage::{user::end_session, PostgresqlBackend};
use sqlx::{PgPool, Postgres, Transaction};
use warp::{hyper::Uri, Filter, Rejection, Reply};
use crate::{
errors::WrapError,
filters::{csrf::protected_form, database::transaction, session::session},
storage::{user::end_session, PostgresqlBackend},
};
pub(super) fn filter(

View File

@ -15,6 +15,7 @@
use hyper::http::uri::{Parts, PathAndQuery};
use mas_config::{CookiesConfig, CsrfConfig};
use mas_data_model::{BrowserSession, StorageBackend};
use mas_storage::{user::authenticate_session, PostgresqlBackend};
use mas_templates::{ReauthContext, TemplateContext, Templates};
use serde::Deserialize;
use sqlx::{pool::PoolConnection, PgPool, Postgres, Transaction};
@ -30,8 +31,8 @@ use crate::{
session::session,
with_templates, CsrfToken,
},
storage::{user::authenticate_session, PostgresqlBackend},
};
#[derive(Deserialize)]
#[serde(bound(deserialize = "S::AuthorizationGrantData: std::str::FromStr,
<S::AuthorizationGrantData as std::str::FromStr>::Err: std::fmt::Display"))]

View File

@ -16,6 +16,10 @@ use argon2::Argon2;
use hyper::http::uri::{Parts, PathAndQuery, Uri};
use mas_config::{CookiesConfig, CsrfConfig};
use mas_data_model::{BrowserSession, StorageBackend};
use mas_storage::{
user::{register_user, start_session},
PostgresqlBackend,
};
use mas_templates::{RegisterContext, TemplateContext, Templates};
use serde::Deserialize;
use sqlx::{pool::PoolConnection, PgPool, Postgres, Transaction};
@ -31,7 +35,6 @@ use crate::{
session::{optional_session, SessionCookie},
with_templates, CsrfToken,
},
storage::{register_user, user::start_session, PostgresqlBackend},
};
#[derive(Deserialize)]

View File

@ -14,12 +14,12 @@
use hyper::Uri;
use mas_data_model::StorageBackend;
use mas_storage::PostgresqlBackend;
use mas_templates::PostAuthContext;
use serde::{Deserialize, Serialize};
use sqlx::PgExecutor;
use super::super::oauth2::ContinueAuthorizationGrant;
use crate::storage::PostgresqlBackend;
#[derive(Deserialize, Serialize, Clone)]
#[serde(rename_all = "snake_case", tag = "next")]

View File

@ -25,7 +25,6 @@ pub mod errors;
pub mod filters;
pub mod handlers;
pub mod reply;
pub mod storage;
pub mod tasks;
pub mod tokens;

View File

@ -29,7 +29,7 @@ impl std::fmt::Debug for CleanupExpired {
#[async_trait::async_trait]
impl Task for CleanupExpired {
async fn run(&self) {
let res = crate::storage::oauth2::access_token::cleanup_expired(&self.0).await;
let res = mas_storage::oauth2::access_token::cleanup_expired(&self.0).await;
match res {
Ok(0) => {
debug!("no token to clean up");

25
crates/storage/Cargo.toml Normal file
View File

@ -0,0 +1,25 @@
[package]
name = "mas-storage"
version = "0.1.0"
authors = ["Quentin Gliech <quenting@element.io>"]
edition = "2021"
license = "Apache-2.0"
[dependencies]
tokio = "1.14.0"
sqlx = { version = "0.5.9", features = ["runtime-tokio-rustls", "postgres", "migrate", "chrono", "offline"] }
chrono = { version = "0.4.19", features = ["serde"] }
serde = { version = "1.0.131", features = ["derive"] }
thiserror = "1.0.30"
anyhow = "1.0.51"
tracing = "0.1.29"
warp = "0.3.2"
# Password hashing
argon2 = { version = "0.3.2", features = ["password-hash"] }
password-hash = { version = "0.3.2", features = ["std"] }
rand = "0.8.4"
url = { version = "2.2.2", features = ["serde"] }
oauth2-types = { path = "../oauth2-types", features = ["sqlx_type"] }
mas-data-model = { path = "../data-model" }

View File

@ -47,10 +47,8 @@ struct IdAndCreationTime {
created_at: DateTime<Utc>,
}
pub(crate) mod oauth2;
pub(crate) mod user;
pub use self::user::{login, lookup_active_session, register_user};
pub mod oauth2;
pub mod user;
/// Embedded migrations, allowing them to run on startup
pub static MIGRATOR: Migrator = sqlx::migrate!();

View File

@ -18,7 +18,7 @@ use mas_data_model::{AccessToken, Authentication, BrowserSession, Client, Sessio
use sqlx::PgExecutor;
use thiserror::Error;
use crate::storage::{DatabaseInconsistencyError, IdAndCreationTime, PostgresqlBackend};
use crate::{DatabaseInconsistencyError, IdAndCreationTime, PostgresqlBackend};
pub async fn add_access_token(
executor: impl PgExecutor<'_>,

View File

@ -26,7 +26,7 @@ use oauth2_types::{pkce::CodeChallengeMethod, requests::ResponseMode, scope::Sco
use sqlx::PgExecutor;
use url::Url;
use crate::storage::{DatabaseInconsistencyError, IdAndCreationTime, PostgresqlBackend};
use crate::{DatabaseInconsistencyError, IdAndCreationTime, PostgresqlBackend};
#[allow(clippy::too_many_arguments)]
pub async fn new_authorization_grant(

View File

@ -12,6 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
pub(crate) mod access_token;
pub(crate) mod authorization_grant;
pub(crate) mod refresh_token;
pub mod access_token;
pub mod authorization_grant;
pub mod refresh_token;

View File

@ -19,7 +19,7 @@ use mas_data_model::{
};
use sqlx::PgExecutor;
use crate::storage::{DatabaseInconsistencyError, IdAndCreationTime, PostgresqlBackend};
use crate::{DatabaseInconsistencyError, IdAndCreationTime, PostgresqlBackend};
pub async fn add_refresh_token(
executor: impl PgExecutor<'_>,

View File

@ -27,7 +27,7 @@ use tracing::{info_span, Instrument};
use warp::reject::Reject;
use super::{DatabaseInconsistencyError, PostgresqlBackend};
use crate::storage::IdAndCreationTime;
use crate::IdAndCreationTime;
#[derive(Debug, Clone)]
struct UserLookup {