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
use crate::{
config::*,
job::{Session, SessionBody, SessionResponseBody, ValueResponseBody},
};
use reqwest::blocking::Client;
use reqwest::header::{HeaderMap, HeaderValue, AUTHORIZATION};
use serde::de::Visitor;
use serde::Deserialize;
use serde::Deserializer;
use serde::Serialize;
use serde::Serializer;
use serde_json::Value;
use std::env::var;
#[derive(Debug, PartialEq)]
pub struct Credential {
pub value: String,
}
#[cfg_attr(feature = "cargo-clippy", allow(deprecated))]
impl Serialize for Credential {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.value)
}
}
struct CredentialVisitor;
#[cfg_attr(feature = "cargo-clippy", allow(deprecated))]
impl<'de> Visitor<'de> for CredentialVisitor {
type Value = Credential;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("string or map")
}
fn visit_str<E>(self, value: &str) -> Result<Credential, E>
where
E: serde::de::Error,
{
Ok(Credential {
value: value.to_string(),
})
}
fn visit_string<E>(self, value: String) -> Result<Credential, E>
where
E: serde::de::Error,
{
Ok(Credential { value })
}
}
#[cfg_attr(feature = "cargo-clippy", allow(deprecated))]
impl<'de> Deserialize<'de> for Credential {
fn deserialize<D>(deserializer: D) -> Result<Credential, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(CredentialVisitor)
}
}
pub fn request_value(credential_key: &str, store_code: &str) -> Result<Value, String> {
if vec!["env", "ENV", "environment"].contains(&store_code) {
return var(credential_key)
.map(Value::String)
.map_err(|error| error.to_string());
}
let backend_endpoint = get_store_hostname(store_code);
let backend_username = get_store_username(store_code);
let backend_password = get_store_password(store_code);
let session_url = format!("{}/sessions", backend_endpoint);
let credential_url = format!("{}/credentials/{}", backend_endpoint, credential_key);
let client = Client::builder().build().map_err(|e| format!("{:?}", e))?;
let session_body = SessionBody {
session: Session {
email: backend_username,
password: backend_password,
},
};
let response: SessionResponseBody = client
.post(&session_url)
.json(&session_body)
.send()
.map_err(|e| e.to_string())?
.json()
.map_err(|e| e.to_string())?;
let mut headers = HeaderMap::new();
headers.insert(
AUTHORIZATION,
HeaderValue::from_str(&response.access_token).map_err(|e| format!("{:?}", e))?,
);
let client = Client::builder()
.default_headers(headers)
.build()
.map_err(|e| e.to_string())?;
let response: ValueResponseBody = client
.get(&credential_url)
.send()
.map_err(|e| e.to_string())?
.json()
.map_err(|e| e.to_string())?;
Ok(response.data.value)
}