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
use std::collections::HashMap;
mod json;
mod tests;
pub struct Zero {
api_url: String,
caller_name: Option<String>,
pick: Vec<String>,
token: String,
}
pub struct Arguments {
pub token: String,
pub pick: Option<Vec<String>>,
pub caller_name: Option<String>,
}
impl Zero {
pub fn set_api_url(mut self, new_api_url: String) -> Self {
self.api_url = new_api_url;
return self;
}
pub fn fetch(self) -> Result<HashMap<String, HashMap<String, String>>, String> {
let response = if let Ok(value) = ureq::post(&self.api_url).send_json(serde_json::json!({
"query":
format!(
"query {{
secrets(zeroToken: \"{}\", pick: [{}]{}) {{
name
fields {{
name value
}}
}}
}}",
&self.token,
&self
.pick
.iter()
.map(|secret| format!("\"{}\"", &secret))
.collect::<Vec<String>>()
.join(", "),
if self.caller_name.is_some() {
format!(", callerName: \"{}\"", &self.caller_name.unwrap_or_default())
} else {
"".to_string()
},
)
})) {
value
} else {
return Err(String::from("Failed to fetch secrets due to network issue"));
};
let response_json = if let Ok(value) = response.into_json::<json::ResponseJson>() {
value
} else {
return Err(String::from("Server returned invalid response"));
};
if response_json.errors.is_some() {
return Err(String::from(&response_json.errors.unwrap()[0].message));
}
if response_json.data.is_none() {
return Err(String::from(
"Server returned invalid response (no secrets)",
));
}
Ok(response_json
.data
.unwrap()
.secrets
.unwrap()
.iter()
.map(|secret| {
(
secret.name.to_owned(),
HashMap::from_iter(
secret
.fields
.iter()
.map(|field| (field.name.to_owned(), field.value.to_owned())),
),
)
})
.collect())
}
pub fn new(arguments: Arguments) -> Result<Self, &'static str> {
if arguments.token == "" {
return Err("Zero-token is empty");
}
Ok(Self {
api_url: String::from("https://core.tryzero.com/v1/graphql"),
caller_name: arguments.caller_name,
pick: arguments.pick.unwrap_or(vec![]),
token: arguments.token,
})
}
}