Remove unnecessary boxing of filters
This might help with error handling, knowing what filter are fallible or not
This commit is contained in:
@@ -12,6 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::convert::Infallible;
|
||||
|
||||
use chacha20poly1305::{
|
||||
aead::{generic_array::GenericArray, Aead, NewAead},
|
||||
ChaCha20Poly1305,
|
||||
@@ -66,32 +68,34 @@ impl EncryptedCookie {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn maybe_encrypted<T>(name: &'static str, options: &CookiesConfig) -> BoxedFilter<(Option<T>,)>
|
||||
pub fn maybe_encrypted<T>(
|
||||
name: &'static str,
|
||||
options: &CookiesConfig,
|
||||
) -> impl Filter<Extract = (Option<T>,), Error = Infallible> + Clone + Send + Sync + 'static
|
||||
where
|
||||
T: DeserializeOwned + Send + 'static,
|
||||
{
|
||||
let secret = options.secret;
|
||||
warp::cookie::optional(name)
|
||||
.map(move |maybe_value: Option<String>| {
|
||||
maybe_value
|
||||
.and_then(|value| EncryptedCookie::from_cookie_value(&value).ok())
|
||||
.and_then(|encrypted| encrypted.decrypt(&secret).ok())
|
||||
})
|
||||
.boxed()
|
||||
warp::cookie::optional(name).map(move |maybe_value: Option<String>| {
|
||||
maybe_value
|
||||
.and_then(|value| EncryptedCookie::from_cookie_value(&value).ok())
|
||||
.and_then(|encrypted| encrypted.decrypt(&secret).ok())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn encrypted<T>(name: &'static str, options: &CookiesConfig) -> BoxedFilter<(T,)>
|
||||
pub fn encrypted<T>(
|
||||
name: &'static str,
|
||||
options: &CookiesConfig,
|
||||
) -> impl Filter<Extract = (T,), Error = Rejection> + Clone + Send + Sync + 'static
|
||||
where
|
||||
T: DeserializeOwned + Send + 'static,
|
||||
{
|
||||
let secret = options.secret;
|
||||
warp::cookie::cookie(name)
|
||||
.and_then(move |value: String| async move {
|
||||
let encrypted = EncryptedCookie::from_cookie_value(&value).wrap_error()?;
|
||||
let decrypted = encrypted.decrypt(&secret).wrap_error()?;
|
||||
Ok::<_, Rejection>(decrypted)
|
||||
})
|
||||
.boxed()
|
||||
warp::cookie::cookie(name).and_then(move |value: String| async move {
|
||||
let encrypted = EncryptedCookie::from_cookie_value(&value).wrap_error()?;
|
||||
let decrypted = encrypted.decrypt(&secret).wrap_error()?;
|
||||
Ok::<_, Rejection>(decrypted)
|
||||
})
|
||||
}
|
||||
|
||||
pub struct WithTypedHeader<R, H> {
|
||||
|
||||
@@ -95,22 +95,22 @@ impl<T> CsrfForm<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn csrf_token(cookies_config: &CookiesConfig) -> BoxedFilter<(CsrfToken,)> {
|
||||
super::cookies::encrypted("csrf", cookies_config)
|
||||
.and_then(move |token: CsrfToken| async move {
|
||||
let verified = token.verify_expiration().wrap_error()?;
|
||||
Ok::<_, Rejection>(verified)
|
||||
})
|
||||
.boxed()
|
||||
pub fn csrf_token(
|
||||
cookies_config: &CookiesConfig,
|
||||
) -> impl Filter<Extract = (CsrfToken,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
super::cookies::encrypted("csrf", cookies_config).and_then(move |token: CsrfToken| async move {
|
||||
let verified = token.verify_expiration().wrap_error()?;
|
||||
Ok::<_, Rejection>(verified)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn updated_csrf_token(
|
||||
cookies_config: &CookiesConfig,
|
||||
csrf_config: &CsrfConfig,
|
||||
) -> BoxedFilter<(CsrfToken,)> {
|
||||
) -> impl Filter<Extract = (CsrfToken,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
let ttl = csrf_config.ttl;
|
||||
super::cookies::maybe_encrypted("csrf", cookies_config)
|
||||
.and_then(move |maybe_token: Option<CsrfToken>| async move {
|
||||
super::cookies::maybe_encrypted("csrf", cookies_config).and_then(
|
||||
move |maybe_token: Option<CsrfToken>| async move {
|
||||
// Explicitely specify the "Error" type here to have the `?` operation working
|
||||
Ok::<_, Rejection>(
|
||||
maybe_token
|
||||
@@ -123,8 +123,8 @@ pub fn updated_csrf_token(
|
||||
|token| token.refresh(ttl),
|
||||
),
|
||||
)
|
||||
})
|
||||
.boxed()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn save_csrf_token<R: Reply, F>(
|
||||
@@ -136,17 +136,16 @@ where
|
||||
save_encrypted("csrf", cookies_config)
|
||||
}
|
||||
|
||||
pub fn protected_form<T>(cookies_config: &CookiesConfig) -> BoxedFilter<(T,)>
|
||||
pub fn protected_form<T>(
|
||||
cookies_config: &CookiesConfig,
|
||||
) -> impl Filter<Extract = (T,), Error = Rejection> + Clone + Send + Sync + 'static
|
||||
where
|
||||
T: DeserializeOwned + Send + 'static,
|
||||
{
|
||||
csrf_token(cookies_config)
|
||||
.and(warp::body::form())
|
||||
.and_then(
|
||||
|csrf_token: CsrfToken, protected_form: CsrfForm<T>| async move {
|
||||
let form = protected_form.verify_csrf(&csrf_token).wrap_error()?;
|
||||
Ok::<_, Rejection>(form)
|
||||
},
|
||||
)
|
||||
.boxed()
|
||||
csrf_token(cookies_config).and(warp::body::form()).and_then(
|
||||
|csrf_token: CsrfToken, protected_form: CsrfForm<T>| async move {
|
||||
let form = protected_form.verify_csrf(&csrf_token).wrap_error()?;
|
||||
Ok::<_, Rejection>(form)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -17,18 +17,24 @@ pub mod csrf;
|
||||
pub mod cookies;
|
||||
pub mod session;
|
||||
|
||||
use std::convert::Infallible;
|
||||
|
||||
use sqlx::PgPool;
|
||||
use warp::{filters::BoxedFilter, Filter};
|
||||
use warp::Filter;
|
||||
|
||||
pub use self::csrf::CsrfToken;
|
||||
use crate::templates::Templates;
|
||||
|
||||
pub fn with_pool(pool: &PgPool) -> BoxedFilter<(PgPool,)> {
|
||||
pub fn with_pool(
|
||||
pool: &PgPool,
|
||||
) -> impl Filter<Extract = (PgPool,), Error = Infallible> + Clone + Send + Sync + 'static {
|
||||
let pool = pool.clone();
|
||||
warp::any().map(move || pool.clone()).boxed()
|
||||
warp::any().map(move || pool.clone())
|
||||
}
|
||||
|
||||
pub fn with_templates(templates: &Templates) -> BoxedFilter<(Templates,)> {
|
||||
pub fn with_templates(
|
||||
templates: &Templates,
|
||||
) -> impl Filter<Extract = (Templates,), Error = Infallible> + Clone + Send + Sync + 'static {
|
||||
let templates = templates.clone();
|
||||
warp::any().map(move || templates.clone()).boxed()
|
||||
warp::any().map(move || templates.clone())
|
||||
}
|
||||
|
||||
@@ -50,7 +50,8 @@ impl Session {
|
||||
pub fn with_optional_session(
|
||||
pool: &PgPool,
|
||||
cookies_config: &CookiesConfig,
|
||||
) -> BoxedFilter<(Option<SessionInfo>,)> {
|
||||
) -> impl Filter<Extract = (Option<SessionInfo>,), Error = Rejection> + Clone + Send + Sync + 'static
|
||||
{
|
||||
maybe_encrypted("session", cookies_config)
|
||||
.and(with_pool(pool))
|
||||
.and_then(|maybe_session: Option<Session>, pool: PgPool| async move {
|
||||
@@ -61,17 +62,18 @@ pub fn with_optional_session(
|
||||
};
|
||||
Ok::<_, Rejection>(maybe_session_info)
|
||||
})
|
||||
.boxed()
|
||||
}
|
||||
|
||||
pub fn with_session(pool: &PgPool, cookies_config: &CookiesConfig) -> BoxedFilter<(SessionInfo,)> {
|
||||
pub fn with_session(
|
||||
pool: &PgPool,
|
||||
cookies_config: &CookiesConfig,
|
||||
) -> impl Filter<Extract = (SessionInfo,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
encrypted("session", cookies_config)
|
||||
.and(with_pool(pool))
|
||||
.and_then(|session: Session, pool: PgPool| async move {
|
||||
let session_info = session.load_session_info(&pool).await.wrap_error()?;
|
||||
Ok::<_, Rejection>(session_info)
|
||||
})
|
||||
.boxed()
|
||||
}
|
||||
|
||||
pub fn save_session<R: Reply, F>(
|
||||
|
||||
@@ -16,16 +16,17 @@ use hyper::header::CONTENT_TYPE;
|
||||
use mime::TEXT_PLAIN;
|
||||
use sqlx::PgPool;
|
||||
use tracing::{info_span, Instrument};
|
||||
use warp::{filters::BoxedFilter, reply::with_header, Filter, Rejection, Reply};
|
||||
use warp::{reply::with_header, Filter, Rejection, Reply};
|
||||
|
||||
use crate::{errors::WrapError, filters::with_pool};
|
||||
|
||||
pub fn filter(pool: &PgPool) -> BoxedFilter<(impl Reply,)> {
|
||||
pub fn filter(
|
||||
pool: &PgPool,
|
||||
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
warp::get()
|
||||
.and(warp::path("health"))
|
||||
.and(with_pool(pool))
|
||||
.and_then(get)
|
||||
.boxed()
|
||||
}
|
||||
|
||||
async fn get(pool: PgPool) -> Result<impl Reply, Rejection> {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
use sqlx::PgPool;
|
||||
use warp::{filters::BoxedFilter, Filter};
|
||||
use warp::{Filter, Rejection, Reply};
|
||||
|
||||
use crate::{config::RootConfig, templates::Templates};
|
||||
|
||||
@@ -27,11 +27,10 @@ pub fn root(
|
||||
pool: &PgPool,
|
||||
templates: &Templates,
|
||||
config: &RootConfig,
|
||||
) -> BoxedFilter<(impl warp::Reply,)> {
|
||||
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
health(pool)
|
||||
.or(oauth2(pool, &config.oauth2, &config.cookies))
|
||||
.or(views(pool, templates, &config.csrf, &config.cookies))
|
||||
//.or(warp::get().map(|| StatusCode::NOT_FOUND)) <- This messes up the error reporting
|
||||
.with(warp::log(module_path!()))
|
||||
.boxed()
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ use oauth2_types::{
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use sqlx::PgPool;
|
||||
use warp::{filters::BoxedFilter, Filter, Rejection, Reply};
|
||||
use warp::{Filter, Rejection, Reply};
|
||||
|
||||
use crate::{
|
||||
config::{CookiesConfig, OAuth2ClientConfig, OAuth2Config},
|
||||
@@ -42,7 +42,7 @@ pub fn filter(
|
||||
pool: &PgPool,
|
||||
oauth2_config: &OAuth2Config,
|
||||
cookies_config: &CookiesConfig,
|
||||
) -> BoxedFilter<(impl Reply,)> {
|
||||
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
let clients = oauth2_config.clients.clone();
|
||||
warp::get()
|
||||
.and(warp::path!("oauth2" / "authorize"))
|
||||
@@ -51,7 +51,6 @@ pub fn filter(
|
||||
.and(with_optional_session(pool, cookies_config))
|
||||
.and(with_pool(pool))
|
||||
.and_then(get)
|
||||
.boxed()
|
||||
}
|
||||
|
||||
async fn get(
|
||||
|
||||
@@ -13,11 +13,13 @@
|
||||
// limitations under the License.
|
||||
|
||||
use oauth2_types::oidc::Metadata;
|
||||
use warp::{filters::BoxedFilter, Filter, Reply};
|
||||
use warp::{Filter, Rejection, Reply};
|
||||
|
||||
use crate::config::OAuth2Config;
|
||||
|
||||
pub(super) fn filter(config: &OAuth2Config) -> BoxedFilter<(impl Reply,)> {
|
||||
pub(super) fn filter(
|
||||
config: &OAuth2Config,
|
||||
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
let base = config.issuer.clone();
|
||||
let metadata = Metadata {
|
||||
authorization_endpoint: base.join("oauth2/authorize").ok(),
|
||||
@@ -38,5 +40,4 @@ pub(super) fn filter(config: &OAuth2Config) -> BoxedFilter<(impl Reply,)> {
|
||||
.and(warp::path!(".well-known" / "openid-configuration"))
|
||||
.map(move || warp::reply::json(&metadata))
|
||||
.with(cors)
|
||||
.boxed()
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
use sqlx::PgPool;
|
||||
use warp::{filters::BoxedFilter, Filter, Reply};
|
||||
use warp::{Filter, Rejection, Reply};
|
||||
|
||||
use crate::config::{CookiesConfig, OAuth2Config};
|
||||
|
||||
@@ -26,8 +26,6 @@ pub fn filter(
|
||||
pool: &PgPool,
|
||||
oauth2_config: &OAuth2Config,
|
||||
cookies_config: &CookiesConfig,
|
||||
) -> BoxedFilter<(impl Reply,)> {
|
||||
discovery(oauth2_config)
|
||||
.or(authorization(pool, oauth2_config, cookies_config))
|
||||
.boxed()
|
||||
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
discovery(oauth2_config).or(authorization(pool, oauth2_config, cookies_config))
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
use sqlx::PgPool;
|
||||
use warp::{filters::BoxedFilter, reply::with_header, wrap_fn, Filter, Rejection, Reply};
|
||||
use warp::{reply::with_header, wrap_fn, Filter, Rejection, Reply};
|
||||
|
||||
use crate::{
|
||||
config::{CookiesConfig, CsrfConfig},
|
||||
@@ -31,7 +31,7 @@ pub(super) fn filter(
|
||||
templates: &Templates,
|
||||
csrf_config: &CsrfConfig,
|
||||
cookies_config: &CookiesConfig,
|
||||
) -> BoxedFilter<(impl Reply,)> {
|
||||
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
warp::get()
|
||||
.and(warp::path::end())
|
||||
.and(with_templates(templates))
|
||||
@@ -40,7 +40,6 @@ pub(super) fn filter(
|
||||
.and_then(get)
|
||||
.untuple_one()
|
||||
.with(wrap_fn(save_csrf_token(cookies_config)))
|
||||
.boxed()
|
||||
}
|
||||
|
||||
async fn get(
|
||||
|
||||
@@ -14,9 +14,7 @@
|
||||
|
||||
use serde::Deserialize;
|
||||
use sqlx::PgPool;
|
||||
use warp::{
|
||||
filters::BoxedFilter, hyper::Uri, reply::with_header, wrap_fn, Filter, Rejection, Reply,
|
||||
};
|
||||
use warp::{hyper::Uri, reply::with_header, wrap_fn, Filter, Rejection, Reply};
|
||||
|
||||
use crate::{
|
||||
config::{CookiesConfig, CsrfConfig},
|
||||
@@ -41,7 +39,7 @@ pub(super) fn filter(
|
||||
templates: &Templates,
|
||||
csrf_config: &CsrfConfig,
|
||||
cookies_config: &CookiesConfig,
|
||||
) -> BoxedFilter<(impl Reply,)> {
|
||||
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
let get = warp::get()
|
||||
.and(with_templates(templates))
|
||||
.and(updated_csrf_token(cookies_config, csrf_config))
|
||||
@@ -56,7 +54,7 @@ pub(super) fn filter(
|
||||
.untuple_one()
|
||||
.with(wrap_fn(save_session(cookies_config)));
|
||||
|
||||
warp::path("login").and(get.or(post)).boxed()
|
||||
warp::path("login").and(get.or(post))
|
||||
}
|
||||
|
||||
async fn get(
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
use sqlx::PgPool;
|
||||
use warp::{filters::BoxedFilter, hyper::Uri, Filter, Rejection, Reply};
|
||||
use warp::{hyper::Uri, Filter, Rejection, Reply};
|
||||
|
||||
use crate::{
|
||||
config::CookiesConfig,
|
||||
@@ -22,14 +22,16 @@ use crate::{
|
||||
storage::SessionInfo,
|
||||
};
|
||||
|
||||
pub(super) fn filter(pool: &PgPool, cookies_config: &CookiesConfig) -> BoxedFilter<(impl Reply,)> {
|
||||
pub(super) fn filter(
|
||||
pool: &PgPool,
|
||||
cookies_config: &CookiesConfig,
|
||||
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
warp::post()
|
||||
.and(warp::path("logout"))
|
||||
.and(with_session(pool, cookies_config))
|
||||
.and(with_pool(pool))
|
||||
.and(protected_form(cookies_config))
|
||||
.and_then(post)
|
||||
.boxed()
|
||||
}
|
||||
|
||||
async fn post(session: SessionInfo, pool: PgPool, _form: ()) -> Result<impl Reply, Rejection> {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
use sqlx::PgPool;
|
||||
use warp::{filters::BoxedFilter, Filter, Reply};
|
||||
use warp::{Filter, Rejection, Reply};
|
||||
|
||||
use crate::{
|
||||
config::{CookiesConfig, CsrfConfig},
|
||||
@@ -35,7 +35,7 @@ pub(super) fn filter(
|
||||
templates: &Templates,
|
||||
csrf_config: &CsrfConfig,
|
||||
cookies_config: &CookiesConfig,
|
||||
) -> BoxedFilter<(impl Reply,)> {
|
||||
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
index(pool, templates, csrf_config, cookies_config)
|
||||
.or(login(pool, templates, csrf_config, cookies_config))
|
||||
.or(logout(pool, cookies_config))
|
||||
|
||||
@@ -14,9 +14,7 @@
|
||||
|
||||
use serde::Deserialize;
|
||||
use sqlx::PgPool;
|
||||
use warp::{
|
||||
filters::BoxedFilter, hyper::Uri, reply::with_header, wrap_fn, Filter, Rejection, Reply,
|
||||
};
|
||||
use warp::{hyper::Uri, reply::with_header, wrap_fn, Filter, Rejection, Reply};
|
||||
|
||||
use crate::{
|
||||
config::{CookiesConfig, CsrfConfig},
|
||||
@@ -40,7 +38,7 @@ pub(super) fn filter(
|
||||
templates: &Templates,
|
||||
csrf_config: &CsrfConfig,
|
||||
cookies_config: &CookiesConfig,
|
||||
) -> BoxedFilter<(impl Reply,)> {
|
||||
) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone + Send + Sync + 'static {
|
||||
let get = warp::get()
|
||||
.and(with_templates(templates))
|
||||
.and(updated_csrf_token(cookies_config, csrf_config))
|
||||
@@ -55,7 +53,7 @@ pub(super) fn filter(
|
||||
.and(protected_form(cookies_config))
|
||||
.and_then(post);
|
||||
|
||||
warp::path("reauth").and(get.or(post)).boxed()
|
||||
warp::path("reauth").and(get.or(post))
|
||||
}
|
||||
|
||||
async fn get(
|
||||
|
||||
Reference in New Issue
Block a user