Skip to content

Commit

Permalink
Include a password complexity checker
Browse files Browse the repository at this point in the history
Run build and test for non-releases
  • Loading branch information
dormant-user committed Sep 26, 2024
1 parent 0fb4fcd commit 81bccac
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 12 deletions.
14 changes: 14 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,20 @@ jobs:
echo "release_id=$release_id" >> "$GITHUB_OUTPUT"
shell: bash

build-and-test:
needs: release
if: needs.release.outputs.release-flag == 'false'
runs-on:
- thevickypedia-lite
- posix
steps:
- name: Build (no release)
run: cargo build
shell: bash
- name: Test (no release)
run: cargo test --no-run
shell: bash

upload_assets:
needs: release
strategy:
Expand Down
2 changes: 0 additions & 2 deletions src/resources/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,10 @@ pub fn get_disk_usage(disks: &Disks) -> u64 {
pub fn get_disks(disks: &Disks) -> Vec<HashMap<String, String>> {
let mut disks_info = vec![];
for disk in disks.list() {
// todo: Check sysinfo source code for a way to get the `Model` information
disks_info.push(
HashMap::from([
("Name".to_string(), disk.name().to_string_lossy().to_string()),
("Size".to_string(), squire::util::size_converter(disk.total_space()).to_string()),
// ("Model".to_string(), disk.name().to_string_lossy().to_string()),
("Kind".to_string(), disk.file_system().to_string_lossy().to_string()),
("Mount Point".to_string(), disk.mount_point().to_string_lossy().to_string()),
])
Expand Down
4 changes: 2 additions & 2 deletions src/routes/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ pub async fn monitor(request: HttpRequest,
// legacy functions have a mechanism to check for physical devices, so it takes precedence
let has_name_and_size = !legacy_disk_info.is_empty() &&
legacy_disk_info.iter().all(|disk| {
disk.contains_key("Name") && disk.contains_key("Size")
});
disk.contains_key("Name") && disk.contains_key("Size")
});
let sys_info_disks = if has_name_and_size {
log::debug!("Using legacy methods for disks!");
legacy_disk_info
Expand Down
87 changes: 79 additions & 8 deletions src/squire/startup.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std;
use std::io::Write;

use chrono::{DateTime, Local};

use crate::squire::settings;
use crate::{constant, squire};
use chrono::{DateTime, Local};
use regex::Regex;

/// Initializes the logger based on the provided debug flag and cargo information.
///
Expand Down Expand Up @@ -238,6 +238,78 @@ fn load_env_vars() -> settings::Config {
}
}

/// Verifies the strength of a password string.
///
/// A secret is considered strong if it meets the following conditions:
/// - At least 32 characters long
/// - Contains at least one digit
/// - Contains at least one uppercase letter
/// - Contains at least one lowercase letter
/// - Contains at least one special character
///
/// # Arguments
///
/// * `password` - A reference to a string slice (`&str`) that represents the password to check.
///
/// # Returns
///
/// This function returns a `Result<(), String>`.
/// - `Ok(())` is returned if all conditions are met.
/// - `Err(String)` is returned with an error message if any condition fails.
pub fn complexity_checker(password: &str) -> Result<(), String> {
let mock_password = "*".repeat(password.len());

// Check minimum length
if password.len() < 8 {
return Err(
format!(
"\npassword\n\t[{}] password must be at least 8 or more characters [value=invalid]\n", mock_password
)
);
}

// Check for at least one digit
let has_digit = Regex::new(r"\d").unwrap();
if !has_digit.is_match(password) {
return Err(
format!(
"\npassword\n\t[{}] password must include at least one digit [value=invalid]\n", mock_password
)
);
}

// Check for at least one uppercase letter
let has_uppercase = Regex::new(r"[A-Z]").unwrap();
if !has_uppercase.is_match(password) {
return Err(
format!(
"\npassword\n\t[{}] password must include at least one uppercase letter [value=invalid]\n", mock_password
)
);
}

// Check for at least one lowercase letter
let has_lowercase = Regex::new(r"[a-z]").unwrap();
if !has_lowercase.is_match(password) {
return Err(
format!(
"\npassword\n\t[{}] password must include at least one lowercase letter [value=invalid]\n", mock_password
)
);
}

// Check for at least one special character
let has_special_char = Regex::new(r###"[ !#$%&'()*+,./:;<=>?@\\^_`{|}~"-]"###).unwrap();
if !has_special_char.is_match(password) {
return Err(
format!(
"\npassword\n\t[{}] password must contain at least one special character [value=invalid]\n", mock_password
)
);
}
Ok(())
}

/// Validates all the required environment variables with the required settings.
///
/// # Returns
Expand All @@ -253,12 +325,11 @@ fn validate_vars() -> settings::Config {
);
errors.push_str(&err1);
}
if config.password.len() < 8 {
let err2 = format!(
"\npassword\n\t[{}] password should be at least 8 or more characters [value=invalid]\n",
"*".repeat(config.password.len())
);
errors.push_str(&err2);
match complexity_checker(&config.password) {
Ok(_) => (),
Err(err) => {
errors.push_str(&err);
}
}
if !errors.is_empty() {
panic!("{}", errors);
Expand Down

0 comments on commit 81bccac

Please sign in to comment.