use diesel::{dsl::update, prelude::*};
use crate::biome::oauth::store::{
diesel::{models::OAuthUserSessionModel, schema::oauth_user_sessions},
InsertableOAuthUserSession, OAuthUserSessionStoreError,
};
use crate::error::{InvalidArgumentError, InvalidStateError};
use super::OAuthUserSessionStoreOperations;
pub trait OAuthUserSessionStoreUpdateSession {
fn update_session(
&self,
session: InsertableOAuthUserSession,
) -> Result<(), OAuthUserSessionStoreError>;
}
impl<'a, C> OAuthUserSessionStoreUpdateSession for OAuthUserSessionStoreOperations<'a, C>
where
C: diesel::Connection,
i64: diesel::deserialize::FromSql<diesel::sql_types::BigInt, C::Backend>,
String: diesel::deserialize::FromSql<diesel::sql_types::Text, C::Backend>,
{
fn update_session(
&self,
session: InsertableOAuthUserSession,
) -> Result<(), OAuthUserSessionStoreError> {
self.conn.transaction::<_, _, _>(|| {
match oauth_user_sessions::table
.find(session.splinter_access_token())
.first::<OAuthUserSessionModel>(self.conn)
.optional()?
{
Some(existing_session) => {
if session.subject() != existing_session.subject {
Err(OAuthUserSessionStoreError::InvalidArgument(
InvalidArgumentError::new(
"session".to_string(),
"Cannot update the 'subject' field for an OAuth user session"
.into(),
),
))
} else {
update(
oauth_user_sessions::table.filter(
oauth_user_sessions::splinter_access_token
.eq(session.splinter_access_token()),
),
)
.set((
oauth_user_sessions::oauth_access_token
.eq(session.oauth_access_token()),
oauth_user_sessions::oauth_refresh_token
.eq(session.oauth_refresh_token()),
))
.execute(self.conn)
.map(|_| ())
.map_err(OAuthUserSessionStoreError::from)
}
}
None => Err(OAuthUserSessionStoreError::InvalidState(
InvalidStateError::with_message(
"An OAuth user session for the given Splinter access token does not exist"
.to_string(),
),
)),
}
})
}
}