diff --git a/src/db/repository/auth.rs b/src/db/repository/auth.rs index e65f046..138fbcb 100644 --- a/src/db/repository/auth.rs +++ b/src/db/repository/auth.rs @@ -181,4 +181,20 @@ impl gpodder::AuthStore for SqliteRepository { .execute(&mut self.pool.get()?) .map(|_| ())?) } + + fn refresh_session( + &self, + session: &gpodder::Session, + timestamp: DateTime, + ) -> Result<(), AuthErr> { + if diesel::update(sessions::table.filter(sessions::id.eq(session.id))) + .set(sessions::last_seen.eq(timestamp.timestamp())) + .execute(&mut self.pool.get()?)? + == 0 + { + Err(AuthErr::UnknownSession) + } else { + Ok(()) + } + } } diff --git a/src/gpodder/mod.rs b/src/gpodder/mod.rs index 8336de1..53abd1f 100644 --- a/src/gpodder/mod.rs +++ b/src/gpodder/mod.rs @@ -52,6 +52,9 @@ pub trait AuthStore { /// Remove the session with the given session ID fn remove_session(&self, session_id: i64) -> Result<(), AuthErr>; + + /// Update the session's timestamp + fn refresh_session(&self, session: &Session, timestamp: DateTime) -> Result<(), AuthErr>; } pub trait DeviceRepository { diff --git a/src/gpodder/repository.rs b/src/gpodder/repository.rs index 411f9cf..cf76904 100644 --- a/src/gpodder/repository.rs +++ b/src/gpodder/repository.rs @@ -20,7 +20,7 @@ impl GpodderRepository { } } - pub fn validate_session(&self, session_id: i64) -> Result { + pub fn get_session(&self, session_id: i64) -> Result { let session = self .store .get_session(session_id)? @@ -65,6 +65,12 @@ impl GpodderRepository { Ok(session) } + pub fn refresh_session(&self, session: &models::Session) -> Result<(), AuthErr> { + let now = Utc::now(); + + self.store.refresh_session(session, now) + } + pub fn remove_session(&self, session_id: i64) -> Result<(), AuthErr> { self.store.remove_session(session_id) } diff --git a/src/server/gpodder/mod.rs b/src/server/gpodder/mod.rs index 776100e..4746323 100644 --- a/src/server/gpodder/mod.rs +++ b/src/server/gpodder/mod.rs @@ -47,10 +47,15 @@ pub async fn auth_middleware(State(ctx): State, mut req: Request, next: .get(SESSION_ID_COOKIE) .and_then(|c| c.value().parse::().ok()) { - let ctx_clone = ctx.clone(); - match tokio::task::spawn_blocking(move || ctx_clone.store.validate_session(session_id)) - .await - .unwrap() + let ctx = ctx.clone(); + match tokio::task::spawn_blocking(move || { + let session = ctx.store.get_session(session_id)?; + ctx.store.refresh_session(&session)?; + + Ok(session) + }) + .await + .unwrap() { Ok(session) => { auth_user = Some(session.user);