feat: added logout POST route

episode-actions
Jef Roosens 2025-02-23 13:05:33 +01:00
parent 2f8181491a
commit 166ae172d0
No known key found for this signature in database
GPG Key ID: 21FD3D77D56BAF49
2 changed files with 66 additions and 3 deletions

View File

@ -23,12 +23,34 @@ impl Session {
.get_result(&mut pool.get()?)?)
}
pub fn user_from_id(pool: &DbPool, id: i64) -> DbResult<Option<super::user::User>> {
pub fn user_from_id(pool: &DbPool, id: i64) -> DbResult<super::user::User> {
Ok(sessions::dsl::sessions
.inner_join(users::table)
.filter(sessions::id.eq(id))
.select(User::as_select())
.get_result(&mut pool.get()?)?)
}
pub fn user(&self, pool: &DbPool) -> DbResult<super::user::User> {
Self::user_from_id(pool, self.id)
}
pub fn by_id(pool: &DbPool, id: i64) -> DbResult<Option<Self>> {
Ok(sessions::dsl::sessions
.find(id)
.get_result(&mut pool.get()?)
.optional()?)
}
pub fn remove(self, pool: &DbPool) -> DbResult<bool> {
Self::remove_by_id(pool, self.id)
}
pub fn remove_by_id(pool: &DbPool, id: i64) -> DbResult<bool> {
Ok(
diesel::delete(sessions::dsl::sessions.filter(sessions::id.eq(id)))
.execute(&mut pool.get()?)?
> 0,
)
}
}

View File

@ -20,8 +20,12 @@ use crate::{
},
};
const SESSION_ID_COOKIE: &str = "sessionid";
pub fn router() -> Router<Context> {
Router::new().route("/{username}/login.json", post(post_login))
Router::new()
.route("/{username}/login.json", post(post_login))
.route("/{username}/logout.json", post(post_logout))
}
async fn post_login(
@ -47,5 +51,42 @@ async fn post_login(
.await
.unwrap()?;
Ok(jar.add(Cookie::build(("sessionid", session.id.to_string())).expires(Expiration::Session)))
Ok(jar.add(
Cookie::build((SESSION_ID_COOKIE, session.id.to_string())).expires(Expiration::Session),
))
}
async fn post_logout(
State(ctx): State<Context>,
Path(username): Path<String>,
jar: CookieJar,
) -> AppResult<CookieJar> {
if let Some(session_id) = jar.get(SESSION_ID_COOKIE) {
let session_id: i64 = session_id
.value()
.parse()
.map_err(|_| AppError::BadRequest)?;
tokio::task::spawn_blocking(move || {
if let Some(session) = Session::by_id(&ctx.pool, session_id)? {
let user = session.user(&ctx.pool)?;
// The requested user to logout should be the same as the one linked to the session
// ID
if username == user.username {
Ok(session.remove(&ctx.pool)?)
} else {
Err(AppError::BadRequest)
}
} else {
Ok(false)
}
})
.await
.unwrap()?;
Ok(jar.remove(SESSION_ID_COOKIE))
} else {
Ok(jar)
}
}