chore: sync repository to current working state
Some checks failed
Build and Test / Build Server (Linux) (push) Has been cancelled
Build and Test / Build Agent (Windows) (push) Has been cancelled
Build and Test / Security Audit (push) Has been cancelled
Build and Test / Build Summary (push) Has been cancelled
Run Tests / Test Server (push) Has been cancelled
Run Tests / Test Agent (push) Has been cancelled
Run Tests / Code Coverage (push) Has been cancelled
Run Tests / Lint and Format Check (push) Has been cancelled

Brings azcomputerguru/guru-connect up to the authoritative working copy that
had been maintained in the claudetools monorepo: Phase 1 security and
infrastructure (middleware, metrics, utils, token blacklist, deployment
scripts, security audits) plus the native-remote-control integration spec.
Preserves the repo .gitignore, .cargo, and server/static/downloads.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-29 06:15:29 -07:00
parent 5b7cf5fb07
commit e3e95f8fa7
73 changed files with 15608 additions and 5757 deletions

View File

@@ -0,0 +1,22 @@
//! IP address extraction from WebSocket connections
use axum::extract::ConnectInfo;
use std::net::{IpAddr, SocketAddr};
/// Extract IP address from Axum ConnectInfo
///
/// # Example
/// ```rust
/// pub async fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) {
/// let ip = extract_ip(&addr);
/// // Use ip for logging
/// }
/// ```
pub fn extract_ip(addr: &SocketAddr) -> IpAddr {
addr.ip()
}
/// Extract IP address as string
pub fn extract_ip_string(addr: &SocketAddr) -> String {
addr.ip().to_string()
}

4
server/src/utils/mod.rs Normal file
View File

@@ -0,0 +1,4 @@
//! Utility functions
pub mod ip_extract;
pub mod validation;

View File

@@ -0,0 +1,58 @@
//! Input validation and security checks
use anyhow::{anyhow, Result};
/// Validate API key meets minimum security requirements
///
/// Requirements:
/// - Minimum 32 characters
/// - Not a common weak key
/// - Sufficient character diversity
pub fn validate_api_key_strength(api_key: &str) -> Result<()> {
// Minimum length check
if api_key.len() < 32 {
return Err(anyhow!("API key must be at least 32 characters long for security"));
}
// Check for common weak keys
let weak_keys = [
"password", "12345", "admin", "test", "api_key",
"secret", "changeme", "default", "guruconnect"
];
let lowercase_key = api_key.to_lowercase();
for weak in &weak_keys {
if lowercase_key.contains(weak) {
return Err(anyhow!("API key contains weak/common patterns and is not secure"));
}
}
// Check for sufficient entropy (basic diversity check)
let unique_chars: std::collections::HashSet<char> = api_key.chars().collect();
if unique_chars.len() < 10 {
return Err(anyhow!(
"API key has insufficient character diversity (need at least 10 unique characters)"
));
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validate_api_key_strength() {
// Too short
assert!(validate_api_key_strength("short").is_err());
// Weak pattern
assert!(validate_api_key_strength("password_but_long_enough_now_123456789").is_err());
// Low entropy
assert!(validate_api_key_strength("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").is_err());
// Good key
assert!(validate_api_key_strength("KfPrjjC3J6YMx9q1yjPxZAYkHLM2JdFy1XRxHJ9oPnw0NU3xH074ufHk7fj").is_ok());
}
}