From d2202a07abea26078e8c4157a85c94e967449a4e Mon Sep 17 00:00:00 2001 From: Sebastian Martinez Date: Tue, 30 May 2023 11:54:07 +0200 Subject: [PATCH] httpd: Add `validate` fn to auth module Check for AuthState and expiry. Signed-off-by: Sebastian Martinez --- radicle-httpd/src/api/auth.rs | 19 ++++++++++++++++++- radicle-httpd/src/api/v1/projects.rs | 24 +++++------------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/radicle-httpd/src/api/auth.rs b/radicle-httpd/src/api/auth.rs index f4c0daba..745802f8 100644 --- a/radicle-httpd/src/api/auth.rs +++ b/radicle-httpd/src/api/auth.rs @@ -1,8 +1,12 @@ -use radicle::crypto::PublicKey; use serde::{Deserialize, Serialize}; use time::serde::timestamp; use time::{Duration, OffsetDateTime}; +use radicle::crypto::PublicKey; + +use crate::api::error::Error; +use crate::api::Context; + pub const UNAUTHORIZED_SESSIONS_EXPIRATION: Duration = Duration::seconds(60); pub const AUTHORIZED_SESSIONS_EXPIRATION: Duration = Duration::weeks(1); @@ -23,3 +27,16 @@ pub struct Session { #[serde(with = "timestamp")] pub expires_at: OffsetDateTime, } + +pub async fn validate(ctx: &Context, token: &str) -> Result<(), Error> { + let sessions_store = ctx.sessions.read().await; + let session = sessions_store + .get(token) + .ok_or(Error::Auth("Unauthorized"))?; + + if session.status != AuthState::Authorized || session.expires_at <= OffsetDateTime::now_utc() { + return Err(Error::Auth("Unauthorized")); + } + + Ok(()) +} diff --git a/radicle-httpd/src/api/v1/projects.rs b/radicle-httpd/src/api/v1/projects.rs index bb97dedc..3a4e32e2 100644 --- a/radicle-httpd/src/api/v1/projects.rs +++ b/radicle-httpd/src/api/v1/projects.rs @@ -64,7 +64,7 @@ pub fn router(ctx: Context) -> Router { ) .route( "/projects/:project/patches/:id", - get(patch_handler).patch(patch_update_handler), + patch(patch_update_handler).get(patch_handler), ) .with_state(ctx) } @@ -481,8 +481,7 @@ async fn issue_create_handler( Path(project): Path, Json(issue): Json, ) -> impl IntoResponse { - let sessions = ctx.sessions.read().await; - sessions.get(&token).ok_or(Error::Auth("Unauthorized"))?; + api::auth::validate(&ctx, &token).await?; let storage = &ctx.profile.storage; let signer = ctx .profile @@ -514,12 +513,7 @@ async fn issue_update_handler( Path((project, issue_id)): Path<(Id, Oid)>, Json(action): Json, ) -> impl IntoResponse { - ctx.sessions - .write() - .await - .get(&token) - .ok_or(Error::Auth("Unauthorized"))?; - + api::auth::validate(&ctx, &token).await?; let storage = &ctx.profile.storage; let signer = ctx.profile.signer().unwrap(); let repo = storage.repository(project)?; @@ -596,11 +590,7 @@ async fn patch_create_handler( Path(project): Path, Json(patch): Json, ) -> impl IntoResponse { - ctx.sessions - .read() - .await - .get(&token) - .ok_or(Error::Auth("Unauthorized"))?; + api::auth::validate(&ctx, &token).await?; let storage = &ctx.profile.storage; let signer = ctx .profile @@ -635,11 +625,7 @@ async fn patch_update_handler( Path((project, patch_id)): Path<(Id, Oid)>, Json(action): Json, ) -> impl IntoResponse { - ctx.sessions - .write() - .await - .get(&token) - .ok_or(Error::Auth("Unauthorized"))?; + api::auth::validate(&ctx, &token).await?; let storage = &ctx.profile.storage; let signer = ctx .profile