summaryrefslogtreecommitdiff
path: root/server/src/main.rs
diff options
context:
space:
mode:
authorKjetil Orbekk <kj@orbekk.com>2022-10-08 17:22:48 -0400
committerKjetil Orbekk <kj@orbekk.com>2022-10-08 17:22:48 -0400
commit30102e5da48b53806b33f04041a46bec4c3b2fa3 (patch)
treecf9fd3ce1f8c449cb4cb1b8837015c7b514b916b /server/src/main.rs
parent1cbf881835fc33859a31645f886c5d3787ed48f8 (diff)
Add token refresh and persist sessions in the db
Diffstat (limited to 'server/src/main.rs')
-rw-r--r--server/src/main.rs68
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())
}
-