You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-08-07 17:03:01 +03:00
Axum migration: /verify route
This commit is contained in:
@@ -95,6 +95,7 @@ where
|
|||||||
"/register",
|
"/register",
|
||||||
get(self::views::register::get).post(self::views::register::post),
|
get(self::views::register::get).post(self::views::register::post),
|
||||||
)
|
)
|
||||||
|
.route("/verify/:code", get(self::views::verify::get))
|
||||||
.fallback(mas_static_files::Assets)
|
.fallback(mas_static_files::Assets)
|
||||||
.layer(Extension(pool.clone()))
|
.layer(Extension(pool.clone()))
|
||||||
.layer(Extension(templates.clone()))
|
.layer(Extension(templates.clone()))
|
||||||
|
@@ -27,7 +27,7 @@ pub mod register;
|
|||||||
pub mod shared;
|
pub mod shared;
|
||||||
pub mod verify;
|
pub mod verify;
|
||||||
|
|
||||||
use self::{account::filter as account, verify::filter as verify};
|
use self::account::filter as account;
|
||||||
pub(crate) use self::{
|
pub(crate) use self::{
|
||||||
login::LoginRequest, reauth::ReauthRequest, register::RegisterRequest, shared::PostAuthAction,
|
login::LoginRequest, reauth::ReauthRequest, register::RegisterRequest, shared::PostAuthAction,
|
||||||
};
|
};
|
||||||
@@ -41,7 +41,6 @@ pub(super) fn filter(
|
|||||||
csrf_config: &CsrfConfig,
|
csrf_config: &CsrfConfig,
|
||||||
) -> BoxedFilter<(Box<dyn Reply>,)> {
|
) -> BoxedFilter<(Box<dyn Reply>,)> {
|
||||||
let account = account(pool, templates, mailer, encrypter, http_config, csrf_config);
|
let account = account(pool, templates, mailer, encrypter, http_config, csrf_config);
|
||||||
let verify = verify(pool, templates, encrypter, csrf_config);
|
|
||||||
|
|
||||||
account.or(verify).unify().boxed()
|
account.boxed()
|
||||||
}
|
}
|
||||||
|
@@ -12,81 +12,59 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use axum::{
|
||||||
|
extract::{Extension, Path},
|
||||||
|
response::{Html, IntoResponse},
|
||||||
|
};
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use mas_config::{CsrfConfig, Encrypter};
|
use mas_axum_utils::{csrf::CsrfExt, fancy_error, FancyError, PrivateCookieJar, SessionInfoExt};
|
||||||
use mas_data_model::BrowserSession;
|
use mas_config::Encrypter;
|
||||||
use mas_storage::{
|
use mas_storage::user::{
|
||||||
user::{
|
consume_email_verification, lookup_user_email_verification_code, mark_user_email_as_verified,
|
||||||
consume_email_verification, lookup_user_email_verification_code,
|
|
||||||
mark_user_email_as_verified,
|
|
||||||
},
|
|
||||||
PostgresqlBackend,
|
|
||||||
};
|
};
|
||||||
use mas_templates::{EmptyContext, TemplateContext, Templates};
|
use mas_templates::{EmptyContext, TemplateContext, Templates};
|
||||||
use mas_warp_utils::{
|
use sqlx::PgPool;
|
||||||
errors::WrapError,
|
|
||||||
filters::{
|
|
||||||
self,
|
|
||||||
cookies::{encrypted_cookie_saver, EncryptedCookieSaver},
|
|
||||||
csrf::updated_csrf_token,
|
|
||||||
database::transaction,
|
|
||||||
session::optional_session,
|
|
||||||
with_templates, CsrfToken,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
use sqlx::{PgPool, Postgres, Transaction};
|
|
||||||
use warp::{filters::BoxedFilter, reply::html, Filter, Rejection, Reply};
|
|
||||||
|
|
||||||
pub(super) fn filter(
|
pub(crate) async fn get(
|
||||||
pool: &PgPool,
|
Extension(templates): Extension<Templates>,
|
||||||
templates: &Templates,
|
Extension(pool): Extension<PgPool>,
|
||||||
encrypter: &Encrypter,
|
Path(code): Path<String>,
|
||||||
csrf_config: &CsrfConfig,
|
cookie_jar: PrivateCookieJar<Encrypter>,
|
||||||
) -> BoxedFilter<(Box<dyn Reply>,)> {
|
) -> Result<impl IntoResponse, FancyError> {
|
||||||
warp::path!("verify" / String)
|
let mut txn = pool.begin().await.map_err(fancy_error(templates.clone()))?;
|
||||||
.and(filters::trace::name("GET /verify"))
|
|
||||||
.and(warp::get())
|
|
||||||
.and(with_templates(templates))
|
|
||||||
.and(encrypted_cookie_saver(encrypter))
|
|
||||||
.and(updated_csrf_token(encrypter, csrf_config))
|
|
||||||
.and(optional_session(pool, encrypter))
|
|
||||||
.and(transaction(pool))
|
|
||||||
.and_then(get)
|
|
||||||
.boxed()
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get(
|
|
||||||
code: String,
|
|
||||||
templates: Templates,
|
|
||||||
cookie_saver: EncryptedCookieSaver,
|
|
||||||
csrf_token: CsrfToken,
|
|
||||||
maybe_session: Option<BrowserSession<PostgresqlBackend>>,
|
|
||||||
mut txn: Transaction<'_, Postgres>,
|
|
||||||
) -> Result<Box<dyn Reply>, Rejection> {
|
|
||||||
// TODO: make those 8 hours configurable
|
// TODO: make those 8 hours configurable
|
||||||
let verification = lookup_user_email_verification_code(&mut txn, &code, Duration::hours(8))
|
let verification = lookup_user_email_verification_code(&mut txn, &code, Duration::hours(8))
|
||||||
.await
|
.await
|
||||||
.wrap_error()?;
|
.map_err(fancy_error(templates.clone()))?;
|
||||||
|
|
||||||
// TODO: display nice errors if the code was already consumed or expired
|
// TODO: display nice errors if the code was already consumed or expired
|
||||||
|
|
||||||
let verification = consume_email_verification(&mut txn, verification)
|
let verification = consume_email_verification(&mut txn, verification)
|
||||||
.await
|
.await
|
||||||
.wrap_error()?;
|
.map_err(fancy_error(templates.clone()))?;
|
||||||
|
|
||||||
let _email = mark_user_email_as_verified(&mut txn, verification.email)
|
let _email = mark_user_email_as_verified(&mut txn, verification.email)
|
||||||
.await
|
.await
|
||||||
.wrap_error()?;
|
.map_err(fancy_error(templates.clone()))?;
|
||||||
|
|
||||||
|
let (csrf_token, cookie_jar) = cookie_jar.csrf_token();
|
||||||
|
let (session_info, cookie_jar) = cookie_jar.session_info();
|
||||||
|
|
||||||
|
let maybe_session = session_info
|
||||||
|
.load_session(&mut txn)
|
||||||
|
.await
|
||||||
|
.map_err(fancy_error(templates.clone()))?;
|
||||||
|
|
||||||
let ctx = EmptyContext
|
let ctx = EmptyContext
|
||||||
.maybe_with_session(maybe_session)
|
.maybe_with_session(maybe_session)
|
||||||
.with_csrf(csrf_token.form_value());
|
.with_csrf(csrf_token.form_value());
|
||||||
|
|
||||||
let content = templates.render_email_verification_done(&ctx).await?;
|
let content = templates
|
||||||
let reply = html(content);
|
.render_email_verification_done(&ctx)
|
||||||
let reply = cookie_saver.save_encrypted(&csrf_token, reply)?;
|
.await
|
||||||
|
.map_err(fancy_error(templates.clone()))?;
|
||||||
|
|
||||||
txn.commit().await.wrap_error()?;
|
txn.commit().await.map_err(fancy_error(templates.clone()))?;
|
||||||
|
|
||||||
Ok(Box::new(reply))
|
Ok((cookie_jar.headers(), Html(content)))
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user