@@ -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 ) ]
308308struct 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}
0 commit comments