authorized_keys_merger/
lib.rs1use std::cmp::Ordering;
2use std::fs;
3
4pub struct Config {
5 pub authorized_keys_fpath: String,
6 pub public_key_fpath: String,
7}
8
9impl Config {
10 pub fn new(args: &[String]) -> Result<Config, &'static str> {
11 match args.len().cmp(&3) {
12 Ordering::Less => Err("not enough arguments"),
13 Ordering::Greater => Err("too many arguments"),
14 Ordering::Equal => Ok(Config {
15 authorized_keys_fpath: args[1].clone(),
16 public_key_fpath: args[2].clone(),
17 }),
18 }
19 }
20}
21
22pub fn run(config: &Config) -> Result<(), Box<dyn std::error::Error>> {
23 let authorized_keys_content = fs::read_to_string(&config.authorized_keys_fpath)?;
24 let authorized_keys = authorized_keys_content.lines().collect::<Vec<_>>();
25
26 let public_keys_content = fs::read_to_string(&config.public_key_fpath)?;
27 let public_keys = public_keys_content.lines().collect::<Vec<_>>();
28
29 for &pub_key in authorized_keys.iter() {
30 println!("{}", pub_key);
31 }
32 for pub_key in extract_keys(&authorized_keys, &public_keys) {
33 println!("{}", pub_key);
34 }
35
36 Ok(())
37}
38
39pub fn extract_keys<'a>(public_keys: &Vec<&'a str>, authorized_keys: &Vec<&str>) -> Vec<String> {
40 let mut keys_to_be_append = Vec::new();
41 for &line in public_keys {
42 let pub_key = line.split(" ").collect::<Vec<_>>()[..2].join(" ");
43 let result = search(pub_key.as_str(), &authorized_keys);
44 if result.len() == 0 {
45 keys_to_be_append.push(pub_key);
47 }
48 }
49 keys_to_be_append
50}
51
52pub fn search<'a>(query: &str, lines: &Vec<&'a str>) -> Vec<&'a str> {
53 let mut results = Vec::new();
54
55 for &line in lines {
56 if line.contains(query) {
57 results.push(line);
58 }
59 }
60
61 results
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67
68 #[test]
69 fn test_extract_keys() {
70 let public_keys = vec![
71 r#"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDfzP+l0IwuGDQT4gQHZZtlLHM7XC07sfZ8B2E5weH1ctepgx23WRWULvr2Dzy5cUUYMdxiuUBeq6E5YJ/6vt+uqvFWjFC8n5SwrwdMsXQiZP8t/cqdIETC9yLrhzYYMyUiVZDrRi0HLv6Ssda/sF+mu7YpT971it155vRKmOvYOX1QlgA7v1cSRklel8pJ7gX2oT9NHwVTj38VYNvrEQDrEF3/wYmUndKgMI2BLI+PUjkk8UL/k6CJJT8NFSa0brU8aQsPQBX07C/8U5CgWX20iWEqNoG065BrSMcyulQ2zndmv/PaWDD973rPH0uU+zXioaHXlpUhKCd4ucdhKOLi+2ZOcFVsBt+1fSAyFR8pjF4fGW3XYwxDehkbx5kAoez1ErJhA3bitlIisfc4d8+pTIYnoG134mKqj04OugLWF5a7kU/D8OXFQkJzPW3bLLr6y2hQlssucb5knCtfPw7hc22T4UoEd6/Pgz/veGNgRsBHxGelmNCVbWd014IZgY0="#,
72 r#"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDHc/gCxwO3wAhRYG1YtUfghy+xOCpwxOBNRpERTdcI5Uk/L2wD09mAYt7w6PU9vrdHYP7bIdTy447WxcanVVs+fycUPI2WTaut0DrNwH/d+ahezSj16h1x4AGsoamKxZ7VrtcPeKUu32NiLGIg6/F1/l1F6ISzYSqIPa4xre68SgcSP8o9wDS9Ixh0ZfFnXZGJ4VwG7IyWPj3s1guqUQn2iC7VsuEpA/9ZXR4YkMIm/ZzNxpb4VkXZuyWOGspFZgMoDxGO4wNwT8IuOEb77uSHKNv71nLTw7vuGxvQH1xHsBA/oAd86WYNtyB0BteB4EOlpDy4d4XEp+uSpx5RPV+cnXBImPlBjq5maRuW/3uNs5mlA/GyHuHlGm83HhD7CFhvz9EFyQBojuFGui9B/kGmPgWWA198wt1MRylIM6gSFGDfar+2ZfIa1miyMpziEkN/nD/3XYl0HPz2ppdLpPuZBBKbTSQnrRSkDjV51A7IXMYEY2pn0mbUivSS/6TzBoM="#,
73 ];
74 let authorized_keys = vec![
75 r#"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDfzP+l0IwuGDQT4gQHZZtlLHM7XC07sfZ8B2E5weH1ctepgx23WRWULvr2Dzy5cUUYMdxiuUBeq6E5YJ/6vt+uqvFWjFC8n5SwrwdMsXQiZP8t/cqdIETC9yLrhzYYMyUiVZDrRi0HLv6Ssda/sF+mu7YpT971it155vRKmOvYOX1QlgA7v1cSRklel8pJ7gX2oT9NHwVTj38VYNvrEQDrEF3/wYmUndKgMI2BLI+PUjkk8UL/k6CJJT8NFSa0brU8aQsPQBX07C/8U5CgWX20iWEqNoG065BrSMcyulQ2zndmv/PaWDD973rPH0uU+zXioaHXlpUhKCd4ucdhKOLi+2ZOcFVsBt+1fSAyFR8pjF4fGW3XYwxDehkbx5kAoez1ErJhA3bitlIisfc4d8+pTIYnoG134mKqj04OugLWF5a7kU/D8OXFQkJzPW3bLLr6y2hQlssucb5knCtfPw7hc22T4UoEd6/Pgz/veGNgRsBHxGelmNCVbWd014IZgY0= polle@pollenjp-pc"#,
76 r#"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCg+ybUzuO5x6dMjjQe42s7XviyiQGUmB6Tc9Hlkopl0bSjTr4unHLBNlLdSAb85i+9WYvDm+q7bqhGber6c60CtIFGCUrfH6yxXO4weQNTZ5M1CgzhDq9VLwq6cDoRsmJnSmeX4s3tt9ezCTtpITsRwljcpFJQLgfJ3QXkFFAxC/8ClblY7RSmqxCwii+sUDWLDeZG8VcTZAnCGlD7FAO+lLJUhjO15J+vf6dSq82DAU0BTVnOeMkPLxToIxwJMF6tFBPhrneThwaI/i9ibF4FTsCMMq6DW6iZTpGuaSaY98vx3Y1F6JvjAE+7wcTiPyyP3GKxLyqiSwRU5M6+kAyDAZAT4YUks2A7WADk2IVjc0UOrUaJJimXZinhUWWLTA3190VETNtB4Azf4SykB6NL56wdoqUVRg2nf+cb2vEfYuRACJ0bCi3acPGMmE2gZIGwyAoQHL20nasiaxO1buMiSYDXxroM/Y2RC8swuM1L4yqSxCE2csZ/Lue50G/cSM0= polle@pollenjp-pc"#,
77 ];
78 assert_eq!(
79 vec![
80 r#"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDHc/gCxwO3wAhRYG1YtUfghy+xOCpwxOBNRpERTdcI5Uk/L2wD09mAYt7w6PU9vrdHYP7bIdTy447WxcanVVs+fycUPI2WTaut0DrNwH/d+ahezSj16h1x4AGsoamKxZ7VrtcPeKUu32NiLGIg6/F1/l1F6ISzYSqIPa4xre68SgcSP8o9wDS9Ixh0ZfFnXZGJ4VwG7IyWPj3s1guqUQn2iC7VsuEpA/9ZXR4YkMIm/ZzNxpb4VkXZuyWOGspFZgMoDxGO4wNwT8IuOEb77uSHKNv71nLTw7vuGxvQH1xHsBA/oAd86WYNtyB0BteB4EOlpDy4d4XEp+uSpx5RPV+cnXBImPlBjq5maRuW/3uNs5mlA/GyHuHlGm83HhD7CFhvz9EFyQBojuFGui9B/kGmPgWWA198wt1MRylIM6gSFGDfar+2ZfIa1miyMpziEkN/nD/3XYl0HPz2ppdLpPuZBBKbTSQnrRSkDjV51A7IXMYEY2pn0mbUivSS/6TzBoM="#,
81 ],
82 extract_keys(&public_keys, &authorized_keys)
83 )
84 }
85
86 #[test]
87 fn test_extract_keys2() {
88 let public_keys = vec![
89 r#"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDfzP+l0IwuGDQT4gQHZZtlLHM7XC07sfZ8B2E5weH1ctepgx23WRWULvr2Dzy5cUUYMdxiuUBeq6E5YJ/6vt+uqvFWjFC8n5SwrwdMsXQiZP8t/cqdIETC9yLrhzYYMyUiVZDrRi0HLv6Ssda/sF+mu7YpT971it155vRKmOvYOX1QlgA7v1cSRklel8pJ7gX2oT9NHwVTj38VYNvrEQDrEF3/wYmUndKgMI2BLI+PUjkk8UL/k6CJJT8NFSa0brU8aQsPQBX07C/8U5CgWX20iWEqNoG065BrSMcyulQ2zndmv/PaWDD973rPH0uU+zXioaHXlpUhKCd4ucdhKOLi+2ZOcFVsBt+1fSAyFR8pjF4fGW3XYwxDehkbx5kAoez1ErJhA3bitlIisfc4d8+pTIYnoG134mKqj04OugLWF5a7kU/D8OXFQkJzPW3bLLr6y2hQlssucb5knCtfPw7hc22T4UoEd6/Pgz/veGNgRsBHxGelmNCVbWd014IZgY0="#,
90 r#"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDHc/gCxwO3wAhRYG1YtUfghy+xOCpwxOBNRpERTdcI5Uk/L2wD09mAYt7w6PU9vrdHYP7bIdTy447WxcanVVs+fycUPI2WTaut0DrNwH/d+ahezSj16h1x4AGsoamKxZ7VrtcPeKUu32NiLGIg6/F1/l1F6ISzYSqIPa4xre68SgcSP8o9wDS9Ixh0ZfFnXZGJ4VwG7IyWPj3s1guqUQn2iC7VsuEpA/9ZXR4YkMIm/ZzNxpb4VkXZuyWOGspFZgMoDxGO4wNwT8IuOEb77uSHKNv71nLTw7vuGxvQH1xHsBA/oAd86WYNtyB0BteB4EOlpDy4d4XEp+uSpx5RPV+cnXBImPlBjq5maRuW/3uNs5mlA/GyHuHlGm83HhD7CFhvz9EFyQBojuFGui9B/kGmPgWWA198wt1MRylIM6gSFGDfar+2ZfIa1miyMpziEkN/nD/3XYl0HPz2ppdLpPuZBBKbTSQnrRSkDjV51A7IXMYEY2pn0mbUivSS/6TzBoM= polle@pollenjp-pc"#,
91 ];
92 let authorized_keys = vec![
93 r#"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDfzP+l0IwuGDQT4gQHZZtlLHM7XC07sfZ8B2E5weH1ctepgx23WRWULvr2Dzy5cUUYMdxiuUBeq6E5YJ/6vt+uqvFWjFC8n5SwrwdMsXQiZP8t/cqdIETC9yLrhzYYMyUiVZDrRi0HLv6Ssda/sF+mu7YpT971it155vRKmOvYOX1QlgA7v1cSRklel8pJ7gX2oT9NHwVTj38VYNvrEQDrEF3/wYmUndKgMI2BLI+PUjkk8UL/k6CJJT8NFSa0brU8aQsPQBX07C/8U5CgWX20iWEqNoG065BrSMcyulQ2zndmv/PaWDD973rPH0uU+zXioaHXlpUhKCd4ucdhKOLi+2ZOcFVsBt+1fSAyFR8pjF4fGW3XYwxDehkbx5kAoez1ErJhA3bitlIisfc4d8+pTIYnoG134mKqj04OugLWF5a7kU/D8OXFQkJzPW3bLLr6y2hQlssucb5knCtfPw7hc22T4UoEd6/Pgz/veGNgRsBHxGelmNCVbWd014IZgY0="#,
94 r#"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCg+ybUzuO5x6dMjjQe42s7XviyiQGUmB6Tc9Hlkopl0bSjTr4unHLBNlLdSAb85i+9WYvDm+q7bqhGber6c60CtIFGCUrfH6yxXO4weQNTZ5M1CgzhDq9VLwq6cDoRsmJnSmeX4s3tt9ezCTtpITsRwljcpFJQLgfJ3QXkFFAxC/8ClblY7RSmqxCwii+sUDWLDeZG8VcTZAnCGlD7FAO+lLJUhjO15J+vf6dSq82DAU0BTVnOeMkPLxToIxwJMF6tFBPhrneThwaI/i9ibF4FTsCMMq6DW6iZTpGuaSaY98vx3Y1F6JvjAE+7wcTiPyyP3GKxLyqiSwRU5M6+kAyDAZAT4YUks2A7WADk2IVjc0UOrUaJJimXZinhUWWLTA3190VETNtB4Azf4SykB6NL56wdoqUVRg2nf+cb2vEfYuRACJ0bCi3acPGMmE2gZIGwyAoQHL20nasiaxO1buMiSYDXxroM/Y2RC8swuM1L4yqSxCE2csZ/Lue50G/cSM0="#,
95 ];
96 assert_eq!(
97 vec![
98 r#"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDHc/gCxwO3wAhRYG1YtUfghy+xOCpwxOBNRpERTdcI5Uk/L2wD09mAYt7w6PU9vrdHYP7bIdTy447WxcanVVs+fycUPI2WTaut0DrNwH/d+ahezSj16h1x4AGsoamKxZ7VrtcPeKUu32NiLGIg6/F1/l1F6ISzYSqIPa4xre68SgcSP8o9wDS9Ixh0ZfFnXZGJ4VwG7IyWPj3s1guqUQn2iC7VsuEpA/9ZXR4YkMIm/ZzNxpb4VkXZuyWOGspFZgMoDxGO4wNwT8IuOEb77uSHKNv71nLTw7vuGxvQH1xHsBA/oAd86WYNtyB0BteB4EOlpDy4d4XEp+uSpx5RPV+cnXBImPlBjq5maRuW/3uNs5mlA/GyHuHlGm83HhD7CFhvz9EFyQBojuFGui9B/kGmPgWWA198wt1MRylIM6gSFGDfar+2ZfIa1miyMpziEkN/nD/3XYl0HPz2ppdLpPuZBBKbTSQnrRSkDjV51A7IXMYEY2pn0mbUivSS/6TzBoM="#,
99 ],
100 extract_keys(&public_keys, &authorized_keys)
101 )
102 }
103
104 #[test]
105 fn test_key_search() {
106 let pub_key =
107 r#"ssh-rsa AAAABasdofadskfalskjdflashdlajdljaALDSKFLKSJDFLSJFLHSDLFSLKHDFLSDJFLSJFD="#;
108 let authorized_keys_content = r#"\
109ssh-rsa AAAABasdofadskfalskjdflashdlajdljaALDSKFLKSJDFLSJFLHSDLFSLKHDFLSDJFLSJFD= pollenjp@fizz
110ssh-rsa AAAABasdofadskfalskjdASLKDFJNLABHHAKDJFKSAHDFLSAJdlfsakjfldsKHDFLSDJFLSF= pollenjp@buzz
111"#;
112
113 let authorized_keys = authorized_keys_content.lines().collect::<Vec<_>>();
114
115 assert_eq!(
116 vec![
117 r#"ssh-rsa AAAABasdofadskfalskjdflashdlajdljaALDSKFLKSJDFLSJFLHSDLFSLKHDFLSDJFLSJFD= pollenjp@fizz"#
118 ],
119 search(pub_key, &authorized_keys)
120 );
121 }
122}