refactor: workspace secrets-core + secrets-mcp MCP SaaS
- Split library (db/crypto/service) and MCP/Web/OAuth binary - Add deploy examples and CI/docs updates Made-with: Cursor
This commit is contained in:
66
crates/secrets-mcp/src/oauth/google.rs
Normal file
66
crates/secrets-mcp/src/oauth/google.rs
Normal file
@@ -0,0 +1,66 @@
|
||||
use anyhow::{Context, Result};
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::{OAuthConfig, OAuthUserInfo};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct TokenResponse {
|
||||
access_token: String,
|
||||
#[allow(dead_code)]
|
||||
token_type: String,
|
||||
#[allow(dead_code)]
|
||||
id_token: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct UserInfo {
|
||||
sub: String,
|
||||
email: Option<String>,
|
||||
name: Option<String>,
|
||||
picture: Option<String>,
|
||||
}
|
||||
|
||||
/// Exchange authorization code for tokens and fetch user profile.
|
||||
pub async fn exchange_code(
|
||||
client: &reqwest::Client,
|
||||
config: &OAuthConfig,
|
||||
code: &str,
|
||||
) -> Result<OAuthUserInfo> {
|
||||
let token_resp: TokenResponse = client
|
||||
.post("https://oauth2.googleapis.com/token")
|
||||
.form(&[
|
||||
("code", code),
|
||||
("client_id", &config.client_id),
|
||||
("client_secret", &config.client_secret),
|
||||
("redirect_uri", &config.redirect_uri),
|
||||
("grant_type", "authorization_code"),
|
||||
])
|
||||
.send()
|
||||
.await
|
||||
.context("failed to exchange Google code")?
|
||||
.error_for_status()
|
||||
.context("Google token endpoint error")?
|
||||
.json()
|
||||
.await
|
||||
.context("failed to parse Google token response")?;
|
||||
|
||||
let user: UserInfo = client
|
||||
.get("https://openidconnect.googleapis.com/v1/userinfo")
|
||||
.bearer_auth(&token_resp.access_token)
|
||||
.send()
|
||||
.await
|
||||
.context("failed to fetch Google userinfo")?
|
||||
.error_for_status()
|
||||
.context("Google userinfo endpoint error")?
|
||||
.json()
|
||||
.await
|
||||
.context("failed to parse Google userinfo")?;
|
||||
|
||||
Ok(OAuthUserInfo {
|
||||
provider: "google".to_string(),
|
||||
provider_id: user.sub,
|
||||
email: user.email,
|
||||
name: user.name,
|
||||
avatar_url: user.picture,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user