diff options
author | Kjetil Orbekk <kj@orbekk.com> | 2022-10-08 18:33:22 -0400 |
---|---|---|
committer | Kjetil Orbekk <kj@orbekk.com> | 2022-10-08 18:33:22 -0400 |
commit | a7d833d6b7729f09bef891b0c8b7bd998ac17abf (patch) | |
tree | 018bba6c2ff1a58ed5b739939f63a3929d0dc662 /server/src/auth.rs | |
parent | 30102e5da48b53806b33f04041a46bec4c3b2fa3 (diff) |
Add bridge table to db; introduce player ids from oauth subject ids
Diffstat (limited to 'server/src/auth.rs')
-rw-r--r-- | server/src/auth.rs | 52 |
1 files changed, 37 insertions, 15 deletions
diff --git a/server/src/auth.rs b/server/src/auth.rs index 44f16ea..e30cd6e 100644 --- a/server/src/auth.rs +++ b/server/src/auth.rs @@ -20,7 +20,7 @@ use openidconnect::{ use protocol::UserInfo; use serde::{Deserialize, Serialize}; use sqlx::PgPool; -use tracing::info; +use tracing::{info, error, debug}; use uuid::Uuid; pub struct LoginState { @@ -30,6 +30,7 @@ pub struct LoginState { #[derive(Debug)] pub struct AuthenticatedSession { + pub player_id: String, pub session_id: SessionId, expiration: DateTime<Utc>, access_token: AccessToken, @@ -142,12 +143,19 @@ impl Authenticator { return Ok(()); } info!("Refreshing expiring token: {}", session.expiration); + let refresh_start = Utc::now(); let new_token = self .client .exchange_refresh_token(&session.refresh_token) .request_async(async_http_client) .await?; - info!("Got new token: {new_token:#?}"); + debug!("Got new token: {new_token:#?}"); + // TODO: Validate token? + if let Some(expires_in) = new_token.expires_in() { + session.expiration = refresh_start + chrono::Duration::from_std(expires_in)?; + } else { + error!("Token is missing expiration! Will refresh token every time."); + } if let Some(refresh_token) = new_token.refresh_token() { session.refresh_token = refresh_token.clone(); } @@ -215,8 +223,9 @@ impl Authenticator { let refresh_token = token .refresh_token() .ok_or(BridgeError::Internal("Expected refresh token".to_string()))?; - + let mut session = AuthenticatedSession { + player_id: claims.subject().to_string(), session_id, expiration: claims.expiration(), access_token: token.access_token().clone(), @@ -230,22 +239,20 @@ impl Authenticator { pub async fn user_info( &self, session: &mut AuthenticatedSession, - ) -> Result<UserInfo, BridgeError> { + ) -> Result<String, BridgeError> { self.maybe_refresh_token(session).await?; let user_info: CoreUserInfoClaims = self .client .user_info(session.access_token.clone(), None)? .request_async(async_http_client) .await?; - info!("Resolved user info: {user_info:#?}"); - Ok(UserInfo { - username: user_info - .preferred_username() - .ok_or(BridgeError::Internal( - "missing preferred username".to_string(), - ))? - .to_string(), - }) + debug!("Resolved user info: {user_info:#?}"); + Ok(user_info + .preferred_username() + .ok_or(BridgeError::Internal( + "missing preferred username".to_string(), + ))? + .to_string()) } } @@ -253,18 +260,30 @@ async fn store_authenticated_session( pool: &PgPool, session: &mut AuthenticatedSession, ) -> Result<(), BridgeError> { - info!( + debug!( "Refresh token length: {}", session.refresh_token.secret().len() ); + sqlx::query!( + r#" + insert into players (id) + values ($1) + on conflict do nothing + "#, + session.player_id + ) + .execute(pool) + .await?; + let record = sqlx::query!( r#" insert into sessions ( id, + player_id, access_token, access_token_expiration, refresh_token - ) values ($1, $2, $3, $4) + ) values ($1, $2, $3, $4, $5) on conflict (id) do update set access_token = EXCLUDED.access_token, access_token_expiration = EXCLUDED.access_token_expiration, @@ -273,12 +292,14 @@ async fn store_authenticated_session( returning * "#, session.session_id.0, + session.player_id, session.access_token.secret(), session.expiration, session.refresh_token.secret() ) .fetch_one(pool) .await?; + session.player_id = record.player_id; session.session_id = SessionId(record.id); session.access_token = AccessToken::new(record.access_token); session.expiration = record.access_token_expiration; @@ -302,6 +323,7 @@ pub async fn fetch_authenticated_session( match record { None => Ok(None), Some(record) => Ok(Some(AuthenticatedSession { + player_id: record.player_id, session_id: SessionId(record.id), access_token: AccessToken::new(record.access_token), expiration: record.access_token_expiration, |