From 723ea13a55af719a920b445d9c8cda0c2545c682 Mon Sep 17 00:00:00 2001 From: Curly Bryce Date: Wed, 3 Jul 2024 15:24:45 -0600 Subject: full session management --- README.md | 16 ++++++++++++++++ src/db.rs | 47 +++++++++++++++++++++++++++++++++++++++-------- src/main.rs | 24 ++++++++++++++++++++---- 3 files changed, 75 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index e46a9a7..778c185 100644 --- a/README.md +++ b/README.md @@ -43,5 +43,21 @@ - JSON `{"id": "ID", "session": "SESSION_KEY"}` - Response - 200 Ok + - 401 Unauthorized + - JSON `"Not Authenticated"` +- POST `/user/logout/all` + - Request + - JSON `{"id": "ID", "session": "SESSION_KEY"}` + - Response + - 200 Ok + - JSON `"Logged out of everything"` + - 401 Unauthorized + - JSON `"Not Authenticated"` +- POST `/user/sessions` + - Request + - JSON `{"id": "ID", "session": "SESSION_KEY"}` + - Response + - 200 Ok + - JSON `["SESSION_KEY":"CLIENT_ID"]` - 401 Unauthorized - JSON `"Not Authenticated"` \ No newline at end of file diff --git a/src/db.rs b/src/db.rs index 43a2cc7..a609fe5 100644 --- a/src/db.rs +++ b/src/db.rs @@ -81,14 +81,21 @@ impl User { } } - fn clear_sessions(&mut self) { - self.sessions.clear() + fn clear_sessions(&mut self, session: &String) { + if self.authenticate(session) { + self.sessions.clear() + } } - fn get_sessions(&mut self) -> Vec<(String, String)> { - self.sessions.iter().map(|(k, v)| { - (k.clone(), v.clone()) - }).collect() + fn get_sessions(&self, session: &String) -> Result, String> { + if self.authenticate(session) { + let v = self.sessions.iter().map(|(k, v)| { + (k.clone(), v.clone()) + }).collect(); + Ok(v) + } else { + Err("Not Authenticated".into()) + } } fn login(&mut self, password: &String, clientid: &String) -> Result { @@ -169,10 +176,10 @@ impl DB { DB { uid_generator: uid::Generator::new(), users: vec![], config } } - pub async fn get_user(&mut self, id: &str) -> Result<&User, String> { + pub async fn get_user(&self, id: &str) -> Result<&User, String> { match UID::from(id.to_string()) { Ok(n) => { - for u in self.users.iter_mut() { + for u in self.users.iter() { if u.id == n { return Ok(u) } @@ -247,6 +254,30 @@ impl DB { Err(n) => Err(n) }; + let _ = self.save().await; + r + } + pub async fn logout_all(&mut self, id: &String, session: &String) -> Result { + let r = match self.get_mut_user(id).await { + Ok(n) => { + n.clear_sessions(session); + Ok("Logged out of everything".into()) + }, + Err(n) => Err(n) + }; + + let _ = self.save().await; + r + } + + pub async fn get_sessions(&self, id: &String, session: &String) -> Result, String> { + let r = match self.get_user(id).await { + Ok(n) => { + n.get_sessions(session) + }, + Err(n) => Err(n) + }; + let _ = self.save().await; r } diff --git a/src/main.rs b/src/main.rs index 281b63b..22c096d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,7 +31,7 @@ impl Into for User { #[get("/")] async fn get_user(user: &str, db: &State>) -> (Status, Result, Json>) { - let mut db = db.lock().await; + let db = db.lock().await; match db.get_user(user).await { Ok(n) => (Status::Ok, Ok(Json(n.clone().into()))), Err(n) => (Status::NotFound, Err(n.into())) @@ -133,11 +133,27 @@ struct LogoutForm { sessionhash: String, } #[post("/logout", data="", format="json")] -async fn logout(data: Json, db: &State>) -> (Status, Result<(), String>) { +async fn logout(data: Json, db: &State>) -> (Status, Result<(), Json>) { let mut db = db.lock().await; match db.logout(&data.id, &data.sessionhash).await { Ok(_) => (Status::Ok, Ok(())), - Err(n) => (Status::Unauthorized, Err(n)), + Err(n) => (Status::Unauthorized, Err(n.into())), + } +} +#[post("/logout/all", data="", format="json")] +async fn logout_all(data: Json, db: &State>) -> (Status, Result, Json>) { + let mut db = db.lock().await; + match db.logout_all(&data.id, &data.sessionhash).await { + Ok(n) => (Status::Ok, Ok(n.into())), + Err(n) => (Status::Unauthorized, Err(n.into())), + } +} +#[post("/sessions", data="", format="json")] +async fn get_sessions(data: Json, db: &State>) -> (Status, Result>, Json>) { + let db = db.lock().await; + match db.get_sessions(&data.id, &data.sessionhash).await { + Ok(n) => (Status::Ok, Ok(n.into())), + Err(n) => (Status::Unauthorized, Err(n.into())), } } @@ -145,5 +161,5 @@ async fn logout(data: Json, db: &State>) -> (Status, Resul fn rocket() -> _ { rocket::build().manage(Mutex::new(DB::load(Config::new()))) .mount("/", routes![index]) - .mount("/user", routes![login, get_users_by_name, get_user, new_user, get_all_users, logout]) + .mount("/user", routes![login, get_users_by_name, get_user, new_user, get_all_users, logout, logout_all, get_sessions]) } \ No newline at end of file -- cgit v1.2.3