You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-31 09:24:31 +03:00
Get rid of warp
This commit is contained in:
@ -20,7 +20,6 @@ This includes:
|
||||
- `mas-static-files`: Frontend static files (CSS/JS). Includes some frontend tooling
|
||||
- `mas-storage`: Interactions with the database
|
||||
- `mas-tasks`: Asynchronous task runner and scheduler
|
||||
- `mas-warp-utils`: Various filters and utilities for the `warp` web framework
|
||||
- `oauth2-types`: Useful structures and types to deal with OAuth 2.0/OpenID Connect endpoints. This might end up published as a standalone library as it can be useful in other contexts.
|
||||
|
||||
## Important crates
|
||||
@ -74,11 +73,6 @@ Both crates work well together and complement each other.
|
||||
Interactions with the database are done through [`sqlx`](https://github.com/launchbadge/sqlx), an async, pure-Rust SQL library with compile-time check of queries.
|
||||
It also handles schema migrations.
|
||||
|
||||
### Web framework: `warp`
|
||||
|
||||
[`warp`](https://docs.rs/warp/*/warp/) is an easy, macro-free web framework.
|
||||
Its composability makes a lot of sense when implementing OAuth 2.0 endpoints, because of the need to deal with a lot of different scenarios.
|
||||
|
||||
### Templates: `tera`
|
||||
|
||||
[Tera](https://tera.netlify.app/) was chosen as template engine for its simplicity as well as its ability to load templates at runtime.
|
||||
|
@ -1,93 +0,0 @@
|
||||
# `warp`
|
||||
|
||||
**Warning: this document is not up to date**
|
||||
|
||||
Warp has a pretty unique approach in terms of routing.
|
||||
It does not have a central router, rather a chain of filters composed together.
|
||||
|
||||
It encourages writing reusable filters to handle stuff like authentication, extracting user sessions, starting database transactions, etc.
|
||||
|
||||
Everything related to `warp` currently lives in the `mas-core` crate:
|
||||
|
||||
- `crates/core/src/`
|
||||
- `handlers/`: The actual handlers for each route
|
||||
- `oauth2/`: Everything related to OAuth 2.0/OIDC endpoints
|
||||
- `views/`: HTML views (login, registration, account management, etc.)
|
||||
- `filters/`: Reusable, composable filters
|
||||
- `reply/`: Composable replies
|
||||
|
||||
## Defining a new endpoint
|
||||
|
||||
We usually keep one endpoint per file and use module roots to combine the filters of endpoints.
|
||||
|
||||
This is how it looks like in the current hierarchy at time of writing:
|
||||
- `mod.rs`: combines the filters from `oauth2`, `views` and `health`
|
||||
- `oauth2/`
|
||||
- `mod.rs`: combines filters from `authorization`, `discovery`, etc.
|
||||
- `authorization.rs`: handles `GET /oauth2/authorize` and `GET /oauth2/authorize/step`
|
||||
- `discovery.rs`: handles `GET /.well-known/openid-configuration`
|
||||
- ...
|
||||
- `views/`
|
||||
- `mod.rs`: combines the filters from `index`, `login`, `logout`, etc.
|
||||
- `index.rs`: handles `GET /`
|
||||
- `login.rs`: handles `GET /login` and `POST /login`
|
||||
- `logout.rs`: handles `POST /logout`
|
||||
- ...
|
||||
- `health.rs`: handles `GET /health`
|
||||
|
||||
All filters are functions that take their dependencies (the database connection pool, the template engine, etc.) as parameters and return an `impl warp::Filter<Extract = (impl warp::Reply,)>`.
|
||||
|
||||
```rust
|
||||
// crates/core/src/handlers/hello.rs
|
||||
|
||||
// Don't be scared by the type at the end, just copy-paste it
|
||||
pub(super) fn filter(
|
||||
pool: &PgPool,
|
||||
templates: &Templates,
|
||||
cookies_config: &CookiesConfig,
|
||||
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
// Handles `GET /hello/:param`
|
||||
warp::path!("hello" / String)
|
||||
.and(warp::get())
|
||||
// Pass the template engine
|
||||
.and(with_templates(templates))
|
||||
// Extract the current user session
|
||||
.and(optional_session(pool, cookies_config))
|
||||
.and_then(get)
|
||||
}
|
||||
|
||||
async fn get(
|
||||
// Parameter from the route
|
||||
parameter: String,
|
||||
// Template engine
|
||||
templates: Templates,
|
||||
// The current user session
|
||||
session: Option<SessionInfo>,
|
||||
) -> Result<impl Reply, Rejection> {
|
||||
let ctx = SomeTemplateContext::new(parameter)
|
||||
.maybe_with_session(session);
|
||||
|
||||
let content = templates.render_something(&ctx)?;
|
||||
let reply = html(content);
|
||||
Ok(reply)
|
||||
}
|
||||
```
|
||||
|
||||
And then, it can be attached to the root handler:
|
||||
|
||||
```rust
|
||||
// crates/core/src/handlers/mod.rs
|
||||
|
||||
use self::{health::filter as health, oauth2::filter as oauth2, hello::filter as hello};
|
||||
|
||||
pub fn root(
|
||||
pool: &PgPool,
|
||||
templates: &Templates,
|
||||
config: &RootConfig,
|
||||
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
health(pool)
|
||||
.or(oauth2(pool, templates, &config.oauth2, &config.cookies))
|
||||
// Attach it here, passing the right dependencies
|
||||
.or(hello(pool, templates, &config.cookies))
|
||||
}
|
||||
```
|
Reference in New Issue
Block a user