Add smbcloud-auth-sdk crate for client-side authentication
- Introduce `crates/smbcloud-auth-sdk` for app-level user authentication - Move client credentials and OIDC logic from smbcloud-auth to new SDK - Update workspace and crate dependencies to include smbcloud-auth-sdk - Remove unused dependencies from smbcloud-auth
keypair34 committed
Apr 10, 2026 at 21:12 UTC
20b776f2d7dea1453c256f26580f9b949e63a730
20 files changed
+537
-141
Cargo.lock
+15
-2
@@ -2443,12 +2443,10 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
2443
name = "smbcloud-auth"
2444
version = "0.3.34"
2445
dependencies = [
2446
- "base64",
2446
"log",
2447
"reqwest",
2448
"serde",
2449
"serde_json",
2451
- "sha2 0.10.9",
2450
"smbcloud-model",
2451
"smbcloud-network",
2452
"smbcloud-networking",
@@ -2470,6 +2468,21 @@ dependencies = [
2468
"tokio",
2469
]
2470
2471
+[[package]]
2472
+name = "smbcloud-auth-sdk"
2473
+version = "0.3.34"
2474
+dependencies = [
2475
+ "base64",
2476
+ "reqwest",
2477
+ "serde",
2478
+ "serde_json",
2479
+ "sha2 0.10.9",
2480
+ "smbcloud-model",
2481
+ "smbcloud-network",
2482
+ "url-builder",
2483
+ "uuid",
2484
+]
2485
+
2486
[[package]]
2487
name = "smbcloud-auth-wasm"
2488
version = "0.3.34"
Cargo.toml
+1
@@ -31,6 +31,7 @@ smbcloud-model = { version = "0.3", path = "crates/smbcloud-model" }
31
smbcloud-network = { version = "0.3", path = "crates/smbcloud-network" }
32
smbcloud-networking = { version = "0.3", path = "crates/smbcloud-networking" }
33
smbcloud-auth = { version = "0.3", path = "crates/smbcloud-auth" }
34
+smbcloud-auth-sdk = { version = "0.3", path = "crates/smbcloud-auth-sdk" }
35
smbcloud-networking-project = { version = "0.3", path = "crates/smbcloud-networking-project" }
36
smbcloud-utils = { version = "0.3", path = "crates/smbcloud-utils" }
37
spinners = "4.1.0"
crates/smbcloud-auth-sdk/Cargo.toml
new
+23
@@ -0,0 +1,23 @@
1
+[package]
2
+name = "smbcloud-auth-sdk"
3
+version = "0.3.34"
4
+edition = "2024"
5
+authors = ["Seto Elkahfi <hej@setoelkahfi.se>"]
6
+description = "Client SDK for smbCloud Auth — authenticate your users via smbCloud Auth service."
7
+license = "Apache-2.0"
8
+repository = "https://github.com/smbcloudXYZ/smbcloud-cli"
9
+documentation = "https://smbcloud.xyz/posts"
10
+keywords = ["auth", "oidc", "authentication", "smbcloud", "sdk"]
11
+categories = ["authentication", "web-programming", "api-bindings"]
12
+readme = "README.md"
13
+
14
+[dependencies]
15
+base64 = "0.22"
16
+reqwest = { workspace = true, features = ["json", "rustls-tls-native-roots"] }
17
+serde = { workspace = true, features = ["derive"] }
18
+serde_json = { workspace = true }
19
+sha2 = "0.10"
20
+smbcloud-model = { workspace = true }
21
+smbcloud-network = { workspace = true }
22
+url-builder = { workspace = true }
23
+uuid = { version = "1", features = ["v4"] }
crates/smbcloud-auth-sdk/README.md
new
+29
@@ -0,0 +1,29 @@
1
+# smbcloud-auth-sdk
2
+
3
+Client SDK for [smbCloud Auth](https://smbcloud.xyz/) — lets you authenticate your users against the smbCloud Auth service using your app credentials (`client_id` / `client_secret`).
4
+
5
+## Usage
6
+
7
+```rust
8
+use smbcloud_auth_sdk::{
9
+ client_credentials::ClientCredentials,
10
+ login::login_with_client,
11
+ signup::signup_with_client,
12
+ me::me_with_client,
13
+};
14
+use smbcloud_network::environment::Environment;
15
+
16
+let client = ClientCredentials {
17
+ app_id: "your-app-id",
18
+ app_secret: "your-app-secret",
19
+};
20
+
21
+// Sign up
22
+let result = signup_with_client(Environment::Production, client, email, password).await?;
23
+
24
+// Sign in
25
+let status = login_with_client(Environment::Production, client, email, password).await?;
26
+
27
+// Profile
28
+let user = me_with_client(Environment::Production, client, &access_token).await?;
29
+```
crates/smbcloud-auth-sdk/src/apple.rs
new
+115
@@ -0,0 +1,115 @@
1
+use {
2
+ crate::client_credentials::{ClientCredentials, base_url_builder as tenant_base_url_builder},
3
+ reqwest::Url,
4
+ serde::{Deserialize, Serialize},
5
+ smbcloud_model::error_codes::{ErrorCode, ErrorResponse},
6
+ smbcloud_network::environment::Environment,
7
+ uuid::Uuid,
8
+};
9
+
10
+const TENANT_APPLE_AUTHORIZE_PATH: &str = "v1/client/oauth/apple/authorize";
11
+
12
+#[derive(Debug, Clone, Serialize, Deserialize)]
13
+pub struct AppleAuthorizationRequest {
14
+ pub authorize_url: String,
15
+ pub redirect_uri: String,
16
+ pub state: String,
17
+}
18
+
19
+#[derive(Debug, Clone, Serialize, Deserialize)]
20
+pub struct AppleAuthSession {
21
+ pub access_token: String,
22
+ pub refresh_token: Option<String>,
23
+ pub email: Option<String>,
24
+ pub name: Option<String>,
25
+ pub provider: String,
26
+ pub provider_account_id: String,
27
+ pub state: Option<String>,
28
+}
29
+
30
+pub fn build_authorization_request_with_client(
31
+ env: Environment,
32
+ client: ClientCredentials<'_>,
33
+ redirect_uri: String,
34
+ state: Option<String>,
35
+) -> Result<AppleAuthorizationRequest, ErrorResponse> {
36
+ let state = state.unwrap_or_else(|| Uuid::new_v4().to_string());
37
+ let mut url_builder = tenant_base_url_builder(env, client);
38
+
39
+ url_builder
40
+ .add_route(TENANT_APPLE_AUTHORIZE_PATH)
41
+ .add_param("redirect_uri", &redirect_uri)
42
+ .add_param("state", &state);
43
+
44
+ Ok(AppleAuthorizationRequest {
45
+ authorize_url: url_builder.build(),
46
+ redirect_uri,
47
+ state,
48
+ })
49
+}
50
+
51
+pub fn parse_callback_url(
52
+ callback_url: &str,
53
+ expected_state: Option<&str>,
54
+) -> Result<AppleAuthSession, ErrorResponse> {
55
+ let url = Url::parse(callback_url).map_err(|err| ErrorResponse::Error {
56
+ error_code: ErrorCode::ParseError,
57
+ message: err.to_string(),
58
+ })?;
59
+
60
+ let mut access_token = None;
61
+ let mut refresh_token = None;
62
+ let mut email = None;
63
+ let mut name = None;
64
+ let mut provider = None;
65
+ let mut provider_account_id = None;
66
+ let mut state = None;
67
+ let mut error = None;
68
+
69
+ for (key, value) in url.query_pairs() {
70
+ match key.as_ref() {
71
+ "access_token" => access_token = Some(value.into_owned()),
72
+ "refresh_token" => refresh_token = Some(value.into_owned()),
73
+ "email" => email = Some(value.into_owned()),
74
+ "name" => name = Some(value.into_owned()),
75
+ "provider" => provider = Some(value.into_owned()),
76
+ "provider_account_id" => provider_account_id = Some(value.into_owned()),
77
+ "state" => state = Some(value.into_owned()),
78
+ "error" => error = Some(value.into_owned()),
79
+ _ => {}
80
+ }
81
+ }
82
+
83
+ if let Some(error) = error {
84
+ return Err(ErrorResponse::Error {
85
+ error_code: ErrorCode::InvalidParams,
86
+ message: error,
87
+ });
88
+ }
89
+
90
+ if let Some(expected_state) = expected_state {
91
+ if state.as_deref() != Some(expected_state) {
92
+ return Err(ErrorResponse::Error {
93
+ error_code: ErrorCode::InvalidParams,
94
+ message: "Apple callback state mismatch.".to_string(),
95
+ });
96
+ }
97
+ }
98
+
99
+ Ok(AppleAuthSession {
100
+ access_token: required_param("access_token", access_token)?,
101
+ refresh_token,
102
+ email,
103
+ name,
104
+ provider: provider.unwrap_or_else(|| "apple".to_string()),
105
+ provider_account_id: required_param("provider_account_id", provider_account_id)?,
106
+ state,
107
+ })
108
+}
109
+
110
+fn required_param(name: &str, value: Option<String>) -> Result<String, ErrorResponse> {
111
+ value.ok_or_else(|| ErrorResponse::Error {
112
+ error_code: ErrorCode::InvalidParams,
113
+ message: format!("Missing `{name}` in Apple callback URL."),
114
+ })
115
+}
crates/smbcloud-auth-sdk/src/client_credentials.rs
new
+17
@@ -0,0 +1,17 @@
1
+use {smbcloud_network::environment::Environment, url_builder::URLBuilder};
2
+
3
+#[derive(Clone, Copy)]
4
+pub struct ClientCredentials<'a> {
5
+ pub app_id: &'a str,
6
+ pub app_secret: &'a str,
7
+}
8
+
9
+pub fn base_url_builder(env: Environment, client: ClientCredentials<'_>) -> URLBuilder {
10
+ let mut url_builder = URLBuilder::new();
11
+ url_builder
12
+ .set_protocol(&env.api_protocol())
13
+ .set_host(&env.api_host())
14
+ .add_param("client_id", client.app_id)
15
+ .add_param("client_secret", client.app_secret);
16
+ url_builder
17
+}
crates/smbcloud-auth-sdk/src/lib.rs
new
+8
@@ -0,0 +1,8 @@
1
+pub mod apple;
2
+pub mod client_credentials;
3
+pub mod login;
4
+pub mod logout;
5
+pub mod me;
6
+pub mod oidc;
7
+pub mod remove;
8
+pub mod signup;
crates/smbcloud-auth-sdk/src/login.rs
new
+34
@@ -0,0 +1,34 @@
1
+use {
2
+ crate::client_credentials::{ClientCredentials, base_url_builder as tenant_base_url_builder},
3
+ reqwest::Client,
4
+ smbcloud_model::{
5
+ error_codes::ErrorResponse,
6
+ login::{AccountStatus, LoginParams, UserParam},
7
+ },
8
+ smbcloud_network::{environment::Environment, network::request_login},
9
+};
10
+
11
+pub async fn login_with_client(
12
+ env: Environment,
13
+ client: ClientCredentials<'_>,
14
+ username: String,
15
+ password: String,
16
+) -> Result<AccountStatus, ErrorResponse> {
17
+ let login_params = LoginParams {
18
+ user: UserParam {
19
+ email: username,
20
+ password,
21
+ },
22
+ };
23
+ let builder = Client::new()
24
+ .post(build_login_url(env, client))
25
+ .json(&login_params)
26
+ .header("User-agent", client.app_id);
27
+ request_login(builder).await
28
+}
29
+
30
+fn build_login_url(env: Environment, client: ClientCredentials<'_>) -> String {
31
+ let mut url_builder = tenant_base_url_builder(env, client);
32
+ url_builder.add_route("v1/client/users/sign_in");
33
+ url_builder.build()
34
+}
crates/smbcloud-auth-sdk/src/logout.rs
new
+43
@@ -0,0 +1,43 @@
1
+use {
2
+ crate::client_credentials::{ClientCredentials, base_url_builder as tenant_base_url_builder},
3
+ reqwest::{Client, StatusCode},
4
+ smbcloud_model::error_codes::{ErrorCode, ErrorResponse},
5
+ smbcloud_network::environment::Environment,
6
+};
7
+
8
+pub async fn logout_with_client(
9
+ env: Environment,
10
+ client: ClientCredentials<'_>,
11
+ access_token: String,
12
+) -> Result<(), ErrorResponse> {
13
+ let response = match Client::new()
14
+ .delete(build_logout_url(env, client))
15
+ .header("Authorization", access_token)
16
+ .header("Accept", "application/json")
17
+ .header("Content-Type", "application/x-www-form-urlencoded")
18
+ .send()
19
+ .await
20
+ {
21
+ Ok(response) => response,
22
+ Err(_) => {
23
+ return Err(ErrorResponse::Error {
24
+ error_code: ErrorCode::Unknown,
25
+ message: ErrorCode::Unknown.message(None).to_string(),
26
+ });
27
+ }
28
+ };
29
+
30
+ match response.status() {
31
+ StatusCode::OK => Ok(()),
32
+ _ => Err(ErrorResponse::Error {
33
+ error_code: ErrorCode::Unauthorized,
34
+ message: ErrorCode::Unauthorized.message(None).to_string(),
35
+ }),
36
+ }
37
+}
38
+
39
+fn build_logout_url(env: Environment, client: ClientCredentials<'_>) -> String {
40
+ let mut url_builder = tenant_base_url_builder(env, client);
41
+ url_builder.add_route("v1/client/users/sign_out");
42
+ url_builder.build()
43
+}
crates/smbcloud-auth-sdk/src/me.rs
new
+25
@@ -0,0 +1,25 @@
1
+use {
2
+ crate::client_credentials::{ClientCredentials, base_url_builder as tenant_base_url_builder},
3
+ reqwest::Client,
4
+ smbcloud_model::{account::User, error_codes::ErrorResponse},
5
+ smbcloud_network::{environment::Environment, network::request},
6
+};
7
+
8
+pub async fn me_with_client(
9
+ env: Environment,
10
+ client: ClientCredentials<'_>,
11
+ access_token: &str,
12
+) -> Result<User, ErrorResponse> {
13
+ let builder = Client::new()
14
+ .get(build_me_url(env, client))
15
+ .header("Authorization", access_token)
16
+ .header("Accept", "application/json")
17
+ .header("Content-Type", "application/x-www-form-urlencoded");
18
+ request(builder).await
19
+}
20
+
21
+fn build_me_url(env: Environment, client: ClientCredentials<'_>) -> String {
22
+ let mut url_builder = tenant_base_url_builder(env, client);
23
+ url_builder.add_route("v1/client/me");
24
+ url_builder.build()
25
+}
crates/smbcloud-auth-sdk/src/oidc.rs
new
+163
@@ -0,0 +1,163 @@
1
+use {
2
+ base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD},
3
+ reqwest::{Client, Url},
4
+ serde::{Deserialize, Serialize},
5
+ sha2::{Digest, Sha256},
6
+ smbcloud_model::error_codes::{ErrorCode, ErrorResponse},
7
+ smbcloud_network::{environment::Environment, network},
8
+ uuid::Uuid,
9
+};
10
+
11
+const AUTHORIZE_PATH: &str = "oauth/authorize";
12
+const TOKEN_PATH: &str = "oauth/token";
13
+const USERINFO_PATH: &str = "oauth/userinfo";
14
+
15
+#[derive(Debug, Clone, Serialize, Deserialize)]
16
+pub struct AuthorizationRequest {
17
+ pub authorize_url: String,
18
+ pub redirect_uri: String,
19
+ pub state: String,
20
+ pub code_verifier: String,
21
+}
22
+
23
+#[derive(Debug, Clone, Serialize, Deserialize)]
24
+pub struct CallbackPayload {
25
+ pub code: String,
26
+ pub state: String,
27
+}
28
+
29
+#[derive(Debug, Clone, Serialize, Deserialize)]
30
+pub struct TokenResponse {
31
+ pub access_token: String,
32
+ pub token_type: String,
33
+ pub expires_in: Option<i32>,
34
+ pub refresh_token: Option<String>,
35
+ pub scope: Option<String>,
36
+ pub id_token: Option<String>,
37
+}
38
+
39
+#[derive(Debug, Clone, Serialize, Deserialize)]
40
+pub struct UserInfo {
41
+ pub sub: String,
42
+ pub email: Option<String>,
43
+ pub email_verified: Option<bool>,
44
+ pub tenant_id: Option<u64>,
45
+ pub tenant_slug: Option<String>,
46
+}
47
+
48
+pub fn build_authorization_request(
49
+ env: Environment,
50
+ oidc_client_id: &str,
51
+ redirect_uri: String,
52
+) -> Result<AuthorizationRequest, ErrorResponse> {
53
+ let code_verifier = format!("{}{}", Uuid::new_v4().simple(), Uuid::new_v4().simple());
54
+ let code_challenge = URL_SAFE_NO_PAD.encode(Sha256::digest(code_verifier.as_bytes()));
55
+ let state = Uuid::new_v4().to_string();
56
+
57
+ let mut url =
58
+ issuer_base_url(env)
59
+ .join(AUTHORIZE_PATH)
60
+ .map_err(|err| ErrorResponse::Error {
61
+ error_code: ErrorCode::ParseError,
62
+ message: err.to_string(),
63
+ })?;
64
+
65
+ url.query_pairs_mut()
66
+ .append_pair("client_id", oidc_client_id)
67
+ .append_pair("redirect_uri", &redirect_uri)
68
+ .append_pair("response_type", "code")
69
+ .append_pair("scope", "openid profile email")
70
+ .append_pair("state", &state)
71
+ .append_pair("code_challenge", &code_challenge)
72
+ .append_pair("code_challenge_method", "S256");
73
+
74
+ Ok(AuthorizationRequest {
75
+ authorize_url: url.to_string(),
76
+ redirect_uri,
77
+ state,
78
+ code_verifier,
79
+ })
80
+}
81
+
82
+pub fn parse_callback_url(callback_url: &str) -> Result<CallbackPayload, ErrorResponse> {
83
+ let url = Url::parse(callback_url).map_err(|err| ErrorResponse::Error {
84
+ error_code: ErrorCode::ParseError,
85
+ message: err.to_string(),
86
+ })?;
87
+
88
+ let mut code = None;
89
+ let mut state = None;
90
+
91
+ for (key, value) in url.query_pairs() {
92
+ match key.as_ref() {
93
+ "code" => code = Some(value.into_owned()),
94
+ "state" => state = Some(value.into_owned()),
95
+ _ => {}
96
+ }
97
+ }
98
+
99
+ match (code, state) {
100
+ (Some(code), Some(state)) => Ok(CallbackPayload { code, state }),
101
+ _ => Err(ErrorResponse::Error {
102
+ error_code: ErrorCode::InvalidParams,
103
+ message: "Missing authorization code or state.".to_string(),
104
+ }),
105
+ }
106
+}
107
+
108
+pub async fn exchange_code(
109
+ env: Environment,
110
+ oidc_client_id: &str,
111
+ redirect_uri: &str,
112
+ code: &str,
113
+ code_verifier: &str,
114
+) -> Result<TokenResponse, ErrorResponse> {
115
+ let url = issuer_base_url(env)
116
+ .join(TOKEN_PATH)
117
+ .map_err(|err| ErrorResponse::Error {
118
+ error_code: ErrorCode::ParseError,
119
+ message: err.to_string(),
120
+ })?;
121
+
122
+ let builder = Client::new()
123
+ .post(url)
124
+ .form(&[
125
+ ("grant_type", "authorization_code"),
126
+ ("client_id", oidc_client_id),
127
+ ("code", code),
128
+ ("redirect_uri", redirect_uri),
129
+ ("code_verifier", code_verifier),
130
+ ])
131
+ .header("Accept", "application/json");
132
+
133
+ network::request(builder).await
134
+}
135
+
136
+pub async fn get_userinfo(
137
+ env: Environment,
138
+ access_token: &str,
139
+ tenant_id: Option<&str>,
140
+) -> Result<UserInfo, ErrorResponse> {
141
+ let url = issuer_base_url(env)
142
+ .join(USERINFO_PATH)
143
+ .map_err(|err| ErrorResponse::Error {
144
+ error_code: ErrorCode::ParseError,
145
+ message: err.to_string(),
146
+ })?;
147
+
148
+ let mut builder = Client::new()
149
+ .get(url)
150
+ .bearer_auth(access_token)
151
+ .header("Accept", "application/json");
152
+
153
+ if let Some(tenant_id) = tenant_id {
154
+ builder = builder.header("X-Smbcloud-Tenant-Id", tenant_id);
155
+ }
156
+
157
+ network::request(builder).await
158
+}
159
+
160
+fn issuer_base_url(env: Environment) -> Url {
161
+ Url::parse(&format!("{}://{}/", env.api_protocol(), env.api_host()))
162
+ .expect("valid smbcloud api base url")
163
+}
crates/smbcloud-auth-sdk/src/remove.rs
new
+24
@@ -0,0 +1,24 @@
1
+use {
2
+ crate::client_credentials::{ClientCredentials, base_url_builder as tenant_base_url_builder},
3
+ reqwest::Client,
4
+ smbcloud_model::error_codes::ErrorResponse,
5
+ smbcloud_network::{environment::Environment, network::request},
6
+};
7
+
8
+pub async fn remove_with_client(
9
+ env: Environment,
10
+ client: ClientCredentials<'_>,
11
+ access_token: &str,
12
+) -> Result<(), ErrorResponse> {
13
+ let builder = Client::new()
14
+ .delete(build_remove_url(env, client))
15
+ .header("Authorization", access_token)
16
+ .header("User-agent", client.app_id);
17
+ request(builder).await
18
+}
19
+
20
+fn build_remove_url(env: Environment, client: ClientCredentials<'_>) -> String {
21
+ let mut url_builder = tenant_base_url_builder(env, client);
22
+ url_builder.add_route("v1/client/me");
23
+ url_builder.build()
24
+}
crates/smbcloud-auth-sdk/src/signup.rs
new
+31
@@ -0,0 +1,31 @@
1
+use {
2
+ crate::client_credentials::{ClientCredentials, base_url_builder as tenant_base_url_builder},
3
+ reqwest::Client,
4
+ smbcloud_model::{
5
+ error_codes::ErrorResponse,
6
+ signup::{SignupEmailParams, SignupResult, SignupUserEmail},
7
+ },
8
+ smbcloud_network::{environment::Environment, network::request},
9
+};
10
+
11
+pub async fn signup_with_client(
12
+ env: Environment,
13
+ client: ClientCredentials<'_>,
14
+ email: String,
15
+ password: String,
16
+) -> Result<SignupResult, ErrorResponse> {
17
+ let params = SignupEmailParams {
18
+ user: SignupUserEmail { email, password },
19
+ };
20
+ let builder = Client::new()
21
+ .post(build_signup_url(env, client))
22
+ .json(¶ms)
23
+ .header("User-agent", client.app_id);
24
+ request(builder).await
25
+}
26
+
27
+fn build_signup_url(env: Environment, client: ClientCredentials<'_>) -> String {
28
+ let mut url_builder = tenant_base_url_builder(env, client);
29
+ url_builder.add_route("v1/client/users");
30
+ url_builder.build()
31
+}
crates/smbcloud-auth/Cargo.toml
+1
-3
@@ -18,14 +18,12 @@ categories = [
18
readme = "README.md"
19
20
[dependencies]
21
-base64 = "0.22"
21
log = { workspace = true }
22
+uuid = { version = "1", features = ["v4", "js"] }
23
reqwest = { workspace = true, features = ["json", "rustls-tls-native-roots"] }
24
serde = { workspace = true, features = ["derive"] }
25
serde_json = { workspace = true }
26
-sha2 = "0.10"
26
smbcloud-model = { workspace = true }
27
smbcloud-network = { workspace = true }
28
smbcloud-networking = { workspace = true }
29
url-builder = { workspace = true }
31
-uuid = { version = "1", features = ["v4", "js"] }
crates/smbcloud-auth/src/lib.rs
-3
@@ -1,11 +1,8 @@
1
-pub mod apple;
1
pub mod check_email;
3
-pub mod client_credentials;
2
pub mod login;
3
pub mod logout;
4
pub mod me;
5
pub mod oauth;
8
-pub mod oidc;
6
pub mod remove;
7
pub mod resend_email_verification;
8
pub mod resend_reset_password_instruction;
crates/smbcloud-auth/src/login.rs
-26
@@ -1,5 +1,4 @@
1
use {
2
- crate::client_credentials::{ClientCredentials, base_url_builder as tenant_base_url_builder},
2
reqwest::Client,
3
smbcloud_model::{
4
error_codes::ErrorResponse,
@@ -32,33 +31,8 @@ pub async fn login(
31
request_login(builder).await
32
}
33
35
-pub async fn login_with_client(
36
- env: Environment,
37
- client: ClientCredentials<'_>,
38
- username: String,
39
- password: String,
40
-) -> Result<AccountStatus, ErrorResponse> {
41
- let login_params = LoginParams {
42
- user: UserParam {
43
- email: username,
44
- password,
45
- },
46
- };
47
- let builder = Client::new()
48
- .post(build_login_url_with_client(env, client))
49
- .json(&login_params)
50
- .header("User-agent", client.app_id);
51
- request_login(builder).await
52
-}
53
-
34
pub(crate) fn build_smb_login_url(env: Environment, client: (&SmbClient, &str)) -> String {
35
let mut url_builder = smb_base_url_builder(env, client);
36
url_builder.add_route(PATH_USERS_SIGN_IN);
37
url_builder.build()
38
}
59
-
60
-fn build_login_url_with_client(env: Environment, client: ClientCredentials<'_>) -> String {
61
- let mut url_builder = tenant_base_url_builder(env, client);
62
- url_builder.add_route("v1/client/users/sign_in");
63
- url_builder.build()
64
-}
crates/smbcloud-auth/src/logout.rs
-38
@@ -1,5 +1,4 @@
1
use {
2
- crate::client_credentials::{ClientCredentials, base_url_builder as tenant_base_url_builder},
2
reqwest::{Client, StatusCode},
3
smbcloud_model::error_codes::{ErrorCode, ErrorResponse},
4
smbcloud_network::environment::Environment,
@@ -39,45 +38,8 @@ pub async fn logout(
38
}
39
}
40
42
-pub async fn logout_with_client(
43
- env: Environment,
44
- client: ClientCredentials<'_>,
45
- access_token: String,
46
-) -> Result<(), ErrorResponse> {
47
- let response = match Client::new()
48
- .delete(build_logout_url_with_client(env, client))
49
- .header("Authorization", access_token)
50
- .header("Accept", "application/json")
51
- .header("Content-Type", "application/x-www-form-urlencoded")
52
- .send()
53
- .await
54
- {
55
- Ok(response) => response,
56
- Err(_) => {
57
- return Err(ErrorResponse::Error {
58
- error_code: ErrorCode::Unknown,
59
- message: ErrorCode::Unknown.message(None).to_string(),
60
- });
61
- }
62
- };
63
-
64
- match response.status() {
65
- StatusCode::OK => Ok(()),
66
- _ => Err(ErrorResponse::Error {
67
- error_code: ErrorCode::Unauthorized,
68
- message: ErrorCode::Unauthorized.message(None).to_string(),
69
- }),
70
- }
71
-}
72
-
41
fn build_smb_logout_url(env: Environment, client: (&SmbClient, &str)) -> String {
42
let mut url_builder = smb_base_url_builder(env, client);
43
url_builder.add_route(PATH_USERS_SIGN_OUT);
44
url_builder.build()
45
}
78
-
79
-fn build_logout_url_with_client(env: Environment, client: ClientCredentials<'_>) -> String {
80
- let mut url_builder = tenant_base_url_builder(env, client);
81
- url_builder.add_route("v1/client/users/sign_out");
82
- url_builder.build()
83
-}
crates/smbcloud-auth/src/me.rs
+6
-25
@@ -1,9 +1,9 @@
1
-use crate::client_credentials::{ClientCredentials, base_url_builder as tenant_base_url_builder};
2
-use reqwest::Client;
3
-use smbcloud_model::account::User;
4
-use smbcloud_model::error_codes::ErrorResponse;
5
-use smbcloud_network::{environment::Environment, network::request};
6
-use smbcloud_networking::{constants::PATH_USERS_ME, smb_base_url_builder, smb_client::SmbClient};
1
+use {
2
+ reqwest::Client,
3
+ smbcloud_model::{account::User, error_codes::ErrorResponse},
4
+ smbcloud_network::{environment::Environment, network::request},
5
+ smbcloud_networking::{constants::PATH_USERS_ME, smb_base_url_builder, smb_client::SmbClient},
6
+};
7
8
pub async fn me(
9
env: Environment,
@@ -18,27 +18,8 @@ pub async fn me(
18
request(builder).await
19
}
20
21
-pub async fn me_with_client(
22
- env: Environment,
23
- client: ClientCredentials<'_>,
24
- access_token: &str,
25
-) -> Result<User, ErrorResponse> {
26
- let builder = Client::new()
27
- .get(build_info_url_with_client(env, client))
28
- .header("Authorization", access_token)
29
- .header("Accept", "application/json")
30
- .header("Content-Type", "application/x-www-form-urlencoded");
31
- request(builder).await
32
-}
33
-
21
fn build_smb_info_url(env: Environment, client: (&SmbClient, &str)) -> String {
22
let mut url_builder = smb_base_url_builder(env, client);
23
url_builder.add_route(PATH_USERS_ME);
24
url_builder.build()
25
}
39
-
40
-fn build_info_url_with_client(env: Environment, client: ClientCredentials<'_>) -> String {
41
- let mut url_builder = tenant_base_url_builder(env, client);
42
- url_builder.add_route("v1/client/me");
43
- url_builder.build()
44
-}
crates/smbcloud-auth/src/remove.rs
+2
-21
@@ -1,5 +1,4 @@
1
use {
2
- crate::client_credentials::{ClientCredentials, base_url_builder as tenant_base_url_builder},
2
reqwest::Client,
3
smbcloud_model::error_codes::ErrorResponse,
4
smbcloud_network::{environment::Environment, network::request},
@@ -12,32 +11,14 @@ pub async fn remove(
11
access_token: &str,
12
) -> Result<(), ErrorResponse> {
13
let builder = Client::new()
15
- .delete(build_smb_signup_url(env, client))
14
+ .delete(build_smb_remove_url(env, client))
15
.header("Authorization", access_token)
16
.header("User-agent", client.0.id());
17
request(builder).await
18
}
19
21
-pub async fn remove_with_client(
22
- env: Environment,
23
- client: ClientCredentials<'_>,
24
- access_token: &str,
25
-) -> Result<(), ErrorResponse> {
26
- let builder = Client::new()
27
- .delete(build_remove_url_with_client(env, client))
28
- .header("Authorization", access_token)
29
- .header("User-agent", client.app_id);
30
- request(builder).await
31
-}
32
-
33
-fn build_smb_signup_url(env: Environment, client: (&SmbClient, &str)) -> String {
20
+fn build_smb_remove_url(env: Environment, client: (&SmbClient, &str)) -> String {
21
let mut url_builder = smb_base_url_builder(env, client);
22
url_builder.add_route(PATH_USERS);
23
url_builder.build()
24
}
38
-
39
-fn build_remove_url_with_client(env: Environment, client: ClientCredentials<'_>) -> String {
40
- let mut url_builder = tenant_base_url_builder(env, client);
41
- url_builder.add_route("v1/client/me");
42
- url_builder.build()
43
-}
crates/smbcloud-auth/src/signup.rs
-23
@@ -1,5 +1,4 @@
1
use {
2
- crate::client_credentials::{ClientCredentials, base_url_builder as tenant_base_url_builder},
2
reqwest::Client,
3
smbcloud_model::{
4
error_codes::ErrorResponse,
@@ -25,30 +24,8 @@ pub async fn signup(
24
request(builder).await
25
}
26
28
-pub async fn signup_with_client(
29
- env: Environment,
30
- client: ClientCredentials<'_>,
31
- email: String,
32
- password: String,
33
-) -> Result<SignupResult, ErrorResponse> {
34
- let params = SignupEmailParams {
35
- user: SignupUserEmail { email, password },
36
- };
37
- let builder = Client::new()
38
- .post(build_signup_url_with_client(env, client))
39
- .json(¶ms)
40
- .header("User-agent", client.app_id);
41
- request(builder).await
42
-}
43
-
27
fn build_smb_signup_url(env: Environment, client: (&SmbClient, &str)) -> String {
28
let mut url_builder = smb_base_url_builder(env, client);
29
url_builder.add_route(PATH_USERS);
30
url_builder.build()
31
}
49
-
50
-fn build_signup_url_with_client(env: Environment, client: ClientCredentials<'_>) -> String {
51
- let mut url_builder = tenant_base_url_builder(env, client);
52
- url_builder.add_route("v1/client/users");
53
- url_builder.build()
54
-}