Skip to content

Commit a4d3dcd

Browse files
committed
Add ACL toml file
1 parent b5e7c1f commit a4d3dcd

File tree

3 files changed

+155
-13
lines changed

3 files changed

+155
-13
lines changed

src/bin/josh-filter.rs

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,24 @@ fn run_filter(args: Vec<String>) -> josh::JoshResult<i32> {
115115
.short("b")
116116
.takes_value(true),
117117
)
118+
.arg(
119+
clap::Arg::with_name("acl")
120+
.long("acl")
121+
.short("a")
122+
.takes_value(true),
123+
)
124+
.arg(
125+
clap::Arg::with_name("user")
126+
.long("user")
127+
.short("u")
128+
.takes_value(true),
129+
)
130+
.arg(
131+
clap::Arg::with_name("repo")
132+
.long("repo")
133+
.short("r")
134+
.takes_value(true),
135+
)
118136
.arg(clap::Arg::with_name("version").long("version").short("v"))
119137
.get_matches_from(args);
120138

@@ -222,14 +240,25 @@ fn run_filter(args: Vec<String>) -> josh::JoshResult<i32> {
222240
let check_permissions = args.is_present("check-permission");
223241
let mut permissions_filter = josh::filter::empty();
224242
if check_permissions {
225-
let whitelist = match args.value_of("whitelist") {
226-
Some(s) => josh::filter::parse(s)?,
227-
_ => josh::filter::nop(),
228-
};
229-
let blacklist = match args.value_of("blacklist") {
230-
Some(s) => josh::filter::parse(s)?,
231-
_ => josh::filter::empty(),
232-
};
243+
let whitelist;
244+
let blacklist;
245+
if args.is_present("acl") && args.is_present("user") && args.is_present("repo") {
246+
let acl = args.value_of("acl").unwrap();
247+
let user = args.value_of("user").unwrap();
248+
let repo = args.value_of("repo").unwrap();
249+
250+
whitelist = josh::get_whitelist(acl, user, repo)?;
251+
blacklist = josh::get_blacklist(acl, user, repo)?;
252+
} else {
253+
whitelist = match args.value_of("whitelist") {
254+
Some(s) => josh::filter::parse(s)?,
255+
_ => josh::filter::nop(),
256+
};
257+
blacklist = match args.value_of("blacklist") {
258+
Some(s) => josh::filter::parse(s)?,
259+
_ => josh::filter::empty(),
260+
};
261+
}
233262
permissions_filter = josh::filter::make_permissions_filter(filterobj, whitelist, blacklist)
234263
}
235264

src/lib.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,3 +298,67 @@ pub fn normalize_path(path: &std::path::Path) -> std::path::PathBuf {
298298
}
299299
ret
300300
}
301+
302+
#[derive(Debug, serde::Deserialize)]
303+
struct Acl {
304+
pub repo: Vec<Repo>,
305+
}
306+
307+
#[derive(Debug, serde::Deserialize)]
308+
struct Repo {
309+
pub name: String,
310+
pub user: Vec<User>,
311+
}
312+
313+
#[derive(Debug, serde::Deserialize)]
314+
struct User {
315+
pub name: String,
316+
pub whitelist: Option<String>,
317+
pub blacklist: Option<String>,
318+
}
319+
320+
pub fn get_whitelist(acl: &str, user: &str, repo: &str) -> JoshResult<filter::Filter> {
321+
let acl = std::fs::read_to_string(acl).map_err(|_| josh_error("failed to read acl file"))?;
322+
let acl: Acl = toml::from_str(&acl)
323+
.map_err(|err| josh_error(format!("failed to parse acl file: {}", err).as_str()))?;
324+
for r in acl.repo {
325+
if r.name == repo {
326+
for u in r.user {
327+
if u.name == user {
328+
match u.whitelist {
329+
Some(w) => {
330+
let filter = filter::parse(&w)?;
331+
return Ok(filter);
332+
}
333+
_ => return Ok(filter::empty()),
334+
}
335+
}
336+
}
337+
}
338+
}
339+
340+
return Ok(filter::empty());
341+
}
342+
343+
pub fn get_blacklist(acl: &str, user: &str, repo: &str) -> JoshResult<filter::Filter> {
344+
let acl = std::fs::read_to_string(acl).map_err(|_| josh_error("failed to read acl file"))?;
345+
let acl: Acl = toml::from_str(&acl)
346+
.map_err(|err| josh_error(format!("failed to parse acl file: {}", err).as_str()))?;
347+
for r in acl.repo {
348+
if r.name == repo {
349+
for u in r.user {
350+
if u.name == user {
351+
match u.blacklist {
352+
Some(b) => {
353+
let filter = filter::parse(&b)?;
354+
return Ok(filter);
355+
}
356+
_ => return Ok(filter::nop()),
357+
}
358+
}
359+
}
360+
}
361+
}
362+
363+
return Ok(filter::nop());
364+
}

tests/filter/permissions.t

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,50 @@
402402
[13] _invert
403403
[16] _paths
404404

405+
# acl
406+
$ cat << EOF > acl.toml
407+
> [[repo]]
408+
> name = "test"
409+
> [[repo.user]]
410+
> name = "LMG"
411+
> whitelist = ":/"
412+
> blacklist = ":empty"
413+
>
414+
> EOF
415+
$ josh-filter -s :/ master --check-permission -a acl.toml -u bob -r test --update refs/josh/filtered
416+
Warning: reference refs/josh/filtered wasn't updated
417+
[1] :[
418+
:/b
419+
:exclude[:/b]
420+
]
421+
[1] :exclude[:/a]
422+
[1] :exclude[:/b]
423+
[1] :exclude[:/c]
424+
[1] :prefix=x
425+
[2] :/a
426+
[3] :/b
427+
[3] :/c
428+
[3] :PATHS
429+
[4] :INVERT
430+
[13] _invert
431+
[16] _paths
432+
$ josh-filter -s :/ master --check-permission -a acl.toml -u LMG -r test --update refs/josh/filtered
433+
[1] :[
434+
:/b
435+
:exclude[:/b]
436+
]
437+
[1] :exclude[:/a]
438+
[1] :exclude[:/b]
439+
[1] :exclude[:/c]
440+
[1] :prefix=x
441+
[2] :/a
442+
[3] :/b
443+
[3] :/c
444+
[3] :PATHS
445+
[4] :INVERT
446+
[13] _invert
447+
[16] _paths
448+
405449
$ git diff $EMPTY_TREE HEAD
406450
diff --git a/a/file_a2 b/a/file_a2
407451
new file mode 100644
@@ -482,14 +526,15 @@
482526
|-- a
483527
| |-- file_a2
484528
| `-- workspace.josh
529+
|-- acl.toml
485530
`-- c
486531
`-- d
487532
|-- e
488533
| `-- file_cd3
489534
|-- file_cd
490535
`-- file_cd2
491536
492-
4 directories, 5 files
537+
4 directories, 6 files
493538
494539
$ git diff $EMPTY_TREE HEAD
495540
diff --git a/a/file_a2 b/a/file_a2
@@ -626,10 +671,11 @@
626671
| |-- file_a2
627672
| |-- newfile
628673
| `-- workspace.josh
674+
|-- acl.toml
629675
`-- b
630676
`-- file_b1
631677
632-
2 directories, 4 files
678+
2 directories, 5 files
633679
634680
$ git diff $EMPTY_TREE HEAD
635681
diff --git a/a/file_a2 b/a/file_a2
@@ -680,10 +726,11 @@
680726
| |-- file_a2
681727
| |-- newfile
682728
| `-- workspace.josh
729+
|-- acl.toml
683730
`-- b
684731
`-- file_b1
685732
686-
2 directories, 4 files
733+
2 directories, 5 files
687734
688735
$ git diff $EMPTY_TREE HEAD
689736
diff --git a/a/file_a2 b/a/file_a2
@@ -758,13 +805,14 @@
758805
$ git checkout refs/josh/filtered 2> /dev/null
759806
$ tree
760807
.
808+
|-- acl.toml
761809
`-- d
762810
|-- e
763811
| `-- file_cd3
764812
|-- file_cd
765813
`-- file_cd2
766814
767-
2 directories, 3 files
815+
2 directories, 4 files
768816
769817
$ git diff $EMPTY_TREE HEAD
770818
diff --git a/d/e/file_cd3 b/d/e/file_cd3
@@ -832,6 +880,7 @@
832880
$ git checkout refs/josh/filtered 2> /dev/null
833881
$ tree
834882
.
883+
|-- acl.toml
835884
|-- cws
836885
| `-- d
837886
| |-- e
@@ -842,7 +891,7 @@
842891
|-- newfile
843892
`-- workspace.josh
844893
845-
3 directories, 6 files
894+
3 directories, 7 files
846895
847896
$ git diff $EMPTY_TREE HEAD
848897
diff --git a/cws/d/e/file_cd3 b/cws/d/e/file_cd3

0 commit comments

Comments
 (0)