movey_utils/
movey_credential.rs1use anyhow::{bail, Context, Result};
5use std::fs;
6use toml_edit::easy::Value;
7
8#[cfg(debug_assertions)]
9pub const MOVEY_URL: &str = "https://movey-app-staging.herokuapp.com";
10#[cfg(not(debug_assertions))]
11pub const MOVEY_URL: &str = "https://www.movey.net";
12pub const MOVEY_CREDENTIAL_PATH: &str = "/movey_credential.toml";
13
14
15pub fn get_registry_api_token(move_home: &str) -> Result<String> {
16 if let Ok(content) = get_api_token(move_home) {
17 Ok(content)
18 } else {
19 bail!(
20 "There seems to be an error with your Movey API token. \
21 Please run `move movey-login` and follow the instructions."
22 )
23 }
24}
25
26pub fn get_api_token(move_home: &str) -> Result<String> {
27 let credential_path = format!("{}{}", move_home, MOVEY_CREDENTIAL_PATH);
28 let mut toml: Value = read_credential_file(&credential_path)?;
29 let token = get_registry_field(&mut toml, "token")?;
30 Ok(token.to_string().replace('\"', ""))
31}
32
33pub fn get_movey_url(move_home: &str) -> Result<String> {
34 let credential_path = format!("{}{}", move_home, MOVEY_CREDENTIAL_PATH);
35 let contents = fs::read_to_string(&credential_path)?;
36 let mut toml: Value = contents.parse()?;
37
38 let movey_url = get_registry_field(&mut toml, "url");
39
40 if let Ok(url) = movey_url {
41 Ok(url.to_string().replace('\"', ""))
42 } else {
43 Ok(MOVEY_URL.to_string())
44 }
45}
46
47fn get_registry_field<'a>(toml: &'a mut Value, field: &'a str) -> Result<&'a mut Value> {
48 let registry = toml
49 .as_table_mut()
50 .context(format!("Error parsing {}", MOVEY_CREDENTIAL_PATH))?
51 .get_mut("registry")
52 .context(format!("Error parsing {}", MOVEY_CREDENTIAL_PATH))?;
53 let value = registry
54 .as_table_mut()
55 .context("Error parsing registry table")?
56 .get_mut(field)
57 .context("Error parsing token")?;
58 Ok(value)
59}
60
61pub fn read_credential_file(credential_path: &str) -> Result<Value> {
62 let content = match fs::read_to_string(credential_path) {
63 Ok(content) => content,
64 Err(error) => bail!("Error reading input: {}", error),
65 };
66 content.parse().map_err(|e| {
67 anyhow::Error::from(e).context(format!(
68 "could not parse input at {} as TOML",
69 &credential_path
70 ))
71 })
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77 use std::{env, fs::File};
78
79 fn setup_move_home(test_path: &str) -> (String, String) {
80 let cwd = env::current_dir().unwrap();
81 let mut move_home: String = String::from(cwd.to_string_lossy());
82 move_home.push_str(test_path);
83 let credential_path = move_home.clone() + MOVEY_CREDENTIAL_PATH;
84
85 (move_home, credential_path)
86 }
87
88 fn clean_up(move_home: &str) {
89 let _ = fs::remove_dir_all(move_home);
90 }
91
92 #[test]
93 fn get_api_token_works() {
94 let test_path = String::from("/get_api_token_works");
95 let (move_home, credential_path) = setup_move_home(&test_path);
96 let _ = fs::create_dir_all(&move_home);
97 File::create(&credential_path).unwrap();
98
99 let content = r#"
100 [registry]
101 token = "test-token"
102 "#;
103 fs::write(&credential_path, content).unwrap();
104
105 let token = get_registry_api_token(&move_home).unwrap();
106 assert!(token.contains("test-token"));
107
108 clean_up(&move_home)
109 }
110
111 #[test]
112 fn get_api_token_fails_if_there_is_no_move_home_directory() {
113 let test_path = String::from("/get_api_token_fails_if_there_is_no_move_home_directory");
114 let (move_home, _) = setup_move_home(&test_path);
115 let _ = fs::remove_dir_all(&move_home);
116
117 let token = get_registry_api_token(&move_home);
118 assert!(token.is_err());
119
120 clean_up(&move_home)
121 }
122
123 #[test]
124 fn get_api_token_fails_if_there_is_no_credential_file() {
125 let test_path = String::from("/get_api_token_fails_if_there_is_no_credential_file");
126 let (move_home, _) = setup_move_home(&test_path);
127 let _ = fs::remove_dir_all(&move_home);
128 fs::create_dir_all(&move_home).unwrap();
129
130 let token = get_registry_api_token(&move_home);
131 assert!(token.is_err());
132
133 clean_up(&move_home)
134 }
135
136 #[test]
137 fn get_api_token_fails_if_credential_file_is_in_wrong_format() {
138 let test_path = String::from("/get_api_token_fails_if_credential_file_is_in_wrong_format");
139 let (move_home, credential_path) = setup_move_home(&test_path);
140 let _ = fs::remove_dir_all(&move_home);
141 fs::create_dir_all(&move_home).unwrap();
142 File::create(&credential_path).unwrap();
143
144 let missing_double_quote = r#"
145 [registry]
146 token = test-token
147 "#;
148 fs::write(&credential_path, missing_double_quote).unwrap();
149 let token = get_registry_api_token(&move_home);
150 assert!(token.is_err());
151
152 let wrong_token_field = r#"
153 [registry]
154 tokens = "test-token"
155 "#;
156 fs::write(&credential_path, wrong_token_field).unwrap();
157 let token = get_registry_api_token(&move_home);
158 assert!(token.is_err());
159
160 clean_up(&move_home)
161 }
162
163 #[test]
164 fn get_movey_url_works() {
165 let test_path = String::from("/get_movey_url_works");
166 let (move_home, credential_path) = setup_move_home(&test_path);
167 let _ = fs::create_dir_all(&move_home);
168 File::create(&credential_path).unwrap();
169 let content = r#"
170 [registry]
171 token = "test-token"
172 url = "test-url"
173 "#;
174 fs::write(&credential_path, content).unwrap();
175
176 let url = get_movey_url(&move_home).unwrap();
177 assert_eq!(url, "test-url");
178
179 clean_up(&move_home)
180 }
181
182 #[test]
183 fn get_movey_url_returns_default_url_if_url_field_not_existed() {
184 let test_path = String::from("/get_movey_url_returns_default_url_if_url_field_not_existed");
185 let (move_home, credential_path) = setup_move_home(&test_path);
186 let _ = fs::create_dir_all(&move_home);
187 File::create(&credential_path).unwrap();
188 let content = r#"
189 [registry]
190 token = "test-token"
191 "#;
192 fs::write(&credential_path, content).unwrap();
193
194 let url = get_movey_url(&move_home).unwrap();
195 assert_eq!(url, MOVEY_URL);
196
197 clean_up(&move_home)
198 }
199}