From b5e7c1f0d634c6c826b9cf95dc962afa8c9c15e8 Mon Sep 17 00:00:00 2001 From: Louis-Marie Givel Date: Tue, 12 Oct 2021 16:06:09 +0200 Subject: [PATCH 1/6] Add permissions check in josh-filter --- josh-proxy/src/bin/josh-proxy.rs | 2 +- src/bin/josh-filter.rs | 90 ++++------ src/filter/mod.rs | 18 ++ src/housekeeping.rs | 2 +- src/lib.rs | 25 ++- tests/filter/empty_head.t | 1 + tests/filter/infofile.t | 2 + tests/filter/permissions.t | 285 +++++++++++++++++++++++++++---- tests/filter/submodule.t | 1 + 9 files changed, 336 insertions(+), 90 deletions(-) diff --git a/josh-proxy/src/bin/josh-proxy.rs b/josh-proxy/src/bin/josh-proxy.rs index c76f52ff6..803c7ac41 100644 --- a/josh-proxy/src/bin/josh-proxy.rs +++ b/josh-proxy/src/bin/josh-proxy.rs @@ -295,7 +295,7 @@ async fn do_filter( let mut headref = headref; - josh::filter_refs(&transaction, filter, &from_to)?; + josh::filter_refs(&transaction, filter, &from_to, josh::filter::empty())?; if headref == "HEAD" { headref = heads_map .read()? diff --git a/src/bin/josh-filter.rs b/src/bin/josh-filter.rs index 027df3cec..12461c298 100644 --- a/src/bin/josh-filter.rs +++ b/src/bin/josh-filter.rs @@ -101,7 +101,18 @@ fn run_filter(args: Vec) -> josh::JoshResult { .arg( clap::Arg::with_name("check-permission") .long("check-permission") - .short("c") + .short("c"), + ) + .arg( + clap::Arg::with_name("whitelist") + .long("whitelist") + .short("w") + .takes_value(true), + ) + .arg( + clap::Arg::with_name("blacklist") + .long("blacklist") + .short("b") .takes_value(true), ) .arg(clap::Arg::with_name("version").long("version").short("v")) @@ -183,6 +194,7 @@ fn run_filter(args: Vec) -> josh::JoshResult { josh::filter::parse(&i)?, input_ref, "refs/JOSH_TMP", + josh::filter::empty(), )?; } } @@ -193,12 +205,6 @@ fn run_filter(args: Vec) -> josh::JoshResult { let target = update_target; let reverse = args.is_present("reverse"); - let check_permissions = args.is_present("check-permission"); - - if check_permissions { - filterobj = josh::filter::chain(josh::filter::parse(":PATHS")?, filterobj); - filterobj = josh::filter::chain(filterobj, josh::filter::parse(":FOLD")?); - } let t = if reverse { "refs/JOSH_TMP".to_owned() @@ -213,21 +219,32 @@ fn run_filter(args: Vec) -> josh::JoshResult { .unwrap() .to_string(); - josh::filter_ref(&transaction, filterobj, &src, &t)?; - - let mut all_paths = vec![]; - + let check_permissions = args.is_present("check-permission"); + let mut permissions_filter = josh::filter::empty(); if check_permissions { - let result_tree = repo.find_reference(&t)?.peel_to_tree()?; + let whitelist = match args.value_of("whitelist") { + Some(s) => josh::filter::parse(s)?, + _ => josh::filter::nop(), + }; + let blacklist = match args.value_of("blacklist") { + Some(s) => josh::filter::parse(s)?, + _ => josh::filter::empty(), + }; + permissions_filter = josh::filter::make_permissions_filter(filterobj, whitelist, blacklist) + } - result_tree.walk(git2::TreeWalkMode::PreOrder, |_, entry| { - let name = entry.name().unwrap(); - if name.starts_with("JOSH_ORIG_PATH_") { - let pathname = josh::from_ns(&name.replacen("JOSH_ORIG_PATH_", "", 1)); - all_paths.push(pathname); - } - git2::TreeWalkResult::Ok - })?; + let updated_refs = josh::filter_ref( + &transaction, + filterobj, + &src, + &t, + permissions_filter, + )?; + if args.value_of("update") != Some("FILTERED_HEAD") && updated_refs == 0 { + println!( + "Warning: reference {} wasn't updated", + args.value_of("update").unwrap() + ); } #[cfg(feature = "search")] @@ -264,39 +281,6 @@ fn run_filter(args: Vec) -> josh::JoshResult { /* println!("\n Search took {:?}", duration); */ } - let mut dedup = vec![]; - - for w in all_paths.as_slice().windows(2) { - if let [a, b, ..] = w { - if !b.starts_with(a) { - dedup.push(a.to_owned()); - } - } - } - - let dedup = all_paths; - - let options = glob::MatchOptions { - case_sensitive: true, - require_literal_separator: true, - require_literal_leading_dot: true, - }; - - if let Some(cp) = args.value_of("check-permission") { - let pattern = glob::Pattern::new(cp)?; - - let mut allowed = !dedup.is_empty(); - for d in dedup.iter() { - let d = std::path::PathBuf::from(d); - let m = pattern.matches_path_with(&d, options); - if !m { - allowed = false; - println!("missing permission for: {:?}", &d); - } - } - println!("Allowed = {:?}", allowed); - } - if reverse { let new = repo.revparse_single(target).unwrap().id(); let old = repo.revparse_single("JOSH_TMP").unwrap().id(); diff --git a/src/filter/mod.rs b/src/filter/mod.rs index 96c96202b..f377b5e2e 100644 --- a/src/filter/mod.rs +++ b/src/filter/mod.rs @@ -33,6 +33,10 @@ pub fn nop() -> Filter { to_filter(Op::Nop) } +pub fn empty() -> Filter { + to_filter(Op::Empty) +} + fn to_filter(op: Op) -> Filter { let s = format!("{:?}", op); let f = Filter( @@ -767,6 +771,20 @@ fn compute_warnings2<'a>( warnings } +pub fn make_permissions_filter(filter: Filter, whitelist: Filter, blacklist: Filter) -> Filter { + rs_tracing::trace_scoped!("make_permissions_filter"); + + let filter = chain(to_filter(Op::Paths), filter); + let filter = chain(filter, to_filter(Op::Invert)); + let filter = chain( + filter, + compose(blacklist, to_filter(Op::Subtract(nop(), whitelist))), + ); + let filter = opt::optimize(filter); + + return filter; +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/housekeeping.rs b/src/housekeeping.rs index 6c98a56c4..b762a5eca 100644 --- a/src/housekeeping.rs +++ b/src/housekeeping.rs @@ -227,7 +227,7 @@ pub fn refresh_known_filters( upstream_repo, ); - updated_count += filter_refs(&t, filter::parse(filter_spec)?, &refs)?; + updated_count += filter_refs(&t, filter::parse(filter_spec)?, &refs, filter::empty())?; } info!("updated {} refs for {:?}", updated_count, upstream_repo); } diff --git a/src/lib.rs b/src/lib.rs index e4d0f44f4..c2b27e686 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -166,12 +166,34 @@ pub fn filter_ref( filterobj: filter::Filter, from_refsname: &str, to_refname: &str, + permissions: filter::Filter, ) -> JoshResult { let mut updated_count = 0; if let Ok(reference) = transaction.repo().revparse_single(from_refsname) { let original_commit = reference.peel_to_commit()?; let oid = original_commit.id(); + let perms_commit = if let Some(s) = transaction.get_ref(permissions, oid) { + s + } else { + tracing::trace!("apply_to_commit (permissions)"); + + filter::apply_to_commit(permissions, &original_commit, &transaction)? + }; + + if perms_commit != git2::Oid::zero() { + let perms_commit = transaction.repo().find_commit(perms_commit)?; + if !perms_commit.tree()?.is_empty() || perms_commit.parents().len() > 0 { + tracing::event!( + tracing::Level::WARN, + msg = "filter_refs: missing permissions for ref", + warn = true, + reference = from_refsname, + ); + return Err(josh_error("missing permissions for ref")); + } + } + let filter_commit = if let Some(s) = transaction.get_ref(filterobj, oid) { s } else { @@ -226,6 +248,7 @@ pub fn filter_refs( transaction: &cache::Transaction, filterobj: filter::Filter, refs: &[(String, String)], + permissions: filter::Filter, ) -> JoshResult { rs_tracing::trace_scoped!("filter_refs", "spec": filter::spec(filterobj)); let s = tracing::Span::current(); @@ -235,7 +258,7 @@ pub fn filter_refs( let mut updated_count = 0; for (k, v) in refs { - updated_count += ok_or!(filter_ref(transaction, filterobj, k, v), { + updated_count += ok_or!(filter_ref(&transaction, filterobj, &k, &v, permissions), { tracing::event!( tracing::Level::WARN, msg = "filter_refs: Can't filter reference", diff --git a/tests/filter/empty_head.t b/tests/filter/empty_head.t index 35385debf..a139652cd 100644 --- a/tests/filter/empty_head.t +++ b/tests/filter/empty_head.t @@ -35,6 +35,7 @@ $ git commit -m "add file5" 1> /dev/null $ josh-filter -s :/sub2 master --update refs/josh/filter/master + Warning: reference refs/josh/filter/master wasn't updated [2] :/sub1 [2] :/sub2 $ git log --graph --pretty=%s josh/filter/master diff --git a/tests/filter/infofile.t b/tests/filter/infofile.t index cf3a99758..45c21ac84 100644 --- a/tests/filter/infofile.t +++ b/tests/filter/infofile.t @@ -30,6 +30,7 @@ * add file1 $ josh-filter -s c=:/sub1 master --update refs/josh/filter/master + Warning: reference refs/josh/filter/master wasn't updated [2] :/sub1 [2] :prefix=c $ git log --graph --pretty=%s josh/filter/master @@ -48,6 +49,7 @@ $ git commit -m "add file5" 1> /dev/null $ josh-filter -s c=:/sub2 master --update refs/josh/filter/master + Warning: reference refs/josh/filter/master wasn't updated [2] :/sub1 [2] :/sub2 [3] :prefix=c diff --git a/tests/filter/permissions.t b/tests/filter/permissions.t index eb1ca2e9b..501491f49 100644 --- a/tests/filter/permissions.t +++ b/tests/filter/permissions.t @@ -260,68 +260,221 @@ 5 directories, 6 files +# default permissions give everything + $ josh-filter -s :/ master --check-permission --update refs/josh/filtered + [1] :/a + [1] :exclude[::c/] + [1] :prefix=x + [3] :/c + [3] :INVERT + [3] :PATHS + [3] :prefix=c + [12] _invert + [16] _paths + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + |-- a + | |-- file_a2 + | `-- workspace.josh + |-- b + | `-- file_b1 + `-- c + `-- d + |-- e + | `-- file_cd3 + |-- file_cd + `-- file_cd2 + + 5 directories, 6 files + +# default same as this + $ josh-filter -s :/ master --check-permission -b :empty -w :nop --update refs/josh/filtered_2 + [1] :/a + [1] :exclude[::c/] + [1] :prefix=x + [3] :/c + [3] :INVERT + [3] :PATHS + [3] :prefix=c + [12] _invert + [16] _paths + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + |-- a + | |-- file_a2 + | `-- workspace.josh + |-- b + | `-- file_b1 + `-- c + `-- d + |-- e + | `-- file_cd3 + |-- file_cd + `-- file_cd2 + + 5 directories, 6 files +# no permissions + $ josh-filter -s :/ master --check-permission -b :nop -w :empty --update refs/josh/filtered + [1] :/a + [1] :exclude[::c/] + [1] :prefix=x + [3] :/c + [3] :INVERT + [3] :PATHS + [3] :prefix=c + [12] _invert + [16] _paths + ERROR: JoshError("missing permissions for ref") + [1] + $ josh-filter -s :/b master --check-permission -w :/a --update refs/josh/filtered + [1] :/b + [1] :exclude[::c/] + [1] :prefix=x + [1] :subtract[ + :/ + :/a + ] + [2] :/a + [3] :/c + [3] :PATHS + [3] :prefix=c + [4] :INVERT + [13] _invert + [16] _paths + ERROR: JoshError("missing permissions for ref") + [1] + $ josh-filter -s :/b master --check-permission -b :/b -w :/b --update refs/josh/filtered + [1] :[ + :/b + :subtract[ + :/ + :/b + ] + ] + [1] :exclude[::c/] + [1] :prefix=x + [1] :subtract[ + :/ + :/a + ] + [1] :subtract[ + :/ + :/b + ] + [2] :/a + [2] :/b + [3] :/c + [3] :PATHS + [3] :prefix=c + [4] :INVERT + [13] _invert + [16] _paths + ERROR: JoshError("missing permissions for ref") + [1] + $ josh-filter -s :/b master --check-permission -w :/b --update refs/josh/filtered + [1] :[ + :/b + :subtract[ + :/ + :/b + ] + ] + [1] :exclude[::c/] + [1] :prefix=x + [1] :subtract[ + :/ + :/a + ] + [1] :subtract[ + :/ + :/b + ] + [2] :/a + [3] :/b + [3] :/c + [3] :PATHS + [3] :prefix=c + [4] :INVERT + [13] _invert + [16] _paths + $ git diff $EMPTY_TREE HEAD diff --git a/a/file_a2 b/a/file_a2 new file mode 100644 - index 0000000..4b2f88e + index 0000000..a024003 --- /dev/null +++ b/a/file_a2 @@ -0,0 +1 @@ - +a/file_a2 - \ No newline at end of file + +contents1 diff --git a/a/workspace.josh b/a/workspace.josh new file mode 100644 - index 0000000..b5fbe37 + index 0000000..3af54d0 --- /dev/null +++ b/a/workspace.josh @@ -0,0 +1 @@ - +a/workspace.josh - \ No newline at end of file + +cws = :/c diff --git a/b/file_b1 b/b/file_b1 new file mode 100644 - index 0000000..413b4ca + index 0000000..a024003 --- /dev/null +++ b/b/file_b1 @@ -0,0 +1 @@ - +b/file_b1 - \ No newline at end of file + +contents1 diff --git a/c/d/e/file_cd3 b/c/d/e/file_cd3 new file mode 100644 - index 0000000..8719808 + index 0000000..340d807 --- /dev/null +++ b/c/d/e/file_cd3 - @@ -0,0 +1 @@ - +c/d/e/file_cd3 - \ No newline at end of file + @@ -0,0 +1,2 @@ + +contents2 + +contents3 diff --git a/c/d/file_cd b/c/d/file_cd new file mode 100644 - index 0000000..bb36c67 + index 0000000..a024003 --- /dev/null +++ b/c/d/file_cd @@ -0,0 +1 @@ - +c/d/file_cd - \ No newline at end of file + +contents1 diff --git a/c/d/file_cd2 b/c/d/file_cd2 new file mode 100644 - index 0000000..26318eb + index 0000000..6b46faa --- /dev/null +++ b/c/d/file_cd2 @@ -0,0 +1 @@ - +c/d/file_cd2 - \ No newline at end of file + +contents2 $ josh-filter -s :PATHS:workspace=a:INVERT master --update refs/josh/filtered - [1] :/a + [1] :[ + :/b + :subtract[ + :/ + :/b + ] + ] [1] :exclude[::c/] [1] :prefix=x + [1] :subtract[ + :/ + :/a + ] + [1] :subtract[ + :/ + :/b + ] + [2] :/a + [3] :/b [3] :/c [3] :PATHS [3] :prefix=c [3] :workspace=a - [6] :INVERT + [7] :INVERT [16] _paths - [22] _invert + [23] _invert $ git checkout refs/josh/filtered 2> /dev/null $ tree @@ -381,17 +534,33 @@ \ No newline at end of file $ josh-filter -s :PATHS:FOLD master --update refs/josh/filtered - [1] :/a + [1] :[ + :/b + :subtract[ + :/ + :/b + ] + ] [1] :exclude[::c/] [1] :prefix=x + [1] :subtract[ + :/ + :/a + ] + [1] :subtract[ + :/ + :/b + ] + [2] :/a + [3] :/b [3] :/c [3] :FOLD [3] :PATHS [3] :prefix=c [3] :workspace=a - [6] :INVERT + [7] :INVERT [16] _paths - [22] _invert + [23] _invert @@ -407,17 +576,33 @@ $ git commit -m "add newfile" 1> /dev/null $ josh-filter -s :PATHS master --update refs/josh/filtered - [1] :/a + [1] :[ + :/b + :subtract[ + :/ + :/b + ] + ] [1] :exclude[::c/] [1] :prefix=x + [1] :subtract[ + :/ + :/a + ] + [1] :subtract[ + :/ + :/b + ] + [2] :/a + [3] :/b [3] :/c [3] :FOLD [3] :prefix=c [3] :workspace=a [5] :PATHS - [6] :INVERT + [7] :INVERT [19] _paths - [22] _invert + [23] _invert $ git log --graph --pretty=%s master * add newfile @@ -537,17 +722,33 @@ $ josh-filter -s :PATHS:/c:FOLD master --update refs/josh/filtered - [1] :/a + [1] :[ + :/b + :subtract[ + :/ + :/b + ] + ] [1] :exclude[::c/] [1] :prefix=x + [1] :subtract[ + :/ + :/a + ] + [1] :subtract[ + :/ + :/b + ] + [2] :/a + [3] :/b [3] :prefix=c [3] :workspace=a [4] :/c [5] :PATHS [6] :FOLD - [6] :INVERT + [7] :INVERT [19] _paths - [22] _invert + [23] _invert $ git log --graph --pretty=%s refs/josh/filtered * add file_cd3 @@ -594,17 +795,33 @@ $ josh-filter -s :PATHS:workspace=a:FOLD master --update refs/josh/filtered - [1] :/a + [1] :[ + :/b + :subtract[ + :/ + :/b + ] + ] [1] :exclude[::c/] [1] :prefix=x + [1] :subtract[ + :/ + :/a + ] + [1] :subtract[ + :/ + :/b + ] + [2] :/a + [3] :/b [3] :prefix=c [4] :/c [5] :PATHS [5] :workspace=a - [6] :INVERT + [7] :INVERT [10] :FOLD [19] _paths - [22] _invert + [23] _invert $ git log --graph --pretty=%s refs/josh/filtered * add newfile diff --git a/tests/filter/submodule.t b/tests/filter/submodule.t index fda41c6f9..6f20c01ca 100644 --- a/tests/filter/submodule.t +++ b/tests/filter/submodule.t @@ -27,6 +27,7 @@ [1] :/libs $ git ls-tree --name-only -r refs/josh/filter/master $ josh-filter -s c=:/libs master --update refs/josh/filter/master + Warning: reference refs/josh/filter/master wasn't updated [1] :/libs [1] :prefix=c $ git ls-tree --name-only -r refs/josh/filter/master From a4d3dcdfdcb963619c48f1763b630de87c580e97 Mon Sep 17 00:00:00 2001 From: Louis-Marie Givel Date: Thu, 14 Oct 2021 10:04:47 +0200 Subject: [PATCH 2/6] Add ACL toml file --- src/bin/josh-filter.rs | 45 ++++++++++++++++++++++----- src/lib.rs | 64 ++++++++++++++++++++++++++++++++++++++ tests/filter/permissions.t | 59 ++++++++++++++++++++++++++++++++--- 3 files changed, 155 insertions(+), 13 deletions(-) diff --git a/src/bin/josh-filter.rs b/src/bin/josh-filter.rs index 12461c298..39ac95aea 100644 --- a/src/bin/josh-filter.rs +++ b/src/bin/josh-filter.rs @@ -115,6 +115,24 @@ fn run_filter(args: Vec) -> josh::JoshResult { .short("b") .takes_value(true), ) + .arg( + clap::Arg::with_name("acl") + .long("acl") + .short("a") + .takes_value(true), + ) + .arg( + clap::Arg::with_name("user") + .long("user") + .short("u") + .takes_value(true), + ) + .arg( + clap::Arg::with_name("repo") + .long("repo") + .short("r") + .takes_value(true), + ) .arg(clap::Arg::with_name("version").long("version").short("v")) .get_matches_from(args); @@ -222,14 +240,25 @@ fn run_filter(args: Vec) -> josh::JoshResult { let check_permissions = args.is_present("check-permission"); let mut permissions_filter = josh::filter::empty(); if check_permissions { - let whitelist = match args.value_of("whitelist") { - Some(s) => josh::filter::parse(s)?, - _ => josh::filter::nop(), - }; - let blacklist = match args.value_of("blacklist") { - Some(s) => josh::filter::parse(s)?, - _ => josh::filter::empty(), - }; + let whitelist; + let blacklist; + if args.is_present("acl") && args.is_present("user") && args.is_present("repo") { + let acl = args.value_of("acl").unwrap(); + let user = args.value_of("user").unwrap(); + let repo = args.value_of("repo").unwrap(); + + whitelist = josh::get_whitelist(acl, user, repo)?; + blacklist = josh::get_blacklist(acl, user, repo)?; + } else { + whitelist = match args.value_of("whitelist") { + Some(s) => josh::filter::parse(s)?, + _ => josh::filter::nop(), + }; + blacklist = match args.value_of("blacklist") { + Some(s) => josh::filter::parse(s)?, + _ => josh::filter::empty(), + }; + } permissions_filter = josh::filter::make_permissions_filter(filterobj, whitelist, blacklist) } diff --git a/src/lib.rs b/src/lib.rs index c2b27e686..7e249c983 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -298,3 +298,67 @@ pub fn normalize_path(path: &std::path::Path) -> std::path::PathBuf { } ret } + +#[derive(Debug, serde::Deserialize)] +struct Acl { + pub repo: Vec, +} + +#[derive(Debug, serde::Deserialize)] +struct Repo { + pub name: String, + pub user: Vec, +} + +#[derive(Debug, serde::Deserialize)] +struct User { + pub name: String, + pub whitelist: Option, + pub blacklist: Option, +} + +pub fn get_whitelist(acl: &str, user: &str, repo: &str) -> JoshResult { + let acl = std::fs::read_to_string(acl).map_err(|_| josh_error("failed to read acl file"))?; + let acl: Acl = toml::from_str(&acl) + .map_err(|err| josh_error(format!("failed to parse acl file: {}", err).as_str()))?; + for r in acl.repo { + if r.name == repo { + for u in r.user { + if u.name == user { + match u.whitelist { + Some(w) => { + let filter = filter::parse(&w)?; + return Ok(filter); + } + _ => return Ok(filter::empty()), + } + } + } + } + } + + return Ok(filter::empty()); +} + +pub fn get_blacklist(acl: &str, user: &str, repo: &str) -> JoshResult { + let acl = std::fs::read_to_string(acl).map_err(|_| josh_error("failed to read acl file"))?; + let acl: Acl = toml::from_str(&acl) + .map_err(|err| josh_error(format!("failed to parse acl file: {}", err).as_str()))?; + for r in acl.repo { + if r.name == repo { + for u in r.user { + if u.name == user { + match u.blacklist { + Some(b) => { + let filter = filter::parse(&b)?; + return Ok(filter); + } + _ => return Ok(filter::nop()), + } + } + } + } + } + + return Ok(filter::nop()); +} diff --git a/tests/filter/permissions.t b/tests/filter/permissions.t index 501491f49..c6e5434a2 100644 --- a/tests/filter/permissions.t +++ b/tests/filter/permissions.t @@ -402,6 +402,50 @@ [13] _invert [16] _paths +# acl + $ cat << EOF > acl.toml + > [[repo]] + > name = "test" + > [[repo.user]] + > name = "LMG" + > whitelist = ":/" + > blacklist = ":empty" + > + > EOF + $ josh-filter -s :/ master --check-permission -a acl.toml -u bob -r test --update refs/josh/filtered + Warning: reference refs/josh/filtered wasn't updated + [1] :[ + :/b + :exclude[:/b] + ] + [1] :exclude[:/a] + [1] :exclude[:/b] + [1] :exclude[:/c] + [1] :prefix=x + [2] :/a + [3] :/b + [3] :/c + [3] :PATHS + [4] :INVERT + [13] _invert + [16] _paths + $ josh-filter -s :/ master --check-permission -a acl.toml -u LMG -r test --update refs/josh/filtered + [1] :[ + :/b + :exclude[:/b] + ] + [1] :exclude[:/a] + [1] :exclude[:/b] + [1] :exclude[:/c] + [1] :prefix=x + [2] :/a + [3] :/b + [3] :/c + [3] :PATHS + [4] :INVERT + [13] _invert + [16] _paths + $ git diff $EMPTY_TREE HEAD diff --git a/a/file_a2 b/a/file_a2 new file mode 100644 @@ -482,6 +526,7 @@ |-- a | |-- file_a2 | `-- workspace.josh + |-- acl.toml `-- c `-- d |-- e @@ -489,7 +534,7 @@ |-- file_cd `-- file_cd2 - 4 directories, 5 files + 4 directories, 6 files $ git diff $EMPTY_TREE HEAD diff --git a/a/file_a2 b/a/file_a2 @@ -626,10 +671,11 @@ | |-- file_a2 | |-- newfile | `-- workspace.josh + |-- acl.toml `-- b `-- file_b1 - 2 directories, 4 files + 2 directories, 5 files $ git diff $EMPTY_TREE HEAD diff --git a/a/file_a2 b/a/file_a2 @@ -680,10 +726,11 @@ | |-- file_a2 | |-- newfile | `-- workspace.josh + |-- acl.toml `-- b `-- file_b1 - 2 directories, 4 files + 2 directories, 5 files $ git diff $EMPTY_TREE HEAD diff --git a/a/file_a2 b/a/file_a2 @@ -758,13 +805,14 @@ $ git checkout refs/josh/filtered 2> /dev/null $ tree . + |-- acl.toml `-- d |-- e | `-- file_cd3 |-- file_cd `-- file_cd2 - 2 directories, 3 files + 2 directories, 4 files $ git diff $EMPTY_TREE HEAD diff --git a/d/e/file_cd3 b/d/e/file_cd3 @@ -832,6 +880,7 @@ $ git checkout refs/josh/filtered 2> /dev/null $ tree . + |-- acl.toml |-- cws | `-- d | |-- e @@ -842,7 +891,7 @@ |-- newfile `-- workspace.josh - 3 directories, 6 files + 3 directories, 7 files $ git diff $EMPTY_TREE HEAD diff --git a/cws/d/e/file_cd3 b/cws/d/e/file_cd3 From b80be6d24b7be74eebac190e7547937dfa92f34e Mon Sep 17 00:00:00 2001 From: Louis-Marie Givel Date: Fri, 15 Oct 2021 09:09:11 +0200 Subject: [PATCH 3/6] Make the repo and users keys in ACL --- src/lib.rs | 69 +++++++++++++------------------------- tests/filter/permissions.t | 8 ++--- 2 files changed, 28 insertions(+), 49 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 7e249c983..4ea004c60 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,6 +35,9 @@ extern crate pest_derive; #[macro_use] extern crate serde_json; +use std::collections::HashMap; +use tracing; + pub mod cache; pub mod filter; pub mod graphql; @@ -299,20 +302,10 @@ pub fn normalize_path(path: &std::path::Path) -> std::path::PathBuf { ret } -#[derive(Debug, serde::Deserialize)] -struct Acl { - pub repo: Vec, -} - -#[derive(Debug, serde::Deserialize)] -struct Repo { - pub name: String, - pub user: Vec, -} +type Acl = HashMap>; #[derive(Debug, serde::Deserialize)] struct User { - pub name: String, pub whitelist: Option, pub blacklist: Option, } @@ -321,44 +314,30 @@ pub fn get_whitelist(acl: &str, user: &str, repo: &str) -> JoshResult { - let filter = filter::parse(&w)?; - return Ok(filter); - } - _ => return Ok(filter::empty()), - } - } - } - } - } - - return Ok(filter::empty()); + return Ok(match acl.get(repo) { + Some(r) => match r.get(user) { + Some(u) => match &u.whitelist { + Some(w) => filter::parse(&w)?, + _ => filter::nop(), + }, + _ => filter::empty(), + }, + _ => filter::empty(), + }); } pub fn get_blacklist(acl: &str, user: &str, repo: &str) -> JoshResult { let acl = std::fs::read_to_string(acl).map_err(|_| josh_error("failed to read acl file"))?; let acl: Acl = toml::from_str(&acl) .map_err(|err| josh_error(format!("failed to parse acl file: {}", err).as_str()))?; - for r in acl.repo { - if r.name == repo { - for u in r.user { - if u.name == user { - match u.blacklist { - Some(b) => { - let filter = filter::parse(&b)?; - return Ok(filter); - } - _ => return Ok(filter::nop()), - } - } - } - } - } - - return Ok(filter::nop()); + return Ok(match acl.get(repo) { + Some(r) => match r.get(user) { + Some(u) => match &u.blacklist { + Some(b) => filter::parse(&b)?, + _ => filter::empty(), + }, + _ => filter::nop(), + }, + _ => filter::nop(), + }); } diff --git a/tests/filter/permissions.t b/tests/filter/permissions.t index c6e5434a2..b364c0b55 100644 --- a/tests/filter/permissions.t +++ b/tests/filter/permissions.t @@ -404,14 +404,13 @@ # acl $ cat << EOF > acl.toml - > [[repo]] - > name = "test" - > [[repo.user]] - > name = "LMG" + > [test] + > [test.LMG] > whitelist = ":/" > blacklist = ":empty" > > EOF +# doesn't work $ josh-filter -s :/ master --check-permission -a acl.toml -u bob -r test --update refs/josh/filtered Warning: reference refs/josh/filtered wasn't updated [1] :[ @@ -429,6 +428,7 @@ [4] :INVERT [13] _invert [16] _paths +# works $ josh-filter -s :/ master --check-permission -a acl.toml -u LMG -r test --update refs/josh/filtered [1] :[ :/b From b53ff150ea2053e23598748f47c9acbd5a093793 Mon Sep 17 00:00:00 2001 From: Louis-Marie Givel Date: Tue, 19 Oct 2021 14:43:46 +0200 Subject: [PATCH 4/6] Add access groups --- src/bin/josh-filter.rs | 24 +++++++---- src/lib.rs | 82 ++++++++++++++++++++++++-------------- tests/filter/permissions.t | 70 ++++++++++++++++++-------------- 3 files changed, 107 insertions(+), 69 deletions(-) diff --git a/src/bin/josh-filter.rs b/src/bin/josh-filter.rs index 39ac95aea..afbd240a8 100644 --- a/src/bin/josh-filter.rs +++ b/src/bin/josh-filter.rs @@ -116,9 +116,13 @@ fn run_filter(args: Vec) -> josh::JoshResult { .takes_value(true), ) .arg( - clap::Arg::with_name("acl") - .long("acl") - .short("a") + clap::Arg::with_name("users") + .long("users") + .takes_value(true), + ) + .arg( + clap::Arg::with_name("groups") + .long("groups") .takes_value(true), ) .arg( @@ -242,13 +246,19 @@ fn run_filter(args: Vec) -> josh::JoshResult { if check_permissions { let whitelist; let blacklist; - if args.is_present("acl") && args.is_present("user") && args.is_present("repo") { - let acl = args.value_of("acl").unwrap(); + if args.is_present("users") + && args.is_present("groups") + && args.is_present("user") + && args.is_present("repo") + { + let users = args.value_of("users").unwrap(); + let groups = args.value_of("groups").unwrap(); let user = args.value_of("user").unwrap(); let repo = args.value_of("repo").unwrap(); - whitelist = josh::get_whitelist(acl, user, repo)?; - blacklist = josh::get_blacklist(acl, user, repo)?; + let acl = josh::get_acl(users, groups, user, repo)?; + whitelist = acl.0; + blacklist = acl.1; } else { whitelist = match args.value_of("whitelist") { Some(s) => josh::filter::parse(s)?, diff --git a/src/lib.rs b/src/lib.rs index 4ea004c60..25b3512fa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -302,42 +302,62 @@ pub fn normalize_path(path: &std::path::Path) -> std::path::PathBuf { ret } -type Acl = HashMap>; +type Users = HashMap; #[derive(Debug, serde::Deserialize)] struct User { - pub whitelist: Option, - pub blacklist: Option, + pub groups: toml::value::Array, } -pub fn get_whitelist(acl: &str, user: &str, repo: &str) -> JoshResult { - let acl = std::fs::read_to_string(acl).map_err(|_| josh_error("failed to read acl file"))?; - let acl: Acl = toml::from_str(&acl) - .map_err(|err| josh_error(format!("failed to parse acl file: {}", err).as_str()))?; - return Ok(match acl.get(repo) { - Some(r) => match r.get(user) { - Some(u) => match &u.whitelist { - Some(w) => filter::parse(&w)?, - _ => filter::nop(), - }, - _ => filter::empty(), - }, - _ => filter::empty(), - }); +type Groups = HashMap>; +#[derive(Debug, serde::Deserialize)] +struct Group { + pub whitelist: String, + pub blacklist: String, } -pub fn get_blacklist(acl: &str, user: &str, repo: &str) -> JoshResult { - let acl = std::fs::read_to_string(acl).map_err(|_| josh_error("failed to read acl file"))?; - let acl: Acl = toml::from_str(&acl) - .map_err(|err| josh_error(format!("failed to parse acl file: {}", err).as_str()))?; - return Ok(match acl.get(repo) { - Some(r) => match r.get(user) { - Some(u) => match &u.blacklist { - Some(b) => filter::parse(&b)?, - _ => filter::empty(), - }, - _ => filter::nop(), - }, - _ => filter::nop(), - }); +pub fn get_acl( + users: &str, + groups: &str, + user: &str, + repo: &str, +) -> JoshResult<(filter::Filter, filter::Filter)> { + let users = + std::fs::read_to_string(users).map_err(|_| josh_error("failed to read users file"))?; + let users: Users = toml::from_str(&users) + .map_err(|err| josh_error(format!("failed to parse users file: {}", err).as_str()))?; + let groups = + std::fs::read_to_string(groups).map_err(|_| josh_error("failed to read groups file"))?; + let groups: Groups = toml::from_str(&groups) + .map_err(|err| josh_error(format!("failed to parse groups file: {}", err).as_str()))?; + + return users + .get(user) + .and_then(|u| { + let mut whitelist = filter::nop(); + let mut blacklist = filter::empty(); + for g in &u.groups { + let group_lists = groups.get(g.as_str()?).and_then(|group| { + group.get(repo).and_then(|repo| { + let w = filter::parse(&repo.whitelist); + let b = filter::parse(&repo.blacklist); + Some((w, b)) + }) + })?; + if let Err(e) = group_lists.0 { + return Some(Err(JoshError(format!("Error parsing whitelist: {}", e)))); + } + if let Err(e) = group_lists.1 { + return Some(Err(JoshError(format!("Error parsing blacklist: {}", e)))); + } + if let Ok(w) = group_lists.0 { + whitelist = filter::compose(whitelist, w); + } + if let Ok(b) = group_lists.1 { + blacklist = filter::compose(blacklist, b); + } + } + Some(Ok((whitelist, blacklist))) + }) + .unwrap_or(Ok((filter::empty(), filter::nop()))); } diff --git a/tests/filter/permissions.t b/tests/filter/permissions.t index b364c0b55..cc81cbf90 100644 --- a/tests/filter/permissions.t +++ b/tests/filter/permissions.t @@ -403,15 +403,18 @@ [16] _paths # acl - $ cat << EOF > acl.toml - > [test] - > [test.LMG] + $ cat << EOF > users.toml + > [LMG] + > groups = ["dev"] + > EOF + $ cat << EOF > groups.toml + > [dev] + > [dev.test] > whitelist = ":/" > blacklist = ":empty" - > > EOF # doesn't work - $ josh-filter -s :/ master --check-permission -a acl.toml -u bob -r test --update refs/josh/filtered + $ josh-filter -s :/ master --check-permission --users users.toml --groups groups.toml -u bob -r test --update refs/josh/filtered Warning: reference refs/josh/filtered wasn't updated [1] :[ :/b @@ -429,7 +432,7 @@ [13] _invert [16] _paths # works - $ josh-filter -s :/ master --check-permission -a acl.toml -u LMG -r test --update refs/josh/filtered + $ josh-filter -s :/ master --check-permission --users users.toml --groups groups.toml -u LMG -r test --update refs/josh/filtered [1] :[ :/b :exclude[:/b] @@ -526,15 +529,16 @@ |-- a | |-- file_a2 | `-- workspace.josh - |-- acl.toml - `-- c - `-- d - |-- e - | `-- file_cd3 - |-- file_cd - `-- file_cd2 + |-- c + | `-- d + | |-- e + | | `-- file_cd3 + | |-- file_cd + | `-- file_cd2 + |-- groups.toml + `-- users.toml - 4 directories, 6 files + 4 directories, 7 files $ git diff $EMPTY_TREE HEAD diff --git a/a/file_a2 b/a/file_a2 @@ -671,11 +675,12 @@ | |-- file_a2 | |-- newfile | `-- workspace.josh - |-- acl.toml - `-- b - `-- file_b1 + |-- b + | `-- file_b1 + |-- groups.toml + `-- users.toml - 2 directories, 5 files + 2 directories, 6 files $ git diff $EMPTY_TREE HEAD diff --git a/a/file_a2 b/a/file_a2 @@ -726,11 +731,12 @@ | |-- file_a2 | |-- newfile | `-- workspace.josh - |-- acl.toml - `-- b - `-- file_b1 + |-- b + | `-- file_b1 + |-- groups.toml + `-- users.toml - 2 directories, 5 files + 2 directories, 6 files $ git diff $EMPTY_TREE HEAD diff --git a/a/file_a2 b/a/file_a2 @@ -805,14 +811,15 @@ $ git checkout refs/josh/filtered 2> /dev/null $ tree . - |-- acl.toml - `-- d - |-- e - | `-- file_cd3 - |-- file_cd - `-- file_cd2 + |-- d + | |-- e + | | `-- file_cd3 + | |-- file_cd + | `-- file_cd2 + |-- groups.toml + `-- users.toml - 2 directories, 4 files + 2 directories, 5 files $ git diff $EMPTY_TREE HEAD diff --git a/d/e/file_cd3 b/d/e/file_cd3 @@ -880,7 +887,6 @@ $ git checkout refs/josh/filtered 2> /dev/null $ tree . - |-- acl.toml |-- cws | `-- d | |-- e @@ -888,10 +894,12 @@ | |-- file_cd | `-- file_cd2 |-- file_a2 + |-- groups.toml |-- newfile + |-- users.toml `-- workspace.josh - 3 directories, 7 files + 3 directories, 8 files $ git diff $EMPTY_TREE HEAD diff --git a/cws/d/e/file_cd3 b/cws/d/e/file_cd3 From 6fcc82054b2b1156b39497152daa8aad7a1ca3f3 Mon Sep 17 00:00:00 2001 From: Louis-Marie Givel Date: Sat, 23 Oct 2021 17:23:05 +0200 Subject: [PATCH 5/6] Move to YAML --- src/bin/josh-filter.rs | 15 +- src/filter/mod.rs | 1 + src/lib.rs | 25 +- tests/filter/permissions.t | 676 ++++++++++++++++++++++++++++++------- 4 files changed, 581 insertions(+), 136 deletions(-) diff --git a/src/bin/josh-filter.rs b/src/bin/josh-filter.rs index afbd240a8..795704c19 100644 --- a/src/bin/josh-filter.rs +++ b/src/bin/josh-filter.rs @@ -103,6 +103,7 @@ fn run_filter(args: Vec) -> josh::JoshResult { .long("check-permission") .short("c"), ) + .arg(clap::Arg::with_name("missing-permission").long("missing-permission")) .arg( clap::Arg::with_name("whitelist") .long("whitelist") @@ -272,13 +273,13 @@ fn run_filter(args: Vec) -> josh::JoshResult { permissions_filter = josh::filter::make_permissions_filter(filterobj, whitelist, blacklist) } - let updated_refs = josh::filter_ref( - &transaction, - filterobj, - &src, - &t, - permissions_filter, - )?; + let missing_permissions = args.is_present("missing-permission"); + if missing_permissions { + filterobj = permissions_filter; + permissions_filter = josh::filter::empty(); + } + + let updated_refs = josh::filter_ref(&transaction, filterobj, &src, &t, permissions_filter)?; if args.value_of("update") != Some("FILTERED_HEAD") && updated_refs == 0 { println!( "Warning: reference {} wasn't updated", diff --git a/src/filter/mod.rs b/src/filter/mod.rs index f377b5e2e..e8500f732 100644 --- a/src/filter/mod.rs +++ b/src/filter/mod.rs @@ -29,6 +29,7 @@ impl std::fmt::Debug for Filter { return to_op(*self).fmt(f); } } + pub fn nop() -> Filter { to_filter(Op::Nop) } diff --git a/src/lib.rs b/src/lib.rs index 25b3512fa..826860be0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -180,6 +180,7 @@ pub fn filter_ref( s } else { tracing::trace!("apply_to_commit (permissions)"); + println!("perm {:?}", permissions); filter::apply_to_commit(permissions, &original_commit, &transaction)? }; @@ -197,6 +198,7 @@ pub fn filter_ref( } } + println!("filter {:?}", filterobj); let filter_commit = if let Some(s) = transaction.get_ref(filterobj, oid) { s } else { @@ -324,39 +326,40 @@ pub fn get_acl( ) -> JoshResult<(filter::Filter, filter::Filter)> { let users = std::fs::read_to_string(users).map_err(|_| josh_error("failed to read users file"))?; - let users: Users = toml::from_str(&users) + let users: Users = serde_yaml::from_str(&users) .map_err(|err| josh_error(format!("failed to parse users file: {}", err).as_str()))?; let groups = std::fs::read_to_string(groups).map_err(|_| josh_error("failed to read groups file"))?; - let groups: Groups = toml::from_str(&groups) + let groups: Groups = serde_yaml::from_str(&groups) .map_err(|err| josh_error(format!("failed to parse groups file: {}", err).as_str()))?; return users .get(user) .and_then(|u| { - let mut whitelist = filter::nop(); + let mut whitelist = filter::empty(); let mut blacklist = filter::empty(); for g in &u.groups { - let group_lists = groups.get(g.as_str()?).and_then(|group| { - group.get(repo).and_then(|repo| { - let w = filter::parse(&repo.whitelist); - let b = filter::parse(&repo.blacklist); + let lists = groups.get(repo).and_then(|repo| { + repo.get(g.as_str()?).and_then(|group| { + let w = filter::parse(&group.whitelist); + let b = filter::parse(&group.blacklist); Some((w, b)) }) })?; - if let Err(e) = group_lists.0 { + if let Err(e) = lists.0 { return Some(Err(JoshError(format!("Error parsing whitelist: {}", e)))); } - if let Err(e) = group_lists.1 { + if let Err(e) = lists.1 { return Some(Err(JoshError(format!("Error parsing blacklist: {}", e)))); } - if let Ok(w) = group_lists.0 { + if let Ok(w) = lists.0 { whitelist = filter::compose(whitelist, w); } - if let Ok(b) = group_lists.1 { + if let Ok(b) = lists.1 { blacklist = filter::compose(blacklist, b); } } + println!("w: {:?}, b: {:?}", whitelist, blacklist); Some(Ok((whitelist, blacklist))) }) .unwrap_or(Ok((filter::empty(), filter::nop()))); diff --git a/tests/filter/permissions.t b/tests/filter/permissions.t index cc81cbf90..2986e2824 100644 --- a/tests/filter/permissions.t +++ b/tests/filter/permissions.t @@ -37,6 +37,8 @@ * add dirs $ josh-filter -s :PATHS master --update refs/josh/filtered + perm Empty + filter Paths [3] :PATHS [16] _paths @@ -115,6 +117,8 @@ $ josh-filter -s :PATHS:/c master --update refs/josh/filtered + perm Empty + filter Chain(Paths, Subdir("c")) [3] :/c [3] :PATHS [16] _paths @@ -164,6 +168,8 @@ $ josh-filter -s :PATHS:/a master --update refs/josh/filtered + perm Empty + filter Chain(Paths, Subdir("a")) [1] :/a [3] :/c [3] :PATHS @@ -182,6 +188,8 @@ $ josh-filter -s :PATHS:exclude[::c/]:prefix=x master --update refs/josh/filtered + perm Empty + filter Chain(Paths, Chain(Exclude(Chain(Subdir("c"), Prefix("c"))), Prefix("x"))) [1] :/a [1] :exclude[::c/] [1] :prefix=x @@ -233,6 +241,8 @@ $ josh-filter -s :PATHS:INVERT master --update refs/josh/filtered + perm Empty + filter Chain(Paths, Invert) [1] :/a [1] :exclude[::c/] [1] :prefix=x @@ -259,9 +269,16 @@ `-- file_cd2 5 directories, 6 files + $ cat a/file_a2 + a/file_a2 (no-eol) + $ cat b/file_b1 + b/file_b1 (no-eol) + # default permissions give everything $ josh-filter -s :/ master --check-permission --update refs/josh/filtered + perm Empty + filter Nop [1] :/a [1] :exclude[::c/] [1] :prefix=x @@ -289,8 +306,11 @@ 5 directories, 6 files + # default same as this $ josh-filter -s :/ master --check-permission -b :empty -w :nop --update refs/josh/filtered_2 + perm Empty + filter Nop [1] :/a [1] :exclude[::c/] [1] :prefix=x @@ -317,8 +337,11 @@ `-- file_cd2 5 directories, 6 files + + # no permissions $ josh-filter -s :/ master --check-permission -b :nop -w :empty --update refs/josh/filtered + perm Chain(Paths, Invert) [1] :/a [1] :exclude[::c/] [1] :prefix=x @@ -330,13 +353,14 @@ [16] _paths ERROR: JoshError("missing permissions for ref") [1] - $ josh-filter -s :/b master --check-permission -w :/a --update refs/josh/filtered + $ josh-filter -s :/b master --check-permission -w ::a/ --update refs/josh/filtered + perm Chain(Paths, Chain(Subdir("b"), Chain(Invert, Subtract(Nop, Chain(Subdir("a"), Prefix("a")))))) [1] :/b [1] :exclude[::c/] [1] :prefix=x [1] :subtract[ :/ - :/a + ::a/ ] [2] :/a [3] :/c @@ -347,23 +371,27 @@ [16] _paths ERROR: JoshError("missing permissions for ref") [1] - $ josh-filter -s :/b master --check-permission -b :/b -w :/b --update refs/josh/filtered + + + $ josh-filter -s :/b master --check-permission -b ::b/ -w ::b/ --update refs/josh/filtered + perm Chain(Paths, Chain(Subdir("b"), Chain(Invert, Compose([Chain(Subdir("b"), Prefix("b")), Subtract(Nop, Chain(Subdir("b"), Prefix("b")))])))) [1] :[ - :/b + ::b/ :subtract[ :/ - :/b + ::b/ ] ] [1] :exclude[::c/] + [1] :prefix=b [1] :prefix=x [1] :subtract[ :/ - :/a + ::a/ ] [1] :subtract[ :/ - :/b + ::b/ ] [2] :/a [2] :/b @@ -375,23 +403,29 @@ [16] _paths ERROR: JoshError("missing permissions for ref") [1] - $ josh-filter -s :/b master --check-permission -w :/b --update refs/josh/filtered + + +# access granted + $ josh-filter -s :/b master --check-permission -w ::b/ --update refs/josh/filtered + perm Chain(Paths, Chain(Subdir("b"), Chain(Invert, Subtract(Nop, Chain(Subdir("b"), Prefix("b")))))) + filter Subdir("b") [1] :[ - :/b + ::b/ :subtract[ :/ - :/b + ::b/ ] ] [1] :exclude[::c/] + [1] :prefix=b [1] :prefix=x [1] :subtract[ :/ - :/a + ::a/ ] [1] :subtract[ :/ - :/b + ::b/ ] [2] :/a [3] :/b @@ -402,126 +436,456 @@ [13] _invert [16] _paths + # acl - $ cat << EOF > users.toml - > [LMG] - > groups = ["dev"] + $ cat << EOF > users.yaml + > LMG: + > groups: ["dev"] + > CSchilling: + > groups: ["dev2"] > EOF - $ cat << EOF > groups.toml - > [dev] - > [dev.test] - > whitelist = ":/" - > blacklist = ":empty" + $ cat << EOF > groups.yaml + > test: + > dev: + > whitelist: ":/" + > blacklist: ":empty" + > dev2: + > blacklist: ":empty" + > whitelist: | + > :[ + > ::b/ + > ::a/ + > ] > EOF + # doesn't work - $ josh-filter -s :/ master --check-permission --users users.toml --groups groups.toml -u bob -r test --update refs/josh/filtered - Warning: reference refs/josh/filtered wasn't updated + $ josh-filter -s :/ master --check-permission --users users.yaml --groups groups.yaml -u CSchilling -r test --update refs/josh/filtered + w: Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))]), b: Empty + perm Chain(Paths, Chain(Invert, Subtract(Nop, Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))])))) [1] :[ - :/b - :exclude[:/b] + ::a/ + ::b/ ] - [1] :exclude[:/a] - [1] :exclude[:/b] - [1] :exclude[:/c] + [1] :[ + ::b/ + :subtract[ + :/ + ::b/ + ] + ] + [1] :exclude[::c/] + [1] :prefix=a [1] :prefix=x - [2] :/a - [3] :/b + [1] :subtract[ + :/ + ::a/ + ] + [1] :subtract[ + :/ + ::b/ + ] + [2] :prefix=b + [3] :/a [3] :/c [3] :PATHS + [3] :prefix=c + [3] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [4] :/b [4] :INVERT [13] _invert [16] _paths -# works - $ josh-filter -s :/ master --check-permission --users users.toml --groups groups.toml -u LMG -r test --update refs/josh/filtered + ERROR: JoshError("missing permissions for ref") + [1] + + $ josh-filter -s :/ master --check-permission --missing-permission --users users.yaml --groups groups.yaml -u CSchilling -r test --update refs/josh/filtered + w: Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))]), b: Empty + perm Empty + filter Chain(Paths, Chain(Invert, Subtract(Nop, Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))])))) [1] :[ - :/b - :exclude[:/b] + ::a/ + ::b/ + ] + [1] :[ + ::b/ + :subtract[ + :/ + ::b/ + ] ] - [1] :exclude[:/a] - [1] :exclude[:/b] - [1] :exclude[:/c] + [1] :exclude[::c/] + [1] :prefix=a [1] :prefix=x - [2] :/a - [3] :/b + [1] :subtract[ + :/ + ::a/ + ] + [1] :subtract[ + :/ + ::b/ + ] + [2] :prefix=b + [3] :/a [3] :/c [3] :PATHS + [3] :prefix=c + [3] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [4] :/b [4] :INVERT [13] _invert [16] _paths + $ git checkout refs/josh/filtered + Previous HEAD position was f69915b edit file_cd3 + HEAD is now at c6749dc add file_cd3 + $ tree + . + |-- c + | `-- d + | |-- e + | | `-- file_cd3 + | |-- file_cd + | `-- file_cd2 + |-- groups.yaml + `-- users.yaml + + 3 directories, 5 files + $ cat b/file_b1 + cat: b/file_b1: No such file or directory + [1] + $ git log + commit c6749dc54b9f93d87e04e89900c0ca1e730c0ca4 + Author: Josh + Date: Thu Apr 7 22:13:13 2005 +0000 + + add file_cd3 + + commit 58bed947100bda96f7b2a90df2623e1cdee685e5 + Author: Josh + Date: Thu Apr 7 22:13:13 2005 +0000 + + add file_cd2 + + commit 838b5164aff95c891164bfc0ed8611dc008c39ea + Author: Josh + Date: Thu Apr 7 22:13:13 2005 +0000 + + add dirs + +# works + $ josh-filter -s :[:/b,:/a] master --check-permission --users users.yaml --groups groups.yaml -u CSchilling -r test --update refs/josh/filtered + w: Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))]), b: Empty + perm Chain(Paths, Chain(Compose([Subdir("b"), Subdir("a")]), Chain(Invert, Subtract(Nop, Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))]))))) + filter Compose([Subdir("b"), Subdir("a")]) + [1] :[ + ::b/ + :subtract[ + :/ + ::b/ + ] + ] + [1] :exclude[::c/] + [1] :prefix=x + [1] :subtract[ + :/ + ::a/ + ] + [1] :subtract[ + :/ + ::b/ + ] + [2] :[ + :/b + :/a + ] + [2] :[ + ::a/ + ::b/ + ] + [2] :prefix=a + [2] :prefix=b + [3] :/c + [3] :PATHS + [3] :prefix=c + [4] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [5] :/a + [5] :/b + [5] :INVERT + [14] _invert + [16] _paths + $ git checkout refs/josh/filtered + Warning: you are leaving 3 commits behind, not connected to + any of your branches: + + c6749dc add file_cd3 + 58bed94 add file_cd2 + 838b516 add dirs + + If you want to keep them by creating a new branch, this may be a good time + to do so with: + + git branch c6749dc + + HEAD is now at b2040aa add dirs + $ tree + . + |-- file_a2 + |-- file_b1 + |-- groups.yaml + |-- users.yaml + `-- workspace.josh + + 0 directories, 5 files + $ cat b/file_b1 + cat: b/file_b1: No such file or directory + [1] + $ josh-filter -s :[:/b,:/a] master --check-permission --missing-permission --users users.yaml --groups groups.yaml -u CSchilling -r test --update refs/josh/filtered + w: Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))]), b: Empty + perm Empty + filter Chain(Paths, Chain(Compose([Subdir("b"), Subdir("a")]), Chain(Invert, Subtract(Nop, Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))]))))) + [1] :[ + ::b/ + :subtract[ + :/ + ::b/ + ] + ] + [1] :exclude[::c/] + [1] :prefix=x + [1] :subtract[ + :/ + ::a/ + ] + [1] :subtract[ + :/ + ::b/ + ] + [2] :[ + :/b + :/a + ] + [2] :[ + ::a/ + ::b/ + ] + [2] :prefix=a + [2] :prefix=b + [3] :/c + [3] :PATHS + [3] :prefix=c + [4] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [5] :/a + [5] :/b + [5] :INVERT + [14] _invert + [16] _paths + $ git checkout refs/josh/filtered + HEAD is now at b2040aa add dirs + $ tree + . + |-- file_a2 + |-- file_b1 + |-- groups.yaml + |-- users.yaml + `-- workspace.josh + + 0 directories, 5 files + $ git log + commit b2040aafa2d613696e8e0740cd3debd555550c1a + Author: Josh + Date: Thu Apr 7 22:13:13 2005 +0000 + + add dirs + $ cat b/file_b1 + cat: b/file_b1: No such file or directory + [1] +# doesn't work + $ josh-filter -s :/ master --check-permission --users users.yaml --groups groups.yaml -u bob -r test --update refs/josh/filtered + perm Chain(Paths, Invert) + [1] :[ + ::b/ + :subtract[ + :/ + ::b/ + ] + ] + [1] :exclude[::c/] + [1] :prefix=x + [1] :subtract[ + :/ + ::a/ + ] + [1] :subtract[ + :/ + ::b/ + ] + [2] :[ + :/b + :/a + ] + [2] :[ + ::a/ + ::b/ + ] + [2] :prefix=a + [2] :prefix=b + [3] :/c + [3] :PATHS + [3] :prefix=c + [4] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [5] :/a + [5] :/b + [5] :INVERT + [14] _invert + [16] _paths + ERROR: JoshError("missing permissions for ref") + [1] +# works + $ josh-filter -s :/ master --check-permission --users users.yaml --groups groups.yaml -u LMG -r test --update refs/josh/filtered + w: Nop, b: Empty + perm Empty + filter Nop + [1] :[ + ::b/ + :subtract[ + :/ + ::b/ + ] + ] + [1] :exclude[::c/] + [1] :prefix=x + [1] :subtract[ + :/ + ::a/ + ] + [1] :subtract[ + :/ + ::b/ + ] + [2] :[ + :/b + :/a + ] + [2] :[ + ::a/ + ::b/ + ] + [2] :prefix=a + [2] :prefix=b + [3] :/c + [3] :PATHS + [3] :prefix=c + [4] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [5] :/a + [5] :/b + [5] :INVERT + [14] _invert + [16] _paths $ git diff $EMPTY_TREE HEAD - diff --git a/a/file_a2 b/a/file_a2 - new file mode 100644 - index 0000000..a024003 - --- /dev/null - +++ b/a/file_a2 - @@ -0,0 +1 @@ - +contents1 - diff --git a/a/workspace.josh b/a/workspace.josh - new file mode 100644 - index 0000000..3af54d0 - --- /dev/null - +++ b/a/workspace.josh - @@ -0,0 +1 @@ - +cws = :/c - diff --git a/b/file_b1 b/b/file_b1 + diff --git a/file_a2 b/file_a2 new file mode 100644 index 0000000..a024003 --- /dev/null - +++ b/b/file_b1 + +++ b/file_a2 @@ -0,0 +1 @@ +contents1 - diff --git a/c/d/e/file_cd3 b/c/d/e/file_cd3 - new file mode 100644 - index 0000000..340d807 - --- /dev/null - +++ b/c/d/e/file_cd3 - @@ -0,0 +1,2 @@ - +contents2 - +contents3 - diff --git a/c/d/file_cd b/c/d/file_cd + diff --git a/file_b1 b/file_b1 new file mode 100644 index 0000000..a024003 --- /dev/null - +++ b/c/d/file_cd + +++ b/file_b1 @@ -0,0 +1 @@ +contents1 - diff --git a/c/d/file_cd2 b/c/d/file_cd2 + diff --git a/workspace.josh b/workspace.josh new file mode 100644 - index 0000000..6b46faa + index 0000000..3af54d0 --- /dev/null - +++ b/c/d/file_cd2 + +++ b/workspace.josh @@ -0,0 +1 @@ - +contents2 + +cws = :/c $ josh-filter -s :PATHS:workspace=a:INVERT master --update refs/josh/filtered + perm Empty + filter Chain(Paths, Chain(Workspace("a"), Invert)) [1] :[ - :/b + ::b/ :subtract[ :/ - :/b + ::b/ ] ] [1] :exclude[::c/] [1] :prefix=x [1] :subtract[ :/ - :/a + ::a/ ] [1] :subtract[ :/ - :/b + ::b/ ] - [2] :/a - [3] :/b + [2] :[ + :/b + :/a + ] + [2] :[ + ::a/ + ::b/ + ] + [2] :prefix=a + [2] :prefix=b [3] :/c [3] :PATHS [3] :prefix=c [3] :workspace=a - [7] :INVERT + [4] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [5] :/a + [5] :/b + [8] :INVERT [16] _paths - [23] _invert + [24] _invert $ git checkout refs/josh/filtered 2> /dev/null $ tree @@ -535,8 +899,8 @@ | | `-- file_cd3 | |-- file_cd | `-- file_cd2 - |-- groups.toml - `-- users.toml + |-- groups.yaml + `-- users.yaml 4 directories, 7 files @@ -583,33 +947,52 @@ \ No newline at end of file $ josh-filter -s :PATHS:FOLD master --update refs/josh/filtered + perm Empty + filter Chain(Paths, Fold) [1] :[ - :/b + ::b/ :subtract[ :/ - :/b + ::b/ ] ] [1] :exclude[::c/] [1] :prefix=x [1] :subtract[ :/ - :/a + ::a/ ] [1] :subtract[ :/ - :/b + ::b/ ] - [2] :/a - [3] :/b + [2] :[ + :/b + :/a + ] + [2] :[ + ::a/ + ::b/ + ] + [2] :prefix=a + [2] :prefix=b [3] :/c [3] :FOLD [3] :PATHS [3] :prefix=c [3] :workspace=a - [7] :INVERT + [4] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [5] :/a + [5] :/b + [8] :INVERT [16] _paths - [23] _invert + [24] _invert @@ -625,33 +1008,52 @@ $ git commit -m "add newfile" 1> /dev/null $ josh-filter -s :PATHS master --update refs/josh/filtered + perm Empty + filter Paths [1] :[ - :/b + ::b/ :subtract[ :/ - :/b + ::b/ ] ] [1] :exclude[::c/] [1] :prefix=x [1] :subtract[ :/ - :/a + ::a/ ] [1] :subtract[ :/ - :/b + ::b/ ] - [2] :/a - [3] :/b + [2] :[ + :/b + :/a + ] + [2] :[ + ::a/ + ::b/ + ] + [2] :prefix=a + [2] :prefix=b [3] :/c [3] :FOLD [3] :prefix=c [3] :workspace=a + [4] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [5] :/a + [5] :/b [5] :PATHS - [7] :INVERT + [8] :INVERT [19] _paths - [23] _invert + [24] _invert $ git log --graph --pretty=%s master * add newfile @@ -677,8 +1079,8 @@ | `-- workspace.josh |-- b | `-- file_b1 - |-- groups.toml - `-- users.toml + |-- groups.yaml + `-- users.yaml 2 directories, 6 files @@ -733,8 +1135,8 @@ | `-- workspace.josh |-- b | `-- file_b1 - |-- groups.toml - `-- users.toml + |-- groups.yaml + `-- users.yaml 2 directories, 6 files @@ -775,33 +1177,52 @@ $ josh-filter -s :PATHS:/c:FOLD master --update refs/josh/filtered + perm Empty + filter Chain(Paths, Chain(Subdir("c"), Fold)) [1] :[ - :/b + ::b/ :subtract[ :/ - :/b + ::b/ ] ] [1] :exclude[::c/] [1] :prefix=x [1] :subtract[ :/ - :/a + ::a/ ] [1] :subtract[ :/ - :/b + ::b/ ] - [2] :/a - [3] :/b + [2] :[ + :/b + :/a + ] + [2] :[ + ::a/ + ::b/ + ] + [2] :prefix=a + [2] :prefix=b [3] :prefix=c [3] :workspace=a [4] :/c + [4] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [5] :/a + [5] :/b [5] :PATHS [6] :FOLD - [7] :INVERT + [8] :INVERT [19] _paths - [23] _invert + [24] _invert $ git log --graph --pretty=%s refs/josh/filtered * add file_cd3 @@ -816,8 +1237,8 @@ | | `-- file_cd3 | |-- file_cd | `-- file_cd2 - |-- groups.toml - `-- users.toml + |-- groups.yaml + `-- users.yaml 2 directories, 5 files @@ -850,33 +1271,52 @@ $ josh-filter -s :PATHS:workspace=a:FOLD master --update refs/josh/filtered + perm Empty + filter Chain(Paths, Chain(Workspace("a"), Fold)) [1] :[ - :/b + ::b/ :subtract[ :/ - :/b + ::b/ ] ] [1] :exclude[::c/] [1] :prefix=x [1] :subtract[ :/ - :/a + ::a/ ] [1] :subtract[ :/ - :/b + ::b/ ] - [2] :/a - [3] :/b + [2] :[ + :/b + :/a + ] + [2] :[ + ::a/ + ::b/ + ] + [2] :prefix=a + [2] :prefix=b [3] :prefix=c [4] :/c + [4] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [5] :/a + [5] :/b [5] :PATHS [5] :workspace=a - [7] :INVERT + [8] :INVERT [10] :FOLD [19] _paths - [23] _invert + [24] _invert $ git log --graph --pretty=%s refs/josh/filtered * add newfile @@ -894,9 +1334,9 @@ | |-- file_cd | `-- file_cd2 |-- file_a2 - |-- groups.toml + |-- groups.yaml |-- newfile - |-- users.toml + |-- users.yaml `-- workspace.josh 3 directories, 8 files From f9a5826de41c5c7966cdc818580a83e8e59edb32 Mon Sep 17 00:00:00 2001 From: Louis-Marie Givel Date: Fri, 10 Dec 2021 15:53:42 +0100 Subject: [PATCH 6/6] Make permissions tests a folder --- src/lib.rs | 2 - tests/filter/permissions.t | 1393 ------------------------ tests/filter/permissions/cli.t | 122 +++ tests/filter/permissions/filters.t | 599 ++++++++++ tests/filter/permissions/permissions.t | 713 ++++++++++++ tests/filter/permissions/setup_repo.sh | 29 + 6 files changed, 1463 insertions(+), 1395 deletions(-) delete mode 100644 tests/filter/permissions.t create mode 100644 tests/filter/permissions/cli.t create mode 100644 tests/filter/permissions/filters.t create mode 100644 tests/filter/permissions/permissions.t create mode 100644 tests/filter/permissions/setup_repo.sh diff --git a/src/lib.rs b/src/lib.rs index 826860be0..b981f18f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -180,7 +180,6 @@ pub fn filter_ref( s } else { tracing::trace!("apply_to_commit (permissions)"); - println!("perm {:?}", permissions); filter::apply_to_commit(permissions, &original_commit, &transaction)? }; @@ -198,7 +197,6 @@ pub fn filter_ref( } } - println!("filter {:?}", filterobj); let filter_commit = if let Some(s) = transaction.get_ref(filterobj, oid) { s } else { diff --git a/tests/filter/permissions.t b/tests/filter/permissions.t deleted file mode 100644 index 2986e2824..000000000 --- a/tests/filter/permissions.t +++ /dev/null @@ -1,1393 +0,0 @@ - $ export TESTTMP=${PWD} - - $ cd ${TESTTMP} - $ git init 1> /dev/null - - $ mkdir a - $ echo "cws = :/c" > a/workspace.josh - $ echo contents1 > a/file_a2 - $ git add a - - $ mkdir b - $ echo contents1 > b/file_b1 - $ git add b - - $ mkdir -p c/d - $ echo contents1 > c/d/file_cd - $ git add c - $ git commit -m "add dirs" 1> /dev/null - - $ echo contents2 > c/d/file_cd2 - $ git add c - $ git commit -m "add file_cd2" 1> /dev/null - - $ mkdir -p c/d/e - $ echo contents2 > c/d/e/file_cd3 - $ git add c - $ git commit -m "add file_cd3" 1> /dev/null - - $ echo contents3 >> c/d/e/file_cd3 - $ git add c - $ git commit -m "edit file_cd3" 1> /dev/null - - $ git log --graph --pretty=%s - * edit file_cd3 - * add file_cd3 - * add file_cd2 - * add dirs - - $ josh-filter -s :PATHS master --update refs/josh/filtered - perm Empty - filter Paths - [3] :PATHS - [16] _paths - - $ git log --graph --pretty=%s refs/josh/filtered - * add file_cd3 - * add file_cd2 - * add dirs - - $ git checkout refs/josh/filtered 2> /dev/null - $ tree - . - |-- a - | |-- file_a2 - | `-- workspace.josh - |-- b - | `-- file_b1 - `-- c - `-- d - |-- e - | `-- file_cd3 - |-- file_cd - `-- file_cd2 - - 5 directories, 6 files - - $ git diff $EMPTY_TREE HEAD - diff --git a/a/file_a2 b/a/file_a2 - new file mode 100644 - index 0000000..4b2f88e - --- /dev/null - +++ b/a/file_a2 - @@ -0,0 +1 @@ - +a/file_a2 - \ No newline at end of file - diff --git a/a/workspace.josh b/a/workspace.josh - new file mode 100644 - index 0000000..c9acb10 - --- /dev/null - +++ b/a/workspace.josh - @@ -0,0 +1,2 @@ - +#a/workspace.josh - +cws = :/c - diff --git a/b/file_b1 b/b/file_b1 - new file mode 100644 - index 0000000..413b4ca - --- /dev/null - +++ b/b/file_b1 - @@ -0,0 +1 @@ - +b/file_b1 - \ No newline at end of file - diff --git a/c/d/e/file_cd3 b/c/d/e/file_cd3 - new file mode 100644 - index 0000000..8719808 - --- /dev/null - +++ b/c/d/e/file_cd3 - @@ -0,0 +1 @@ - +c/d/e/file_cd3 - \ No newline at end of file - diff --git a/c/d/file_cd b/c/d/file_cd - new file mode 100644 - index 0000000..bb36c67 - --- /dev/null - +++ b/c/d/file_cd - @@ -0,0 +1 @@ - +c/d/file_cd - \ No newline at end of file - diff --git a/c/d/file_cd2 b/c/d/file_cd2 - new file mode 100644 - index 0000000..26318eb - --- /dev/null - +++ b/c/d/file_cd2 - @@ -0,0 +1 @@ - +c/d/file_cd2 - \ No newline at end of file - - - - $ josh-filter -s :PATHS:/c master --update refs/josh/filtered - perm Empty - filter Chain(Paths, Subdir("c")) - [3] :/c - [3] :PATHS - [16] _paths - - $ git log --graph --pretty=%s refs/josh/filtered - * add file_cd3 - * add file_cd2 - * add dirs - - $ git checkout refs/josh/filtered 2> /dev/null - $ tree - . - `-- d - |-- e - | `-- file_cd3 - |-- file_cd - `-- file_cd2 - - 2 directories, 3 files - - $ git diff $EMPTY_TREE HEAD - diff --git a/d/e/file_cd3 b/d/e/file_cd3 - new file mode 100644 - index 0000000..8719808 - --- /dev/null - +++ b/d/e/file_cd3 - @@ -0,0 +1 @@ - +c/d/e/file_cd3 - \ No newline at end of file - diff --git a/d/file_cd b/d/file_cd - new file mode 100644 - index 0000000..bb36c67 - --- /dev/null - +++ b/d/file_cd - @@ -0,0 +1 @@ - +c/d/file_cd - \ No newline at end of file - diff --git a/d/file_cd2 b/d/file_cd2 - new file mode 100644 - index 0000000..26318eb - --- /dev/null - +++ b/d/file_cd2 - @@ -0,0 +1 @@ - +c/d/file_cd2 - \ No newline at end of file - - - - $ josh-filter -s :PATHS:/a master --update refs/josh/filtered - perm Empty - filter Chain(Paths, Subdir("a")) - [1] :/a - [3] :/c - [3] :PATHS - [16] _paths - - $ git log --graph --pretty=%s refs/josh/filtered - * add dirs - - $ git checkout refs/josh/filtered 2> /dev/null - $ tree - . - |-- file_a2 - `-- workspace.josh - - 0 directories, 2 files - - - $ josh-filter -s :PATHS:exclude[::c/]:prefix=x master --update refs/josh/filtered - perm Empty - filter Chain(Paths, Chain(Exclude(Chain(Subdir("c"), Prefix("c"))), Prefix("x"))) - [1] :/a - [1] :exclude[::c/] - [1] :prefix=x - [3] :/c - [3] :PATHS - [3] :prefix=c - [16] _paths - - $ git log --graph --pretty=%s refs/josh/filtered - * add dirs - - $ git checkout refs/josh/filtered 2> /dev/null - $ tree - . - `-- x - |-- a - | |-- file_a2 - | `-- workspace.josh - `-- b - `-- file_b1 - - 3 directories, 3 files - - $ git diff $EMPTY_TREE HEAD - diff --git a/x/a/file_a2 b/x/a/file_a2 - new file mode 100644 - index 0000000..4b2f88e - --- /dev/null - +++ b/x/a/file_a2 - @@ -0,0 +1 @@ - +a/file_a2 - \ No newline at end of file - diff --git a/x/a/workspace.josh b/x/a/workspace.josh - new file mode 100644 - index 0000000..c9acb10 - --- /dev/null - +++ b/x/a/workspace.josh - @@ -0,0 +1,2 @@ - +#a/workspace.josh - +cws = :/c - diff --git a/x/b/file_b1 b/x/b/file_b1 - new file mode 100644 - index 0000000..413b4ca - --- /dev/null - +++ b/x/b/file_b1 - @@ -0,0 +1 @@ - +b/file_b1 - \ No newline at end of file - - - $ josh-filter -s :PATHS:INVERT master --update refs/josh/filtered - perm Empty - filter Chain(Paths, Invert) - [1] :/a - [1] :exclude[::c/] - [1] :prefix=x - [3] :/c - [3] :INVERT - [3] :PATHS - [3] :prefix=c - [12] _invert - [16] _paths - - $ git checkout refs/josh/filtered 2> /dev/null - $ tree - . - |-- a - | |-- file_a2 - | `-- workspace.josh - |-- b - | `-- file_b1 - `-- c - `-- d - |-- e - | `-- file_cd3 - |-- file_cd - `-- file_cd2 - - 5 directories, 6 files - $ cat a/file_a2 - a/file_a2 (no-eol) - $ cat b/file_b1 - b/file_b1 (no-eol) - - -# default permissions give everything - $ josh-filter -s :/ master --check-permission --update refs/josh/filtered - perm Empty - filter Nop - [1] :/a - [1] :exclude[::c/] - [1] :prefix=x - [3] :/c - [3] :INVERT - [3] :PATHS - [3] :prefix=c - [12] _invert - [16] _paths - - $ git checkout refs/josh/filtered 2> /dev/null - $ tree - . - |-- a - | |-- file_a2 - | `-- workspace.josh - |-- b - | `-- file_b1 - `-- c - `-- d - |-- e - | `-- file_cd3 - |-- file_cd - `-- file_cd2 - - 5 directories, 6 files - - -# default same as this - $ josh-filter -s :/ master --check-permission -b :empty -w :nop --update refs/josh/filtered_2 - perm Empty - filter Nop - [1] :/a - [1] :exclude[::c/] - [1] :prefix=x - [3] :/c - [3] :INVERT - [3] :PATHS - [3] :prefix=c - [12] _invert - [16] _paths - - $ git checkout refs/josh/filtered 2> /dev/null - $ tree - . - |-- a - | |-- file_a2 - | `-- workspace.josh - |-- b - | `-- file_b1 - `-- c - `-- d - |-- e - | `-- file_cd3 - |-- file_cd - `-- file_cd2 - - 5 directories, 6 files - - -# no permissions - $ josh-filter -s :/ master --check-permission -b :nop -w :empty --update refs/josh/filtered - perm Chain(Paths, Invert) - [1] :/a - [1] :exclude[::c/] - [1] :prefix=x - [3] :/c - [3] :INVERT - [3] :PATHS - [3] :prefix=c - [12] _invert - [16] _paths - ERROR: JoshError("missing permissions for ref") - [1] - $ josh-filter -s :/b master --check-permission -w ::a/ --update refs/josh/filtered - perm Chain(Paths, Chain(Subdir("b"), Chain(Invert, Subtract(Nop, Chain(Subdir("a"), Prefix("a")))))) - [1] :/b - [1] :exclude[::c/] - [1] :prefix=x - [1] :subtract[ - :/ - ::a/ - ] - [2] :/a - [3] :/c - [3] :PATHS - [3] :prefix=c - [4] :INVERT - [13] _invert - [16] _paths - ERROR: JoshError("missing permissions for ref") - [1] - - - $ josh-filter -s :/b master --check-permission -b ::b/ -w ::b/ --update refs/josh/filtered - perm Chain(Paths, Chain(Subdir("b"), Chain(Invert, Compose([Chain(Subdir("b"), Prefix("b")), Subtract(Nop, Chain(Subdir("b"), Prefix("b")))])))) - [1] :[ - ::b/ - :subtract[ - :/ - ::b/ - ] - ] - [1] :exclude[::c/] - [1] :prefix=b - [1] :prefix=x - [1] :subtract[ - :/ - ::a/ - ] - [1] :subtract[ - :/ - ::b/ - ] - [2] :/a - [2] :/b - [3] :/c - [3] :PATHS - [3] :prefix=c - [4] :INVERT - [13] _invert - [16] _paths - ERROR: JoshError("missing permissions for ref") - [1] - - -# access granted - $ josh-filter -s :/b master --check-permission -w ::b/ --update refs/josh/filtered - perm Chain(Paths, Chain(Subdir("b"), Chain(Invert, Subtract(Nop, Chain(Subdir("b"), Prefix("b")))))) - filter Subdir("b") - [1] :[ - ::b/ - :subtract[ - :/ - ::b/ - ] - ] - [1] :exclude[::c/] - [1] :prefix=b - [1] :prefix=x - [1] :subtract[ - :/ - ::a/ - ] - [1] :subtract[ - :/ - ::b/ - ] - [2] :/a - [3] :/b - [3] :/c - [3] :PATHS - [3] :prefix=c - [4] :INVERT - [13] _invert - [16] _paths - - -# acl - $ cat << EOF > users.yaml - > LMG: - > groups: ["dev"] - > CSchilling: - > groups: ["dev2"] - > EOF - $ cat << EOF > groups.yaml - > test: - > dev: - > whitelist: ":/" - > blacklist: ":empty" - > dev2: - > blacklist: ":empty" - > whitelist: | - > :[ - > ::b/ - > ::a/ - > ] - > EOF - -# doesn't work - $ josh-filter -s :/ master --check-permission --users users.yaml --groups groups.yaml -u CSchilling -r test --update refs/josh/filtered - w: Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))]), b: Empty - perm Chain(Paths, Chain(Invert, Subtract(Nop, Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))])))) - [1] :[ - ::a/ - ::b/ - ] - [1] :[ - ::b/ - :subtract[ - :/ - ::b/ - ] - ] - [1] :exclude[::c/] - [1] :prefix=a - [1] :prefix=x - [1] :subtract[ - :/ - ::a/ - ] - [1] :subtract[ - :/ - ::b/ - ] - [2] :prefix=b - [3] :/a - [3] :/c - [3] :PATHS - [3] :prefix=c - [3] :subtract[ - :/ - :[ - ::a/ - ::b/ - ] - ] - [4] :/b - [4] :INVERT - [13] _invert - [16] _paths - ERROR: JoshError("missing permissions for ref") - [1] - - $ josh-filter -s :/ master --check-permission --missing-permission --users users.yaml --groups groups.yaml -u CSchilling -r test --update refs/josh/filtered - w: Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))]), b: Empty - perm Empty - filter Chain(Paths, Chain(Invert, Subtract(Nop, Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))])))) - [1] :[ - ::a/ - ::b/ - ] - [1] :[ - ::b/ - :subtract[ - :/ - ::b/ - ] - ] - [1] :exclude[::c/] - [1] :prefix=a - [1] :prefix=x - [1] :subtract[ - :/ - ::a/ - ] - [1] :subtract[ - :/ - ::b/ - ] - [2] :prefix=b - [3] :/a - [3] :/c - [3] :PATHS - [3] :prefix=c - [3] :subtract[ - :/ - :[ - ::a/ - ::b/ - ] - ] - [4] :/b - [4] :INVERT - [13] _invert - [16] _paths - $ git checkout refs/josh/filtered - Previous HEAD position was f69915b edit file_cd3 - HEAD is now at c6749dc add file_cd3 - $ tree - . - |-- c - | `-- d - | |-- e - | | `-- file_cd3 - | |-- file_cd - | `-- file_cd2 - |-- groups.yaml - `-- users.yaml - - 3 directories, 5 files - $ cat b/file_b1 - cat: b/file_b1: No such file or directory - [1] - $ git log - commit c6749dc54b9f93d87e04e89900c0ca1e730c0ca4 - Author: Josh - Date: Thu Apr 7 22:13:13 2005 +0000 - - add file_cd3 - - commit 58bed947100bda96f7b2a90df2623e1cdee685e5 - Author: Josh - Date: Thu Apr 7 22:13:13 2005 +0000 - - add file_cd2 - - commit 838b5164aff95c891164bfc0ed8611dc008c39ea - Author: Josh - Date: Thu Apr 7 22:13:13 2005 +0000 - - add dirs - -# works - $ josh-filter -s :[:/b,:/a] master --check-permission --users users.yaml --groups groups.yaml -u CSchilling -r test --update refs/josh/filtered - w: Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))]), b: Empty - perm Chain(Paths, Chain(Compose([Subdir("b"), Subdir("a")]), Chain(Invert, Subtract(Nop, Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))]))))) - filter Compose([Subdir("b"), Subdir("a")]) - [1] :[ - ::b/ - :subtract[ - :/ - ::b/ - ] - ] - [1] :exclude[::c/] - [1] :prefix=x - [1] :subtract[ - :/ - ::a/ - ] - [1] :subtract[ - :/ - ::b/ - ] - [2] :[ - :/b - :/a - ] - [2] :[ - ::a/ - ::b/ - ] - [2] :prefix=a - [2] :prefix=b - [3] :/c - [3] :PATHS - [3] :prefix=c - [4] :subtract[ - :/ - :[ - ::a/ - ::b/ - ] - ] - [5] :/a - [5] :/b - [5] :INVERT - [14] _invert - [16] _paths - $ git checkout refs/josh/filtered - Warning: you are leaving 3 commits behind, not connected to - any of your branches: - - c6749dc add file_cd3 - 58bed94 add file_cd2 - 838b516 add dirs - - If you want to keep them by creating a new branch, this may be a good time - to do so with: - - git branch c6749dc - - HEAD is now at b2040aa add dirs - $ tree - . - |-- file_a2 - |-- file_b1 - |-- groups.yaml - |-- users.yaml - `-- workspace.josh - - 0 directories, 5 files - $ cat b/file_b1 - cat: b/file_b1: No such file or directory - [1] - $ josh-filter -s :[:/b,:/a] master --check-permission --missing-permission --users users.yaml --groups groups.yaml -u CSchilling -r test --update refs/josh/filtered - w: Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))]), b: Empty - perm Empty - filter Chain(Paths, Chain(Compose([Subdir("b"), Subdir("a")]), Chain(Invert, Subtract(Nop, Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))]))))) - [1] :[ - ::b/ - :subtract[ - :/ - ::b/ - ] - ] - [1] :exclude[::c/] - [1] :prefix=x - [1] :subtract[ - :/ - ::a/ - ] - [1] :subtract[ - :/ - ::b/ - ] - [2] :[ - :/b - :/a - ] - [2] :[ - ::a/ - ::b/ - ] - [2] :prefix=a - [2] :prefix=b - [3] :/c - [3] :PATHS - [3] :prefix=c - [4] :subtract[ - :/ - :[ - ::a/ - ::b/ - ] - ] - [5] :/a - [5] :/b - [5] :INVERT - [14] _invert - [16] _paths - $ git checkout refs/josh/filtered - HEAD is now at b2040aa add dirs - $ tree - . - |-- file_a2 - |-- file_b1 - |-- groups.yaml - |-- users.yaml - `-- workspace.josh - - 0 directories, 5 files - $ git log - commit b2040aafa2d613696e8e0740cd3debd555550c1a - Author: Josh - Date: Thu Apr 7 22:13:13 2005 +0000 - - add dirs - $ cat b/file_b1 - cat: b/file_b1: No such file or directory - [1] -# doesn't work - $ josh-filter -s :/ master --check-permission --users users.yaml --groups groups.yaml -u bob -r test --update refs/josh/filtered - perm Chain(Paths, Invert) - [1] :[ - ::b/ - :subtract[ - :/ - ::b/ - ] - ] - [1] :exclude[::c/] - [1] :prefix=x - [1] :subtract[ - :/ - ::a/ - ] - [1] :subtract[ - :/ - ::b/ - ] - [2] :[ - :/b - :/a - ] - [2] :[ - ::a/ - ::b/ - ] - [2] :prefix=a - [2] :prefix=b - [3] :/c - [3] :PATHS - [3] :prefix=c - [4] :subtract[ - :/ - :[ - ::a/ - ::b/ - ] - ] - [5] :/a - [5] :/b - [5] :INVERT - [14] _invert - [16] _paths - ERROR: JoshError("missing permissions for ref") - [1] -# works - $ josh-filter -s :/ master --check-permission --users users.yaml --groups groups.yaml -u LMG -r test --update refs/josh/filtered - w: Nop, b: Empty - perm Empty - filter Nop - [1] :[ - ::b/ - :subtract[ - :/ - ::b/ - ] - ] - [1] :exclude[::c/] - [1] :prefix=x - [1] :subtract[ - :/ - ::a/ - ] - [1] :subtract[ - :/ - ::b/ - ] - [2] :[ - :/b - :/a - ] - [2] :[ - ::a/ - ::b/ - ] - [2] :prefix=a - [2] :prefix=b - [3] :/c - [3] :PATHS - [3] :prefix=c - [4] :subtract[ - :/ - :[ - ::a/ - ::b/ - ] - ] - [5] :/a - [5] :/b - [5] :INVERT - [14] _invert - [16] _paths - - $ git diff $EMPTY_TREE HEAD - diff --git a/file_a2 b/file_a2 - new file mode 100644 - index 0000000..a024003 - --- /dev/null - +++ b/file_a2 - @@ -0,0 +1 @@ - +contents1 - diff --git a/file_b1 b/file_b1 - new file mode 100644 - index 0000000..a024003 - --- /dev/null - +++ b/file_b1 - @@ -0,0 +1 @@ - +contents1 - diff --git a/workspace.josh b/workspace.josh - new file mode 100644 - index 0000000..3af54d0 - --- /dev/null - +++ b/workspace.josh - @@ -0,0 +1 @@ - +cws = :/c - - - $ josh-filter -s :PATHS:workspace=a:INVERT master --update refs/josh/filtered - perm Empty - filter Chain(Paths, Chain(Workspace("a"), Invert)) - [1] :[ - ::b/ - :subtract[ - :/ - ::b/ - ] - ] - [1] :exclude[::c/] - [1] :prefix=x - [1] :subtract[ - :/ - ::a/ - ] - [1] :subtract[ - :/ - ::b/ - ] - [2] :[ - :/b - :/a - ] - [2] :[ - ::a/ - ::b/ - ] - [2] :prefix=a - [2] :prefix=b - [3] :/c - [3] :PATHS - [3] :prefix=c - [3] :workspace=a - [4] :subtract[ - :/ - :[ - ::a/ - ::b/ - ] - ] - [5] :/a - [5] :/b - [8] :INVERT - [16] _paths - [24] _invert - - $ git checkout refs/josh/filtered 2> /dev/null - $ tree - . - |-- a - | |-- file_a2 - | `-- workspace.josh - |-- c - | `-- d - | |-- e - | | `-- file_cd3 - | |-- file_cd - | `-- file_cd2 - |-- groups.yaml - `-- users.yaml - - 4 directories, 7 files - - $ git diff $EMPTY_TREE HEAD - diff --git a/a/file_a2 b/a/file_a2 - new file mode 100644 - index 0000000..ee73843 - --- /dev/null - +++ b/a/file_a2 - @@ -0,0 +1 @@ - +file_a2 - \ No newline at end of file - diff --git a/a/workspace.josh b/a/workspace.josh - new file mode 100644 - index 0000000..0ab7ce1 - --- /dev/null - +++ b/a/workspace.josh - @@ -0,0 +1 @@ - +workspace.josh - \ No newline at end of file - diff --git a/c/d/e/file_cd3 b/c/d/e/file_cd3 - new file mode 100644 - index 0000000..ed74419 - --- /dev/null - +++ b/c/d/e/file_cd3 - @@ -0,0 +1 @@ - +cws/d/e/file_cd3 - \ No newline at end of file - diff --git a/c/d/file_cd b/c/d/file_cd - new file mode 100644 - index 0000000..7afa8f7 - --- /dev/null - +++ b/c/d/file_cd - @@ -0,0 +1 @@ - +cws/d/file_cd - \ No newline at end of file - diff --git a/c/d/file_cd2 b/c/d/file_cd2 - new file mode 100644 - index 0000000..4fbc84d - --- /dev/null - +++ b/c/d/file_cd2 - @@ -0,0 +1 @@ - +cws/d/file_cd2 - \ No newline at end of file - - $ josh-filter -s :PATHS:FOLD master --update refs/josh/filtered - perm Empty - filter Chain(Paths, Fold) - [1] :[ - ::b/ - :subtract[ - :/ - ::b/ - ] - ] - [1] :exclude[::c/] - [1] :prefix=x - [1] :subtract[ - :/ - ::a/ - ] - [1] :subtract[ - :/ - ::b/ - ] - [2] :[ - :/b - :/a - ] - [2] :[ - ::a/ - ::b/ - ] - [2] :prefix=a - [2] :prefix=b - [3] :/c - [3] :FOLD - [3] :PATHS - [3] :prefix=c - [3] :workspace=a - [4] :subtract[ - :/ - :[ - ::a/ - ::b/ - ] - ] - [5] :/a - [5] :/b - [8] :INVERT - [16] _paths - [24] _invert - - - - $ git checkout master 2> /dev/null - $ git rm -r c/d - rm 'c/d/e/file_cd3' - rm 'c/d/file_cd' - rm 'c/d/file_cd2' - $ git commit -m "rm" 1> /dev/null - - $ echo contents2 > a/newfile - $ git add a - $ git commit -m "add newfile" 1> /dev/null - - $ josh-filter -s :PATHS master --update refs/josh/filtered - perm Empty - filter Paths - [1] :[ - ::b/ - :subtract[ - :/ - ::b/ - ] - ] - [1] :exclude[::c/] - [1] :prefix=x - [1] :subtract[ - :/ - ::a/ - ] - [1] :subtract[ - :/ - ::b/ - ] - [2] :[ - :/b - :/a - ] - [2] :[ - ::a/ - ::b/ - ] - [2] :prefix=a - [2] :prefix=b - [3] :/c - [3] :FOLD - [3] :prefix=c - [3] :workspace=a - [4] :subtract[ - :/ - :[ - ::a/ - ::b/ - ] - ] - [5] :/a - [5] :/b - [5] :PATHS - [8] :INVERT - [19] _paths - [24] _invert - - $ git log --graph --pretty=%s master - * add newfile - * rm - * edit file_cd3 - * add file_cd3 - * add file_cd2 - * add dirs - - $ git log --graph --pretty=%s refs/josh/filtered - * add newfile - * rm - * add file_cd3 - * add file_cd2 - * add dirs - - $ git checkout refs/josh/filtered 2> /dev/null - $ tree - . - |-- a - | |-- file_a2 - | |-- newfile - | `-- workspace.josh - |-- b - | `-- file_b1 - |-- groups.yaml - `-- users.yaml - - 2 directories, 6 files - - $ git diff $EMPTY_TREE HEAD - diff --git a/a/file_a2 b/a/file_a2 - new file mode 100644 - index 0000000..4b2f88e - --- /dev/null - +++ b/a/file_a2 - @@ -0,0 +1 @@ - +a/file_a2 - \ No newline at end of file - diff --git a/a/newfile b/a/newfile - new file mode 100644 - index 0000000..17b95ba - --- /dev/null - +++ b/a/newfile - @@ -0,0 +1 @@ - +a/newfile - \ No newline at end of file - diff --git a/a/workspace.josh b/a/workspace.josh - new file mode 100644 - index 0000000..c9acb10 - --- /dev/null - +++ b/a/workspace.josh - @@ -0,0 +1,2 @@ - +#a/workspace.josh - +cws = :/c - diff --git a/b/file_b1 b/b/file_b1 - new file mode 100644 - index 0000000..413b4ca - --- /dev/null - +++ b/b/file_b1 - @@ -0,0 +1 @@ - +b/file_b1 - \ No newline at end of file - - - $ git log --graph --pretty=%s refs/josh/filtered - * add newfile - * rm - * add file_cd3 - * add file_cd2 - * add dirs - - $ git checkout refs/josh/filtered 2> /dev/null - $ tree - . - |-- a - | |-- file_a2 - | |-- newfile - | `-- workspace.josh - |-- b - | `-- file_b1 - |-- groups.yaml - `-- users.yaml - - 2 directories, 6 files - - $ git diff $EMPTY_TREE HEAD - diff --git a/a/file_a2 b/a/file_a2 - new file mode 100644 - index 0000000..4b2f88e - --- /dev/null - +++ b/a/file_a2 - @@ -0,0 +1 @@ - +a/file_a2 - \ No newline at end of file - diff --git a/a/newfile b/a/newfile - new file mode 100644 - index 0000000..17b95ba - --- /dev/null - +++ b/a/newfile - @@ -0,0 +1 @@ - +a/newfile - \ No newline at end of file - diff --git a/a/workspace.josh b/a/workspace.josh - new file mode 100644 - index 0000000..c9acb10 - --- /dev/null - +++ b/a/workspace.josh - @@ -0,0 +1,2 @@ - +#a/workspace.josh - +cws = :/c - diff --git a/b/file_b1 b/b/file_b1 - new file mode 100644 - index 0000000..413b4ca - --- /dev/null - +++ b/b/file_b1 - @@ -0,0 +1 @@ - +b/file_b1 - \ No newline at end of file - - - - $ josh-filter -s :PATHS:/c:FOLD master --update refs/josh/filtered - perm Empty - filter Chain(Paths, Chain(Subdir("c"), Fold)) - [1] :[ - ::b/ - :subtract[ - :/ - ::b/ - ] - ] - [1] :exclude[::c/] - [1] :prefix=x - [1] :subtract[ - :/ - ::a/ - ] - [1] :subtract[ - :/ - ::b/ - ] - [2] :[ - :/b - :/a - ] - [2] :[ - ::a/ - ::b/ - ] - [2] :prefix=a - [2] :prefix=b - [3] :prefix=c - [3] :workspace=a - [4] :/c - [4] :subtract[ - :/ - :[ - ::a/ - ::b/ - ] - ] - [5] :/a - [5] :/b - [5] :PATHS - [6] :FOLD - [8] :INVERT - [19] _paths - [24] _invert - - $ git log --graph --pretty=%s refs/josh/filtered - * add file_cd3 - * add file_cd2 - * add dirs - - $ git checkout refs/josh/filtered 2> /dev/null - $ tree - . - |-- d - | |-- e - | | `-- file_cd3 - | |-- file_cd - | `-- file_cd2 - |-- groups.yaml - `-- users.yaml - - 2 directories, 5 files - - $ git diff $EMPTY_TREE HEAD - diff --git a/d/e/file_cd3 b/d/e/file_cd3 - new file mode 100644 - index 0000000..8719808 - --- /dev/null - +++ b/d/e/file_cd3 - @@ -0,0 +1 @@ - +c/d/e/file_cd3 - \ No newline at end of file - diff --git a/d/file_cd b/d/file_cd - new file mode 100644 - index 0000000..bb36c67 - --- /dev/null - +++ b/d/file_cd - @@ -0,0 +1 @@ - +c/d/file_cd - \ No newline at end of file - diff --git a/d/file_cd2 b/d/file_cd2 - new file mode 100644 - index 0000000..26318eb - --- /dev/null - +++ b/d/file_cd2 - @@ -0,0 +1 @@ - +c/d/file_cd2 - \ No newline at end of file - - - - $ josh-filter -s :PATHS:workspace=a:FOLD master --update refs/josh/filtered - perm Empty - filter Chain(Paths, Chain(Workspace("a"), Fold)) - [1] :[ - ::b/ - :subtract[ - :/ - ::b/ - ] - ] - [1] :exclude[::c/] - [1] :prefix=x - [1] :subtract[ - :/ - ::a/ - ] - [1] :subtract[ - :/ - ::b/ - ] - [2] :[ - :/b - :/a - ] - [2] :[ - ::a/ - ::b/ - ] - [2] :prefix=a - [2] :prefix=b - [3] :prefix=c - [4] :/c - [4] :subtract[ - :/ - :[ - ::a/ - ::b/ - ] - ] - [5] :/a - [5] :/b - [5] :PATHS - [5] :workspace=a - [8] :INVERT - [10] :FOLD - [19] _paths - [24] _invert - - $ git log --graph --pretty=%s refs/josh/filtered - * add newfile - * add file_cd3 - * add file_cd2 - * add dirs - - $ git checkout refs/josh/filtered 2> /dev/null - $ tree - . - |-- cws - | `-- d - | |-- e - | | `-- file_cd3 - | |-- file_cd - | `-- file_cd2 - |-- file_a2 - |-- groups.yaml - |-- newfile - |-- users.yaml - `-- workspace.josh - - 3 directories, 8 files - - $ git diff $EMPTY_TREE HEAD - diff --git a/cws/d/e/file_cd3 b/cws/d/e/file_cd3 - new file mode 100644 - index 0000000..8719808 - --- /dev/null - +++ b/cws/d/e/file_cd3 - @@ -0,0 +1 @@ - +c/d/e/file_cd3 - \ No newline at end of file - diff --git a/cws/d/file_cd b/cws/d/file_cd - new file mode 100644 - index 0000000..bb36c67 - --- /dev/null - +++ b/cws/d/file_cd - @@ -0,0 +1 @@ - +c/d/file_cd - \ No newline at end of file - diff --git a/cws/d/file_cd2 b/cws/d/file_cd2 - new file mode 100644 - index 0000000..26318eb - --- /dev/null - +++ b/cws/d/file_cd2 - @@ -0,0 +1 @@ - +c/d/file_cd2 - \ No newline at end of file - diff --git a/file_a2 b/file_a2 - new file mode 100644 - index 0000000..4b2f88e - --- /dev/null - +++ b/file_a2 - @@ -0,0 +1 @@ - +a/file_a2 - \ No newline at end of file - diff --git a/newfile b/newfile - new file mode 100644 - index 0000000..17b95ba - --- /dev/null - +++ b/newfile - @@ -0,0 +1 @@ - +a/newfile - \ No newline at end of file - diff --git a/workspace.josh b/workspace.josh - new file mode 100644 - index 0000000..c9acb10 - --- /dev/null - +++ b/workspace.josh - @@ -0,0 +1,2 @@ - +#a/workspace.josh - +cws = :/c - diff --git a/tests/filter/permissions/cli.t b/tests/filter/permissions/cli.t new file mode 100644 index 000000000..ec62c8a6f --- /dev/null +++ b/tests/filter/permissions/cli.t @@ -0,0 +1,122 @@ + $ export TESTTMP=${PWD} + + $ . ${TESTDIR}/setup_repo.sh + +# default permissions give everything + $ josh-filter -s :/ master --check-permission --update refs/josh/filtered + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + |-- a + | |-- file_a2 + | `-- workspace.josh + |-- b + | `-- file_b1 + `-- c + `-- d + |-- e + | `-- file_cd3 + |-- file_cd + `-- file_cd2 + + 5 directories, 6 files + + +# default same as this + $ josh-filter -s :/ master --check-permission -b :empty -w :nop --update refs/josh/filtered_2 + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + |-- a + | |-- file_a2 + | `-- workspace.josh + |-- b + | `-- file_b1 + `-- c + `-- d + |-- e + | `-- file_cd3 + |-- file_cd + `-- file_cd2 + + 5 directories, 6 files + + +# no permissions + $ josh-filter -s :/ master --check-permission -b :nop -w :empty --update refs/josh/filtered + [3] :INVERT + [3] :PATHS + [12] _invert + [16] _paths + ERROR: JoshError("missing permissions for ref") + [1] + $ josh-filter -s :/b master --check-permission -w ::a/ --update refs/josh/filtered + [1] :/a + [1] :/b + [1] :subtract[ + :/ + ::a/ + ] + [3] :PATHS + [4] :INVERT + [13] _invert + [16] _paths + ERROR: JoshError("missing permissions for ref") + [1] + + + $ josh-filter -s :/b master --check-permission -b ::b/ -w ::b/ --update refs/josh/filtered + [1] :/a + [1] :[ + ::b/ + :subtract[ + :/ + ::b/ + ] + ] + [1] :prefix=b + [1] :subtract[ + :/ + ::a/ + ] + [1] :subtract[ + :/ + ::b/ + ] + [2] :/b + [3] :PATHS + [4] :INVERT + [13] _invert + [16] _paths + ERROR: JoshError("missing permissions for ref") + [1] + + +# access granted + $ josh-filter -s :/b master --check-permission -w ::b/ --update refs/josh/filtered + [1] :/a + [1] :[ + ::b/ + :subtract[ + :/ + ::b/ + ] + ] + [1] :prefix=b + [1] :subtract[ + :/ + ::a/ + ] + [1] :subtract[ + :/ + ::b/ + ] + [3] :/b + [3] :PATHS + [4] :INVERT + [13] _invert + [16] _paths + + diff --git a/tests/filter/permissions/filters.t b/tests/filter/permissions/filters.t new file mode 100644 index 000000000..b9fedc392 --- /dev/null +++ b/tests/filter/permissions/filters.t @@ -0,0 +1,599 @@ + $ export TESTTMP=${PWD} + + $ . ${TESTDIR}/setup_repo.sh + + $ josh-filter -s :PATHS master --update refs/josh/filtered + [3] :PATHS + [16] _paths + + $ git log --graph --pretty=%s refs/josh/filtered + * add file_cd3 + * add file_cd2 + * add dirs + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + |-- a + | |-- file_a2 + | `-- workspace.josh + |-- b + | `-- file_b1 + `-- c + `-- d + |-- e + | `-- file_cd3 + |-- file_cd + `-- file_cd2 + + 5 directories, 6 files + + $ git diff $EMPTY_TREE HEAD + diff --git a/a/file_a2 b/a/file_a2 + new file mode 100644 + index 0000000..4b2f88e + --- /dev/null + +++ b/a/file_a2 + @@ -0,0 +1 @@ + +a/file_a2 + \ No newline at end of file + diff --git a/a/workspace.josh b/a/workspace.josh + new file mode 100644 + index 0000000..c9acb10 + --- /dev/null + +++ b/a/workspace.josh + @@ -0,0 +1,2 @@ + +#a/workspace.josh + +cws = :/c + diff --git a/b/file_b1 b/b/file_b1 + new file mode 100644 + index 0000000..413b4ca + --- /dev/null + +++ b/b/file_b1 + @@ -0,0 +1 @@ + +b/file_b1 + \ No newline at end of file + diff --git a/c/d/e/file_cd3 b/c/d/e/file_cd3 + new file mode 100644 + index 0000000..8719808 + --- /dev/null + +++ b/c/d/e/file_cd3 + @@ -0,0 +1 @@ + +c/d/e/file_cd3 + \ No newline at end of file + diff --git a/c/d/file_cd b/c/d/file_cd + new file mode 100644 + index 0000000..bb36c67 + --- /dev/null + +++ b/c/d/file_cd + @@ -0,0 +1 @@ + +c/d/file_cd + \ No newline at end of file + diff --git a/c/d/file_cd2 b/c/d/file_cd2 + new file mode 100644 + index 0000000..26318eb + --- /dev/null + +++ b/c/d/file_cd2 + @@ -0,0 +1 @@ + +c/d/file_cd2 + \ No newline at end of file + + + + $ josh-filter -s :PATHS:/c master --update refs/josh/filtered + [3] :/c + [3] :PATHS + [16] _paths + + $ git log --graph --pretty=%s refs/josh/filtered + * add file_cd3 + * add file_cd2 + * add dirs + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + `-- d + |-- e + | `-- file_cd3 + |-- file_cd + `-- file_cd2 + + 2 directories, 3 files + + $ git diff $EMPTY_TREE HEAD + diff --git a/d/e/file_cd3 b/d/e/file_cd3 + new file mode 100644 + index 0000000..8719808 + --- /dev/null + +++ b/d/e/file_cd3 + @@ -0,0 +1 @@ + +c/d/e/file_cd3 + \ No newline at end of file + diff --git a/d/file_cd b/d/file_cd + new file mode 100644 + index 0000000..bb36c67 + --- /dev/null + +++ b/d/file_cd + @@ -0,0 +1 @@ + +c/d/file_cd + \ No newline at end of file + diff --git a/d/file_cd2 b/d/file_cd2 + new file mode 100644 + index 0000000..26318eb + --- /dev/null + +++ b/d/file_cd2 + @@ -0,0 +1 @@ + +c/d/file_cd2 + \ No newline at end of file + + + + $ josh-filter -s :PATHS:/a master --update refs/josh/filtered + [1] :/a + [3] :/c + [3] :PATHS + [16] _paths + + $ git log --graph --pretty=%s refs/josh/filtered + * add dirs + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + |-- file_a2 + `-- workspace.josh + + 0 directories, 2 files + + + $ josh-filter -s :PATHS:exclude[::c/]:prefix=x master --update refs/josh/filtered + [1] :/a + [1] :exclude[::c/] + [1] :prefix=x + [3] :/c + [3] :PATHS + [3] :prefix=c + [16] _paths + + $ git log --graph --pretty=%s refs/josh/filtered + * add dirs + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + `-- x + |-- a + | |-- file_a2 + | `-- workspace.josh + `-- b + `-- file_b1 + + 3 directories, 3 files + + $ git diff $EMPTY_TREE HEAD + diff --git a/x/a/file_a2 b/x/a/file_a2 + new file mode 100644 + index 0000000..4b2f88e + --- /dev/null + +++ b/x/a/file_a2 + @@ -0,0 +1 @@ + +a/file_a2 + \ No newline at end of file + diff --git a/x/a/workspace.josh b/x/a/workspace.josh + new file mode 100644 + index 0000000..c9acb10 + --- /dev/null + +++ b/x/a/workspace.josh + @@ -0,0 +1,2 @@ + +#a/workspace.josh + +cws = :/c + diff --git a/x/b/file_b1 b/x/b/file_b1 + new file mode 100644 + index 0000000..413b4ca + --- /dev/null + +++ b/x/b/file_b1 + @@ -0,0 +1 @@ + +b/file_b1 + \ No newline at end of file + + + $ josh-filter -s :PATHS:INVERT master --update refs/josh/filtered + [1] :/a + [1] :exclude[::c/] + [1] :prefix=x + [3] :/c + [3] :INVERT + [3] :PATHS + [3] :prefix=c + [12] _invert + [16] _paths + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + |-- a + | |-- file_a2 + | `-- workspace.josh + |-- b + | `-- file_b1 + `-- c + `-- d + |-- e + | `-- file_cd3 + |-- file_cd + `-- file_cd2 + + 5 directories, 6 files + $ cat a/file_a2 + a/file_a2 (no-eol) + $ cat b/file_b1 + b/file_b1 (no-eol) + + + $ josh-filter -s :PATHS:workspace=a:INVERT master --update refs/josh/filtered + [1] :/a + [1] :exclude[::c/] + [1] :prefix=x + [3] :/c + [3] :PATHS + [3] :prefix=c + [3] :workspace=a + [6] :INVERT + [16] _paths + [22] _invert + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + |-- a + | |-- file_a2 + | `-- workspace.josh + `-- c + `-- d + |-- e + | `-- file_cd3 + |-- file_cd + `-- file_cd2 + + 4 directories, 5 files + + $ git diff $EMPTY_TREE HEAD + diff --git a/a/file_a2 b/a/file_a2 + new file mode 100644 + index 0000000..ee73843 + --- /dev/null + +++ b/a/file_a2 + @@ -0,0 +1 @@ + +file_a2 + \ No newline at end of file + diff --git a/a/workspace.josh b/a/workspace.josh + new file mode 100644 + index 0000000..0ab7ce1 + --- /dev/null + +++ b/a/workspace.josh + @@ -0,0 +1 @@ + +workspace.josh + \ No newline at end of file + diff --git a/c/d/e/file_cd3 b/c/d/e/file_cd3 + new file mode 100644 + index 0000000..ed74419 + --- /dev/null + +++ b/c/d/e/file_cd3 + @@ -0,0 +1 @@ + +cws/d/e/file_cd3 + \ No newline at end of file + diff --git a/c/d/file_cd b/c/d/file_cd + new file mode 100644 + index 0000000..7afa8f7 + --- /dev/null + +++ b/c/d/file_cd + @@ -0,0 +1 @@ + +cws/d/file_cd + \ No newline at end of file + diff --git a/c/d/file_cd2 b/c/d/file_cd2 + new file mode 100644 + index 0000000..4fbc84d + --- /dev/null + +++ b/c/d/file_cd2 + @@ -0,0 +1 @@ + +cws/d/file_cd2 + \ No newline at end of file + + $ josh-filter -s :PATHS:FOLD master --update refs/josh/filtered + [1] :/a + [1] :exclude[::c/] + [1] :prefix=x + [3] :/c + [3] :FOLD + [3] :PATHS + [3] :prefix=c + [3] :workspace=a + [6] :INVERT + [16] _paths + [22] _invert + + + + $ git checkout master 2> /dev/null + $ git rm -r c/d + rm 'c/d/e/file_cd3' + rm 'c/d/file_cd' + rm 'c/d/file_cd2' + $ git commit -m "rm" 1> /dev/null + + $ echo contents2 > a/newfile + $ git add a + $ git commit -m "add newfile" 1> /dev/null + + $ josh-filter -s :PATHS master --update refs/josh/filtered + [1] :/a + [1] :exclude[::c/] + [1] :prefix=x + [3] :/c + [3] :FOLD + [3] :prefix=c + [3] :workspace=a + [5] :PATHS + [6] :INVERT + [19] _paths + [22] _invert + + $ git log --graph --pretty=%s master + * add newfile + * rm + * edit file_cd3 + * add file_cd3 + * add file_cd2 + * add dirs + + $ git log --graph --pretty=%s refs/josh/filtered + * add newfile + * rm + * add file_cd3 + * add file_cd2 + * add dirs + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + |-- a + | |-- file_a2 + | |-- newfile + | `-- workspace.josh + `-- b + `-- file_b1 + + 2 directories, 4 files + + $ git diff $EMPTY_TREE HEAD + diff --git a/a/file_a2 b/a/file_a2 + new file mode 100644 + index 0000000..4b2f88e + --- /dev/null + +++ b/a/file_a2 + @@ -0,0 +1 @@ + +a/file_a2 + \ No newline at end of file + diff --git a/a/newfile b/a/newfile + new file mode 100644 + index 0000000..17b95ba + --- /dev/null + +++ b/a/newfile + @@ -0,0 +1 @@ + +a/newfile + \ No newline at end of file + diff --git a/a/workspace.josh b/a/workspace.josh + new file mode 100644 + index 0000000..c9acb10 + --- /dev/null + +++ b/a/workspace.josh + @@ -0,0 +1,2 @@ + +#a/workspace.josh + +cws = :/c + diff --git a/b/file_b1 b/b/file_b1 + new file mode 100644 + index 0000000..413b4ca + --- /dev/null + +++ b/b/file_b1 + @@ -0,0 +1 @@ + +b/file_b1 + \ No newline at end of file + + + $ git log --graph --pretty=%s refs/josh/filtered + * add newfile + * rm + * add file_cd3 + * add file_cd2 + * add dirs + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + |-- a + | |-- file_a2 + | |-- newfile + | `-- workspace.josh + `-- b + `-- file_b1 + + 2 directories, 4 files + + $ git diff $EMPTY_TREE HEAD + diff --git a/a/file_a2 b/a/file_a2 + new file mode 100644 + index 0000000..4b2f88e + --- /dev/null + +++ b/a/file_a2 + @@ -0,0 +1 @@ + +a/file_a2 + \ No newline at end of file + diff --git a/a/newfile b/a/newfile + new file mode 100644 + index 0000000..17b95ba + --- /dev/null + +++ b/a/newfile + @@ -0,0 +1 @@ + +a/newfile + \ No newline at end of file + diff --git a/a/workspace.josh b/a/workspace.josh + new file mode 100644 + index 0000000..c9acb10 + --- /dev/null + +++ b/a/workspace.josh + @@ -0,0 +1,2 @@ + +#a/workspace.josh + +cws = :/c + diff --git a/b/file_b1 b/b/file_b1 + new file mode 100644 + index 0000000..413b4ca + --- /dev/null + +++ b/b/file_b1 + @@ -0,0 +1 @@ + +b/file_b1 + \ No newline at end of file + + + + $ josh-filter -s :PATHS:/c:FOLD master --update refs/josh/filtered + [1] :/a + [1] :exclude[::c/] + [1] :prefix=x + [3] :prefix=c + [3] :workspace=a + [4] :/c + [5] :PATHS + [6] :FOLD + [6] :INVERT + [19] _paths + [22] _invert + + $ git log --graph --pretty=%s refs/josh/filtered + * add file_cd3 + * add file_cd2 + * add dirs + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + `-- d + |-- e + | `-- file_cd3 + |-- file_cd + `-- file_cd2 + + 2 directories, 3 files + + $ git diff $EMPTY_TREE HEAD + diff --git a/d/e/file_cd3 b/d/e/file_cd3 + new file mode 100644 + index 0000000..8719808 + --- /dev/null + +++ b/d/e/file_cd3 + @@ -0,0 +1 @@ + +c/d/e/file_cd3 + \ No newline at end of file + diff --git a/d/file_cd b/d/file_cd + new file mode 100644 + index 0000000..bb36c67 + --- /dev/null + +++ b/d/file_cd + @@ -0,0 +1 @@ + +c/d/file_cd + \ No newline at end of file + diff --git a/d/file_cd2 b/d/file_cd2 + new file mode 100644 + index 0000000..26318eb + --- /dev/null + +++ b/d/file_cd2 + @@ -0,0 +1 @@ + +c/d/file_cd2 + \ No newline at end of file + + + + $ josh-filter -s :PATHS:workspace=a:FOLD master --update refs/josh/filtered + [1] :/a + [1] :exclude[::c/] + [1] :prefix=x + [3] :prefix=c + [4] :/c + [5] :PATHS + [5] :workspace=a + [6] :INVERT + [10] :FOLD + [19] _paths + [22] _invert + + $ git log --graph --pretty=%s refs/josh/filtered + * add newfile + * add file_cd3 + * add file_cd2 + * add dirs + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + |-- cws + | `-- d + | |-- e + | | `-- file_cd3 + | |-- file_cd + | `-- file_cd2 + |-- file_a2 + |-- newfile + `-- workspace.josh + + 3 directories, 6 files + + $ git diff $EMPTY_TREE HEAD + diff --git a/cws/d/e/file_cd3 b/cws/d/e/file_cd3 + new file mode 100644 + index 0000000..8719808 + --- /dev/null + +++ b/cws/d/e/file_cd3 + @@ -0,0 +1 @@ + +c/d/e/file_cd3 + \ No newline at end of file + diff --git a/cws/d/file_cd b/cws/d/file_cd + new file mode 100644 + index 0000000..bb36c67 + --- /dev/null + +++ b/cws/d/file_cd + @@ -0,0 +1 @@ + +c/d/file_cd + \ No newline at end of file + diff --git a/cws/d/file_cd2 b/cws/d/file_cd2 + new file mode 100644 + index 0000000..26318eb + --- /dev/null + +++ b/cws/d/file_cd2 + @@ -0,0 +1 @@ + +c/d/file_cd2 + \ No newline at end of file + diff --git a/file_a2 b/file_a2 + new file mode 100644 + index 0000000..4b2f88e + --- /dev/null + +++ b/file_a2 + @@ -0,0 +1 @@ + +a/file_a2 + \ No newline at end of file + diff --git a/newfile b/newfile + new file mode 100644 + index 0000000..17b95ba + --- /dev/null + +++ b/newfile + @@ -0,0 +1 @@ + +a/newfile + \ No newline at end of file + diff --git a/workspace.josh b/workspace.josh + new file mode 100644 + index 0000000..c9acb10 + --- /dev/null + +++ b/workspace.josh + @@ -0,0 +1,2 @@ + +#a/workspace.josh + +cws = :/c + diff --git a/tests/filter/permissions/permissions.t b/tests/filter/permissions/permissions.t new file mode 100644 index 000000000..4a10d1686 --- /dev/null +++ b/tests/filter/permissions/permissions.t @@ -0,0 +1,713 @@ + $ export TESTTMP=${PWD} + + $ . ${TESTDIR}/setup_repo.sh + +# acl + $ cat << EOF > users.yaml + > LMG: + > groups: ["dev"] + > CSchilling: + > groups: ["dev2"] + > EOF + $ cat << EOF > groups.yaml + > test: + > dev: + > whitelist: ":/" + > blacklist: ":empty" + > dev2: + > blacklist: ":empty" + > whitelist: | + > :[ + > ::b/ + > ::a/ + > ] + > EOF + +# doesn't work + $ josh-filter -s :/ master --check-permission --users users.yaml --groups groups.yaml -u CSchilling -r test --update refs/josh/filtered + w: Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))]), b: Empty + [1] :/a + [1] :/b + [1] :[ + ::a/ + ::b/ + ] + [1] :prefix=a + [1] :prefix=b + [3] :INVERT + [3] :PATHS + [3] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [12] _invert + [16] _paths + ERROR: JoshError("missing permissions for ref") + [1] + + $ josh-filter -s :/ master --check-permission --missing-permission --users users.yaml --groups groups.yaml -u CSchilling -r test --update refs/josh/filtered + w: Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))]), b: Empty + [1] :/a + [1] :/b + [1] :[ + ::a/ + ::b/ + ] + [1] :prefix=a + [1] :prefix=b + [3] :INVERT + [3] :PATHS + [3] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [12] _invert + [16] _paths + $ git checkout refs/josh/filtered + Note: switching to 'refs/josh/filtered'. + + You are in 'detached HEAD' state. You can look around, make experimental + changes and commit them, and you can discard any commits you make in this + state without impacting any branches by switching back to a branch. + + If you want to create a new branch to retain commits you create, you may + do so (now or later) by using -c with the switch command. Example: + + git switch -c + + Or undo this operation with: + + git switch - + + Turn off this advice by setting config variable advice.detachedHead to false + + HEAD is now at c6749dc add file_cd3 + $ tree + . + |-- c + | `-- d + | |-- e + | | `-- file_cd3 + | |-- file_cd + | `-- file_cd2 + |-- groups.yaml + `-- users.yaml + + 3 directories, 5 files + $ cat b/file_b1 + cat: b/file_b1: No such file or directory + [1] + $ git log + commit c6749dc54b9f93d87e04e89900c0ca1e730c0ca4 + Author: Josh + Date: Thu Apr 7 22:13:13 2005 +0000 + + add file_cd3 + + commit 58bed947100bda96f7b2a90df2623e1cdee685e5 + Author: Josh + Date: Thu Apr 7 22:13:13 2005 +0000 + + add file_cd2 + + commit 838b5164aff95c891164bfc0ed8611dc008c39ea + Author: Josh + Date: Thu Apr 7 22:13:13 2005 +0000 + + add dirs + +# works + $ josh-filter -s :[::b/,::a/] master --check-permission --users users.yaml --groups groups.yaml -u CSchilling -r test --update refs/josh/filtered + w: Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))]), b: Empty + [2] :prefix=b + [3] :PATHS + [3] :prefix=a + [4] :/a + [4] :/b + [4] :INVERT + [4] :[ + ::a/ + ::b/ + ] + [4] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [13] _invert + [16] _paths + $ git checkout refs/josh/filtered + Warning: you are leaving 3 commits behind, not connected to + any of your branches: + + c6749dc add file_cd3 + 58bed94 add file_cd2 + 838b516 add dirs + + If you want to keep them by creating a new branch, this may be a good time + to do so with: + + git branch c6749dc + + HEAD is now at 3259647 add dirs + $ tree + . + |-- a + | |-- file_a2 + | `-- workspace.josh + |-- b + | `-- file_b1 + |-- groups.yaml + `-- users.yaml + + 2 directories, 5 files + $ cat b/file_b1 + contents1 + $ josh-filter -s :[::b/,::a/] master --check-permission --missing-permission --users users.yaml --groups groups.yaml -u CSchilling -r test --update refs/josh/filtered + w: Compose([Chain(Subdir("a"), Prefix("a")), Chain(Subdir("b"), Prefix("b"))]), b: Empty + [2] :prefix=b + [3] :PATHS + [3] :prefix=a + [4] :/a + [4] :/b + [4] :INVERT + [4] :[ + ::a/ + ::b/ + ] + [4] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [13] _invert + [16] _paths + $ git checkout refs/josh/filtered + HEAD is now at 3259647 add dirs + $ tree + . + |-- a + | |-- file_a2 + | `-- workspace.josh + |-- b + | `-- file_b1 + |-- groups.yaml + `-- users.yaml + + 2 directories, 5 files + $ git log + commit 3259647798774e12c657ea4cb057c61b1233165a + Author: Josh + Date: Thu Apr 7 22:13:13 2005 +0000 + + add dirs + $ cat b/file_b1 + contents1 +# doesn't work + $ josh-filter -s :/ master --check-permission --users users.yaml --groups groups.yaml -u bob -r test --update refs/josh/filtered + [2] :prefix=b + [3] :PATHS + [3] :prefix=a + [4] :/a + [4] :/b + [4] :INVERT + [4] :[ + ::a/ + ::b/ + ] + [4] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [13] _invert + [16] _paths + ERROR: JoshError("missing permissions for ref") + [1] +# works + $ josh-filter -s :/ master --check-permission --users users.yaml --groups groups.yaml -u LMG -r test --update refs/josh/filtered + w: Nop, b: Empty + [2] :prefix=b + [3] :PATHS + [3] :prefix=a + [4] :/a + [4] :/b + [4] :INVERT + [4] :[ + ::a/ + ::b/ + ] + [4] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [13] _invert + [16] _paths + + $ git diff $EMPTY_TREE HEAD + diff --git a/a/file_a2 b/a/file_a2 + new file mode 100644 + index 0000000..a024003 + --- /dev/null + +++ b/a/file_a2 + @@ -0,0 +1 @@ + +contents1 + diff --git a/a/workspace.josh b/a/workspace.josh + new file mode 100644 + index 0000000..3af54d0 + --- /dev/null + +++ b/a/workspace.josh + @@ -0,0 +1 @@ + +cws = :/c + diff --git a/b/file_b1 b/b/file_b1 + new file mode 100644 + index 0000000..a024003 + --- /dev/null + +++ b/b/file_b1 + @@ -0,0 +1 @@ + +contents1 + + + $ josh-filter -s :PATHS:workspace=a:INVERT master --update refs/josh/filtered + [2] :prefix=b + [3] :PATHS + [3] :prefix=a + [3] :workspace=a + [4] :/a + [4] :/b + [4] :[ + ::a/ + ::b/ + ] + [4] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [7] :INVERT + [16] _paths + [23] _invert + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + |-- a + | |-- file_a2 + | `-- workspace.josh + |-- c + | `-- d + | |-- e + | | `-- file_cd3 + | |-- file_cd + | `-- file_cd2 + |-- groups.yaml + `-- users.yaml + + 4 directories, 7 files + + $ git diff $EMPTY_TREE HEAD + diff --git a/a/file_a2 b/a/file_a2 + new file mode 100644 + index 0000000..ee73843 + --- /dev/null + +++ b/a/file_a2 + @@ -0,0 +1 @@ + +file_a2 + \ No newline at end of file + diff --git a/a/workspace.josh b/a/workspace.josh + new file mode 100644 + index 0000000..0ab7ce1 + --- /dev/null + +++ b/a/workspace.josh + @@ -0,0 +1 @@ + +workspace.josh + \ No newline at end of file + diff --git a/c/d/e/file_cd3 b/c/d/e/file_cd3 + new file mode 100644 + index 0000000..ed74419 + --- /dev/null + +++ b/c/d/e/file_cd3 + @@ -0,0 +1 @@ + +cws/d/e/file_cd3 + \ No newline at end of file + diff --git a/c/d/file_cd b/c/d/file_cd + new file mode 100644 + index 0000000..7afa8f7 + --- /dev/null + +++ b/c/d/file_cd + @@ -0,0 +1 @@ + +cws/d/file_cd + \ No newline at end of file + diff --git a/c/d/file_cd2 b/c/d/file_cd2 + new file mode 100644 + index 0000000..4fbc84d + --- /dev/null + +++ b/c/d/file_cd2 + @@ -0,0 +1 @@ + +cws/d/file_cd2 + \ No newline at end of file + + $ josh-filter -s :PATHS:FOLD master --update refs/josh/filtered + [2] :prefix=b + [3] :FOLD + [3] :PATHS + [3] :prefix=a + [3] :workspace=a + [4] :/a + [4] :/b + [4] :[ + ::a/ + ::b/ + ] + [4] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [7] :INVERT + [16] _paths + [23] _invert + + + + $ git checkout master 2> /dev/null + $ git rm -r c/d + rm 'c/d/e/file_cd3' + rm 'c/d/file_cd' + rm 'c/d/file_cd2' + $ git commit -m "rm" 1> /dev/null + + $ echo contents2 > a/newfile + $ git add a + $ git commit -m "add newfile" 1> /dev/null + + $ josh-filter -s :PATHS master --update refs/josh/filtered + [2] :prefix=b + [3] :FOLD + [3] :prefix=a + [3] :workspace=a + [4] :/a + [4] :/b + [4] :[ + ::a/ + ::b/ + ] + [4] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [5] :PATHS + [7] :INVERT + [19] _paths + [23] _invert + + $ git log --graph --pretty=%s master + * add newfile + * rm + * edit file_cd3 + * add file_cd3 + * add file_cd2 + * add dirs + + $ git log --graph --pretty=%s refs/josh/filtered + * add newfile + * rm + * add file_cd3 + * add file_cd2 + * add dirs + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + |-- a + | |-- file_a2 + | |-- newfile + | `-- workspace.josh + |-- b + | `-- file_b1 + |-- groups.yaml + `-- users.yaml + + 2 directories, 6 files + + $ git diff $EMPTY_TREE HEAD + diff --git a/a/file_a2 b/a/file_a2 + new file mode 100644 + index 0000000..4b2f88e + --- /dev/null + +++ b/a/file_a2 + @@ -0,0 +1 @@ + +a/file_a2 + \ No newline at end of file + diff --git a/a/newfile b/a/newfile + new file mode 100644 + index 0000000..17b95ba + --- /dev/null + +++ b/a/newfile + @@ -0,0 +1 @@ + +a/newfile + \ No newline at end of file + diff --git a/a/workspace.josh b/a/workspace.josh + new file mode 100644 + index 0000000..c9acb10 + --- /dev/null + +++ b/a/workspace.josh + @@ -0,0 +1,2 @@ + +#a/workspace.josh + +cws = :/c + diff --git a/b/file_b1 b/b/file_b1 + new file mode 100644 + index 0000000..413b4ca + --- /dev/null + +++ b/b/file_b1 + @@ -0,0 +1 @@ + +b/file_b1 + \ No newline at end of file + + + $ git log --graph --pretty=%s refs/josh/filtered + * add newfile + * rm + * add file_cd3 + * add file_cd2 + * add dirs + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + |-- a + | |-- file_a2 + | |-- newfile + | `-- workspace.josh + |-- b + | `-- file_b1 + |-- groups.yaml + `-- users.yaml + + 2 directories, 6 files + + $ git diff $EMPTY_TREE HEAD + diff --git a/a/file_a2 b/a/file_a2 + new file mode 100644 + index 0000000..4b2f88e + --- /dev/null + +++ b/a/file_a2 + @@ -0,0 +1 @@ + +a/file_a2 + \ No newline at end of file + diff --git a/a/newfile b/a/newfile + new file mode 100644 + index 0000000..17b95ba + --- /dev/null + +++ b/a/newfile + @@ -0,0 +1 @@ + +a/newfile + \ No newline at end of file + diff --git a/a/workspace.josh b/a/workspace.josh + new file mode 100644 + index 0000000..c9acb10 + --- /dev/null + +++ b/a/workspace.josh + @@ -0,0 +1,2 @@ + +#a/workspace.josh + +cws = :/c + diff --git a/b/file_b1 b/b/file_b1 + new file mode 100644 + index 0000000..413b4ca + --- /dev/null + +++ b/b/file_b1 + @@ -0,0 +1 @@ + +b/file_b1 + \ No newline at end of file + + + + $ josh-filter -s :PATHS:/c:FOLD master --update refs/josh/filtered + [2] :prefix=b + [3] :prefix=a + [3] :workspace=a + [4] :/a + [4] :/b + [4] :/c + [4] :[ + ::a/ + ::b/ + ] + [4] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [5] :PATHS + [6] :FOLD + [7] :INVERT + [19] _paths + [23] _invert + + $ git log --graph --pretty=%s refs/josh/filtered + * add file_cd3 + * add file_cd2 + * add dirs + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + |-- d + | |-- e + | | `-- file_cd3 + | |-- file_cd + | `-- file_cd2 + |-- groups.yaml + `-- users.yaml + + 2 directories, 5 files + + $ git diff $EMPTY_TREE HEAD + diff --git a/d/e/file_cd3 b/d/e/file_cd3 + new file mode 100644 + index 0000000..8719808 + --- /dev/null + +++ b/d/e/file_cd3 + @@ -0,0 +1 @@ + +c/d/e/file_cd3 + \ No newline at end of file + diff --git a/d/file_cd b/d/file_cd + new file mode 100644 + index 0000000..bb36c67 + --- /dev/null + +++ b/d/file_cd + @@ -0,0 +1 @@ + +c/d/file_cd + \ No newline at end of file + diff --git a/d/file_cd2 b/d/file_cd2 + new file mode 100644 + index 0000000..26318eb + --- /dev/null + +++ b/d/file_cd2 + @@ -0,0 +1 @@ + +c/d/file_cd2 + \ No newline at end of file + + + + $ josh-filter -s :PATHS:workspace=a:FOLD master --update refs/josh/filtered + [2] :prefix=b + [3] :prefix=a + [4] :/a + [4] :/b + [4] :/c + [4] :[ + ::a/ + ::b/ + ] + [4] :subtract[ + :/ + :[ + ::a/ + ::b/ + ] + ] + [5] :PATHS + [5] :workspace=a + [7] :INVERT + [10] :FOLD + [19] _paths + [23] _invert + + $ git log --graph --pretty=%s refs/josh/filtered + * add newfile + * add file_cd3 + * add file_cd2 + * add dirs + + $ git checkout refs/josh/filtered 2> /dev/null + $ tree + . + |-- cws + | `-- d + | |-- e + | | `-- file_cd3 + | |-- file_cd + | `-- file_cd2 + |-- file_a2 + |-- groups.yaml + |-- newfile + |-- users.yaml + `-- workspace.josh + + 3 directories, 8 files + + $ git diff $EMPTY_TREE HEAD + diff --git a/cws/d/e/file_cd3 b/cws/d/e/file_cd3 + new file mode 100644 + index 0000000..8719808 + --- /dev/null + +++ b/cws/d/e/file_cd3 + @@ -0,0 +1 @@ + +c/d/e/file_cd3 + \ No newline at end of file + diff --git a/cws/d/file_cd b/cws/d/file_cd + new file mode 100644 + index 0000000..bb36c67 + --- /dev/null + +++ b/cws/d/file_cd + @@ -0,0 +1 @@ + +c/d/file_cd + \ No newline at end of file + diff --git a/cws/d/file_cd2 b/cws/d/file_cd2 + new file mode 100644 + index 0000000..26318eb + --- /dev/null + +++ b/cws/d/file_cd2 + @@ -0,0 +1 @@ + +c/d/file_cd2 + \ No newline at end of file + diff --git a/file_a2 b/file_a2 + new file mode 100644 + index 0000000..4b2f88e + --- /dev/null + +++ b/file_a2 + @@ -0,0 +1 @@ + +a/file_a2 + \ No newline at end of file + diff --git a/newfile b/newfile + new file mode 100644 + index 0000000..17b95ba + --- /dev/null + +++ b/newfile + @@ -0,0 +1 @@ + +a/newfile + \ No newline at end of file + diff --git a/workspace.josh b/workspace.josh + new file mode 100644 + index 0000000..c9acb10 + --- /dev/null + +++ b/workspace.josh + @@ -0,0 +1,2 @@ + +#a/workspace.josh + +cws = :/c + diff --git a/tests/filter/permissions/setup_repo.sh b/tests/filter/permissions/setup_repo.sh new file mode 100644 index 000000000..bd8e5d47d --- /dev/null +++ b/tests/filter/permissions/setup_repo.sh @@ -0,0 +1,29 @@ +cd ${TESTTMP} +git init 1> /dev/null + +mkdir a +echo "cws = :/c" > a/workspace.josh +echo contents1 > a/file_a2 +git add a + +mkdir b +echo contents1 > b/file_b1 +git add b + +mkdir -p c/d +echo contents1 > c/d/file_cd +git add c +git commit -m "add dirs" 1> /dev/null + +echo contents2 > c/d/file_cd2 +git add c +git commit -m "add file_cd2" 1> /dev/null + +mkdir -p c/d/e +echo contents2 > c/d/e/file_cd3 +git add c +git commit -m "add file_cd3" 1> /dev/null + +echo contents3 >> c/d/e/file_cd3 +git add c +git commit -m "edit file_cd3" 1> /dev/null