pub use super::_entities::o_auth2_sessions::{ActiveModel, Column, Entity, Model}; use crate::models::{o_auth2_sessions, users}; use async_trait::async_trait; use chrono::Utc; use loco_oauth2::base_oauth2::{basic::BasicTokenResponse, TokenResponse}; use loco_oauth2::models::oauth2_sessions::OAuth2SessionsTrait; use loco_rs::prelude::*; use sea_orm::entity::prelude::*; pub type OAuth2Sessions = Entity; #[async_trait::async_trait] impl ActiveModelBehavior for ActiveModel { async fn before_save(self, _db: &C, insert: bool) -> std::result::Result where C: ConnectionTrait, { if !insert && self.updated_at.is_unchanged() { let mut this = self; this.updated_at = sea_orm::ActiveValue::Set(Utc::now()); Ok(this) } else { Ok(self) } } } #[async_trait] impl OAuth2SessionsTrait for Model { /// Whether the session identified by `session_id` has expired. async fn is_expired(db: &DatabaseConnection, session_id: &str) -> ModelResult { let session = o_auth2_sessions::Entity::find() .filter(o_auth2_sessions::Column::SessionId.eq(session_id)) .one(db) .await? .ok_or_else(|| ModelError::EntityNotFound)?; Ok(session.expires_at < Utc::now()) } /// Create or refresh the session row for `user` from the provider token. async fn upsert_with_oauth2( db: &DatabaseConnection, token: &BasicTokenResponse, user: &users::Model, ) -> ModelResult { let txn = db.begin().await?; let session_id = token.access_token().secret().clone(); let expires_at = Utc::now() + token .expires_in() .unwrap_or(std::time::Duration::from_secs(3600)); let session = match o_auth2_sessions::Entity::find() .filter(o_auth2_sessions::Column::UserId.eq(user.id)) .one(&txn) .await? { Some(session) => { let mut session: o_auth2_sessions::ActiveModel = session.into(); session.session_id = ActiveValue::set(session_id); session.expires_at = ActiveValue::set(expires_at); session.updated_at = ActiveValue::set(Utc::now()); session.update(&txn).await? } None => { o_auth2_sessions::ActiveModel { session_id: ActiveValue::set(session_id), expires_at: ActiveValue::set(expires_at), user_id: ActiveValue::set(user.id), ..Default::default() } .insert(&txn) .await? } }; txn.commit().await?; Ok(session) } }