get Authentication and Sessions working

This commit is contained in:
Samuel Lorch 2023-10-26 00:28:17 +02:00
parent acfa0cc83a
commit 3a9be114d8

View file

@ -1,12 +1,14 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::error::Error;
use std::hash::Hash; use std::hash::Hash;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use uuid::Uuid;
use super::super::AppState; use super::super::AppState;
use axum::routing::post; use axum::routing::post;
use axum::{Json, Router}; use axum::{Json, Router};
use serde::Deserialize; use serde::Deserialize;
use tower_cookies::Cookies; use tower_cookies::{Cookie, Cookies};
use axum::{ use axum::{
extract::Extension, extract::Extension,
@ -16,6 +18,13 @@ use axum::{
response::{IntoResponse, Response}, response::{IntoResponse, Response},
}; };
use custom_error::custom_error;
custom_error! { AuthError
NoSessionCookie = "No Session Cookie Found",
InvalidSession = "Invalid Session"
}
const SESSION_COOKIE: &str = "session"; const SESSION_COOKIE: &str = "session";
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -25,8 +34,10 @@ pub struct SessionState {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Session { pub struct Session {
username: String, pub username: String,
//expires: time, //expires: time,
// TODO have permissions here for fast access, update Permissions with a config manager apply function
// permissions
} }
#[derive(Clone, Debug, Deserialize)] #[derive(Clone, Debug, Deserialize)]
@ -46,50 +57,91 @@ async fn login_handler(
cookies: Cookies, cookies: Cookies,
State(state): State<AppState>, State(state): State<AppState>,
Json(payload): Json<LoginParameters>, Json(payload): Json<LoginParameters>,
// mut session_state: SessionState,
) -> impl IntoResponse { ) -> impl IntoResponse {
//cookies.add(Cookie::new()); if let Some(user) = state
todo!() .config_manager
.get_current_config()
.system
.users
.get(&payload.username.to_string())
{
// TODO use propper hash algorithm compatible with /etc/passwd
if payload.password == "nfsense" {
let mut sessions = state.session_state.sessions.write().unwrap();
let id = Uuid::new_v4().to_string();
sessions.insert(
id.clone(),
Session {
username: payload.username,
},
);
cookies.add(Cookie::new(SESSION_COOKIE, id));
return StatusCode::OK;
}
}
StatusCode::UNAUTHORIZED
} }
async fn logout_handler(cookies: Cookies, app_state: State<AppState>) -> impl IntoResponse { async fn logout_handler(cookies: Cookies, state: State<AppState>) -> impl IntoResponse {
/* let session_cookie = cookies.get(SESSION_COOKIE);
if let Some(session_cookie) = cookies.get(SESSION_COOKIE) { match session_cookie {
let session_id = session_cookie.value(); Some(s) => {
let session_id = s.value();
// TODO check that sessions_id is a valid uuidv4 let mut sessions = state.session_state.sessions.write().unwrap();
session_state.sessions.remove(session_id); // TODO Fix Cookie remove
cookies.remove(session_cookie); // cookies.remove(s.clone());
if let Some(session) = sessions.get(session_id) {
sessions.remove(session_id);
return StatusCode::OK;
}
return StatusCode::UNAUTHORIZED;
}
None => return StatusCode::UNAUTHORIZED,
}
}
fn get_session(cookies: Cookies, state: SessionState) -> Result<Session, AuthError> {
let session_cookie = cookies.get(SESSION_COOKIE);
match session_cookie {
Some(s) => {
let session_id = s.value();
let sessions = state.sessions.write().unwrap();
if let Some(session) = sessions.get(session_id) {
return Ok(session.clone());
}
return Err(AuthError::InvalidSession);
}
None => return Err(AuthError::NoSessionCookie),
} }
*/
todo!()
} }
async fn session_handler(cookies: Cookies, State(state): State<AppState>) -> impl IntoResponse { async fn session_handler(cookies: Cookies, State(state): State<AppState>) -> impl IntoResponse {
//return Err(StatusCode::UNAUTHORIZED); match get_session(cookies, state.session_state) {
todo!() // TODO Return build git commit hash as json result for frontend reloading
Ok(_) => return StatusCode::OK,
Err(_) => return StatusCode::UNAUTHORIZED,
}
} }
pub async fn mw_auth<B>( pub async fn mw_auth<B>(
app_state: State<AppState>, state: State<AppState>,
cookies: Cookies, cookies: Cookies,
mut req: Request<B>, mut req: Request<B>,
next: Next<B>, next: Next<B>,
// session_state: SessionState, // session_state: SessionState,
) -> Result<Response, StatusCode> { ) -> Result<Response, StatusCode> {
/* match get_session(cookies, state.session_state.clone()) {
if let Some(session_cookie) = cookies.get(SESSION_COOKIE) { Ok(session) => {
let session_id = session_cookie.value();
// TODO check that sessions_id is a valid uuidv4
if let Some(session) = session_state.sessions.get(session_id) {
req.extensions_mut().insert(session.clone()); req.extensions_mut().insert(session.clone());
return Ok(next.run(req).await); return Ok(next.run(req).await);
} }
Err(_) => return Err(StatusCode::UNAUTHORIZED),
} }
return Err(StatusCode::UNAUTHORIZED);
*/
todo!()
} }