Skip to content

Commit 792d06b

Browse files
committed
Merge branch 'development'
2 parents a516444 + 6771c9c commit 792d06b

File tree

25 files changed

+742
-131
lines changed

25 files changed

+742
-131
lines changed

crates/cli/src/account/login/process.rs

Lines changed: 14 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use {
1212
console::style,
1313
dialoguer::{console::Term, theme::ColorfulTheme, Confirm, Input, Password, Select},
1414
log::debug,
15-
reqwest::{Client, StatusCode},
15+
reqwest::Client,
1616
smbcloud_model::{
1717
account::{
1818
ErrorCode::{
@@ -21,20 +21,19 @@ use {
2121
},
2222
GithubInfo, SmbAuthorization, User,
2323
},
24-
forgot::{Param, UserUpdatePassword},
2524
login::{AccountStatus, LoginArgs},
2625
signup::{GithubEmail, Provider, SignupGithubParams, SignupUserGithub},
2726
},
2827
smbcloud_network::environment::Environment,
2928
smbcloud_networking::{
30-
constants::{
31-
PATH_LINK_GITHUB_ACCOUNT, PATH_RESEND_CONFIRMATION, PATH_RESET_PASSWORD_INSTRUCTIONS,
32-
PATH_USERS_PASSWORD,
33-
},
34-
smb_base_url_builder,
35-
smb_client::SmbClient,
29+
constants::PATH_LINK_GITHUB_ACCOUNT, smb_base_url_builder, smb_client::SmbClient,
30+
},
31+
smbcloud_networking_account::{
32+
check_email::check_email, login::login,
33+
resend_email_verification::resend_email_verification as account_resend_email_verification,
34+
resend_reset_password_instruction::resend_reset_password_instruction as account_resend_reset_password_instruction,
35+
reset_password::reset_password as account_reset_password,
3636
},
37-
smbcloud_networking_account::{check_email::check_email, login::login},
3837
smbcloud_utils::email_validation,
3938
spinners::Spinner,
4039
};
@@ -215,17 +214,8 @@ async fn resend_email_verification(env: Environment, user: User) -> Result<Comma
215214
.bold()
216215
.to_string(),
217216
);
218-
219-
let response = Client::new()
220-
.post(build_smb_resend_email_verification_url(env))
221-
.body(format!("id={}", user.id))
222-
.header("Accept", "application/json")
223-
.header("Content-Type", "application/x-www-form-urlencoded")
224-
.send()
225-
.await?;
226-
227-
match response.status() {
228-
reqwest::StatusCode::OK => Ok(CommandResult {
217+
match account_resend_email_verification(env, SmbClient::Cli, user.email).await {
218+
Ok(_) => Ok(CommandResult {
229219
spinner,
230220
symbol: succeed_symbol(),
231221
msg: succeed_message("Verification email sent!"),
@@ -475,16 +465,9 @@ async fn resend_reset_password_instruction(env: Environment, user: User) -> Resu
475465
spinners::Spinners::SimpleDotsScrolling,
476466
succeed_message("Sending reset password instruction..."),
477467
);
478-
let response = Client::new()
479-
.post(build_smb_resend_reset_password_instructions_url(env))
480-
.body(format!("id={}", user.id))
481-
.header("Accept", "application/json")
482-
.header("Content-Type", "application/x-www-form-urlencoded")
483-
.send()
484-
.await?;
485468

486-
match response.status() {
487-
StatusCode::OK => {
469+
match account_resend_reset_password_instruction(env, SmbClient::Cli, user.email).await {
470+
Ok(_) => {
488471
spinner.stop_and_persist(
489472
"✅",
490473
"Reset password instruction sent! Please check your email.".to_owned(),
@@ -526,26 +509,8 @@ async fn input_reset_password_token(env: Environment) -> Result<CommandResult> {
526509
style("Resetting password...").green().bold().to_string(),
527510
);
528511

529-
let password_confirmation = password.clone();
530-
531-
let params = Param {
532-
user: UserUpdatePassword {
533-
reset_password_token: token,
534-
password,
535-
password_confirmation,
536-
},
537-
};
538-
539-
let response = Client::new()
540-
.put(build_smb_reset_password_url(env))
541-
.json(&params)
542-
.header("Accept", "application/json")
543-
.header("Content-Type", "application/x-www-form-urlencoded")
544-
.send()
545-
.await?;
546-
547-
match response.status() {
548-
StatusCode::OK => Ok(CommandResult {
512+
match account_reset_password(env, SmbClient::Cli, token, password).await {
513+
Ok(_) => Ok(CommandResult {
549514
spinner,
550515
symbol: succeed_symbol(),
551516
msg: succeed_message("Password reset!"),
@@ -554,24 +519,6 @@ async fn input_reset_password_token(env: Environment) -> Result<CommandResult> {
554519
}
555520
}
556521

557-
fn build_smb_resend_email_verification_url(env: Environment) -> String {
558-
let mut url_builder = smb_base_url_builder(env, &SmbClient::Cli);
559-
url_builder.add_route(PATH_RESEND_CONFIRMATION);
560-
url_builder.build()
561-
}
562-
563-
fn build_smb_resend_reset_password_instructions_url(env: Environment) -> String {
564-
let mut url_builder = smb_base_url_builder(env, &SmbClient::Cli);
565-
url_builder.add_route(PATH_RESET_PASSWORD_INSTRUCTIONS);
566-
url_builder.build()
567-
}
568-
569-
fn build_smb_reset_password_url(env: Environment) -> String {
570-
let mut url_builder = smb_base_url_builder(env, &SmbClient::Cli);
571-
url_builder.add_route(PATH_USERS_PASSWORD);
572-
url_builder.build()
573-
}
574-
575522
fn build_smb_connect_github_url(env: Environment) -> String {
576523
let mut url_builder = smb_base_url_builder(env, &SmbClient::Cli);
577524
url_builder.add_route(PATH_LINK_GITHUB_ACCOUNT);

crates/smbcloud-model/src/account.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub struct SmbAuthorization {
4848
pub error_code: Option<ErrorCode>,
4949
}
5050

51+
/// TODO: Move to ErrorResponse
5152
#[derive(Debug, Serialize_repr, Deserialize_repr, PartialEq)]
5253
#[repr(u32)]
5354
#[tsync]

crates/smbcloud-model/src/error_codes.rs

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,25 +44,49 @@ pub enum ErrorCode {
4444
// Account
4545
#[error("Unauthorized access.")]
4646
Unauthorized = 100,
47+
#[error("Invalid params.")]
48+
InvalidParams = 101,
49+
// Account not ready errors.
50+
#[error("Email not found.")]
51+
EmailNotFound = 1000,
52+
#[error("Email unverified.")]
53+
EmailNotVerified = 1001,
54+
#[error("Email confirmation failed.")]
55+
EmailConfirmationFailed = 1002,
56+
#[error("Password is unset.")]
57+
PasswordNotSet = 1003,
58+
#[error("GitHub email is not connected.")]
59+
GitHubEmailNotConnected = 1004,
4760
#[error("Email already exists.")]
4861
EmailAlreadyExist = 1005,
62+
#[error("Invalid password.")]
63+
InvalidPassword = 1006,
4964
// Projects
5065
#[error("Project not found.")]
51-
ProjectNotFound = 1000,
66+
ProjectNotFound = 2000,
5267
#[error("Runner not supported.")]
53-
UnsupportedRunner = 1001,
68+
UnsupportedRunner = 2001,
5469
}
5570

5671
impl ErrorCode {
5772
/// Cannot expose the ErrorCode enum directly to Ruby,
5873
/// so we need to get it from i32.
5974
pub fn from_i32(value: i32) -> Self {
6075
match value {
61-
// Account
76+
// Generic
6277
100 => ErrorCode::Unauthorized,
78+
101 => ErrorCode::InvalidParams,
79+
// Account not ready errors
80+
1000 => ErrorCode::EmailNotFound,
81+
1001 => ErrorCode::EmailNotVerified,
82+
1002 => ErrorCode::EmailConfirmationFailed,
83+
1003 => ErrorCode::PasswordNotSet,
84+
1004 => ErrorCode::GitHubEmailNotConnected,
6385
1005 => ErrorCode::EmailAlreadyExist,
86+
1006 => ErrorCode::InvalidPassword,
6487
// Projects
65-
1000 => ErrorCode::ProjectNotFound,
88+
2000 => ErrorCode::ProjectNotFound, // Projects
89+
2001 => ErrorCode::UnsupportedRunner,
6690
// Generic errors
6791
5 => ErrorCode::Cancel,
6892
4 => ErrorCode::MissingConfig,
@@ -79,19 +103,28 @@ impl ErrorCode {
79103
debug!("Language code: {:?}, {}", l, self);
80104
match self {
81105
ErrorCode::Unknown => "Unknown error.",
82-
ErrorCode::ProjectNotFound => "Project not found.",
106+
// Networking
83107
ErrorCode::ParseError => "Parse error.",
84108
ErrorCode::NetworkError => {
85109
"Network error. Please check your internet connection and try again."
86110
}
87-
// Accounts
111+
// Generic
88112
ErrorCode::Unauthorized => "Unauthorized access.",
113+
ErrorCode::InvalidParams => "Invalid parameters.",
114+
// Account not ready errors
115+
ErrorCode::EmailNotFound => "Email not found.",
116+
ErrorCode::EmailNotVerified => "Email not verified.",
117+
ErrorCode::EmailConfirmationFailed => "Email confirmation faile.",
118+
ErrorCode::PasswordNotSet => "Password is not set.",
119+
ErrorCode::GitHubEmailNotConnected => "GitHub email is not connected.",
89120
ErrorCode::EmailAlreadyExist => "Email already exists.",
90-
121+
ErrorCode::InvalidPassword => "Invalid password.",
122+
// CLI Generic errors
91123
ErrorCode::InputError => "Input error.",
92124
ErrorCode::MissingConfig => "Missing config.",
93125
ErrorCode::Cancel => "Cancelled operation.",
94126
// Projects
127+
ErrorCode::ProjectNotFound => "Project not found.",
95128
ErrorCode::UnsupportedRunner => "Unsupported runner.",
96129
}
97130
}

crates/smbcloud-model/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub mod login;
66
pub mod oauth;
77
pub mod project;
88
pub mod repository;
9+
pub mod reset_password_response;
910
pub mod runner;
1011
pub mod signup;
1112

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use {
2+
serde::{Deserialize, Serialize},
3+
tsync::tsync,
4+
};
5+
6+
#[derive(Debug, Serialize, Deserialize)]
7+
#[tsync]
8+
pub struct ResetPasswordResponse {
9+
pub code: Option<i32>,
10+
pub message: String,
11+
}

crates/smbcloud-network/src/network.rs

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub async fn check_internet_connection() -> bool {
5252
pub async fn parse_error_response<T: DeserializeOwned>(
5353
response: Response,
5454
) -> Result<T, ErrorResponse> {
55-
let response_body = match response.text().await {
55+
let error_response_body = match response.text().await {
5656
Ok(body) => body,
5757
Err(e) => {
5858
error!("Failed to get response body: {:?}", e);
@@ -66,13 +66,13 @@ pub async fn parse_error_response<T: DeserializeOwned>(
6666
if LOG_RESPONSE_BODY {
6767
println!();
6868
println!("Parse Error >>>>");
69-
println!("{:?}", serde_json::to_string_pretty(&response_body));
69+
println!("{:?}", serde_json::to_string_pretty(&error_response_body));
7070
println!("Parse Error >>>>");
7171
println!();
7272
}
7373

74-
let e = match serde_json::from_str::<ErrorResponse>(&response_body) {
75-
Ok(json) => json,
74+
let error_response = match serde_json::from_str(&error_response_body) {
75+
Ok(error_response) => error_response,
7676
Err(e) => {
7777
error!("Failed to parse error response: {:?}", e);
7878
return Err(ErrorResponse::Error {
@@ -81,41 +81,29 @@ pub async fn parse_error_response<T: DeserializeOwned>(
8181
});
8282
}
8383
};
84-
error!("Error response: {:?}", e);
85-
Err(e)
84+
// The parsing itself is succeed.
85+
// Why is this an ErrorResponse.
86+
Err(error_response)
8687
}
8788

8889
pub async fn request_login(builder: RequestBuilder) -> Result<AccountStatus, ErrorResponse> {
8990
let response = builder.send().await;
9091
let response = match response {
9192
Ok(response) => response,
9293
Err(e) => {
93-
error!("Failed to get response: {:?}", e);
94+
error!("request_login: Failed to get response: {:?}", e);
9495
return Err(ErrorResponse::Error {
9596
error_code: ErrorCode::NetworkError,
9697
message: ErrorCode::NetworkError.message(None).to_string(),
9798
});
9899
}
99100
};
100101

101-
let response = match response.status() {
102-
reqwest::StatusCode::OK
103-
| reqwest::StatusCode::NOT_FOUND
104-
| reqwest::StatusCode::UNPROCESSABLE_ENTITY => response,
105-
status => {
106-
error!(
107-
"Response are neither OK, NOT_FOUND, or UNPROCESSABLE_ENTITY: {:?}",
108-
status
109-
);
110-
return parse_error_response(response).await;
111-
}
112-
};
113-
114102
if LOG_RESPONSE_BODY {
115103
println!();
116-
println!("Parse >>>>");
104+
println!("request_login: Parse >>>>");
117105
println!("{:?}", &response.status());
118-
println!("Parse >>>>");
106+
println!("request_login: Parse >>>>");
119107
println!();
120108
}
121109

@@ -133,6 +121,30 @@ pub async fn request_login(builder: RequestBuilder) -> Result<AccountStatus, Err
133121
};
134122
Ok(AccountStatus::Ready { access_token })
135123
}
124+
(StatusCode::OK, None) => {
125+
// Silent login from oauth. Need improvement.
126+
let error_response = match parse_error_response::<ErrorResponse>(response).await {
127+
Ok(error) => error,
128+
Err(_) => return Ok(AccountStatus::NotFound),
129+
};
130+
match error_response {
131+
ErrorResponse::Error {
132+
error_code,
133+
message,
134+
} => match error_code {
135+
ErrorCode::EmailNotVerified => Ok(AccountStatus::Incomplete {
136+
status: smbcloud_model::account::ErrorCode::EmailUnverified,
137+
}),
138+
ErrorCode::PasswordNotSet => Ok(AccountStatus::Incomplete {
139+
status: smbcloud_model::account::ErrorCode::PasswordNotSet,
140+
}),
141+
ErrorCode::Unknown => Ok(AccountStatus::Ready {
142+
access_token: "tokenization".to_string(),
143+
}),
144+
_ => Ok(AccountStatus::NotFound),
145+
},
146+
}
147+
}
136148
(StatusCode::NOT_FOUND, _) => {
137149
// Account not found
138150
Ok(AccountStatus::NotFound)
@@ -193,6 +205,7 @@ pub async fn request<R: DeserializeOwned>(builder: RequestBuilder) -> Result<R,
193205
reqwest::StatusCode::OK | reqwest::StatusCode::CREATED => response,
194206
status => {
195207
error!("Failed to get response: {:?}", status);
208+
// This should handle parsing the error response.
196209
return parse_error_response(response).await;
197210
}
198211
};

crates/smbcloud-networking-account/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@ pub mod logout;
44
pub mod me;
55
pub mod oauth;
66
pub mod remove;
7+
pub mod resend_email_verification;
8+
pub mod resend_reset_password_instruction;
9+
pub mod reset_password;
710
pub mod signup;

crates/smbcloud-networking-account/src/login.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub async fn login(
2121
let login_params = LoginParams {
2222
user: UserParam {
2323
email: username,
24-
password: password,
24+
password,
2525
},
2626
};
2727
let builder = Client::new()

0 commit comments

Comments
 (0)