@@ -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,29 @@ 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+ {
307+ Ok ( acl) => acl,
308+ Err ( e) => {
309+ tracing:: error!( "Failed to read ACL file: {:?}" , e) ;
310+ ( josh:: filter:: empty ( ) , josh:: filter:: nop ( ) )
311+ }
312+ } ;
313+ let whitelist = acl. 0 ;
314+ let blacklist = acl. 1 ;
315+ tracing:: info!( "Whitelist: {:?}, Blacklist: {:?}" , whitelist, blacklist) ;
316+ josh:: filter:: make_permissions_filter ( filter, whitelist, blacklist)
317+ } else {
318+ josh:: filter:: empty ( )
319+ } ;
320+
321+ tracing:: info!( "Permissions: {:?}" , permissions_filter) ;
322+
323+ josh:: filter_refs ( & transaction, filter, & from_to, permissions_filter) ?;
299324 if headref == "HEAD" {
300325 headref = heads_map
301326 . read ( ) ?
@@ -517,6 +542,7 @@ async fn call_service(
517542 & parsed_url. upstream_repo ,
518543 & parsed_url. filter ,
519544 & headref,
545+ & username,
520546 )
521547 . in_current_span ( )
522548 . await ?;
@@ -598,6 +624,7 @@ async fn prepare_namespace(
598624 upstream_repo : & str ,
599625 filter_spec : & str ,
600626 headref : & str ,
627+ user : & str ,
601628) -> josh:: JoshResult < std:: sync:: Arc < josh_proxy:: TmpGitNamespace > > {
602629 let temp_ns = Arc :: new ( josh_proxy:: TmpGitNamespace :: new (
603630 & serv. repo_path ,
@@ -606,13 +633,16 @@ async fn prepare_namespace(
606633
607634 let serv = serv. clone ( ) ;
608635
636+ let user = if user == "" { "anonymous" } else { user } ;
637+
609638 do_filter (
610639 serv. repo_path . clone ( ) ,
611640 serv. clone ( ) ,
612641 upstream_repo. to_owned ( ) ,
613642 temp_ns. to_owned ( ) ,
614643 filter_spec. to_owned ( ) ,
615644 headref. to_string ( ) ,
645+ user. to_string ( ) ,
616646 )
617647 . await ?;
618648
@@ -635,6 +665,20 @@ async fn run_proxy() -> josh::JoshResult<i32> {
635665 josh_proxy:: create_repo ( & local) ?;
636666 josh:: cache:: load ( & local) ?;
637667
668+ let acl = if ARGS . is_present ( "users" ) && ARGS . is_present ( "groups" ) {
669+ println ! (
670+ "{}, {}" ,
671+ ARGS . value_of( "users" ) . unwrap( ) . to_string( ) ,
672+ ARGS . value_of( "groups" ) . unwrap( ) . to_string( )
673+ ) ;
674+ Some ( (
675+ ARGS . value_of ( "users" ) . unwrap ( ) . to_string ( ) ,
676+ ARGS . value_of ( "groups" ) . unwrap ( ) . to_string ( ) ,
677+ ) )
678+ } else {
679+ None
680+ } ;
681+
638682 let proxy_service = Arc :: new ( JoshProxyService {
639683 port,
640684 repo_path : local. to_owned ( ) ,
@@ -646,6 +690,7 @@ async fn run_proxy() -> josh::JoshResult<i32> {
646690 ARGS . value_of ( "n" ) . unwrap_or ( "1" ) . parse ( ) ?,
647691 ) ) ,
648692 filter_permits : Arc :: new ( tokio:: sync:: Semaphore :: new ( 10 ) ) ,
693+ acl,
649694 } ) ;
650695
651696 let ps = proxy_service. clone ( ) ;
@@ -800,6 +845,18 @@ fn parse_args() -> clap::ArgMatches<'static> {
800845 . help ( "Duration between forced cache refresh" )
801846 . takes_value ( true ) ,
802847 )
848+ . arg (
849+ clap:: Arg :: with_name ( "users" )
850+ . long ( "users" )
851+ . takes_value ( true )
852+ . help ( "YAML file listing the groups of the users" ) ,
853+ )
854+ . arg (
855+ clap:: Arg :: with_name ( "groups" )
856+ . long ( "groups" )
857+ . takes_value ( true )
858+ . help ( "YAML file listing the access rights of the groups" ) ,
859+ )
803860 . get_matches_from ( args)
804861}
805862
0 commit comments