diff options
| author | KunoiSayami <[email protected]> | 2026-06-11 14:53:23 +0800 |
|---|---|---|
| committer | KunoiSayami <[email protected]> | 2026-06-11 14:53:23 +0800 |
| commit | 9e67f120b797bae10bd226bbb4632f8d19a24361 (patch) | |
| tree | d94a9a067eb05cf78bee7282ff7c9f093c360bfc /src | |
| parent | c708a63f7e5b9b22f8095ede0be56115eccbbac8 (diff) | |
fix: Fix OsRng import and refactor Redis connection setup
- Fix password-hash version mismatch (0.6→0.5) causing OsRng to be
gated behind missing getrandom feature; enable argon2 rand feature
- Extract get_redis_connection() helper to deduplicate Redis client
setup across authentication, repo control, and tests
- Tighten username validation regex to require ≥2 chars and disallow
leading/trailing dots or hyphens
- Handle malformed cookies without split_once gracefully (continue
instead of panic)
- Fix typos: "rated commands" → "related commands" in CLI help text
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Signed-off-by: KunoiSayami <[email protected]>
Diffstat (limited to 'src')
| -rw-r--r-- | src/authentication.rs | 16 | ||||
| -rw-r--r-- | src/datastructures.rs | 11 | ||||
| -rw-r--r-- | src/main.rs | 6 | ||||
| -rw-r--r-- | src/test.rs | 10 |
4 files changed, 27 insertions, 16 deletions
diff --git a/src/authentication.rs b/src/authentication.rs index 05707f0..dd27c25 100644 --- a/src/authentication.rs +++ b/src/authentication.rs @@ -42,8 +42,9 @@ impl<R: BufRead, W: Write> IOModule<R, W> { log::trace!("Method is {}", cfg.get_authorizer().method()); // Establish Redis connection early for rate limiting + session storage - let redis_client = redis::Client::open(cfg.get_config().redis_url.as_str())?; - let mut conn = redis_client.get_multiplexed_async_connection().await?; + let mut conn = + crate::datastructures::get_redis_connection(cfg.get_config().redis_url.as_str()) + .await?; // Rate limit check let max_attempts = cfg.get_config().max_login_attempts; @@ -166,8 +167,7 @@ pub(crate) async fn cmd_authenticate_cookie(matches: &ArgMatches, cfg: Config) - return Ok(false); } - let redis_conn = redis::Client::open(cfg.redis_url.as_str())?; - let mut conn = redis_conn.get_multiplexed_async_connection().await?; + let mut conn = crate::datastructures::get_redis_connection(cfg.redis_url.as_str()).await?; let redis_key = format!("cgit_repo_{repo}"); if !repo.is_empty() && !conn.exists(&redis_key).await? { @@ -289,7 +289,7 @@ pub(crate) async fn cmd_body(matches: &ArgMatches, _cfg: Config) { } pub(crate) async fn cmd_add_user(matches: &ArgMatches, cfg: Config) -> Result<()> { - let re = regex::Regex::new(r"^\w+$").unwrap(); + let re = regex::Regex::new(r"^[a-zA-Z0-9_][a-zA-Z0-9_.\-]*[a-zA-Z0-9_]$").unwrap(); let user = matches .get_one::<String>("user") .map(|s| s.as_str()) @@ -308,7 +308,7 @@ pub(crate) async fn cmd_add_user(matches: &ArgMatches, cfg: Config) -> Result<() if !re.is_match(user) { return Err(anyhow::Error::msg( - "Username must pass regex check\"^\\w+$\"", + "Username must be at least 2 characters, contain only alphanumeric characters, underscores, dots, or hyphens, and must not start or end with a dot or hyphen", )); } @@ -504,8 +504,8 @@ pub(crate) async fn cmd_repo_user_control( return Err(anyhow::Error::msg("Invalid repository or username")); } - let redis_client = redis::Client::open(cfg.redis_url.as_str())?; - let mut redis_conn = redis_client.get_multiplexed_async_connection().await?; + let mut redis_conn = + crate::datastructures::get_redis_connection(cfg.redis_url.as_str()).await?; let mut conn = SqliteConnection::connect(cfg.get_database_location()).await?; diff --git a/src/datastructures.rs b/src/datastructures.rs index 4ca1a00..82c0325 100644 --- a/src/datastructures.rs +++ b/src/datastructures.rs @@ -71,6 +71,13 @@ pub fn rand_str(len: usize) -> String { password } +pub(crate) async fn get_redis_connection( + redis_url: &str, +) -> Result<redis::aio::MultiplexedConnection> { + let client = redis::Client::open(redis_url)?; + Ok(client.get_multiplexed_async_connection().await?) +} + pub(crate) trait TestSuite { fn generate_test_config() -> Self; } @@ -532,7 +539,9 @@ impl Cookie { pub fn load_from_request(cookies: &str) -> Result<Option<Self>> { let mut cookie_self = None; for cookie in cookies.split(';').map(|x| x.trim()) { - let (key, value) = cookie.split_once('=').unwrap(); + let Some((key, value)) = cookie.split_once('=') else { + continue; + }; if key.eq("cgit_auth") { let value = base64::engine::general_purpose::STANDARD .decode(value) diff --git a/src/main.rs b/src/main.rs index 318a94c..3b9e04b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -133,7 +133,7 @@ fn get_arg_matches(arguments: Option<Vec<&str>>) -> ArgMatches { ) .subcommand( Command::new("database") - .about("Database rated commands") + .about("Database related commands") .subcommand( Command::new("init") .about("Init sqlite database") @@ -154,7 +154,7 @@ fn get_arg_matches(arguments: Option<Vec<&str>>) -> ArgMatches { ) .subcommand( Command::new("user") - .about("Users rated commands") + .about("User related commands") .subcommand( Command::new("add") .about("Add user to database") @@ -177,7 +177,7 @@ fn get_arg_matches(arguments: Option<Vec<&str>>) -> ArgMatches { ) .subcommand( Command::new("repo") - .about("Repository ACL rated commands") + .about("Repository ACL related commands") .subcommand( Command::new("add") .about("Add user to repository") diff --git a/src/test.rs b/src/test.rs index 7628921..e71aee4 100644 --- a/src/test.rs +++ b/src/test.rs @@ -55,8 +55,9 @@ mod core { } async fn async_test_redis() -> anyhow::Result<()> { - let redis_conn = redis::Client::open(crate::datastructures::DEFAULT_REDIS_URL)?; - let mut conn = redis_conn.get_multiplexed_async_connection().await?; + let mut conn = + crate::datastructures::get_redis_connection(crate::datastructures::DEFAULT_REDIS_URL) + .await?; let s = rand_str(crate::datastructures::COOKIE_LENGTH); conn.set_ex::<_, _, String>("auth_test", &s, 60).await?; @@ -344,8 +345,9 @@ mod core { } async fn clear_redis_setting() -> anyhow::Result<()> { - let client = redis::Client::open(crate::datastructures::DEFAULT_REDIS_URL)?; - let mut conn = client.get_multiplexed_async_connection().await?; + let mut conn = + crate::datastructures::get_redis_connection(crate::datastructures::DEFAULT_REDIS_URL) + .await?; for key in &[ "cgit_repo_test", |
