From 58eeb3ab9111dcc1ec5f7bb10ad85192a74cf63b Mon Sep 17 00:00:00 2001 From: Sebastian Martinez Date: Thu, 2 Feb 2023 12:23:15 -0300 Subject: [PATCH] httpd: Refactor auth and session handling Signed-off-by: Sebastian Martinez --- radicle-httpd/src/api.rs | 2 +- radicle-httpd/src/api/auth.rs | 18 ++++--------- radicle-httpd/src/api/v1/sessions.rs | 40 +++++++++++++++------------- 3 files changed, 28 insertions(+), 32 deletions(-) diff --git a/radicle-httpd/src/api.rs b/radicle-httpd/src/api.rs index a6cf2af5..216786d9 100644 --- a/radicle-httpd/src/api.rs +++ b/radicle-httpd/src/api.rs @@ -33,7 +33,7 @@ type SessionId = String; #[derive(Clone)] pub struct Context { profile: Arc, - sessions: Arc>>, + sessions: Arc>>, } impl Context { diff --git a/radicle-httpd/src/api/auth.rs b/radicle-httpd/src/api/auth.rs index a73d59e2..317ef983 100644 --- a/radicle-httpd/src/api/auth.rs +++ b/radicle-httpd/src/api/auth.rs @@ -11,25 +11,17 @@ impl Serialize for DateTime { } } -#[derive(Clone)] +#[derive(Clone, Serialize, PartialEq)] +#[serde(rename_all = "lowercase")] pub enum AuthState { - Authorized(Session), - Unauthorized(Session), + Authorized, + Unauthorized, } #[derive(Clone)] pub struct Session { - pub status: String, + pub status: AuthState, pub public_key: PublicKey, pub issued_at: DateTime, pub expires_at: DateTime, } - -impl From for Session { - fn from(other: AuthState) -> Self { - match other { - AuthState::Authorized(s) => s, - AuthState::Unauthorized(s) => s, - } - } -} diff --git a/radicle-httpd/src/api/v1/sessions.rs b/radicle-httpd/src/api/v1/sessions.rs index 08317802..7b02a424 100644 --- a/radicle-httpd/src/api/v1/sessions.rs +++ b/radicle-httpd/src/api/v1/sessions.rs @@ -1,4 +1,3 @@ -use std::convert::Into; use std::iter::repeat_with; use axum::extract::State; @@ -46,17 +45,20 @@ async fn session_create_handler(State(ctx): State) -> impl IntoResponse .checked_add(UNAUTHORIZED_SESSIONS_EXPIRATION) .unwrap(); let session = Session { - status: String::from("unauthorized"), + status: AuthState::Unauthorized, public_key: *signer.public_key(), issued_at: DateTime(OffsetDateTime::now_utc()), expires_at: DateTime(expiration_time), }; let mut sessions = ctx.sessions.write().await; - sessions.insert(session_id.clone(), AuthState::Unauthorized(session)); + sessions.insert(session_id.clone(), session.clone()); - Ok::<_, Error>(Json( - json!({"sessionId": session_id, "publicKey": signer.public_key()}), - )) + Ok::<_, Error>(Json(json!({ + "sessionId": session_id, + "publicKey": session.public_key, + "issuedAt": session.issued_at, + "expiresAt": session.expires_at + }))) } /// Get a session. @@ -66,12 +68,14 @@ async fn session_handler( Path(session_id): Path, ) -> impl IntoResponse { let sessions = ctx.sessions.read().await; - let auth_state = sessions.get(&session_id).ok_or(Error::NotFound)?; - let session = Session::from(auth_state.clone()); + let session = sessions.get(&session_id).ok_or(Error::NotFound)?; - Ok::<_, Error>(Json( - json!({"publicKey": session.public_key, "issuedAt": session.issued_at, "expiresAt": session.expires_at}), - )) + Ok::<_, Error>(Json(json!({ + "status": session.status, + "publicKey": session.public_key, + "issuedAt": session.issued_at, + "expiresAt": session.expires_at + }))) } /// Update session. @@ -83,11 +87,11 @@ async fn session_signin_handler( ) -> impl IntoResponse { let mut sessions = ctx.sessions.write().await; let session = sessions.get(&session_id).ok_or(Error::NotFound)?; - if let AuthState::Unauthorized(s) = session { - if s.public_key != request.pk { + if session.status == AuthState::Unauthorized { + if session.public_key != request.pk { return Err(Error::Auth("Invalid public key")); } - if s.expires_at <= DateTime(OffsetDateTime::now_utc()) { + if session.expires_at <= DateTime(OffsetDateTime::now_utc()) { return Err(Error::Auth("Session expired")); } let payload = format!("{}:{}", session_id, request.pk); @@ -99,14 +103,14 @@ async fn session_signin_handler( .checked_add(AUTHORIZED_SESSIONS_EXPIRATION) .unwrap(); let session = Session { - status: String::from("authorized"), + status: AuthState::Authorized, public_key: request.pk, - issued_at: DateTime(OffsetDateTime::now_utc()), + issued_at: session.issued_at.to_owned(), expires_at: DateTime(expiration_time), }; - sessions.insert(session_id.clone(), AuthState::Authorized(session)); + sessions.insert(session_id.clone(), session); - return Ok::<_, Error>(()); + return Ok::<_, Error>(Json(json!({ "success": true }))); } Err(Error::Auth("Session already authorized"))