From 2e84602de722694c5cce4172e7455f592cee6a03 Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Tue, 28 Mar 2023 21:23:26 +0200 Subject: Git push is now limited to only appropriate paths --- tests/server_shell.rs | 98 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 70 insertions(+), 28 deletions(-) (limited to 'tests') diff --git a/tests/server_shell.rs b/tests/server_shell.rs index 721716b..a22b732 100644 --- a/tests/server_shell.rs +++ b/tests/server_shell.rs @@ -169,6 +169,36 @@ fn clone_git_repo_relative_path(c: &TestContext, repo_name: &str) -> Assert { clone_git_repo(c, &format!("/~/git/shukkie/{}.git", repo_name)) } +fn push_git_repo(c: &TestContext, repo_name: &str) -> Assert { + let repo_dir = c.workdir.as_ref().join(repo_name); + Command::new("git") + .args(["push", "origin", "main"]) + .current_dir(&repo_dir) + .env("GIT_SSH_COMMAND", GIT_SSH_COMMAND) + .timeout(std::time::Duration::from_secs(3)) + .assert() +} + +fn commit_dummy_content(c: &TestContext, repo_name: &str) -> Result<()> { + let repo_dir = c.workdir.as_ref().join(repo_name); + + let file_name = "yay-a-file"; + let file_path = repo_dir.join(file_name); + fs::write(&file_path, "doesn't matter what this is")?; + + Command::new("git") + .args(["add", "-A"]) + .current_dir(&repo_dir) + .assert() + .success(); + Command::new("git") + .args(["commit", "-m", "commitment"]) + .current_dir(&repo_dir) + .assert() + .success(); + Ok(()) +} + #[test] fn git_clone_works_with_an_empty_repo() -> Result<()> { let c = spawn_ssh_server()?; @@ -185,51 +215,63 @@ fn git_push_works() -> Result<()> { let repo_name = "my-new-pushable-repo"; make_new_repo(&c, repo_name)?; clone_git_repo_relative_path(&c, repo_name).success(); + commit_dummy_content(&c, repo_name)?; + push_git_repo(&c, repo_name).success(); - let repo_dir = c.workdir.as_ref().join(repo_name); + Ok(()) +} - let file_name = "yay-a-file"; - let file_path = repo_dir.join(file_name); - fs::write(&file_path, "doesn't matter what this is")?; +#[test] +fn git_clone_can_not_target_repo_outside_allowed_paths() -> Result<()> { + fn test_git_clone_unallowed_path(repo_name: &str) -> Result<()> { + let c = spawn_ssh_server()?; + clone_git_repo(&c, &format!("/~/{}.git", repo_name)) + .failure() + .stderr(predicates::str::contains("Path is not accessible")); + Ok(()) + } + test_git_clone_unallowed_path("disallowed")?; + test_git_clone_unallowed_path("disallowed-doesnt-exist")?; + Ok(()) +} +fn init_local_git_dir(c: &TestContext, repo_name: &str) { Command::new("git") - .args(["add", "-A"]) - .current_dir(&repo_dir) - .assert() - .success(); - Command::new("git") - .args(["commit", "-m", "commitment"]) - .current_dir(&repo_dir) + .args(["init", repo_name]) + .current_dir(&c.workdir) + .timeout(std::time::Duration::from_secs(3)) .assert() .success(); + let repo_dir = c.workdir.as_ref().join(repo_name); Command::new("git") - .args(["push", "origin"]) + .args([ + "remote", + "add", + "origin", + &format!("ssh://shukkie@localhost:{}/~/{}.git", c.ssh_port, repo_name), + ]) .current_dir(&repo_dir) - .env("GIT_SSH_COMMAND", GIT_SSH_COMMAND) .timeout(std::time::Duration::from_secs(3)) .assert() .success(); - - Ok(()) } #[test] -fn git_clone_can_not_target_repo_outside_allowed_paths() -> Result<()> { - let c = spawn_ssh_server()?; - clone_git_repo(&c, "/~/disallowed.git") - .failure() - .stderr(predicates::str::contains("Path is not accessible")); +fn git_push_can_not_target_repo_outside_allowed_paths() -> Result<()> { + fn test_push_to_unallowed_path(repo_name: &str) -> Result<()> { + let c = spawn_ssh_server()?; + init_local_git_dir(&c, &repo_name); + commit_dummy_content(&c, repo_name)?; - Ok(()) -} + push_git_repo(&c, repo_name) + .failure() + .stderr(predicates::str::contains("Path is not accessible")); -#[test] -fn git_clone_can_not_target_repo_outside_allowed_paths_where_path_doesnt_exist() -> Result<()> { - let c = spawn_ssh_server()?; - clone_git_repo(&c, "/~/disallowed-doesnt-exist.git") - .failure() - .stderr(predicates::str::contains("Path is not accessible")); + Ok(()) + } + test_push_to_unallowed_path("disallowed")?; + test_push_to_unallowed_path("disallowed-doesnt-exist")?; Ok(()) } -- cgit v1.2.3