upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/config.rs
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2024-06-24 09:39:18 +0100
committerDanConwayDev <DanConwayDev@protonmail.com>2024-06-24 09:39:18 +0100
commit173ab188b326fbe78cfba4ab455a74619f4556bb (patch)
tree743a2413c241f7babd4efb336718c510eb743847 /src/config.rs
parent681fdd7683363c62251ecd8dabcc1931a18f4840 (diff)
feat(login): store in git config and use cache
replace ngit yaml file config with: * nsec / ncryptsec / npub in git config in nostr.* namespace * sql database cache for metadata and relay events allow different logins to be used for different git repositories by storing login in local git config
Diffstat (limited to 'src/config.rs')
-rw-r--r--src/config.rs189
1 files changed, 2 insertions, 187 deletions
diff --git a/src/config.rs b/src/config.rs
index 7fca446..56619b8 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,107 +1,19 @@
1use std::{fs::File, io::BufReader}; 1use anyhow::{anyhow, Result};
2
3use anyhow::{anyhow, Context, Result};
4use directories::ProjectDirs; 2use directories::ProjectDirs;
5#[cfg(test)] 3use nostr::PublicKey;
6use mockall::*;
7use nostr::{PublicKey, ToBech32};
8use serde::{self, Deserialize, Serialize}; 4use serde::{self, Deserialize, Serialize};
9 5
10#[derive(Default)]
11#[allow(clippy::module_name_repetitions)]
12pub struct ConfigManager;
13
14#[cfg_attr(test, automock)]
15#[allow(clippy::module_name_repetitions)]
16pub trait ConfigManagement {
17 fn load(&self) -> Result<MyConfig>;
18 fn save(&self, cfg: &MyConfig) -> Result<()>;
19}
20
21pub fn get_dirs() -> Result<ProjectDirs> { 6pub fn get_dirs() -> Result<ProjectDirs> {
22 ProjectDirs::from("", "CodeCollaboration", "ngit").ok_or(anyhow!( 7 ProjectDirs::from("", "CodeCollaboration", "ngit").ok_or(anyhow!(
23 "should find operating system home directories with rust-directories crate" 8 "should find operating system home directories with rust-directories crate"
24 )) 9 ))
25} 10}
26 11
27impl ConfigManagement for ConfigManager {
28 fn load(&self) -> Result<MyConfig> {
29 let config_path = get_dirs()?.config_dir().join("config.json");
30 if config_path.exists() {
31 let file =
32 File::open(config_path).context("should open application configuration file")?;
33 let reader = BufReader::new(file);
34 let config: MyConfig = serde_json::from_reader(reader)
35 .context("should read config from config file with serde_json")?;
36 Ok(config)
37 } else {
38 Ok(MyConfig::default())
39 }
40 }
41 fn save(&self, cfg: &MyConfig) -> Result<()> {
42 let dirs = get_dirs()?;
43 let config_path = dirs.config_dir().join("config.json");
44 let file = if config_path.exists() {
45 std::fs::OpenOptions::new()
46 .create(true)
47 .write(true)
48 .truncate(true)
49 .open(config_path)
50 .context(
51 "should open application configuration file with write and truncate options",
52 )?
53 } else {
54 std::fs::create_dir_all(dirs.config_dir())
55 .context("should create application config directories")?;
56 std::fs::File::create(config_path).context("should create application config file")?
57 };
58 serde_json::to_writer_pretty(file, cfg)
59 .context("should write configuration to config file with serde_json")
60 }
61}
62
63#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)]
64#[allow(clippy::module_name_repetitions)]
65pub struct MyConfig {
66 pub version: u8,
67 pub users: Vec<UserRef>,
68}
69
70#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] 12#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
71pub struct UserRef { 13pub struct UserRef {
72 pub public_key: PublicKey, 14 pub public_key: PublicKey,
73 pub encrypted_key: String,
74 pub metadata: UserMetadata, 15 pub metadata: UserMetadata,
75 pub relays: UserRelays, 16 pub relays: UserRelays,
76 pub last_checked: u64,
77}
78
79impl UserRef {
80 pub fn new(public_key: PublicKey, encrypted_key: String) -> Self {
81 Self {
82 public_key,
83 encrypted_key,
84 relays: UserRelays {
85 relays: vec![],
86 created_at: 0,
87 },
88 metadata: UserMetadata {
89 #[allow(clippy::expect_used)]
90 name: public_key
91 .to_bech32()
92 .expect("public key should always produce bech32"),
93 // name: format!(
94 // "{}",
95 // public_key
96 // .to_bech32()
97 // .expect("public key should always produce bech32"),
98 // )
99 // .as_str()[..10].to_string(),
100 created_at: 0,
101 },
102 last_checked: 0,
103 }
104 }
105} 17}
106 18
107#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] 19#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
@@ -132,100 +44,3 @@ pub struct UserRelayRef {
132 pub read: bool, 44 pub read: bool,
133 pub write: bool, 45 pub write: bool,
134} 46}
135
136#[cfg(test)]
137mod tests {
138 use anyhow::Result;
139 use serial_test::serial;
140
141 use super::*;
142
143 fn backup_existing_config() -> Result<()> {
144 let config_path = get_dirs()?.config_dir().join("config.json");
145 let backup_config_path = get_dirs()?.config_dir().join("config-backup.json");
146 if config_path.exists() {
147 std::fs::rename(config_path, backup_config_path)?;
148 }
149 Ok(())
150 }
151
152 fn restore_config_backup() -> Result<()> {
153 let config_path = get_dirs()?.config_dir().join("config.json");
154 let backup_config_path = get_dirs()?.config_dir().join("config-backup.json");
155 if config_path.exists() {
156 std::fs::remove_file(&config_path)?;
157 }
158 if backup_config_path.exists() {
159 std::fs::rename(backup_config_path, config_path)?;
160 }
161 Ok(())
162 }
163
164 mod load {
165 use super::*;
166
167 #[test]
168 #[serial]
169 fn when_config_file_doesnt_exist_defaults_are_returned() -> Result<()> {
170 backup_existing_config()?;
171 let c = ConfigManager;
172 assert_eq!(c.load()?, MyConfig::default());
173 restore_config_backup()?;
174 Ok(())
175 }
176
177 #[test]
178 #[serial]
179 fn when_config_file_exists_it_is_returned() -> Result<()> {
180 backup_existing_config()?;
181 let c = ConfigManager;
182 let new_config = MyConfig {
183 version: 255,
184 ..MyConfig::default()
185 };
186 c.save(&new_config)?;
187 assert_eq!(c.load()?, new_config);
188 restore_config_backup()?;
189 Ok(())
190 }
191 }
192
193 mod save {
194 use super::*;
195
196 #[test]
197 #[serial]
198 fn when_config_file_doesnt_config_is_saved() -> Result<()> {
199 backup_existing_config()?;
200 let c = ConfigManager;
201 let new_config = MyConfig {
202 version: 255,
203 ..MyConfig::default()
204 };
205 c.save(&new_config)?;
206 assert_eq!(c.load().unwrap(), new_config);
207 restore_config_backup()?;
208 Ok(())
209 }
210
211 #[test]
212 #[serial]
213 fn when_config_file_exists_new_config_is_saved() -> Result<()> {
214 backup_existing_config()?;
215 let c = ConfigManager;
216 let config = MyConfig {
217 version: 255,
218 ..MyConfig::default()
219 };
220 c.save(&config)?;
221 let new_config = MyConfig {
222 version: 254,
223 ..MyConfig::default()
224 };
225 c.save(&new_config)?;
226 assert_eq!(c.load().unwrap(), new_config);
227 restore_config_backup()?;
228 Ok(())
229 }
230 }
231}