145 lines
4.6 KiB
Rust
145 lines
4.6 KiB
Rust
use chrono::DateTime;
|
|
use diesel::prelude::*;
|
|
use gpodder::AuthErr;
|
|
|
|
use super::SqliteRepository;
|
|
use crate::{
|
|
models::{
|
|
session::Session,
|
|
user::{NewUser, User},
|
|
},
|
|
schema::*,
|
|
DbError,
|
|
};
|
|
|
|
impl From<User> for gpodder::User {
|
|
fn from(value: User) -> Self {
|
|
Self {
|
|
id: value.id,
|
|
username: value.username,
|
|
password_hash: value.password_hash,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl gpodder::AuthStore for SqliteRepository {
|
|
fn get_user(&self, username: &str) -> Result<Option<gpodder::models::User>, AuthErr> {
|
|
Ok(users::table
|
|
.select(User::as_select())
|
|
.filter(users::username.eq(username))
|
|
.first(&mut self.pool.get().map_err(DbError::from)?)
|
|
.optional()
|
|
.map_err(DbError::from)?
|
|
.map(gpodder::User::from))
|
|
}
|
|
|
|
fn insert_user(&self, username: &str, password_hash: &str) -> Result<gpodder::User, AuthErr> {
|
|
let conn = &mut self.pool.get().map_err(DbError::from)?;
|
|
|
|
Ok(diesel::insert_into(users::table)
|
|
.values(NewUser {
|
|
username,
|
|
password_hash,
|
|
})
|
|
.returning(User::as_returning())
|
|
.get_result(conn)
|
|
.map(gpodder::User::from)
|
|
.map_err(DbError::from)?)
|
|
}
|
|
|
|
fn get_session(&self, session_id: i64) -> Result<Option<gpodder::models::Session>, AuthErr> {
|
|
match sessions::table
|
|
.inner_join(users::table)
|
|
.filter(sessions::id.eq(session_id))
|
|
.select((Session::as_select(), User::as_select()))
|
|
.get_result(&mut self.pool.get().map_err(DbError::from)?)
|
|
.optional()
|
|
{
|
|
Ok(Some((session, user))) => Ok(Some(gpodder::Session {
|
|
id: session.id,
|
|
last_seen: DateTime::from_timestamp(session.last_seen, 0).unwrap(),
|
|
user: user.into(),
|
|
user_agent: session.user_agent.clone(),
|
|
})),
|
|
Ok(None) => Ok(None),
|
|
Err(err) => Err(DbError::from(err).into()),
|
|
}
|
|
}
|
|
|
|
fn remove_session(&self, session_id: i64) -> Result<(), AuthErr> {
|
|
Ok(
|
|
diesel::delete(sessions::table.filter(sessions::id.eq(session_id)))
|
|
.execute(&mut self.pool.get().map_err(DbError::from)?)
|
|
.map(|_| ())
|
|
.map_err(DbError::from)?,
|
|
)
|
|
}
|
|
|
|
fn insert_session(&self, session: &gpodder::Session) -> Result<(), AuthErr> {
|
|
Ok(Session {
|
|
id: session.id,
|
|
user_id: session.user.id,
|
|
last_seen: session.last_seen.timestamp(),
|
|
user_agent: session.user_agent.clone(),
|
|
}
|
|
.insert_into(sessions::table)
|
|
.execute(&mut self.pool.get().map_err(DbError::from)?)
|
|
.map(|_| ())
|
|
.map_err(DbError::from)?)
|
|
}
|
|
|
|
fn refresh_session(
|
|
&self,
|
|
session: &gpodder::Session,
|
|
timestamp: DateTime<chrono::Utc>,
|
|
) -> 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().map_err(DbError::from)?)
|
|
.map_err(DbError::from)?
|
|
== 0
|
|
{
|
|
Err(AuthErr::UnknownSession)
|
|
} else {
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
fn remove_old_sessions(&self, min_last_seen: DateTime<chrono::Utc>) -> Result<usize, AuthErr> {
|
|
let min_last_seen = min_last_seen.timestamp();
|
|
|
|
Ok(
|
|
diesel::delete(sessions::table.filter(sessions::last_seen.lt(min_last_seen)))
|
|
.execute(&mut self.pool.get().map_err(DbError::from)?)
|
|
.map_err(DbError::from)?,
|
|
)
|
|
}
|
|
|
|
fn paginated_sessions(
|
|
&self,
|
|
user: &gpodder::User,
|
|
page: gpodder::Page,
|
|
) -> Result<Vec<gpodder::Session>, AuthErr> {
|
|
(|| {
|
|
let sessions = sessions::table
|
|
.filter(sessions::user_id.eq(user.id))
|
|
.order(sessions::last_seen.desc())
|
|
.offset((page.page * page.per_page) as i64)
|
|
.limit(page.per_page as i64)
|
|
.select(Session::as_select())
|
|
.get_results(&mut self.pool.get()?)?
|
|
.into_iter()
|
|
.map(|session| gpodder::Session {
|
|
id: session.id,
|
|
last_seen: DateTime::from_timestamp(session.last_seen, 0).unwrap(),
|
|
user_agent: session.user_agent,
|
|
user: user.clone(),
|
|
})
|
|
.collect();
|
|
|
|
Ok::<_, DbError>(sessions)
|
|
})()
|
|
.map_err(AuthErr::from)
|
|
}
|
|
}
|