use crate::api::RequestFailure;
use http::HeaderMap;
use reqwest;
use serde_json::{Value, json};
#[derive(Debug)]
pub struct CreateApiKeyRequest<'a> {
server: &'a str,
challenge_id: &'a str,
code: &'a str,
}
impl<'a> CreateApiKeyRequest<'a> {
pub fn new(server: &'a str) -> Self {
CreateApiKeyRequest {
server,
challenge_id: "",
code: "",
}
}
pub fn challenge_id(mut self, challenge_id: &'a str) -> Self {
self.challenge_id = challenge_id;
self
}
pub fn code(mut self, code: &'a str) -> Self {
self.code = code;
self
}
pub async fn send(&self) -> Result<String, RequestFailure> {
let endpoint = "/v1/auth/api_keys".to_string();
let body = json!({
"challenge_id": self.challenge_id,
"code": self.code
});
match send_to_server(self.server, &endpoint, &body).await {
Ok(response) => {
if response.status() == http::StatusCode::CREATED {
return Ok(response_to_api_key(response).await);
} else {
let possible_status: Vec<http::StatusCode> = Vec::from([
http::StatusCode::BAD_REQUEST,
http::StatusCode::INTERNAL_SERVER_ERROR,
]);
return Err(RequestFailure::api_error(response, possible_status).await);
}
}
Err(e) => Err(RequestFailure::reqwest_error(e)),
}
}
}
#[derive(Debug)]
pub struct CreateChallengeRequest<'a> {
server: &'a str,
app_name: &'a str,
}
impl<'a> CreateChallengeRequest<'a> {
pub fn new(server: &'a str) -> Self {
CreateChallengeRequest {
server,
app_name: "",
}
}
pub fn app_name(mut self, app_name: &'a str) -> Self {
self.app_name = app_name;
self
}
pub async fn send(&self) -> Result<String, RequestFailure> {
let endpoint = "/v1/auth/challenges".to_string();
let body = json!({
"app_name": self.app_name,
});
match send_to_server(self.server, &endpoint, &body).await {
Ok(response) => {
if response.status() == http::StatusCode::CREATED {
return Ok(response_to_challenge_id(response).await);
} else {
let possible_status: Vec<http::StatusCode> = Vec::from([
http::StatusCode::BAD_REQUEST,
http::StatusCode::INTERNAL_SERVER_ERROR,
]);
return Err(RequestFailure::api_error(response, possible_status).await);
}
}
Err(e) => Err(RequestFailure::reqwest_error(e)),
}
}
}
async fn send_to_server(
server: &str,
endpoint: &str,
body: &Value,
) -> Result<reqwest::Response, reqwest::Error> {
let mut map = HeaderMap::new();
map.insert("ACCEPT", "application/json".parse().unwrap());
let client = reqwest::Client::new();
let url = format!("{}{}", server, endpoint);
client
.post(url)
.headers(map)
.body(body.to_string())
.send()
.await
}
async fn response_to_api_key(response: reqwest::Response) -> String {
let json_input = response.text().await.unwrap();
let json: Value = serde_json::from_str(json_input.as_ref()).unwrap();
json["api_key"].clone().as_str().unwrap().to_string()
}
async fn response_to_challenge_id(response: reqwest::Response) -> String {
let json_input = response.text().await.unwrap();
let json: Value = serde_json::from_str(json_input.as_ref()).unwrap();
json["challenge_id"].clone().as_str().unwrap().to_string()
}