From 42aba64bc24bb485e07604f9727f27fe89c316b2 Mon Sep 17 00:00:00 2001 From: Chris Jean-Marie Date: Wed, 25 Sep 2024 20:14:50 +0000 Subject: [PATCH] Update profile to include all available fields from Google --- backend/Cargo.toml | 2 +- backend/src/main.rs | 6 ++++-- backend/src/middlewares.rs | 23 +++++++++++------------ backend/src/oauth.rs | 24 +++++++++++++++++++++++- backend/src/routes.rs | 14 ++++++++++---- backend/templates/base.html | 2 +- backend/templates/profile.html | 7 +++++-- 7 files changed, 55 insertions(+), 23 deletions(-) diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 58cc602..c9dce47 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -23,7 +23,7 @@ oauth2 = "4.4" http = "1.1" tower-http = { version = "0.6.1", features = ["full"] } chrono = { version = "0.4.38", features = ["serde"] } -sqlx = { version = "0.8", features = ["sqlite", "runtime-tokio"] } +sqlx = { version = "0.8", features = ["sqlite", "runtime-tokio", "macros"] } uuid = { version = "1.10", features = ["v4"] } dotenvy = "0.15" constant_time_eq = "0.3" diff --git a/backend/src/main.rs b/backend/src/main.rs index fc5e5bf..9cde9db 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -56,8 +56,10 @@ pub struct UserData { #[allow(dead_code)] pub id: i64, pub email: String, -/* pub name: String, - pub discriminator: String, + pub name: String, + pub family_name: String, + pub given_name: String, +/* pub discriminator: String, pub avatar: String, pub access_token: String, pub refresh_token: String, diff --git a/backend/src/middlewares.rs b/backend/src/middlewares.rs index b380e89..83f1302 100644 --- a/backend/src/middlewares.rs +++ b/backend/src/middlewares.rs @@ -43,18 +43,17 @@ pub async fn inject_user_data( let id = query.0; let expires_at = query.1; if expires_at > Utc::now().timestamp() { - let query: Result<(String,), _> = - sqlx::query_as(r#"SELECT email FROM users WHERE id=?"#) - .bind(id) - .fetch_one(&db_pool) - .await; - if let Ok(query) = query { - let email = query.0; - request.extensions_mut().insert(Some(UserData { - id, - email, - })); - } + let row = sqlx::query_as!(UserData, "SELECT * FROM users WHERE id = ?", id) + .fetch_one(&db_pool) + .await?; + + request.extensions_mut().insert(Some(UserData { + id: row.id, + email: row.email, + name: row.name, + family_name: row.family_name, + given_name: row.given_name, + })); } } } diff --git a/backend/src/oauth.rs b/backend/src/oauth.rs index aae4871..3b9b471 100644 --- a/backend/src/oauth.rs +++ b/backend/src/oauth.rs @@ -81,6 +81,9 @@ pub async fn login( .add_scope(Scope::new( "https://www.googleapis.com/auth/userinfo.email".to_string(), )) + .add_scope(Scope::new( + "https://www.googleapis.com/auth/userinfo.profile".to_string(), + )) .set_pkce_challenge(pkce_code_challenge) .url(); @@ -151,11 +154,27 @@ pub async fn google_auth_return( .map_err(|_| "OAuth: reqwest received invalid userinfo")?; let mut body: serde_json::Value = serde_json::from_str(body.as_str()).map_err(|_| "OAuth: Serde failed to parse userinfo")?; + println!("body: {}", body); let email = body["email"] .take() .as_str() .ok_or("OAuth: Serde failed to parse email address")? .to_owned(); + let name = body["name"] + .take() + .as_str() + .ok_or("OAuth: Serde failed to parse email address")? + .to_owned(); + let family_name = body["family_name"] + .take() + .as_str() + .ok_or("OAuth: Serde failed to parse email address")? + .to_owned(); + let given_name = body["given_name"] + .take() + .as_str() + .ok_or("OAuth: Serde failed to parse email address")? + .to_owned(); let verified_email = body["verified_email"] .take() .as_bool() @@ -174,8 +193,11 @@ pub async fn google_auth_return( let user_id = if let Ok(query) = query { query.0 } else { - let query: (i64,) = sqlx::query_as("INSERT INTO users (email) VALUES (?) RETURNING id") + let query: (i64,) = sqlx::query_as("INSERT INTO users (email, name, family_name, given_name) VALUES (?, ?, ?, ?) RETURNING id") .bind(email) + .bind(name) + .bind(family_name) + .bind(given_name) .fetch_one(&db_pool) .await?; query.0 diff --git a/backend/src/routes.rs b/backend/src/routes.rs index 48533d0..d4e9ffe 100644 --- a/backend/src/routes.rs +++ b/backend/src/routes.rs @@ -10,17 +10,23 @@ use crate::{HtmlTemplate, UserData}; struct ProfileTemplate { logged_in: bool, name: String, + family_name: String, + given_name: String, + email: String, } pub async fn profile( Extension(user_data): Extension>, _request: Request, ) -> impl IntoResponse { - let email = user_data.map(|s| s.email); - let logged_in = email.is_some(); - let name = email.unwrap_or_default(); - let template = ProfileTemplate { logged_in, name}; + let Some(UserData {id, email, family_name, given_name, name}) = user_data + else { + return HtmlTemplate(ProfileTemplate { logged_in: false, name: "".to_owned(), given_name: "".to_owned(), family_name: "".to_owned(), email: "".to_owned() }); + }; + let logged_in = id > 0; + + let template = ProfileTemplate { logged_in, name, given_name, family_name, email }; HtmlTemplate(template) } diff --git a/backend/templates/base.html b/backend/templates/base.html index 649e3d8..e210775 100644 --- a/backend/templates/base.html +++ b/backend/templates/base.html @@ -44,7 +44,7 @@

Back to top

-

© 2022 Jean-Marie family

+

© 2024 Jean-Marie family

diff --git a/backend/templates/profile.html b/backend/templates/profile.html index b8a9c8b..5d2c362 100644 --- a/backend/templates/profile.html +++ b/backend/templates/profile.html @@ -1,6 +1,9 @@ {% extends "base.html" %} {% block title %}User Profile{% endblock %} {% block content %} -This is your user profile page.
-Your email address: {{ name }}. +

User Profile

+Full name: {{ name }}
+Given name: {{ given_name }}
+Family name: {{ family_name }}
+Your email address: {{ email }}