summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin Wernick <justin@worthe-it.co.za>2023-03-30 00:03:59 +0200
committerJustin Wernick <justin@worthe-it.co.za>2023-03-30 00:03:59 +0200
commit3c59f9494f6b3cf9c8f9fb6cca0580d053329cf0 (patch)
treed5c80b5cdf79c8e377c085de5bde2af6abbecc7c /src
parent745cd8ab27480a3cf516a2684db2c4fd7cf2144c (diff)
Update path restrictions to allow shared repos
Diffstat (limited to 'src')
-rw-r--r--src/git.rs54
1 files changed, 37 insertions, 17 deletions
diff --git a/src/git.rs b/src/git.rs
index dcdb71b..7337a6a 100644
--- a/src/git.rs
+++ b/src/git.rs
@@ -3,19 +3,20 @@ use crate::{
ShackleError,
};
use git2::{Repository, RepositoryInitMode, RepositoryInitOptions};
-use std::{
- path::{Path, PathBuf},
- process::Command,
-};
+use std::{path::PathBuf, process::Command};
use user_info::{get_user_groups, get_username};
pub struct GitInitResult {
pub path: PathBuf,
}
+fn git_dir_prefix() -> PathBuf {
+ PathBuf::from("git")
+}
+
fn personal_git_dir() -> Result<PathBuf, ShackleError> {
let username = get_username().ok_or(ShackleError::UserReadError)?;
- Ok(Path::new("git").join(username))
+ Ok(git_dir_prefix().join(username))
}
fn group_git_dir(group: &str) -> Result<PathBuf, ShackleError> {
@@ -23,26 +24,45 @@ fn group_git_dir(group: &str) -> Result<PathBuf, ShackleError> {
if !groups.iter().any(|g| g == group) {
Err(ShackleError::InvalidGroup)
} else {
- Ok(Path::new("git").join(group))
+ Ok(git_dir_prefix().join(group))
}
}
-fn is_valid_personal_git_repo(path: &PathBuf) -> Result<bool, ShackleError> {
- let valid_dir = personal_git_dir()?;
- let relative_path = match path.strip_prefix(&valid_dir) {
+fn is_valid_git_repo_path(path: &PathBuf) -> Result<bool, ShackleError> {
+ let prefix = git_dir_prefix();
+ let relative_path = match path.strip_prefix(&prefix) {
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);
+ let mut it = relative_path.iter();
+ let group = it.next();
+ let repo_name = it.next();
+ let end = it.next();
+
+ match (group, repo_name, end) {
+ (_, _, Some(_)) | (None, _, _) | (_, None, _) => Ok(false),
+ (Some(group_name), Some(_repo_name), _) => {
+ if relative_path.extension().map(|ext| ext == "git") != Some(true) {
+ Ok(false)
+ } else {
+ let group_name = group_name.to_string_lossy();
+
+ let user_name = get_username();
+ let is_valid_personal_repo_path = user_name
+ .map(|user_name| user_name == group_name)
+ .unwrap_or(false);
+
+ let user_groups = get_user_groups();
+ let is_valid_shared_repo_path =
+ user_groups.iter().any(|group| group.as_ref() == group_name);
+
+ Ok(is_valid_personal_repo_path || is_valid_shared_repo_path)
+ }
+ }
}
-
- Ok(true)
}
pub fn init(repo_name: &str, group: &Option<String>) -> Result<GitInitResult, ShackleError> {
@@ -80,7 +100,7 @@ pub fn init(repo_name: &str, group: &Option<String>) -> Result<GitInitResult, Sh
}
pub fn upload_pack(upload_pack_args: &GitUploadPackArgs) -> Result<(), ShackleError> {
- if !is_valid_personal_git_repo(&upload_pack_args.directory)? {
+ if !is_valid_git_repo_path(&upload_pack_args.directory)? {
return Err(ShackleError::InvalidDirectory);
}
@@ -107,7 +127,7 @@ pub fn upload_pack(upload_pack_args: &GitUploadPackArgs) -> Result<(), ShackleEr
}
pub fn receive_pack(receive_pack_args: &GitReceivePackArgs) -> Result<(), ShackleError> {
- if !is_valid_personal_git_repo(&receive_pack_args.directory)? {
+ if !is_valid_git_repo_path(&receive_pack_args.directory)? {
return Err(ShackleError::InvalidDirectory);
}