@smbcloud / cli / commits / de10964

add google oauth

Seto committed Nov 25, 2025 at 12:43 UTC de10964bad2efd6e4ffd1f454bc996c07fc6180f
8 files changed +87
Cargo.lock
+2
@@ -1998,7 +1998,9 @@ dependencies = [
1998 name = "smbcloud-networking-account"
1999 version = "0.3.26"
2000 dependencies = [
2001 + "log",
2002 "reqwest",
2003 + "serde_json",
2004 "smbcloud-model",
2005 "smbcloud-network",
2006 "smbcloud-networking",
crates/smbcloud-model/src/lib.rs
+1
@@ -3,6 +3,7 @@ pub mod app_auth;
3 pub mod error_codes;
4 pub mod forgot;
5 pub mod login;
6 +pub mod oauth;
7 pub mod project;
8 pub mod repository;
9 pub mod runner;
crates/smbcloud-model/src/oauth.rs new
+36
@@ -0,0 +1,36 @@
1 +use {
2 + serde::{Deserialize, Serialize},
3 + tsync::tsync,
4 +};
5 +
6 +#[derive(Serialize, Deserialize, Debug, Clone)]
7 +#[tsync]
8 +pub struct TokenResponse {
9 + pub access_token: String,
10 + pub expires_in: i32,
11 + pub refresh_token: Option<String>,
12 + pub refresh_token_expires_in: Option<String>,
13 + pub scope: String,
14 + pub token_type: String,
15 +}
16 +
17 +#[derive(Serialize, Deserialize, Debug, Clone)]
18 +#[tsync]
19 +pub struct OauthRedirect {
20 + pub code: String,
21 + pub scope: String,
22 + pub authuser: i32,
23 + pub prompt: String,
24 +}
25 +
26 +#[derive(Serialize, Deserialize, Debug, Clone)]
27 +#[tsync]
28 +pub struct UserInfo {
29 + pub id: String,
30 + pub email: String,
31 + pub verified_email: bool,
32 + pub name: String,
33 + pub given_name: String,
34 + pub family_name: String,
35 + pub picture: String,
36 +}
crates/smbcloud-networking-account/Cargo.toml
+2
@@ -18,7 +18,9 @@ categories = [
18 readme = "README.md"
19
20 [dependencies]
21 +log = { workspace = true }
22 reqwest = { workspace = true, features = ["json"] }
23 +serde_json = { workspace = true }
24 smbcloud-model = { workspace = true }
25 smbcloud-network = { workspace = true }
26 smbcloud-networking = { workspace = true }
crates/smbcloud-networking-account/src/lib.rs
+1
@@ -2,5 +2,6 @@ pub mod check_email;
2 pub mod login;
3 pub mod logout;
4 pub mod me;
5 +pub mod oauth;
6 pub mod remove;
7 pub mod signup;
crates/smbcloud-networking-account/src/oauth/get_profile.rs new
+15
@@ -0,0 +1,15 @@
1 +use {
2 + log::debug,
3 + reqwest::Client,
4 + smbcloud_model::{error_codes::ErrorResponse, oauth::UserInfo},
5 + smbcloud_network::network::{self},
6 +};
7 +
8 +pub async fn get_profile(access_token: String) -> Result<UserInfo, ErrorResponse> {
9 + let base_url = "https://www.googleapis.com/oauth2/v1/userinfo?alt=json";
10 + debug!("Get profile with token: {}", access_token);
11 + let builder = Client::new()
12 + .get(base_url)
13 + .header("Authorization", format!("Bearer {}", access_token));
14 + network::request(builder).await
15 +}
crates/smbcloud-networking-account/src/oauth/get_token.rs new
+28
@@ -0,0 +1,28 @@
1 +use {
2 + log::debug,
3 + reqwest::Client,
4 + serde_json::json,
5 + smbcloud_model::{
6 + error_codes::ErrorResponse,
7 + oauth::{OauthRedirect, TokenResponse},
8 + },
9 + smbcloud_network::network::{self},
10 +};
11 +
12 +pub async fn get_token(
13 + oauth_redirect: OauthRedirect,
14 + client_id: String,
15 + client_secret: String,
16 +) -> Result<TokenResponse, ErrorResponse> {
17 + let base_url = format!("https://oauth2.googleapis.com/token");
18 + debug!("Exchange code with token: {}", oauth_redirect.code);
19 + let paylod = json!({
20 + "client_id": client_id,
21 + "client_secret": client_secret,
22 + "code": oauth_redirect.code,
23 + "grant_type": "authorization_code",
24 + "redirect_uri": "http://localhost:8000"
25 + });
26 + let builder = Client::new().post(base_url).json(&paylod);
27 + network::request(builder).await
28 +}
crates/smbcloud-networking-account/src/oauth/mod.rs new
+2
@@ -0,0 +1,2 @@
1 +pub mod get_profile;
2 +pub mod get_token;