Fetch User Keys - simple tool for fetching SSH keys from various sources
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

style: reformat codebase

+49 -62
+3 -12
cli/src/config.rs
··· 15 15 16 16 impl Entry { 17 17 pub fn fetch(&self) -> (String, Vec<ssh_key::PublicKey>) { 18 - let mut stream: Vec<_> = self.keys 19 - .par_iter() 20 - .map(|k| k.fetch()) 21 - .flatten() 22 - .collect(); 18 + let mut stream: Vec<_> = self.keys.par_iter().map(|k| k.fetch()).flatten().collect(); 23 19 24 20 // Deduplicate keys, no need for duplicated entries 25 21 stream.sort(); 26 - stream.dedup_by(|a, b| { 27 - a.key_data() == b.key_data() 28 - }); 22 + stream.dedup_by(|a, b| a.key_data() == b.key_data()); 29 23 30 24 (self.name.clone(), stream) 31 25 } ··· 39 33 40 34 impl Config { 41 35 pub fn fetch(&self) -> Result<Output, ()> { 42 - let keys = self.entries 43 - .par_iter() 44 - .map(Entry::fetch) 45 - .collect(); 36 + let keys = self.entries.par_iter().map(Entry::fetch).collect(); 46 37 47 38 Ok(Output { keys }) 48 39 }
+2 -2
cli/src/main.rs
··· 2 2 // 3 3 // SPDX-License-Identifier: EUPL-1.2 4 4 5 - use simple_eyre::eyre::Result; 6 5 use clap::Parser; 7 - use std::path::Path; 6 + use simple_eyre::eyre::Result; 8 7 use std::fs::File; 9 8 use std::io::{self, prelude::*}; 9 + use std::path::Path; 10 10 11 11 #[derive(Debug, Clone)] 12 12 enum Input {
+1 -1
cli/src/output/mod.rs
··· 42 42 "json-pretty" => Format::JSONPretty, 43 43 "toml" => Format::TOML, 44 44 "toml-pretty" => Format::TOMLPretty, 45 - _ => unreachable!() 45 + _ => unreachable!(), 46 46 } 47 47 } 48 48 }
+6 -1
cli/src/sources/atproto.rs
··· 196 196 197 197 url.set_path("xrpc/com.atproto.repo.listRecords"); 198 198 199 - let data = ureq::get(&url.to_string()).call().unwrap().body_mut().read_to_string().unwrap(); 199 + let data = ureq::get(&url.to_string()) 200 + .call() 201 + .unwrap() 202 + .body_mut() 203 + .read_to_string() 204 + .unwrap(); 200 205 201 206 let decoded: resp::Resp = serde_json::from_str(&data).unwrap(); 202 207
+1 -1
cli/src/sources/helpers.rs
··· 2 2 // 3 3 // SPDX-License-Identifier: EUPL-1.2 4 4 5 - use std::str::FromStr; 6 5 use std::fmt; 6 + use std::str::FromStr; 7 7 8 8 use serde::{de, Deserialize, Deserializer}; 9 9
+16 -33
cli/src/sources/mod.rs
··· 37 37 Source::Raw(ref raw) => raw.fetch(), 38 38 Source::Hosts(ref raw) => raw.fetch(), 39 39 Source::Http(ref raw) => raw.fetch(), 40 - Source::Github(ref user) => { 41 - Http { 42 - url: format!("https://github.com/{user}.keys"), 43 - } 44 - .fetch() 40 + Source::Github(ref user) => Http { 41 + url: format!("https://github.com/{user}.keys"), 45 42 } 46 - Source::Sourcehut(ref user) => { 47 - Http { 48 - url: format!("https://meta.sr.ht/{user}.keys"), 49 - } 50 - .fetch() 43 + .fetch(), 44 + Source::Sourcehut(ref user) => Http { 45 + url: format!("https://meta.sr.ht/{user}.keys"), 51 46 } 52 - Source::Gitlab(ref user) => { 53 - Http { 54 - url: format!("https://gitlab.com/{user}.keys"), 55 - } 56 - .fetch() 47 + .fetch(), 48 + Source::Gitlab(ref user) => Http { 49 + url: format!("https://gitlab.com/{user}.keys"), 57 50 } 58 - Source::Codeberg(ref user) => { 59 - Http { 60 - url: format!("https://codeberg.org/{user}.keys"), 61 - } 62 - .fetch() 51 + .fetch(), 52 + Source::Codeberg(ref user) => Http { 53 + url: format!("https://codeberg.org/{user}.keys"), 63 54 } 55 + .fetch(), 64 56 Source::Tangled(ref atproto) => atproto.fetch(), 65 57 } 66 58 } ··· 81 73 impl Fetch for Hosts { 82 74 fn fetch(&self) -> Vec<PublicKey> { 83 75 // TODO: Check if we can do it in-process instead of shelling out to `ssh-keyscan` 84 - let result = Command::new("ssh-keyscan") 85 - .args(&self.0) 86 - .output() 87 - .unwrap(); 76 + let result = Command::new("ssh-keyscan").args(&self.0).output().unwrap(); 88 77 89 78 std::str::from_utf8(&result.stdout) 90 79 .unwrap() ··· 93 82 .map(str::trim) 94 83 // Remove comments 95 84 .filter(|line| !line.starts_with("#")) 96 - .map(|line| { 97 - // Ignore first column as it contain hostname which is not 98 - // needed there 99 - line.split(' ') 100 - .skip(1) 101 - .collect::<Box<[_]>>() 102 - .join(" ") 103 - .to_owned() 104 - }) 85 + // Ignore first column as it contain hostname which is not 86 + // needed there 87 + .map(|line| line.split_once(' ').unwrap().1) 105 88 .map(|k| PublicKey::from_openssh(&k).unwrap()) 106 89 .collect() 107 90 }
+13 -9
flake.lock
··· 37 37 "nixpkgs": "nixpkgs_3" 38 38 }, 39 39 "locked": { 40 - "lastModified": 1744588088, 41 - "narHash": "sha256-jymEVhRPzvzVP8XrXJcnVFUmle/FKLZIfSq+9EiobQE=", 40 + "lastModified": 1744815543, 41 + "narHash": "sha256-ybqhaIuv8OU0f14Rr+1ilxE4iTCnguXi/60g4ys6JOI=", 42 42 "owner": "cachix", 43 43 "repo": "devenv", 44 - "rev": "1e6c06a058dae3791c0303eb99636cee9605c8d9", 44 + "rev": "2e0e691414835585eeddd1e4e740b45b362052cc", 45 45 "type": "github" 46 46 }, 47 47 "original": { ··· 267 267 }, 268 268 "nixpkgs_4": { 269 269 "locked": { 270 - "lastModified": 0, 271 - "narHash": "sha256-bWSjxDwq7iVePrhmA7tY2dyMWHuNJo8knkO4y+q4ZkY=", 272 - "path": "/nix/store/5r0zii3rap2dyfyip31pdf9f0hpvv3d7-source", 273 - "type": "path" 270 + "lastModified": 1744536153, 271 + "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", 272 + "owner": "NixOS", 273 + "repo": "nixpkgs", 274 + "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", 275 + "type": "github" 274 276 }, 275 277 "original": { 276 - "id": "nixpkgs", 277 - "type": "indirect" 278 + "owner": "NixOS", 279 + "ref": "nixpkgs-unstable", 280 + "repo": "nixpkgs", 281 + "type": "github" 278 282 } 279 283 }, 280 284 "root": {
+4 -2
flake.nix
··· 7 7 8 8 inputs = { 9 9 flake-parts.url = "github:hercules-ci/flake-parts"; 10 - nixpkgs.url = "flake:nixpkgs"; 10 + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 11 11 devenv.url = "github:cachix/devenv"; 12 12 }; 13 13 ··· 42 42 }; 43 43 44 44 devenv.shells.default = { 45 - languages.rust.enable = true; 45 + languages.rust = { 46 + enable = true; 47 + }; 46 48 47 49 packages = 48 50 [
+3 -1
xtask/src/main.rs
··· 16 16 let entry = entry?; 17 17 let file_name = entry.file_name(); 18 18 let file_name = Path::new(&file_name); 19 - if file_name.extension() != Some(std::ffi::OsStr::new("scd")) { continue } 19 + if file_name.extension() != Some(std::ffi::OsStr::new("scd")) { 20 + continue; 21 + } 20 22 21 23 let outname = Path::file_stem(file_name).unwrap(); 22 24 let page = Path::new(outname).extension().unwrap().to_str().unwrap();