1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
use serde::Deserialize;
use std::collections::HashMap;
use crate::user::{UserTypes, User};
use super::Client;
use std::error::Error;
use std::fmt;
#[derive(Debug, Clone)]
struct AuthenticationError;
impl fmt::Display for AuthenticationError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Authentication Failed")
}
}
impl Error for AuthenticationError {
fn description(&self) -> &str {
"Authentication Failed!"
}
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct SuccessAuthResponse {
pub token: String
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct FailuredAuthResponse {
pub code: String,
pub message: String,
pub data: HashMap<String, String>
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase", untagged)]
pub enum AuthResponse {
SuccessAuthResponse(SuccessAuthResponse),
FailuredAuthResponse(FailuredAuthResponse)
}
impl Client {
pub async fn auth_via_email<'a>(
&mut self,
email: String, password: String,
usertype: UserTypes
) -> Result<(), Box<dyn Error>>
{
let mut credentials: HashMap<String, String> = HashMap::new();
credentials.insert(String::from("email"), email);
credentials.insert(String::from("password"), password);
match usertype {
UserTypes::User => self.authenticate_user(&credentials).await,
UserTypes::Admin => self.authenticate_admin(&credentials).await,
}
}
async fn authenticate_user(&mut self, credentials: &HashMap<String, String>) -> Result<(), Box<dyn Error>> {
let auth_response = self.post(String::from("users/auth-via-email"), &credentials).await;
let parsed_resp = match auth_response {
Ok(response) => {
match response.json::<AuthResponse>().await {
Ok(resp) => Ok(resp),
Err(err) => Err(Box::new(err) as Box<dyn Error>)
}
},
Err(err) => Err(err)
};
match parsed_resp {
Ok(body) => {
match body {
AuthResponse::SuccessAuthResponse(response) => {
self.user = Some(
User {
usertype: UserTypes::User,
token: response.token
}
);
Ok(())
},
AuthResponse::FailuredAuthResponse(_response) => {
Err(Box::new(AuthenticationError))
}
}
},
Err(err) => Err(err)
}
}
async fn authenticate_admin(&mut self, credentials: &HashMap<String, String>) -> Result<(), Box<dyn Error>> {
let auth_response = self.post(String::from("admins/auth-via-email"), &credentials).await;
let parsed_resp = match auth_response {
Ok(response) => {
match response.json::<AuthResponse>().await {
Ok(resp) => Ok(resp),
Err(err) => Err(Box::new(err) as Box<dyn Error>)
}
},
Err(err) => Err(err)
};
match parsed_resp {
Ok(body) => {
match body {
AuthResponse::SuccessAuthResponse(response) => {
self.user = Some(
User {
usertype: UserTypes::Admin,
token: response.token
}
);
Ok(())
},
AuthResponse::FailuredAuthResponse(_response) => {
Err(Box::new(AuthenticationError))
}
}
},
Err(err) => Err(err)
}
}
}