@@ -46,6 +46,7 @@ struct JoshProxyService {
4646 fetch_permits : Arc < tokio:: sync:: Semaphore > ,
4747 filter_permits : Arc < tokio:: sync:: Semaphore > ,
4848 poll : Polls ,
49+ acl : Option < ( String , String ) > ,
4950}
5051
5152impl std:: fmt:: Debug for JoshProxyService {
@@ -244,9 +245,11 @@ async fn do_filter(
244245 temp_ns : Arc < josh_proxy:: TmpGitNamespace > ,
245246 filter_spec : String ,
246247 headref : String ,
248+ user : String ,
247249) -> josh:: JoshResult < ( ) > {
248250 let permit = service. filter_permits . acquire ( ) . await ;
249251 let heads_map = service. heads_map . clone ( ) ;
252+ let acl = service. acl . clone ( ) ;
250253
251254 let s = tracing:: span!( tracing:: Level :: TRACE , "do_filter worker" ) ;
252255 let r = tokio:: task:: spawn_blocking ( move || {
@@ -295,7 +298,28 @@ async fn do_filter(
295298
296299 let mut headref = headref;
297300
298- josh:: filter_refs ( & transaction, filter, & from_to, josh:: filter:: empty ( ) ) ?;
301+ let permissions_filter = if let Some ( acl) = acl {
302+ let users = & acl. 0 ;
303+ let groups = & acl. 1 ;
304+ tracing:: info!( "User: {:?}, Repo: {:?}" , user, upstream_repo) ;
305+ let acl = match josh:: get_acl ( & users, & groups, & user, & upstream_repo) {
306+ Ok ( acl) => acl,
307+ Err ( e) => {
308+ tracing:: error!( "Failed to read ACL file: {:?}" , e) ;
309+ ( josh:: filter:: empty ( ) , josh:: filter:: nop ( ) )
310+ }
311+ } ;
312+ let whitelist = acl. 0 ;
313+ let blacklist = acl. 1 ;
314+ tracing:: info!( "Whitelist: {:?}, Blacklist: {:?}" , whitelist, blacklist) ;
315+ josh:: filter:: make_permissions_filter ( filter, whitelist, blacklist)
316+ } else {
317+ josh:: filter:: empty ( )
318+ } ;
319+
320+ tracing:: info!( "Permissions: {:?}" , permissions_filter) ;
321+
322+ josh:: filter_refs ( & transaction, filter, & from_to, permissions_filter) ?;
299323 if headref == "HEAD" {
300324 headref = heads_map
301325 . read ( ) ?
@@ -517,6 +541,7 @@ async fn call_service(
517541 & parsed_url. upstream_repo ,
518542 & parsed_url. filter ,
519543 & headref,
544+ & username,
520545 )
521546 . in_current_span ( )
522547 . await ?;
@@ -598,6 +623,7 @@ async fn prepare_namespace(
598623 upstream_repo : & str ,
599624 filter_spec : & str ,
600625 headref : & str ,
626+ user : & str ,
601627) -> josh:: JoshResult < std:: sync:: Arc < josh_proxy:: TmpGitNamespace > > {
602628 let temp_ns = Arc :: new ( josh_proxy:: TmpGitNamespace :: new (
603629 & serv. repo_path ,
@@ -606,13 +632,16 @@ async fn prepare_namespace(
606632
607633 let serv = serv. clone ( ) ;
608634
635+ let user = if user == "" { "anonymous" } else { user } ;
636+
609637 do_filter (
610638 serv. repo_path . clone ( ) ,
611639 serv. clone ( ) ,
612640 upstream_repo. to_owned ( ) ,
613641 temp_ns. to_owned ( ) ,
614642 filter_spec. to_owned ( ) ,
615643 headref. to_string ( ) ,
644+ user. to_string ( ) ,
616645 )
617646 . await ?;
618647
@@ -635,6 +664,20 @@ async fn run_proxy() -> josh::JoshResult<i32> {
635664 josh_proxy:: create_repo ( & local) ?;
636665 josh:: cache:: load ( & local) ?;
637666
667+ let acl = if ARGS . is_present ( "users" ) && ARGS . is_present ( "groups" ) {
668+ println ! (
669+ "{}, {}" ,
670+ ARGS . value_of( "users" ) . unwrap( ) . to_string( ) ,
671+ ARGS . value_of( "groups" ) . unwrap( ) . to_string( )
672+ ) ;
673+ Some ( (
674+ ARGS . value_of ( "users" ) . unwrap ( ) . to_string ( ) ,
675+ ARGS . value_of ( "groups" ) . unwrap ( ) . to_string ( ) ,
676+ ) )
677+ } else {
678+ None
679+ } ;
680+
638681 let proxy_service = Arc :: new ( JoshProxyService {
639682 port,
640683 repo_path : local. to_owned ( ) ,
@@ -646,6 +689,7 @@ async fn run_proxy() -> josh::JoshResult<i32> {
646689 ARGS . value_of ( "n" ) . unwrap_or ( "1" ) . parse ( ) ?,
647690 ) ) ,
648691 filter_permits : Arc :: new ( tokio:: sync:: Semaphore :: new ( 10 ) ) ,
692+ acl,
649693 } ) ;
650694
651695 let ps = proxy_service. clone ( ) ;
@@ -800,6 +844,18 @@ fn parse_args() -> clap::ArgMatches<'static> {
800844 . help ( "Duration between forced cache refresh" )
801845 . takes_value ( true ) ,
802846 )
847+ . arg (
848+ clap:: Arg :: with_name ( "users" )
849+ . long ( "users" )
850+ . takes_value ( true )
851+ . help ( "YAML file listing the groups of the users" ) ,
852+ )
853+ . arg (
854+ clap:: Arg :: with_name ( "groups" )
855+ . long ( "groups" )
856+ . takes_value ( true )
857+ . help ( "YAML file listing the access rights of the groups" ) ,
858+ )
803859 . get_matches_from ( args)
804860}
805861
0 commit comments