feat: added support for account registration
This commit is contained in:
parent
14f1c54575
commit
f85081e449
30
src/error.rs
30
src/error.rs
|
@ -23,3 +23,33 @@ pub enum AuthError {
|
|||
#[error("Failed to authenticate: account not verified")]
|
||||
NotVerified,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum RegisterError {
|
||||
#[error("Failed to register: the API complains about a malformed request")]
|
||||
BadRequest,
|
||||
|
||||
#[error("Failed to register: unprocessable API response")]
|
||||
BadResponse,
|
||||
|
||||
#[error("Failed to register: failed to send request")]
|
||||
RequestSend(reqwest::Error),
|
||||
|
||||
#[error("Failed to register: blocked for security reasons")]
|
||||
Forbidden,
|
||||
|
||||
#[error("Failed to register: the username is already taken")]
|
||||
UsernameTaken,
|
||||
|
||||
#[error("Failed to register: the email is already in use")]
|
||||
EmailTaken,
|
||||
|
||||
#[error("Failed to register: the username does not meet the criteria")]
|
||||
UsernameInvalid,
|
||||
|
||||
#[error("Failed to register: the email is not a valid email address")]
|
||||
EmailInvalid,
|
||||
|
||||
#[error("Failed to register: password does not meet the criteria")]
|
||||
PasswordInvalid,
|
||||
}
|
||||
|
|
55
src/lib.rs
55
src/lib.rs
|
@ -2,7 +2,7 @@ mod error;
|
|||
pub mod request;
|
||||
pub mod response;
|
||||
|
||||
use crate::{error::AuthError, request::AccountAuthenticate};
|
||||
use crate::error::{AuthError, RegisterError};
|
||||
use anyhow::Result;
|
||||
use reqwest::StatusCode;
|
||||
use std::fmt::Debug;
|
||||
|
@ -40,7 +40,7 @@ impl Session {
|
|||
) -> Result<(), AuthError> {
|
||||
let url = format!("{}/account/authenticate", &self.base_url);
|
||||
|
||||
let body = AccountAuthenticate { username, password };
|
||||
let body = request::AccountAuthenticate { username, password };
|
||||
|
||||
let request = self.client.post(&url).json(&body);
|
||||
let response = request
|
||||
|
@ -52,7 +52,7 @@ impl Session {
|
|||
StatusCode::OK => {
|
||||
self.auth_token = Some(
|
||||
response
|
||||
.json::<response::AccountAuthenticateResponse>()
|
||||
.json::<response::AccountAuthenticate>()
|
||||
.await
|
||||
.map_err(|_| AuthError::BadResponse)?
|
||||
.token,
|
||||
|
@ -68,6 +68,55 @@ impl Session {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn register(
|
||||
&self,
|
||||
username: String,
|
||||
password: String,
|
||||
email: String,
|
||||
) -> Result<(), RegisterError> {
|
||||
let url = format!("{}/account/register", &self.base_url);
|
||||
|
||||
let body = request::AccountRegister {
|
||||
username,
|
||||
password,
|
||||
email,
|
||||
};
|
||||
|
||||
let request = self.client.post(&url).json(&body);
|
||||
let response = request
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| RegisterError::RequestSend(e))?;
|
||||
|
||||
match response.status() {
|
||||
StatusCode::OK => Ok(()),
|
||||
StatusCode::BAD_REQUEST => Err(RegisterError::BadRequest),
|
||||
StatusCode::FORBIDDEN => Err(RegisterError::Forbidden),
|
||||
StatusCode::CONFLICT => match response
|
||||
.json::<response::AccountRegisterConflict>()
|
||||
.await
|
||||
.map_err(|_| RegisterError::BadResponse)?
|
||||
{
|
||||
response::AccountRegisterConflict::Username => Err(RegisterError::UsernameTaken),
|
||||
response::AccountRegisterConflict::Email => Err(RegisterError::EmailTaken),
|
||||
},
|
||||
StatusCode::UNPROCESSABLE_ENTITY => match response
|
||||
.json::<response::AccountRegisterUnprocessable>()
|
||||
.await
|
||||
.map_err(|_| RegisterError::BadResponse)?
|
||||
{
|
||||
response::AccountRegisterUnprocessable::Username => {
|
||||
Err(RegisterError::UsernameInvalid)
|
||||
}
|
||||
response::AccountRegisterUnprocessable::Email => Err(RegisterError::EmailInvalid),
|
||||
response::AccountRegisterUnprocessable::Password => {
|
||||
Err(RegisterError::PasswordInvalid)
|
||||
}
|
||||
},
|
||||
_ => Err(RegisterError::BadResponse),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_authenticated(&self) -> bool {
|
||||
self.auth_token.is_some()
|
||||
}
|
||||
|
|
|
@ -4,4 +4,11 @@ use serde::Serialize;
|
|||
pub struct AccountAuthenticate {
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Clone)]
|
||||
pub struct AccountRegister {
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
pub email: String,
|
||||
}
|
||||
|
|
|
@ -1,6 +1,21 @@
|
|||
use serde::Deserialize;
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
pub struct AccountAuthenticateResponse {
|
||||
pub struct AccountAuthenticate {
|
||||
pub token: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[serde(tag = "conflict", rename_all = "snake_case")]
|
||||
pub enum AccountRegisterConflict {
|
||||
Username,
|
||||
Email,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[serde(tag = "problem", rename_all = "snake_case")]
|
||||
pub enum AccountRegisterUnprocessable {
|
||||
Username,
|
||||
Email,
|
||||
Password,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue