From 8b21be5e14f44c4f9b0d995ed73709bdde30028f Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Fri, 24 Mar 2023 08:46:13 +0200 Subject: Added checking for a valid path, but the test is failing for the wrong reason --- readme.org | 8 +++++++- src/git.rs | 38 ++++++++++++++++++++++++++++++++------ src/lib.rs | 2 ++ tests/server_shell.rs | 1 - 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/readme.org b/readme.org index 590dc87..3674200 100644 --- a/readme.org +++ b/readme.org @@ -13,6 +13,8 @@ Pijul. * Roadmap +** MVP + - [X] interactive command prompt - [X] non-interactive commands can be run with -c - [X] exit command @@ -32,8 +34,12 @@ Pijul. - [ ] listing of repos - [ ] set repo descriptions - [ ] set the main branch of a repo -- [ ] git archive with git upload-archive - [ ] help docs on all the commands + +** Post-MVP + +- [ ] git archive with git upload-archive +- [ ] git config management around protected branches - [ ] move a repo to a different group - [ ] housekeeping git tasks (git fsck, git gc) - [ ] pijul fetch and pijul push diff --git a/src/git.rs b/src/git.rs index 24b376d..877e336 100644 --- a/src/git.rs +++ b/src/git.rs @@ -3,19 +3,42 @@ use crate::{ ShackleError, }; use git2::{Repository, RepositoryInitOptions}; -use std::{path::PathBuf, process::Command}; +use std::{ + path::{Path, PathBuf}, + process::Command, +}; use user_info::get_username; pub struct GitInitResult { pub path: PathBuf, } -pub fn init(repo_name: &str) -> Result { +fn personal_git_dir() -> Result { let username = get_username().ok_or(ShackleError::UserReadError)?; - let mut path = PathBuf::from("git"); - path.push(username); - path.push(repo_name); - path.set_extension("git"); + Ok(Path::new("git").join(username)) +} + +fn is_valid_personal_git_repo(path: &PathBuf) -> Result { + let valid_dir = personal_git_dir()?.canonicalize()?; + let canonical_path = path.canonicalize()?; + let relative_path = match canonical_path.strip_prefix(&valid_dir) { + Ok(relative_path) => relative_path, + Err(_) => { + return Ok(false); + } + }; + + if relative_path.parent() != Some(Path::new("")) + || relative_path.extension().map(|ext| ext == "git") != Some(true) + { + return Ok(false); + } + + Ok(true) +} + +pub fn init(repo_name: &str) -> Result { + let path = personal_git_dir()?.join(repo_name).with_extension("git"); Repository::init_opts( &path, @@ -29,6 +52,9 @@ pub fn init(repo_name: &str) -> Result { pub fn upload_pack(upload_pack_args: &GitUploadPackArgs) -> Result<(), ShackleError> { let mut command = Command::new("git-upload-pack"); + if !is_valid_personal_git_repo(&upload_pack_args.directory)? { + return Err(ShackleError::InvalidDirectory); + } if upload_pack_args.strict { command.arg("strict"); diff --git a/src/lib.rs b/src/lib.rs index 99d8877..595e3ec 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,4 +39,6 @@ pub enum ShackleError { ReadlineError(#[from] ReadlineError), #[error("Could not get the current user name")] UserReadError, + #[error("Path is not accessible")] + InvalidDirectory, } diff --git a/tests/server_shell.rs b/tests/server_shell.rs index 72329d3..756c5a8 100644 --- a/tests/server_shell.rs +++ b/tests/server_shell.rs @@ -215,7 +215,6 @@ fn git_push_works() -> Result<()> { } #[test] -#[ignore = "Need to put the repo in the right dir first"] fn git_clone_can_not_target_repo_outside_allowed_paths() -> Result<()> { let c = spawn_ssh_server()?; clone_git_repo(&c, "/home/shukkie/disallowed.git") -- cgit v1.2.3