diff options
-rw-r--r-- | Cargo.lock | 3 | ||||
-rw-r--r-- | Cargo.toml | 3 | ||||
-rw-r--r-- | README.md | 37 | ||||
-rw-r--r-- | src/main.rs | 178 | ||||
-rw-r--r-- | src/test.rs | 62 |
5 files changed, 183 insertions, 100 deletions
@@ -377,7 +377,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cgit-simple-authentication" -version = "1.0.0" +version = "2.0.0" dependencies = [ "anyhow", "argon2", @@ -394,7 +394,6 @@ dependencies = [ "redis", "regex", "serde", - "serde_derive", "serde_json", "sqlx", "tempdir", @@ -1,6 +1,6 @@ [package] name = "cgit-simple-authentication" -version = "1.0.0" +version = "2.0.0" authors = ["KunoiSayami <[email protected]>"] edition = "2018" @@ -9,7 +9,6 @@ log = { version = "0.4", features = ["max_level_trace", "release_max_level_debug env_logger = "0.8" tokio = { version = "1", features = ["full"] } serde_json = "1" -serde_derive = "1" serde = { version = "1", features = ["derive"] } anyhow = "1" toml = "0.5" @@ -25,7 +25,7 @@ cgit-simple-auth-full-protect=true Available options for repositories: -_Should set `cgit-simple-auth-full-protect=false`_ +_You should set `cgit-simple-auth-full-protect=false`_ ```conf repo.url=test @@ -33,6 +33,41 @@ repo.url=test repo.protect=true ``` +## Usage + +You should initialize your database first + +```shell +cargo run -- database init +``` + +Then add user with + +```shell +cargo run -- user add admin hunter2 +``` + +More usage information, see `--help`. + +## Program help + +```plain +Simple Authentication Filter for cgit + +USAGE: + cgit-simple-authentication.exe [SUBCOMMAND] + +FLAGS: + -h, --help Prints help information + -V, --version Prints version information + +SUBCOMMANDS: + database Database rated commands + repo Repository ACL rated commands + user Users rated commands + help Prints this message or the help of the given subcommand(s) +``` + ## Source Most of the ideas come from: https://github.com/varphone/cgit-gogs-auth-filter diff --git a/src/main.rs b/src/main.rs index 45fb166..be653fc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,7 +25,7 @@ mod test; use crate::datastructures::{Config, Cookie, FormData, TestSuite}; use anyhow::Result; use argon2::password_hash::PasswordHash; -use clap::{App, Arg, ArgMatches, SubCommand}; +use clap::{App, AppSettings, Arg, ArgMatches, SubCommand}; use handlebars::Handlebars; use log4rs::append::file::FileAppender; use log4rs::config::{Appender, Root}; @@ -128,6 +128,7 @@ async fn cmd_authenticate_cookie(matches: &ArgMatches<'_>, cfg: Config) -> Resul if !repo.is_empty() && !conn.exists(&redis_key).await? { let mut sql_conn = SqliteConnectOptions::from_str(cfg.get_database_location())? .read_only(true) + .disable_statement_logging() .connect() .await?; if let Some((users,)) = @@ -146,6 +147,7 @@ async fn cmd_authenticate_cookie(matches: &ArgMatches<'_>, cfg: Config) -> Resul .get::<_, String>(format!("cgit_auth_{}", cookie.get_key())) .await { + log::debug!("Cookie is valid"); if cookie.eq_body(r.as_str()) { if repo.is_empty() { return Ok(true); @@ -616,31 +618,40 @@ async fn async_main(arg_matches: ArgMatches<'_>) -> Result<i32> { ("body", Some(matches)) => { cmd_body(matches, cfg).await; } - ("init", Some(_matches)) => { - cmd_init(cfg).await?; - } - ("adduser", Some(matches)) => { - cmd_add_user(matches, cfg).await?; - } - ("users", Some(_matches)) => { - cmd_list_user(cfg).await?; - } - ("deluser", Some(matches)) => { - cmd_delete_user(matches, cfg).await?; - } - ("reset", Some(matches)) => { - cmd_reset_database(matches, cfg).await?; - } - ("upgrade", Some(_matches)) => { - cmd_upgrade_database(cfg).await?; - } - ("repoadd", Some(matches)) => cmd_repo_user_control(matches, cfg, false).await?, - ("repodel", Some(matches)) => { - cmd_repo_user_control(matches, cfg, true).await?; - } - ("repos", Some(matches)) => { - cmd_list_repos_acl(matches, cfg).await?; - } + ("user", Some(matches)) => match matches.subcommand() { + ("add", Some(matches)) => { + cmd_add_user(matches, cfg).await?; + } + ("del", Some(matches)) => { + cmd_delete_user(matches, cfg).await?; + } + ("list", Some(_matches)) => { + cmd_list_user(cfg).await?; + } + _ => {} + }, + ("database", Some(matches)) => match matches.subcommand() { + ("init", Some(_matches)) => { + cmd_init(cfg).await?; + } + ("upgrade", Some(_matches)) => { + cmd_upgrade_database(cfg).await?; + } + ("reset", Some(matches)) => { + cmd_reset_database(matches, cfg).await?; + } + _ => {} + }, + ("repo", Some(matches)) => match matches.subcommand() { + ("add", Some(matches)) => cmd_repo_user_control(matches, cfg, false).await?, + ("del", Some(matches)) => { + cmd_repo_user_control(matches, cfg, true).await?; + } + ("list", Some(matches)) => { + cmd_list_repos_acl(matches, cfg).await?; + } + _ => {} + }, _ => {} } Ok(0) @@ -667,61 +678,94 @@ fn get_arg_matches(arguments: Option<Vec<&str>>) -> ArgMatches { .subcommand( SubCommand::with_name("authenticate-cookie") .about("Processing authenticated cookie") - .args(sub_args), + .args(sub_args) + .setting(AppSettings::Hidden), ) .subcommand( SubCommand::with_name("authenticate-post") .about("Processing posted username and password") - .args(sub_args), + .args(sub_args) + .setting(AppSettings::Hidden), ) .subcommand( SubCommand::with_name("body") .about("Return the login form") - .args(sub_args), - ) - .subcommand(SubCommand::with_name("init").about("Init sqlite database")) - .subcommand(SubCommand::with_name("users").about("List all register user in database")) - .subcommand( - SubCommand::with_name("adduser") - .about("Add user to database") - .arg(Arg::with_name("user").required(true)) - .arg(Arg::with_name("password").required(true)), - ) - .subcommand( - SubCommand::with_name("deluser") - .about("Delete user from database") - .arg(Arg::with_name("user").required(true)), - ) - .subcommand( - SubCommand::with_name("reset") - .about("Reset database") - .arg(Arg::with_name("confirm").long("confirm")), - ) - .subcommand( - SubCommand::with_name("upgrade") - .about("Upgrade database from v2(v0.3.x) to v3(^v0.4.x)"), + .args(sub_args) + .setting(AppSettings::Hidden), ) .subcommand( - SubCommand::with_name("repoadd") - .about("Add user to repository") - .arg(Arg::with_name("repo").required(true)) - .arg(Arg::with_name("user").required(true)), + SubCommand::with_name("database") + .about("Database rated commands") + .subcommand( + SubCommand::with_name("init") + .about("Init sqlite database") + .display_order(0), + ) + .subcommand( + SubCommand::with_name("reset") + .about("Reset database") + .arg(Arg::with_name("confirm").long("confirm")) + .display_order(0), + ) + .subcommand( + SubCommand::with_name("upgrade") + .about("Upgrade database from v2(v0.3.x) to v3(^v0.4.x)") + .display_order(0), + ) + .display_order(0), ) .subcommand( - SubCommand::with_name("repodel") - .about("Del user from repository") - .arg(Arg::with_name("repo").required(true)) - .arg(Arg::with_name("user").takes_value(true)) - .arg( - Arg::with_name("clear-all") - .long("--clear-all") - .conflicts_with("user"), - ), + SubCommand::with_name("user") + .about("Users rated commands") + .subcommand( + SubCommand::with_name("add") + .about("Add user to database") + .arg(Arg::with_name("user").required(true)) + .arg(Arg::with_name("password").required(true)) + .display_order(0), + ) + .subcommand( + SubCommand::with_name("del") + .about("Delete user from database") + .arg(Arg::with_name("user").required(true)) + .display_order(0), + ) + .subcommand( + SubCommand::with_name("list") + .about("List all users") + .display_order(0), + ) + .display_order(0), ) .subcommand( - SubCommand::with_name("repos") - .about("Show all repositories or only show specify repository detail") - .arg(Arg::with_name("repo").takes_value(true)), + SubCommand::with_name("repo") + .about("Repository ACL rated commands") + .subcommand( + SubCommand::with_name("add") + .about("Add user to repository") + .arg(Arg::with_name("repo").required(true)) + .arg(Arg::with_name("user").required(true)) + .display_order(0), + ) + .subcommand( + SubCommand::with_name("del") + .about("Del user from repository") + .arg(Arg::with_name("repo").required(true)) + .arg(Arg::with_name("user").takes_value(true)) + .arg( + Arg::with_name("clear-all") + .long("clear-all") + .conflicts_with("user"), + ) + .display_order(0), + ) + .subcommand( + SubCommand::with_name("list") + .about("Show all repositories or only show specify repository detail") + .arg(Arg::with_name("repo").takes_value(true)) + .display_order(0), + ) + .display_order(0), ); let matches = if let Some(args) = arguments { diff --git a/src/test.rs b/src/test.rs index 098a70d..09a1556 100644 --- a/src/test.rs +++ b/src/test.rs @@ -19,7 +19,7 @@ */ #[cfg(test)] -mod core_test { +mod core { use crate::datastructures::{rand_str, Config, TestSuite}; use crate::{cmd_add_user, cmd_authenticate_cookie, cmd_init, cmd_repo_user_control}; use crate::{get_arg_matches, IOModule}; @@ -158,17 +158,20 @@ mod core_test { #[test] fn test_02_insert_user() { lock(&PathBuf::from("test/DATABASE_INITED"), 3); - let matches = crate::get_arg_matches(Some(vec!["a", "adduser", "hunter2", "hunter2"])); + let matches = crate::get_arg_matches(Some(vec!["a", "user", "add", "hunter2", "hunter2"])); match matches.subcommand() { - ("adduser", Some(matches)) => { - tokio::runtime::Builder::new_current_thread() - .enable_all() - .build() - .unwrap() - .block_on(cmd_add_user(matches, Config::generate_test_config())) - .unwrap(); - std::fs::File::create("test/USER_WRITTEN").unwrap(); - } + ("user", Some(matches)) => match matches.subcommand() { + ("add", Some(matches)) => { + tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap() + .block_on(cmd_add_user(matches, Config::generate_test_config())) + .unwrap(); + std::fs::File::create("test/USER_WRITTEN").unwrap(); + } + _ => unreachable!(), + }, _ => unreachable!(), } assert!(Path::new("test/COMMIT").exists()) @@ -178,25 +181,28 @@ mod core_test { fn test_03_insert_repo() { lock(&PathBuf::from("test/USER_WRITTEN"), 5); let args = vec![ - vec!["a", "repoadd", "test", "hunter2"], - vec!["a", "repoadd", "repo", "hunter"], + vec!["a", "repo", "add", "test", "hunter2"], + vec!["a", "repo", "add", "repo", "hunter"], ]; for x in args { let matches = crate::get_arg_matches(Some(x)); match matches.subcommand() { - ("repoadd", Some(matches)) => { - tokio::runtime::Builder::new_current_thread() - .enable_all() - .build() - .unwrap() - .block_on(cmd_repo_user_control( - matches, - Config::generate_test_config(), - false, - )) - .unwrap(); - std::fs::File::create("test/REPO_USER_ADDED").unwrap(); - } + ("repo", Some(matches)) => match matches.subcommand() { + ("add", Some(matches)) => { + tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap() + .block_on(cmd_repo_user_control( + matches, + Config::generate_test_config(), + false, + )) + .unwrap(); + std::fs::File::create("test/REPO_USER_ADDED").unwrap(); + } + _ => unreachable!(), + }, _ => unreachable!(), } } @@ -227,7 +233,7 @@ mod core_test { #[test] #[should_panic] - fn test_93_authenticate_cookie() { + fn test_93_authenticate_cookie_failure() { test_authenticate_cookie("repo", Some("test/COOKIE_TEST_2")); } @@ -297,7 +303,7 @@ mod core_test { } #[test] - fn test_02_protected_repo_parser() { + fn test_protected_repo_parser() { let tmpdir = tempdir::TempDir::new("test").unwrap(); let another_file_path = format!( |