@@ -101,7 +101,41 @@ fn run_filter(args: Vec<String>) -> josh::JoshResult<i32> {
101101 . arg (
102102 clap:: Arg :: with_name ( "check-permission" )
103103 . long ( "check-permission" )
104- . short ( "c" )
104+ . short ( "c" ) ,
105+ )
106+ . arg ( clap:: Arg :: with_name ( "missing-permission" ) . long ( "missing-permission" ) )
107+ . arg (
108+ clap:: Arg :: with_name ( "whitelist" )
109+ . long ( "whitelist" )
110+ . short ( "w" )
111+ . takes_value ( true ) ,
112+ )
113+ . arg (
114+ clap:: Arg :: with_name ( "blacklist" )
115+ . long ( "blacklist" )
116+ . short ( "b" )
117+ . takes_value ( true ) ,
118+ )
119+ . arg (
120+ clap:: Arg :: with_name ( "users" )
121+ . long ( "users" )
122+ . takes_value ( true ) ,
123+ )
124+ . arg (
125+ clap:: Arg :: with_name ( "groups" )
126+ . long ( "groups" )
127+ . takes_value ( true ) ,
128+ )
129+ . arg (
130+ clap:: Arg :: with_name ( "user" )
131+ . long ( "user" )
132+ . short ( "u" )
133+ . takes_value ( true ) ,
134+ )
135+ . arg (
136+ clap:: Arg :: with_name ( "repo" )
137+ . long ( "repo" )
138+ . short ( "r" )
105139 . takes_value ( true ) ,
106140 )
107141 . arg ( clap:: Arg :: with_name ( "version" ) . long ( "version" ) . short ( "v" ) )
@@ -183,6 +217,7 @@ fn run_filter(args: Vec<String>) -> josh::JoshResult<i32> {
183217 josh:: filter:: parse ( & i) ?,
184218 input_ref,
185219 "refs/JOSH_TMP" ,
220+ josh:: filter:: empty ( ) ,
186221 ) ?;
187222 }
188223 }
@@ -193,12 +228,6 @@ fn run_filter(args: Vec<String>) -> josh::JoshResult<i32> {
193228 let target = update_target;
194229
195230 let reverse = args. is_present ( "reverse" ) ;
196- let check_permissions = args. is_present ( "check-permission" ) ;
197-
198- if check_permissions {
199- filterobj = josh:: filter:: chain ( josh:: filter:: parse ( ":PATHS" ) ?, filterobj) ;
200- filterobj = josh:: filter:: chain ( filterobj, josh:: filter:: parse ( ":FOLD" ) ?) ;
201- }
202231
203232 let t = if reverse {
204233 "refs/JOSH_TMP" . to_owned ( )
@@ -213,21 +242,49 @@ fn run_filter(args: Vec<String>) -> josh::JoshResult<i32> {
213242 . unwrap ( )
214243 . to_string ( ) ;
215244
216- josh:: filter_ref ( & transaction, filterobj, & src, & t) ?;
217-
218- let mut all_paths = vec ! [ ] ;
219-
245+ let check_permissions = args. is_present ( "check-permission" ) ;
246+ let mut permissions_filter = josh:: filter:: empty ( ) ;
220247 if check_permissions {
221- let result_tree = repo. find_reference ( & t) ?. peel_to_tree ( ) ?;
248+ let whitelist;
249+ let blacklist;
250+ if args. is_present ( "users" )
251+ && args. is_present ( "groups" )
252+ && args. is_present ( "user" )
253+ && args. is_present ( "repo" )
254+ {
255+ let users = args. value_of ( "users" ) . unwrap ( ) ;
256+ let groups = args. value_of ( "groups" ) . unwrap ( ) ;
257+ let user = args. value_of ( "user" ) . unwrap ( ) ;
258+ let repo = args. value_of ( "repo" ) . unwrap ( ) ;
259+
260+ let acl = josh:: get_acl ( users, groups, user, repo) ?;
261+ whitelist = acl. 0 ;
262+ blacklist = acl. 1 ;
263+ } else {
264+ whitelist = match args. value_of ( "whitelist" ) {
265+ Some ( s) => josh:: filter:: parse ( s) ?,
266+ _ => josh:: filter:: nop ( ) ,
267+ } ;
268+ blacklist = match args. value_of ( "blacklist" ) {
269+ Some ( s) => josh:: filter:: parse ( s) ?,
270+ _ => josh:: filter:: empty ( ) ,
271+ } ;
272+ }
273+ permissions_filter = josh:: filter:: make_permissions_filter ( filterobj, whitelist, blacklist)
274+ }
222275
223- result_tree. walk ( git2:: TreeWalkMode :: PreOrder , |_, entry| {
224- let name = entry. name ( ) . unwrap ( ) ;
225- if name. starts_with ( "JOSH_ORIG_PATH_" ) {
226- let pathname = josh:: from_ns ( & name. replacen ( "JOSH_ORIG_PATH_" , "" , 1 ) ) ;
227- all_paths. push ( pathname) ;
228- }
229- git2:: TreeWalkResult :: Ok
230- } ) ?;
276+ let missing_permissions = args. is_present ( "missing-permission" ) ;
277+ if missing_permissions {
278+ filterobj = permissions_filter;
279+ permissions_filter = josh:: filter:: empty ( ) ;
280+ }
281+
282+ let updated_refs = josh:: filter_ref ( & transaction, filterobj, & src, & t, permissions_filter) ?;
283+ if args. value_of ( "update" ) != Some ( "FILTERED_HEAD" ) && updated_refs == 0 {
284+ println ! (
285+ "Warning: reference {} wasn't updated" ,
286+ args. value_of( "update" ) . unwrap( )
287+ ) ;
231288 }
232289
233290 #[ cfg( feature = "search" ) ]
@@ -264,39 +321,6 @@ fn run_filter(args: Vec<String>) -> josh::JoshResult<i32> {
264321 /* println!("\n Search took {:?}", duration); */
265322 }
266323
267- let mut dedup = vec ! [ ] ;
268-
269- for w in all_paths. as_slice ( ) . windows ( 2 ) {
270- if let [ a, b, ..] = w {
271- if !b. starts_with ( a) {
272- dedup. push ( a. to_owned ( ) ) ;
273- }
274- }
275- }
276-
277- let dedup = all_paths;
278-
279- let options = glob:: MatchOptions {
280- case_sensitive : true ,
281- require_literal_separator : true ,
282- require_literal_leading_dot : true ,
283- } ;
284-
285- if let Some ( cp) = args. value_of ( "check-permission" ) {
286- let pattern = glob:: Pattern :: new ( cp) ?;
287-
288- let mut allowed = !dedup. is_empty ( ) ;
289- for d in dedup. iter ( ) {
290- let d = std:: path:: PathBuf :: from ( d) ;
291- let m = pattern. matches_path_with ( & d, options) ;
292- if !m {
293- allowed = false ;
294- println ! ( "missing permission for: {:?}" , & d) ;
295- }
296- }
297- println ! ( "Allowed = {:?}" , allowed) ;
298- }
299-
300324 if reverse {
301325 let new = repo. revparse_single ( target) . unwrap ( ) . id ( ) ;
302326 let old = repo. revparse_single ( "JOSH_TMP" ) . unwrap ( ) . id ( ) ;
0 commit comments