diff options
author | Kjetil Orbekk <kj@orbekk.com> | 2022-10-08 17:22:48 -0400 |
---|---|---|
committer | Kjetil Orbekk <kj@orbekk.com> | 2022-10-08 17:22:48 -0400 |
commit | 30102e5da48b53806b33f04041a46bec4c3b2fa3 (patch) | |
tree | cf9fd3ce1f8c449cb4cb1b8837015c7b514b916b /server/src/main.rs | |
parent | 1cbf881835fc33859a31645f886c5d3787ed48f8 (diff) |
Add token refresh and persist sessions in the db
Diffstat (limited to 'server/src/main.rs')
-rw-r--r-- | server/src/main.rs | 68 |
1 files changed, 46 insertions, 22 deletions
diff --git a/server/src/main.rs b/server/src/main.rs index 4183abb..87f95e4 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -1,10 +1,10 @@ -use std::{collections::HashMap, env, sync::Arc}; +use std::{collections::HashMap, env, str::FromStr, sync::Arc}; use axum::{ extract::{Extension, Query}, - response::{Redirect, IntoResponse}, + response::Redirect, routing::get, - Json, Router, http::StatusCode, + Json, Router, }; use protocol::UserInfo; use tower_cookies::{Cookie, CookieManagerLayer, Cookies}; @@ -13,9 +13,9 @@ use tracing::info; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; mod auth; mod error; -use crate::auth::{Authenticator, EndUserId}; -use sqlx::{postgres::PgPoolOptions, PgPool}; +use crate::auth::{Authenticator, SessionId}; use crate::error::BridgeError; +use sqlx::{postgres::PgPoolOptions, PgPool}; pub struct ServerContext { pub app_url: String, @@ -39,7 +39,9 @@ async fn main() { let db_url = env::var("DATABASE_URL").unwrap(); let db_pool: PgPool = PgPoolOptions::new() .max_connections(10) - .connect(&db_url).await.expect("db connection"); + .connect(&db_url) + .await + .expect("db connection"); info!("Running db migrations"); sqlx::migrate!().run(&db_pool).await.expect("db migration"); @@ -51,8 +53,8 @@ async fn main() { let state = Arc::new(ServerContext { app_url: app_url, - authenticator: Authenticator::from_env().await, - db: db_pool, + authenticator: Authenticator::from_env(db_pool.clone()).await, + db: db_pool, }); let app = Router::new() @@ -69,32 +71,54 @@ async fn main() { .unwrap(); } -async fn user_info() -> Json<Option<UserInfo>> { - Json(None) +async fn user_info( + cookies: Cookies, + extension: ContextExtension, +) -> Result<Json<Option<UserInfo>>, BridgeError> { + let cookie = match cookies.get("user-id") { + None => return Ok(Json(None)), + Some(v) => v, + }; + + let session_id: SessionId = match SessionId::from_str(cookie.value()) { + Err(e) => { + info!("Clearing cookie that failed to parse {cookie:?}: {e}"); + cookies.remove(cookie.into_owned()); + return Ok(Json(None)); + } + Ok(s) => s, + }; + let mut session = + match crate::auth::fetch_authenticated_session(&extension.db, &session_id).await? { + None => return Ok(Json(None)), + Some(v) => v, + }; + Ok(Json(Some(extension.authenticator.user_info(&mut session).await?))) } async fn login_callback( cookies: Cookies, Query(params): Query<HashMap<String, String>>, extension: ContextExtension, -) -> Result<(), BridgeError> { +) -> Result<Redirect, BridgeError> { let cookie = cookies.get("user-id").unwrap(); - let user_id: EndUserId = - serde_json::from_str(&urlencoding::decode(cookie.value()).unwrap()).unwrap(); - info!("cookie: {cookie:?}"); - info!("params: {params:?}"); - extension.authenticator.authenticate(user_id, params).await?; - Ok(()) + let user_id: SessionId = SessionId::from_str(cookie.value())?; + let session = extension + .authenticator + .authenticate(&extension.db, user_id, params) + .await?; + info!("Logged in session: {session:?}"); + Ok(Redirect::temporary(&extension.app_url)) } async fn login(cookies: Cookies, extension: ContextExtension) -> Redirect { let (user_id, auth_url) = extension.authenticator.get_login_url().await; info!("Creating auth url for {user_id:?}"); let user_id = serde_json::to_string(&user_id).unwrap(); - cookies.add(Cookie::new( - "user-id", - urlencoding::encode(&user_id).to_string(), - )); + let mut cookie = Cookie::new("user-id", user_id.to_string()); + cookie.set_http_only(true); + cookie.set_secure(true); + cookie.set_same_site(cookie::SameSite::Lax); + cookies.add(cookie); Redirect::temporary(auth_url.as_str()) } - |