summaryrefslogtreecommitdiff
path: root/server/src/auth.rs
diff options
context:
space:
mode:
authorKjetil Orbekk <kj@orbekk.com>2022-10-08 18:33:22 -0400
committerKjetil Orbekk <kj@orbekk.com>2022-10-08 18:33:22 -0400
commita7d833d6b7729f09bef891b0c8b7bd998ac17abf (patch)
tree018bba6c2ff1a58ed5b739939f63a3929d0dc662 /server/src/auth.rs
parent30102e5da48b53806b33f04041a46bec4c3b2fa3 (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.rs52
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,