Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
httpd: Refactor auth and session handling
Sebastian Martinez committed 3 years ago
commit ffdf7c171d4e0205fc7da39d79f2b3eb1297a140
parent f689cb2c9f3f855815b2a55f515ce77b82324515
3 files changed +29 -33
modified radicle-httpd/src/api.rs
@@ -33,7 +33,7 @@ type SessionId = String;
#[derive(Clone)]
pub struct Context {
    profile: Arc<Profile>,
-
    sessions: Arc<RwLock<HashMap<SessionId, auth::AuthState>>>,
+
    sessions: Arc<RwLock<HashMap<SessionId, auth::Session>>>,
}

impl Context {
modified 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<AuthState> for Session {
-
    fn from(other: AuthState) -> Self {
-
        match other {
-
            AuthState::Authorized(s) => s,
-
            AuthState::Unauthorized(s) => s,
-
        }
-
    }
-
}
modified 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<Context>) -> 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));
-

-
    Ok::<_, Error>(Json(
-
        json!({"sessionId": session_id, "publicKey": signer.public_key()}),
-
    ))
+
    sessions.insert(session_id.clone(), session.clone());
+

+
    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<String>,
) -> 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"))