Skip to content

Commit b53ff15

Browse files
committed
Add access groups
1 parent b80be6d commit b53ff15

File tree

3 files changed

+107
-69
lines changed

3 files changed

+107
-69
lines changed

src/bin/josh-filter.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,13 @@ fn run_filter(args: Vec<String>) -> josh::JoshResult<i32> {
116116
.takes_value(true),
117117
)
118118
.arg(
119-
clap::Arg::with_name("acl")
120-
.long("acl")
121-
.short("a")
119+
clap::Arg::with_name("users")
120+
.long("users")
121+
.takes_value(true),
122+
)
123+
.arg(
124+
clap::Arg::with_name("groups")
125+
.long("groups")
122126
.takes_value(true),
123127
)
124128
.arg(
@@ -242,13 +246,19 @@ fn run_filter(args: Vec<String>) -> josh::JoshResult<i32> {
242246
if check_permissions {
243247
let whitelist;
244248
let blacklist;
245-
if args.is_present("acl") && args.is_present("user") && args.is_present("repo") {
246-
let acl = args.value_of("acl").unwrap();
249+
if args.is_present("users")
250+
&& args.is_present("groups")
251+
&& args.is_present("user")
252+
&& args.is_present("repo")
253+
{
254+
let users = args.value_of("users").unwrap();
255+
let groups = args.value_of("groups").unwrap();
247256
let user = args.value_of("user").unwrap();
248257
let repo = args.value_of("repo").unwrap();
249258

250-
whitelist = josh::get_whitelist(acl, user, repo)?;
251-
blacklist = josh::get_blacklist(acl, user, repo)?;
259+
let acl = josh::get_acl(users, groups, user, repo)?;
260+
whitelist = acl.0;
261+
blacklist = acl.1;
252262
} else {
253263
whitelist = match args.value_of("whitelist") {
254264
Some(s) => josh::filter::parse(s)?,

src/lib.rs

Lines changed: 51 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -302,42 +302,62 @@ pub fn normalize_path(path: &std::path::Path) -> std::path::PathBuf {
302302
ret
303303
}
304304

305-
type Acl = HashMap<String, HashMap<String, User>>;
305+
type Users = HashMap<String, User>;
306306

307307
#[derive(Debug, serde::Deserialize)]
308308
struct User {
309-
pub whitelist: Option<String>,
310-
pub blacklist: Option<String>,
309+
pub groups: toml::value::Array,
311310
}
312311

313-
pub fn get_whitelist(acl: &str, user: &str, repo: &str) -> JoshResult<filter::Filter> {
314-
let acl = std::fs::read_to_string(acl).map_err(|_| josh_error("failed to read acl file"))?;
315-
let acl: Acl = toml::from_str(&acl)
316-
.map_err(|err| josh_error(format!("failed to parse acl file: {}", err).as_str()))?;
317-
return Ok(match acl.get(repo) {
318-
Some(r) => match r.get(user) {
319-
Some(u) => match &u.whitelist {
320-
Some(w) => filter::parse(&w)?,
321-
_ => filter::nop(),
322-
},
323-
_ => filter::empty(),
324-
},
325-
_ => filter::empty(),
326-
});
312+
type Groups = HashMap<String, HashMap<String, Group>>;
313+
#[derive(Debug, serde::Deserialize)]
314+
struct Group {
315+
pub whitelist: String,
316+
pub blacklist: String,
327317
}
328318

329-
pub fn get_blacklist(acl: &str, user: &str, repo: &str) -> JoshResult<filter::Filter> {
330-
let acl = std::fs::read_to_string(acl).map_err(|_| josh_error("failed to read acl file"))?;
331-
let acl: Acl = toml::from_str(&acl)
332-
.map_err(|err| josh_error(format!("failed to parse acl file: {}", err).as_str()))?;
333-
return Ok(match acl.get(repo) {
334-
Some(r) => match r.get(user) {
335-
Some(u) => match &u.blacklist {
336-
Some(b) => filter::parse(&b)?,
337-
_ => filter::empty(),
338-
},
339-
_ => filter::nop(),
340-
},
341-
_ => filter::nop(),
342-
});
319+
pub fn get_acl(
320+
users: &str,
321+
groups: &str,
322+
user: &str,
323+
repo: &str,
324+
) -> JoshResult<(filter::Filter, filter::Filter)> {
325+
let users =
326+
std::fs::read_to_string(users).map_err(|_| josh_error("failed to read users file"))?;
327+
let users: Users = toml::from_str(&users)
328+
.map_err(|err| josh_error(format!("failed to parse users file: {}", err).as_str()))?;
329+
let groups =
330+
std::fs::read_to_string(groups).map_err(|_| josh_error("failed to read groups file"))?;
331+
let groups: Groups = toml::from_str(&groups)
332+
.map_err(|err| josh_error(format!("failed to parse groups file: {}", err).as_str()))?;
333+
334+
return users
335+
.get(user)
336+
.and_then(|u| {
337+
let mut whitelist = filter::nop();
338+
let mut blacklist = filter::empty();
339+
for g in &u.groups {
340+
let group_lists = groups.get(g.as_str()?).and_then(|group| {
341+
group.get(repo).and_then(|repo| {
342+
let w = filter::parse(&repo.whitelist);
343+
let b = filter::parse(&repo.blacklist);
344+
Some((w, b))
345+
})
346+
})?;
347+
if let Err(e) = group_lists.0 {
348+
return Some(Err(JoshError(format!("Error parsing whitelist: {}", e))));
349+
}
350+
if let Err(e) = group_lists.1 {
351+
return Some(Err(JoshError(format!("Error parsing blacklist: {}", e))));
352+
}
353+
if let Ok(w) = group_lists.0 {
354+
whitelist = filter::compose(whitelist, w);
355+
}
356+
if let Ok(b) = group_lists.1 {
357+
blacklist = filter::compose(blacklist, b);
358+
}
359+
}
360+
Some(Ok((whitelist, blacklist)))
361+
})
362+
.unwrap_or(Ok((filter::empty(), filter::nop())));
343363
}

tests/filter/permissions.t

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -403,15 +403,18 @@
403403
[16] _paths
404404

405405
# acl
406-
$ cat << EOF > acl.toml
407-
> [test]
408-
> [test.LMG]
406+
$ cat << EOF > users.toml
407+
> [LMG]
408+
> groups = ["dev"]
409+
> EOF
410+
$ cat << EOF > groups.toml
411+
> [dev]
412+
> [dev.test]
409413
> whitelist = ":/"
410414
> blacklist = ":empty"
411-
>
412415
> EOF
413416
# doesn't work
414-
$ josh-filter -s :/ master --check-permission -a acl.toml -u bob -r test --update refs/josh/filtered
417+
$ josh-filter -s :/ master --check-permission --users users.toml --groups groups.toml -u bob -r test --update refs/josh/filtered
415418
Warning: reference refs/josh/filtered wasn't updated
416419
[1] :[
417420
:/b
@@ -429,7 +432,7 @@
429432
[13] _invert
430433
[16] _paths
431434
# works
432-
$ josh-filter -s :/ master --check-permission -a acl.toml -u LMG -r test --update refs/josh/filtered
435+
$ josh-filter -s :/ master --check-permission --users users.toml --groups groups.toml -u LMG -r test --update refs/josh/filtered
433436
[1] :[
434437
:/b
435438
:exclude[:/b]
@@ -526,15 +529,16 @@
526529
|-- a
527530
| |-- file_a2
528531
| `-- workspace.josh
529-
|-- acl.toml
530-
`-- c
531-
`-- d
532-
|-- e
533-
| `-- file_cd3
534-
|-- file_cd
535-
`-- file_cd2
532+
|-- c
533+
| `-- d
534+
| |-- e
535+
| | `-- file_cd3
536+
| |-- file_cd
537+
| `-- file_cd2
538+
|-- groups.toml
539+
`-- users.toml
536540

537-
4 directories, 6 files
541+
4 directories, 7 files
538542

539543
$ git diff $EMPTY_TREE HEAD
540544
diff --git a/a/file_a2 b/a/file_a2
@@ -671,11 +675,12 @@
671675
| |-- file_a2
672676
| |-- newfile
673677
| `-- workspace.josh
674-
|-- acl.toml
675-
`-- b
676-
`-- file_b1
678+
|-- b
679+
| `-- file_b1
680+
|-- groups.toml
681+
`-- users.toml
677682

678-
2 directories, 5 files
683+
2 directories, 6 files
679684

680685
$ git diff $EMPTY_TREE HEAD
681686
diff --git a/a/file_a2 b/a/file_a2
@@ -726,11 +731,12 @@
726731
| |-- file_a2
727732
| |-- newfile
728733
| `-- workspace.josh
729-
|-- acl.toml
730-
`-- b
731-
`-- file_b1
734+
|-- b
735+
| `-- file_b1
736+
|-- groups.toml
737+
`-- users.toml
732738

733-
2 directories, 5 files
739+
2 directories, 6 files
734740

735741
$ git diff $EMPTY_TREE HEAD
736742
diff --git a/a/file_a2 b/a/file_a2
@@ -805,14 +811,15 @@
805811
$ git checkout refs/josh/filtered 2> /dev/null
806812
$ tree
807813
.
808-
|-- acl.toml
809-
`-- d
810-
|-- e
811-
| `-- file_cd3
812-
|-- file_cd
813-
`-- file_cd2
814+
|-- d
815+
| |-- e
816+
| | `-- file_cd3
817+
| |-- file_cd
818+
| `-- file_cd2
819+
|-- groups.toml
820+
`-- users.toml
814821

815-
2 directories, 4 files
822+
2 directories, 5 files
816823

817824
$ git diff $EMPTY_TREE HEAD
818825
diff --git a/d/e/file_cd3 b/d/e/file_cd3
@@ -880,18 +887,19 @@
880887
$ git checkout refs/josh/filtered 2> /dev/null
881888
$ tree
882889
.
883-
|-- acl.toml
884890
|-- cws
885891
| `-- d
886892
| |-- e
887893
| | `-- file_cd3
888894
| |-- file_cd
889895
| `-- file_cd2
890896
|-- file_a2
897+
|-- groups.toml
891898
|-- newfile
899+
|-- users.toml
892900
`-- workspace.josh
893901

894-
3 directories, 7 files
902+
3 directories, 8 files
895903

896904
$ git diff $EMPTY_TREE HEAD
897905
diff --git a/cws/d/e/file_cd3 b/cws/d/e/file_cd3

0 commit comments

Comments
 (0)