https_everywhere_lib_core/
update_channels.rs1use openssl::{rsa::Rsa, pkey::Public};
2use serde_json::Value;
3use crate::strings::ERROR_SERDE_PARSE;
4
5struct StaticJsonStrings {
6 pub name: &'static str,
7 pub update_path_prefix: &'static str,
8 pub scope: &'static str,
9 pub replaces_default_rulesets: &'static str,
10 pub pem: &'static str,
11}
12
13const JSON_STRINGS: StaticJsonStrings = StaticJsonStrings {
14 name: "name",
15 update_path_prefix: "update_path_prefix",
16 scope: "scope",
17 replaces_default_rulesets: "replaces_default_rulesets",
18 pem: "pem",
19};
20
21
22#[derive(Debug)]
26pub struct UpdateChannel {
27 pub name: String,
28 pub key: Rsa<Public>,
29 pub update_path_prefix: String,
30 pub scope: Option<String>,
31 pub replaces_default_rulesets: bool,
32}
33
34impl From<&String> for UpdateChannel {
35 fn from(json_string: &String) -> UpdateChannel {
47 let update_channel: Value = serde_json::from_str(&json_string).expect(ERROR_SERDE_PARSE);
48 UpdateChannel::from(&update_channel)
49 }
50}
51
52impl From<&Value> for UpdateChannel {
53 fn from(json_value: &Value) -> UpdateChannel {
57 if let Value::Object(update_channel) = json_value {
58 let name = match update_channel.get(JSON_STRINGS.name) {
59 Some(Value::String(name)) => name.to_string(),
60 _ => panic!("Name can not be blank")
61 };
62 let update_path_prefix = match update_channel.get(JSON_STRINGS.update_path_prefix) {
63 Some(Value::String(update_path_prefix)) => update_path_prefix.to_string(),
64 _ => panic!("Update path prefix can not be blank")
65 };
66 let scope = match update_channel.get(JSON_STRINGS.scope) {
67 Some(Value::String(scope)) if scope == "" => None,
68 Some(Value::String(scope)) => Some(scope.to_string()),
69 _ => None
70 };
71 let replaces_default_rulesets = match update_channel.get(JSON_STRINGS.replaces_default_rulesets) {
72 Some(Value::Bool(replaces_default_rulesets)) => replaces_default_rulesets.clone(),
73 _ => false
74 };
75 let key = match update_channel.get(JSON_STRINGS.pem) {
76 Some(Value::String(pem)) => {
77 match Rsa::public_key_from_pem(&pem.clone().into_bytes()) {
78 Ok(key) => key,
79 _ => panic!("Could not parse public key")
80 }
81 },
82 _ => panic!("Pem can not be blank")
83 };
84 UpdateChannel {
85 name,
86 key,
87 update_path_prefix,
88 scope,
89 replaces_default_rulesets,
90 }
91 } else {
92 panic!("Unexpected: update channel is not an object");
93 }
94 }
95}
96
97
98#[derive(Debug)]
100pub struct UpdateChannels(Vec<UpdateChannel>);
101
102impl UpdateChannels {
103 pub fn get_all(&self) -> &Vec<UpdateChannel>{
105 &self.0
106 }
107
108 pub fn get_all_mut(&mut self) -> &mut Vec<UpdateChannel>{
110 &mut self.0
111 }
112}
113
114impl From<&String> for UpdateChannels {
122 fn from(json_string: &String) -> UpdateChannels {
123 if let Value::Array(update_channels) = serde_json::from_str(&json_string).expect(ERROR_SERDE_PARSE) {
124 UpdateChannels(update_channels.into_iter().map(|uc| {
125 UpdateChannel::from(&uc)
126 }).collect())
127 } else {
128 panic!("Unexpected: update channels is not an array")
129 }
130 }
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136 use std::fs;
137
138 fn mock_update_channels_json() -> String {
139 fs::read_to_string("tests/update_channels.json").unwrap()
140 }
141
142 fn create_mock_update_channels() -> UpdateChannels {
143 UpdateChannels::from(&mock_update_channels_json())
144 }
145
146 #[test]
147 fn creates_update_channels_correctly() {
148 let ucs = create_mock_update_channels();
149
150 let update_channels_representation = fs::read_to_string("tests/update_channels_representation.txt").unwrap();
151 assert_eq!(format!("{:?}", ucs), update_channels_representation);
152 }
153
154 #[test]
155 #[should_panic]
156 fn panics_if_no_name_specified() {
157 let mut update_channels: Value = serde_json::from_str(&mock_update_channels_json()).expect(ERROR_SERDE_PARSE);
158 update_channels.get_mut(0).unwrap().get_mut(JSON_STRINGS.name).unwrap().take();
159 UpdateChannel::from(update_channels.get(0).unwrap());
160 }
161
162 #[test]
163 #[should_panic]
164 fn panics_if_no_update_path_prefix_specified() {
165 let mut update_channels: Value = serde_json::from_str(&mock_update_channels_json()).expect(ERROR_SERDE_PARSE);
166 update_channels.get_mut(0).unwrap().get_mut(JSON_STRINGS.update_path_prefix).unwrap().take();
167 UpdateChannel::from(update_channels.get(0).unwrap());
168 }
169
170 #[test]
171 #[should_panic]
172 fn panics_if_no_pem_specified() {
173 let mut update_channels: Value = serde_json::from_str(&mock_update_channels_json()).expect(ERROR_SERDE_PARSE);
174 update_channels.get_mut(0).unwrap().get_mut(JSON_STRINGS.pem).unwrap().take();
175 UpdateChannel::from(update_channels.get(0).unwrap());
176 }
177
178 #[test]
179 #[should_panic]
180 fn panics_if_pem_specified_incorrectly() {
181 let mut update_channels: Value = serde_json::from_str(&mock_update_channels_json()).expect(ERROR_SERDE_PARSE);
182 let pem = update_channels.get_mut(0).unwrap().get_mut(JSON_STRINGS.pem).unwrap();
183 *pem = Value::String(String::from("Not a pem value"));
184 UpdateChannel::from(update_channels.get(0).unwrap());
185 }
186}