use serde::{Deserialize, Serialize};
use crate::{
api::enums::{GrantType, Scope},
send_access::{SendAccessCredentials, SendAccessTokenRequest},
};
#[derive(Serialize, Debug)]
#[serde(untagged)]
pub(crate) enum SendAccessTokenPayloadCredentials {
#[allow(missing_docs)]
Password { password_hash_b64: String },
#[allow(missing_docs)]
Email { email: String },
#[allow(missing_docs)]
EmailOtp { email: String, otp: String },
Anonymous,
}
impl From<Option<SendAccessCredentials>> for SendAccessTokenPayloadCredentials {
fn from(credentials: Option<SendAccessCredentials>) -> Self {
match credentials {
Some(SendAccessCredentials::Password(credentials)) => {
SendAccessTokenPayloadCredentials::Password {
password_hash_b64: credentials.password_hash_b64,
}
}
Some(SendAccessCredentials::Email(credentials)) => {
SendAccessTokenPayloadCredentials::Email {
email: credentials.email,
}
}
Some(SendAccessCredentials::EmailOtp(credentials)) => {
SendAccessTokenPayloadCredentials::EmailOtp {
email: credentials.email,
otp: credentials.otp,
}
}
None => SendAccessTokenPayloadCredentials::Anonymous,
}
}
}
#[derive(Serialize, Deserialize, Debug)]
pub(crate) enum SendAccessClientType {
#[serde(rename = "send")]
Send,
}
#[derive(Serialize, Debug)]
pub(crate) struct SendAccessTokenRequestPayload {
pub(crate) client_id: SendAccessClientType,
pub(crate) grant_type: GrantType,
pub(crate) scope: Scope,
pub(crate) send_id: String,
#[serde(flatten)]
pub(crate) credentials: SendAccessTokenPayloadCredentials,
}
const SEND_ACCESS_CLIENT_ID: SendAccessClientType = SendAccessClientType::Send;
const SEND_ACCESS_GRANT_TYPE: GrantType = GrantType::SendAccess;
const SEND_ACCESS_SCOPE: Scope = Scope::ApiSendAccess;
impl From<SendAccessTokenRequest> for SendAccessTokenRequestPayload {
fn from(request: SendAccessTokenRequest) -> Self {
SendAccessTokenRequestPayload {
client_id: SEND_ACCESS_CLIENT_ID,
grant_type: SEND_ACCESS_GRANT_TYPE,
scope: SEND_ACCESS_SCOPE,
send_id: request.send_id,
credentials: request.send_access_credentials.into(),
}
}
}
#[cfg(test)]
mod tests {
use serde_json;
use super::*;
mod send_access_token_payload_tests {
use super::*;
#[test]
fn test_serialize_send_access_token_password_payload() {
let payload = SendAccessTokenRequestPayload {
client_id: SendAccessClientType::Send,
grant_type: GrantType::SendAccess,
scope: Scope::ApiSendAccess,
send_id: "example_send_id".into(),
credentials: SendAccessTokenPayloadCredentials::Password {
password_hash_b64: "example_hash".into(),
},
};
let serialized = serde_json::to_string_pretty(&payload).unwrap();
let got: serde_json::Value = serde_json::from_str(&serialized).unwrap();
let want = serde_json::json!({
"client_id": "send",
"grant_type": "send_access",
"scope": "api.send.access",
"send_id": "example_send_id",
"password_hash_b64": "example_hash"
});
assert_eq!(got, want);
}
#[test]
fn test_serialize_send_access_token_email_payload() {
let payload = SendAccessTokenRequestPayload {
client_id: SendAccessClientType::Send,
grant_type: GrantType::SendAccess,
scope: Scope::ApiSendAccess,
send_id: "example_send_id".into(),
credentials: SendAccessTokenPayloadCredentials::Email {
email: "example_email".into(),
},
};
let serialized = serde_json::to_string_pretty(&payload).unwrap();
let got: serde_json::Value = serde_json::from_str(&serialized).unwrap();
let want = serde_json::json!({
"client_id": "send",
"grant_type": "send_access",
"scope": "api.send.access",
"send_id": "example_send_id",
"email": "example_email"
});
assert_eq!(got, want);
}
#[test]
fn test_serialize_send_access_token_email_otp_payload() {
let payload = SendAccessTokenRequestPayload {
client_id: SendAccessClientType::Send,
grant_type: GrantType::SendAccess,
scope: Scope::ApiSendAccess,
send_id: "example_send_id".into(),
credentials: SendAccessTokenPayloadCredentials::EmailOtp {
email: "example_email".into(),
otp: "example_otp".into(),
},
};
let serialized = serde_json::to_string_pretty(&payload).unwrap();
let got: serde_json::Value = serde_json::from_str(&serialized).unwrap();
let want = serde_json::json!({
"client_id": "send",
"grant_type": "send_access",
"scope": "api.send.access",
"send_id": "example_send_id",
"email": "example_email",
"otp": "example_otp"
});
assert_eq!(got, want);
}
}
}