From f82c742d8bb8e160a44338ba775ffa7bb04b366c Mon Sep 17 00:00:00 2001 From: abdoufermat5 Date: Fri, 29 Aug 2025 19:46:10 +0200 Subject: [PATCH] fix: update default configuration for better user experience - Change default user from hardcoded 'admin' to current system user - Disable Kerberos by default (changed from true to false) - Add whoami dependency for system user detection - Update all documentation examples to reflect new defaults - Fix clippy linting issues and code formatting - Bump version to 1.1.1 (patch release) --- CHANGELOG.md | 17 +++++++ Cargo.toml | 3 +- README.md | 4 +- docs/README.md | 12 ++--- docs/advanced-usage.md | 12 ++--- src/cli/commands/connect.rs | 89 +++++++++++++++++++++++++++++++------ src/cli/commands/edit.rs | 52 +++++++++++++++++----- src/cli/commands/remove.rs | 64 ++++++++++++++++++++------ src/cli/commands/show.rs | 51 ++++++++++++++++----- src/config/mod.rs | 4 +- src/database/mod.rs | 30 ++++++------- src/services/ssh.rs | 3 +- 12 files changed, 256 insertions(+), 85 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cc0750..c422ad2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,23 @@ All notable changes to Bayesian SSH will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.1.1] - 2025-08-29 + +### Fixed +- **Configuration defaults**: Changed default user from hardcoded "admin" to current system user +- **Kerberos default**: Disabled Kerberos by default (changed from `true` to `false`) +- **Documentation**: Updated all examples to reflect new sensible defaults + +### Changed +- **Default configuration**: Application now uses current Linux username instead of "admin" +- **Kerberos behavior**: Kerberos authentication is now opt-in rather than default +- **Documentation examples**: Updated configuration commands and JSON examples across all docs + +### Technical +- **Dependencies**: Added `whoami` crate for system user detection +- **Configuration**: Updated `AppConfig::default()` implementation +- **Documentation**: Updated README.md, docs/README.md, and docs/advanced-usage.md + ## [1.1.0] - 2025-08-28 ### Added diff --git a/Cargo.toml b/Cargo.toml index 6109702..be799af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bayesian-ssh" -version = "1.1.0" +version = "1.1.1" edition = "2021" authors = ["Abdoufermat5"] description = "A fast and lightweight SSH session manager with Kerberos support" @@ -35,6 +35,7 @@ tracing-subscriber = "0.3" # Configuration config = "0.13" dirs = "5.0" +whoami = "1.5" # Utilities chrono = { version = "0.4", features = ["serde"] } diff --git a/README.md b/README.md index 45aa4d9..83828cf 100644 --- a/README.md +++ b/README.md @@ -102,8 +102,8 @@ The app automatically creates configuration in `~/.config/bayesian-ssh/`: # View current config bayesian-ssh config -# Set defaults -bayesian-ssh config --default-user admin --use-kerberos +# Set defaults (Kerberos is disabled by default, current user is used) +bayesian-ssh config --use-kerberos --default-user customuser ``` ## šŸ“š Documentation diff --git a/docs/README.md b/docs/README.md index 1e683f9..e1a0a7c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -71,7 +71,7 @@ bayesian-ssh list bayesian-ssh connect "Server Name" # Connect with custom parameters -bayesian-ssh connect "Server Name" --no-bastion --user admin +bayesian-ssh connect "Server Name" --no-bastion --user customuser # Show connection details bayesian-ssh show "Server Name" @@ -88,8 +88,8 @@ bayesian-ssh remove "Server Name" # View current configuration bayesian-ssh config -# Update configuration -bayesian-ssh config --default-user admin --use-kerberos +# Update configuration (Kerberos disabled by default) +bayesian-ssh config --use-kerberos --default-user customuser # Set default bastion bayesian-ssh config --default-bastion bastion.company.com @@ -119,10 +119,10 @@ bayesian-ssh import --file /path/to/ssh/config ### Key Configuration Options ```json { - "default_user": "admin", + "default_user": "current-system-user", "default_bastion": "bastion.company.com", - "default_bastion_user": "admin", - "use_kerberos_by_default": true, + "default_bastion_user": "current-system-user", + "use_kerberos_by_default": false, "log_level": "info", "auto_save_history": true, "max_history_size": 1000 diff --git a/docs/advanced-usage.md b/docs/advanced-usage.md index 027440f..7d6c97b 100644 --- a/docs/advanced-usage.md +++ b/docs/advanced-usage.md @@ -6,7 +6,7 @@ ```bash # Set up default enterprise configuration bayesian-ssh config \ - --default-user admin \ + --default-user currentuser \ --default-bastion bastion-server.company.priv \ --use-kerberos @@ -106,7 +106,7 @@ bayesian-ssh add "DB EC2" ec2-db.company.com \ # Application instance bayesian-ssh add "App EC2" ec2-app.company.com \ - --user admin \ + --user currentuser \ --kerberos false \ --key ~/.ssh/ec2-app-key.pem \ --tags ec2,production,application @@ -143,7 +143,7 @@ bayesian-ssh add "K8s Web Pod" web-pod.namespace.svc.cluster.local \ # Service access bayesian-ssh add "K8s Service" web-service.namespace.svc.cluster.local \ - --user admin \ + --user currentuser \ --kerberos false \ --tags kubernetes,service,web ``` @@ -200,12 +200,12 @@ bayesian-ssh add "GCP App" gcp-app.company.com \ ```bash # Primary load balancer bayesian-ssh add "LB Primary" lb-primary.company.com \ - --user admin \ + --user currentuser \ --tags loadbalancer,primary,production # Secondary load balancer bayesian-ssh add "LB Secondary" lb-secondary.company.com \ - --user admin \ + --user currentuser \ --tags loadbalancer,secondary,production # Backend servers @@ -431,7 +431,7 @@ kinit -f ssh -t -A -K user@bastion.company.com # Test with specific bastion user -bayesian-ssh connect "Target Server" --bastion-user admin +bayesian-ssh connect "Target Server" --bastion-user currentuser # Test bastion port bayesian-ssh connect "Target Server" --bastion-port 2222 diff --git a/src/cli/commands/connect.rs b/src/cli/commands/connect.rs index b700909..6009517 100644 --- a/src/cli/commands/connect.rs +++ b/src/cli/commands/connect.rs @@ -37,7 +37,10 @@ pub async fn execute( Ok(_) => return Ok(()), // Exact match found and connected Err(_) => { // No exact match, try fuzzy search - info!("No exact match found for '{}', attempting fuzzy search", target); + info!( + "No exact match found for '{}', attempting fuzzy search", + target + ); } } @@ -53,14 +56,27 @@ pub async fn execute( if !recent.is_empty() { println!("\nšŸ“… Recent connections:"); for (i, conn) in recent.iter().enumerate() { - let last_used = conn.last_used + let last_used = conn + .last_used .map(|dt| format!(" (last used: {})", format_duration(dt))) - .unwrap_or_else(|| "".to_string()); + .unwrap_or_default(); println!(" {}. {}{}", i + 1, conn.name, last_used); } - if let Some(selection) = interactive_selection(&recent, "Select recent connection")? { - return ssh_service.connect_to_connection(&selection, user, port, kerberos, bastion, no_bastion, bastion_user, key).await; + if let Some(selection) = interactive_selection(&recent, "Select recent connection")? + { + return ssh_service + .connect_to_connection( + &selection, + user, + port, + kerberos, + bastion, + no_bastion, + bastion_user, + key, + ) + .await; } } else { println!("No recent connections found."); @@ -81,7 +97,18 @@ pub async fn execute( let input = input.trim().to_lowercase(); if matches!(input.as_str(), "y" | "yes") { - return ssh_service.connect_to_connection(conn, user, port, kerberos, bastion, no_bastion, bastion_user, key).await; + return ssh_service + .connect_to_connection( + conn, + user, + port, + kerberos, + bastion, + no_bastion, + bastion_user, + key, + ) + .await; } else { println!("Connection cancelled."); return Ok(()); @@ -89,7 +116,11 @@ pub async fn execute( } _ => { // Multiple matches - interactive selection - println!("šŸ” Found {} similar connections for '{}':", matches.len(), target); + println!( + "šŸ” Found {} similar connections for '{}':", + matches.len(), + target + ); println!(); for (i, conn) in matches.iter().enumerate() { @@ -97,7 +128,18 @@ pub async fn execute( } if let Some(selection) = interactive_selection(&matches, "Select connection")? { - return ssh_service.connect_to_connection(&selection, user, port, kerberos, bastion, no_bastion, bastion_user, key).await; + return ssh_service + .connect_to_connection( + &selection, + user, + port, + kerberos, + bastion, + no_bastion, + bastion_user, + key, + ) + .await; } } } @@ -112,12 +154,21 @@ fn print_connection_info(connection: &crate::models::Connection, index: usize) { format!(" [{}]", connection.tags.join(", ")) }; - let last_used = connection.last_used + let last_used = connection + .last_used .map(|dt| format!(" (last used: {})", format_duration(dt))) - .unwrap_or_else(|| "".to_string()); + .unwrap_or_default(); println!(" {}. {} ({})", index, connection.name, connection.host); - println!(" Tags: {}{}", if tags_str.is_empty() { "none" } else { &tags_str[1..tags_str.len()-1] }, last_used); + println!( + " Tags: {}{}", + if tags_str.is_empty() { + "none" + } else { + &tags_str[1..tags_str.len() - 1] + }, + last_used + ); println!(); } @@ -148,9 +199,16 @@ fn format_duration(dt: chrono::DateTime) -> String { } } -fn interactive_selection(connections: &[crate::models::Connection], prompt: &str) -> Result> { +fn interactive_selection( + connections: &[crate::models::Connection], + prompt: &str, +) -> Result> { loop { - print!("{} [1-{}, 's' to search again, 'q' to quit]: ", prompt, connections.len()); + print!( + "{} [1-{}, 's' to search again, 'q' to quit]: ", + prompt, + connections.len() + ); io::stdout().flush()?; let mut input = String::new(); @@ -184,7 +242,10 @@ fn interactive_selection(connections: &[crate::models::Connection], prompt: &str if index >= 1 && index <= connections.len() { return Ok(Some(connections[index - 1].clone())); } else { - println!("Invalid selection. Please enter a number between 1 and {}.", connections.len()); + println!( + "Invalid selection. Please enter a number between 1 and {}.", + connections.len() + ); } } else { println!("Invalid input. Please enter a number, 's' to search again, or 'q' to quit."); diff --git a/src/cli/commands/edit.rs b/src/cli/commands/edit.rs index b66ae0f..41338d8 100644 --- a/src/cli/commands/edit.rs +++ b/src/cli/commands/edit.rs @@ -45,7 +45,10 @@ pub async fn execute( } // No exact match, try fuzzy search - info!("No exact match found for '{}', attempting fuzzy search", target); + info!( + "No exact match found for '{}', attempting fuzzy search", + target + ); let matches = ssh_service.fuzzy_search(&target, 10).await?; @@ -58,13 +61,16 @@ pub async fn execute( if !recent.is_empty() { println!("\nRecent connections:"); for (i, conn) in recent.iter().enumerate() { - let last_used = conn.last_used + let last_used = conn + .last_used .map(|dt| format!(" (last: {})", format_duration(dt))) - .unwrap_or_else(|| "".to_string()); + .unwrap_or_default(); println!(" {}. {}{}", i + 1, conn.name, last_used); } - if let Some(selection) = interactive_selection(&recent, "Select connection to edit")? { + if let Some(selection) = + interactive_selection(&recent, "Select connection to edit")? + { return update_connection( ssh_service, selection, @@ -123,7 +129,11 @@ pub async fn execute( } _ => { // Multiple matches - interactive selection - println!("Found {} similar connections for '{}':", matches.len(), target); + println!( + "Found {} similar connections for '{}':", + matches.len(), + target + ); println!(); for (i, conn) in matches.iter().enumerate() { @@ -154,6 +164,7 @@ pub async fn execute( Ok(()) } +#[allow(clippy::too_many_arguments)] async fn update_connection( ssh_service: SshService, mut connection: crate::models::Connection, @@ -247,12 +258,21 @@ fn print_connection_info(connection: &crate::models::Connection, index: usize) { format!(" [{}]", connection.tags.join(", ")) }; - let last_used = connection.last_used + let last_used = connection + .last_used .map(|dt| format!(" (last used: {})", format_duration(dt))) - .unwrap_or_else(|| "".to_string()); + .unwrap_or_default(); println!(" {}. {} ({})", index, connection.name, connection.host); - println!(" Tags: {}{}", if tags_str.is_empty() { "none" } else { &tags_str[1..tags_str.len()-1] }, last_used); + println!( + " Tags: {}{}", + if tags_str.is_empty() { + "none" + } else { + &tags_str[1..tags_str.len() - 1] + }, + last_used + ); println!(); } @@ -283,9 +303,16 @@ fn format_duration(dt: chrono::DateTime) -> String { } } -fn interactive_selection(connections: &[crate::models::Connection], prompt: &str) -> Result> { +fn interactive_selection( + connections: &[crate::models::Connection], + prompt: &str, +) -> Result> { loop { - print!("{} [1-{}, 's' to search again, 'q' to quit]: ", prompt, connections.len()); + print!( + "{} [1-{}, 's' to search again, 'q' to quit]: ", + prompt, + connections.len() + ); io::stdout().flush()?; let mut input = String::new(); @@ -318,7 +345,10 @@ fn interactive_selection(connections: &[crate::models::Connection], prompt: &str if index >= 1 && index <= connections.len() { return Ok(Some(connections[index - 1].clone())); } else { - println!("Invalid selection. Please enter a number between 1 and {}.", connections.len()); + println!( + "Invalid selection. Please enter a number between 1 and {}.", + connections.len() + ); } } else { println!("Invalid input. Please enter a number, 's' to search again, or 'q' to quit."); diff --git a/src/cli/commands/remove.rs b/src/cli/commands/remove.rs index e51f2d5..0ef59e5 100644 --- a/src/cli/commands/remove.rs +++ b/src/cli/commands/remove.rs @@ -16,7 +16,10 @@ pub async fn execute(target: String, config: AppConfig) -> Result<()> { } // No exact match, try fuzzy search - info!("No exact match found for '{}', attempting fuzzy search", target); + info!( + "No exact match found for '{}', attempting fuzzy search", + target + ); let matches = ssh_service.fuzzy_search(&target, 10).await?; @@ -29,13 +32,16 @@ pub async fn execute(target: String, config: AppConfig) -> Result<()> { if !recent.is_empty() { println!("\nRecent connections:"); for (i, conn) in recent.iter().enumerate() { - let last_used = conn.last_used + let last_used = conn + .last_used .map(|dt| format!(" (last: {})", format_duration(dt))) - .unwrap_or_else(|| "".to_string()); + .unwrap_or_default(); println!(" {}. {}{}", i + 1, conn.name, last_used); } - if let Some(selection) = interactive_selection(&recent, "Select connection to remove")? { + if let Some(selection) = + interactive_selection(&recent, "Select connection to remove")? + { return remove_connection_with_confirmation(&ssh_service, &selection).await; } } else { @@ -63,14 +69,19 @@ pub async fn execute(target: String, config: AppConfig) -> Result<()> { } _ => { // Multiple matches - interactive selection - println!("Found {} similar connections for '{}':", matches.len(), target); + println!( + "Found {} similar connections for '{}':", + matches.len(), + target + ); println!(); for (i, conn) in matches.iter().enumerate() { print_connection_info(conn, i + 1); } - if let Some(selection) = interactive_selection(&matches, "Select connection to remove")? { + if let Some(selection) = interactive_selection(&matches, "Select connection to remove")? + { return remove_connection_with_confirmation(&ssh_service, &selection).await; } } @@ -79,7 +90,10 @@ pub async fn execute(target: String, config: AppConfig) -> Result<()> { Ok(()) } -async fn remove_connection_with_confirmation(ssh_service: &SshService, connection: &crate::models::Connection) -> Result<()> { +async fn remove_connection_with_confirmation( + ssh_service: &SshService, + connection: &crate::models::Connection, +) -> Result<()> { println!("\nāš ļø WARNING: You are about to remove the following connection:"); println!(" Name: {}", connection.name); println!(" Host: {}:{}", connection.host, connection.port); @@ -89,7 +103,10 @@ async fn remove_connection_with_confirmation(ssh_service: &SshService, connectio println!(" Tags: {}", connection.tags.join(", ")); } - print!("\nType the connection name '{}' to confirm removal: ", connection.name); + print!( + "\nType the connection name '{}' to confirm removal: ", + connection.name + ); io::stdout().flush()?; let mut confirmation = String::new(); @@ -116,12 +133,21 @@ fn print_connection_info(connection: &crate::models::Connection, index: usize) { format!(" [{}]", connection.tags.join(", ")) }; - let last_used = connection.last_used + let last_used = connection + .last_used .map(|dt| format!(" (last used: {})", format_duration(dt))) - .unwrap_or_else(|| "".to_string()); + .unwrap_or_default(); println!(" {}. {} ({})", index, connection.name, connection.host); - println!(" Tags: {}{}", if tags_str.is_empty() { "none" } else { &tags_str[1..tags_str.len()-1] }, last_used); + println!( + " Tags: {}{}", + if tags_str.is_empty() { + "none" + } else { + &tags_str[1..tags_str.len() - 1] + }, + last_used + ); println!(); } @@ -152,9 +178,16 @@ fn format_duration(dt: chrono::DateTime) -> String { } } -fn interactive_selection(connections: &[crate::models::Connection], prompt: &str) -> Result> { +fn interactive_selection( + connections: &[crate::models::Connection], + prompt: &str, +) -> Result> { loop { - print!("{} [1-{}, 's' to search again, 'q' to quit]: ", prompt, connections.len()); + print!( + "{} [1-{}, 's' to search again, 'q' to quit]: ", + prompt, + connections.len() + ); io::stdout().flush()?; let mut input = String::new(); @@ -187,7 +220,10 @@ fn interactive_selection(connections: &[crate::models::Connection], prompt: &str if index >= 1 && index <= connections.len() { return Ok(Some(connections[index - 1].clone())); } else { - println!("Invalid selection. Please enter a number between 1 and {}.", connections.len()); + println!( + "Invalid selection. Please enter a number between 1 and {}.", + connections.len() + ); } } else { println!("Invalid input. Please enter a number, 's' to search again, or 'q' to quit."); diff --git a/src/cli/commands/show.rs b/src/cli/commands/show.rs index c465d40..b3ef899 100644 --- a/src/cli/commands/show.rs +++ b/src/cli/commands/show.rs @@ -15,7 +15,10 @@ pub async fn execute(target: String, config: AppConfig) -> Result<()> { } // No exact match, try fuzzy search - info!("No exact match found for '{}', attempting fuzzy search", target); + info!( + "No exact match found for '{}', attempting fuzzy search", + target + ); let matches = ssh_service.fuzzy_search(&target, 10).await?; @@ -28,13 +31,16 @@ pub async fn execute(target: String, config: AppConfig) -> Result<()> { if !recent.is_empty() { println!("\nRecent connections:"); for (i, conn) in recent.iter().enumerate() { - let last_used = conn.last_used + let last_used = conn + .last_used .map(|dt| format!(" (last: {})", format_duration(dt))) - .unwrap_or_else(|| "".to_string()); + .unwrap_or_default(); println!(" {}. {}{}", i + 1, conn.name, last_used); } - if let Some(selection) = interactive_selection(&recent, "Select connection to show")? { + if let Some(selection) = + interactive_selection(&recent, "Select connection to show")? + { return show_connection_details(&selection); } } else { @@ -63,7 +69,11 @@ pub async fn execute(target: String, config: AppConfig) -> Result<()> { } _ => { // Multiple matches - interactive selection - println!("Found {} similar connections for '{}':", matches.len(), target); + println!( + "Found {} similar connections for '{}':", + matches.len(), + target + ); println!(); for (i, conn) in matches.iter().enumerate() { @@ -134,12 +144,21 @@ fn print_connection_info(connection: &crate::models::Connection, index: usize) { format!(" [{}]", connection.tags.join(", ")) }; - let last_used = connection.last_used + let last_used = connection + .last_used .map(|dt| format!(" (last used: {})", format_duration(dt))) - .unwrap_or_else(|| "".to_string()); + .unwrap_or_default(); println!(" {}. {} ({})", index, connection.name, connection.host); - println!(" Tags: {}{}", if tags_str.is_empty() { "none" } else { &tags_str[1..tags_str.len()-1] }, last_used); + println!( + " Tags: {}{}", + if tags_str.is_empty() { + "none" + } else { + &tags_str[1..tags_str.len() - 1] + }, + last_used + ); println!(); } @@ -170,9 +189,16 @@ fn format_duration(dt: chrono::DateTime) -> String { } } -fn interactive_selection(connections: &[crate::models::Connection], prompt: &str) -> Result> { +fn interactive_selection( + connections: &[crate::models::Connection], + prompt: &str, +) -> Result> { loop { - print!("{} [1-{}, 's' to search again, 'q' to quit]: ", prompt, connections.len()); + print!( + "{} [1-{}, 's' to search again, 'q' to quit]: ", + prompt, + connections.len() + ); io::stdout().flush()?; let mut input = String::new(); @@ -205,7 +231,10 @@ fn interactive_selection(connections: &[crate::models::Connection], prompt: &str if index >= 1 && index <= connections.len() { return Ok(Some(connections[index - 1].clone())); } else { - println!("Invalid selection. Please enter a number between 1 and {}.", connections.len()); + println!( + "Invalid selection. Please enter a number between 1 and {}.", + connections.len() + ); } } else { println!("Invalid input. Please enter a number, 's' to search again, or 'q' to quit."); diff --git a/src/config/mod.rs b/src/config/mod.rs index 1791e32..779d477 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -24,11 +24,11 @@ impl Default for AppConfig { Self { database_path: config_dir.join("history.db"), - default_user: "admin".to_string(), + default_user: whoami::username(), default_bastion: None, default_bastion_user: None, default_port: 22, - use_kerberos_by_default: true, + use_kerberos_by_default: false, ssh_config_path: dirs::home_dir().map(|h| h.join(".ssh/config")), log_level: "info".to_string(), auto_save_history: true, diff --git a/src/database/mod.rs b/src/database/mod.rs index 18c069c..439de4b 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -422,23 +422,16 @@ impl Database { // 2. Word-based matching - split query into words and find them let query_words: Vec<&str> = query.split_whitespace().collect(); if query_words.len() > 1 { - let all_words_found = query_words.iter() - .all(|word| name.contains(word)); + let all_words_found = query_words.iter().all(|word| name.contains(word)); if all_words_found { return true; } } // 3. Handle common separators (hyphens, underscores, dots) - let normalized_name = name - .replace("-", "") - .replace("_", "") - .replace(".", ""); + let normalized_name = name.replace("-", "").replace("_", "").replace(".", ""); - let normalized_query = query - .replace("-", "") - .replace("_", "") - .replace(".", ""); + let normalized_query = query.replace("-", "").replace("_", "").replace(".", ""); // Check if normalized versions match if normalized_name.contains(&normalized_query) { @@ -449,7 +442,8 @@ impl Database { if query.len() >= 2 { let words: Vec<&str> = name.split(&['-', '_', ' '][..]).collect(); if words.len() > 1 { - let acronym: String = words.iter() + let acronym: String = words + .iter() .filter_map(|word| word.chars().next()) .collect(); if acronym.to_lowercase().contains(&query) { @@ -460,9 +454,7 @@ impl Database { // 5. Partial acronym matching if query.len() >= 2 { - let name_chars: String = name.chars() - .filter(|c| c.is_alphanumeric()) - .collect(); + let name_chars: String = name.chars().filter(|c| c.is_alphanumeric()).collect(); if name_chars.to_lowercase().starts_with(&query) { return true; } @@ -508,7 +500,9 @@ impl Database { connections.sort_by(|a, b| { let score_a = self.calculate_relevance_score(a, query); let score_b = self.calculate_relevance_score(b, query); - score_b.partial_cmp(&score_a).unwrap_or(std::cmp::Ordering::Equal) + score_b + .partial_cmp(&score_a) + .unwrap_or(std::cmp::Ordering::Equal) }); } @@ -558,9 +552,11 @@ impl Database { if hours_since_used < 24 { score += 30.0; - } else if hours_since_used < 168 { // 1 week + } else if hours_since_used < 168 { + // 1 week score += 15.0; - } else if hours_since_used < 720 { // 1 month + } else if hours_since_used < 720 { + // 1 month score += 5.0; } } diff --git a/src/services/ssh.rs b/src/services/ssh.rs index b63f4b7..4a77682 100644 --- a/src/services/ssh.rs +++ b/src/services/ssh.rs @@ -304,7 +304,8 @@ impl SshService { } pub async fn get_recent_connections(&self, limit: usize) -> Result> { - self.database.list_connections(None, true) + self.database + .list_connections(None, true) .map(|mut connections| { connections.truncate(limit); connections