@@ -74,10 +74,6 @@ struct RestrictedPathAggregateLogData<'a> {
7474}
7575
7676/// Complete Scuba row payload for restricted-path access logging.
77- ///
78- /// `aggregate` is optional in this no-op refactor because Shadow source
79- /// comparison still emits error-only rows when config fails. The follow-up
80- /// behavior diff can make it required after those rows stop being logged.
8177struct RestrictedPathLogData < ' a > {
8278 repo_id : RepositoryId ,
8379 access_data : RestrictedPathAccessData ,
@@ -256,8 +252,8 @@ pub async fn is_part_of_group(
256252/// This emits one row when a Shadow-mode lookup source either finds a
257253/// restriction or fails. Aggregate authorization fields remain
258254/// config-authoritative, while source disagreement is summarized with compact
259- /// mismatch fields. If neither source ran, or every source that ran completed
260- /// unrestricted, no row is written.
255+ /// mismatch fields. If every available source completed unrestricted, no row
256+ /// is written.
261257#[ cfg_attr(
262258 not( test) ,
263259 expect(
@@ -268,7 +264,7 @@ pub async fn is_part_of_group(
268264pub ( crate ) fn log_source_results_to_scuba (
269265 ctx : & CoreContext ,
270266 repo_id : RepositoryId ,
271- config_result : Option < & SourceRestrictionResult > ,
267+ config_result : & SourceRestrictionResult ,
272268 acl_manifest_result : Option < & SourceRestrictionResult > ,
273269 acl_manifest_mode : AclManifestMode ,
274270 access_data : RestrictedPathAccessData ,
@@ -285,52 +281,60 @@ pub(crate) fn log_source_results_to_scuba(
285281 RestrictedPathLogData {
286282 repo_id,
287283 access_data,
288- aggregate : config_result. and_then ( |result| {
289- let result = result. as_ref ( ) . ok ( ) ?;
290- Some ( RestrictedPathAggregateLogData {
291- restricted_paths : result. restriction_paths . as_deref ( ) ,
284+ aggregate : config_result
285+ . as_ref ( )
286+ . ok ( )
287+ . map ( |config| RestrictedPathAggregateLogData {
288+ restricted_paths : config. restriction_paths . as_deref ( ) ,
292289 authorization : LoggedAuthorization {
293- has_authorization : result . has_authorization ,
294- is_allowlisted_tooling : result . is_allowlisted_tooling ,
295- is_rollout_allowlisted : result . is_rollout_allowlisted ,
296- has_acl_access : result . has_acl_access ,
290+ has_authorization : config . has_authorization ,
291+ is_allowlisted_tooling : config . is_allowlisted_tooling ,
292+ is_rollout_allowlisted : config . is_rollout_allowlisted ,
293+ has_acl_access : config . has_acl_access ,
297294 } ,
298- acls : result. restriction_acls . iter ( ) . collect ( ) ,
299- } )
300- } ) ,
295+ acls : config. restriction_acls . iter ( ) . collect ( ) ,
296+ } ) ,
301297 considered_restricted_by : considered_restricted_by_for_source_results (
302298 config_result,
303299 acl_manifest_result,
304300 ) ,
305301 source_comparison : Some ( source_comparison) ,
306302 } ,
307303 scuba,
308- )
304+ ) ?;
305+
306+ config_result
307+ . as_ref ( )
308+ . map ( |_| ( ) )
309+ . map_err ( |err| anyhow:: anyhow!( "{:#}" , err) )
309310}
310311
311312/// Build the source-comparison fields for rows that need Shadow telemetry.
312313///
313314/// Returns `None` when every source that ran completed unrestricted, matching
314315/// the old behavior of skipping those rows entirely.
315316fn source_comparison_log_context (
316- config_result : Option < & SourceRestrictionResult > ,
317+ config_result : & SourceRestrictionResult ,
317318 acl_manifest_result : Option < & SourceRestrictionResult > ,
318319 acl_manifest_mode : AclManifestMode ,
319320) -> Option < SourceComparisonLogContext > {
320321 let any_source_restricted =
321- is_source_restricted ( config_result) || is_source_restricted ( acl_manifest_result) ;
322- let any_source_failed = is_source_error ( config_result) || is_source_error ( acl_manifest_result) ;
322+ is_source_restricted ( Some ( config_result) ) || is_source_restricted ( acl_manifest_result) ;
323+ let any_source_failed =
324+ is_source_error ( Some ( config_result) ) || is_source_error ( acl_manifest_result) ;
323325 if !any_source_restricted && !any_source_failed {
324326 return None ;
325327 }
326328
327329 Some ( SourceComparisonLogContext {
328330 acl_manifest_mode,
329- config_error : config_result
330- . and_then ( |result| result. as_ref ( ) . err ( ) . map ( |err| format ! ( "{:#}" , err) ) ) ,
331+ config_error : config_result. as_ref ( ) . err ( ) . map ( |err| format ! ( "{:#}" , err) ) ,
331332 acl_manifest_error : acl_manifest_result
332333 . and_then ( |result| result. as_ref ( ) . err ( ) . map ( |err| format ! ( "{:#}" , err) ) ) ,
333- shadow_mismatch : shadow_mismatch_for_source_results ( config_result, acl_manifest_result) ,
334+ shadow_mismatch : shadow_mismatch_for_source_results (
335+ Some ( config_result) ,
336+ acl_manifest_result,
337+ ) ,
334338 shadow_mismatch_detail : shadow_mismatch_detail_for_source_results (
335339 config_result,
336340 acl_manifest_result,
@@ -339,17 +343,17 @@ fn source_comparison_log_context(
339343}
340344
341345fn considered_restricted_by_for_source_results (
342- config_result : Option < & SourceRestrictionResult > ,
346+ config_result : & SourceRestrictionResult ,
343347 acl_manifest_result : Option < & SourceRestrictionResult > ,
344348) -> Vec < String > {
345- [
346- ( SourceKind :: Config , config_result) ,
347- ( SourceKind :: AclManifest , acl_manifest_result ) ,
348- ]
349- . into_iter ( )
350- . filter ( | & ( _ , result ) | is_source_restricted ( result ) )
351- . map ( | ( source , _ ) | source . as_scuba_value ( ) . to_string ( ) )
352- . collect ( )
349+ let mut restricted_sources = Vec :: new ( ) ;
350+ if is_source_restricted ( Some ( config_result) ) {
351+ restricted_sources . push ( SourceKind :: Config . as_scuba_value ( ) . to_string ( ) ) ;
352+ }
353+ if is_source_restricted ( acl_manifest_result ) {
354+ restricted_sources . push ( SourceKind :: AclManifest . as_scuba_value ( ) . to_string ( ) ) ;
355+ }
356+ restricted_sources
353357}
354358
355359fn is_source_restricted ( result : Option < & SourceRestrictionResult > ) -> bool {
@@ -361,7 +365,7 @@ fn is_source_error(result: Option<&SourceRestrictionResult>) -> bool {
361365}
362366
363367fn shadow_mismatch_detail_for_source_results (
364- config_result : Option < & SourceRestrictionResult > ,
368+ config_result : & SourceRestrictionResult ,
365369 acl_manifest_result : Option < & SourceRestrictionResult > ,
366370) -> Option < String > {
367371 let differences = shadow_mismatch_differences ( config_result, acl_manifest_result) ;
@@ -370,7 +374,7 @@ fn shadow_mismatch_detail_for_source_results(
370374 }
371375
372376 let mut detail = serde_json:: Map :: new ( ) ;
373- if let Some ( config_detail) = source_result_detail ( config_result) {
377+ if let Some ( config_detail) = source_result_detail ( Some ( config_result) ) {
374378 detail. insert ( "config" . to_string ( ) , config_detail) ;
375379 }
376380 if let Some ( acl_manifest_detail) = source_result_detail ( acl_manifest_result) {
@@ -407,8 +411,8 @@ fn shadow_mismatch_for_source_results(
407411 return true ;
408412 }
409413
410- successful_source_comparison ( config_result)
411- . zip ( successful_source_comparison ( acl_manifest_result) )
414+ successful_source_result_comparison ( config_result)
415+ . zip ( successful_source_result_comparison ( acl_manifest_result) )
412416 . is_some_and ( |( config, acl_manifest) | {
413417 restriction_comparison ( config) != restriction_comparison ( acl_manifest)
414418 } )
@@ -419,21 +423,17 @@ fn source_error_status(result: Option<&SourceRestrictionResult>) -> Option<bool>
419423}
420424
421425fn shadow_mismatch_differences (
422- config_result : Option < & SourceRestrictionResult > ,
426+ config_result : & SourceRestrictionResult ,
423427 acl_manifest_result : Option < & SourceRestrictionResult > ,
424428) -> Vec < & ' static str > {
425429 let error_differences = [
426- ( SourceKind :: Config , config_result) ,
427- ( SourceKind :: AclManifest , acl_manifest_result) ,
428- ]
429- . into_iter ( )
430- . filter_map ( |( source_kind, result) | {
431- is_source_error ( result) . then_some ( source_kind. error_field ( ) )
432- } ) ;
430+ is_source_error ( Some ( config_result) ) . then_some ( SourceKind :: Config . error_field ( ) ) ,
431+ is_source_error ( acl_manifest_result) . then_some ( SourceKind :: AclManifest . error_field ( ) ) ,
432+ ] ;
433433
434434 let successful_source_differences = match (
435- successful_source_comparison ( config_result) ,
436- successful_source_comparison ( acl_manifest_result) ,
435+ successful_source_result_comparison ( Some ( config_result) ) ,
436+ successful_source_result_comparison ( acl_manifest_result) ,
437437 ) {
438438 ( Some ( config) , Some ( acl_manifest) ) => [
439439 ( config. restricted != acl_manifest. restricted , "restricted" ) ,
@@ -457,43 +457,53 @@ fn shadow_mismatch_differences(
457457 } ;
458458
459459 error_differences
460+ . into_iter ( )
461+ . flatten ( )
460462 . chain ( successful_source_differences)
461463 . collect ( )
462464}
463465
464466fn source_result_detail ( result : Option < & SourceRestrictionResult > ) -> Option < Value > {
465467 match result? {
466- Ok ( result) => Some ( json ! ( {
467- "restricted" : result. is_restricted( ) ,
468- "has_authorization" : result. has_authorization,
469- "restriction_acls" : sorted_acls_to_strings( & result. restriction_acls) ,
470- "restriction_paths" : result
471- . restriction_paths
472- . as_deref( )
473- . map( sorted_paths_to_strings) ,
474- } ) ) ,
468+ Ok ( result) => Some ( successful_source_detail ( result) ) ,
475469 Err ( err) => Some ( json ! ( {
476470 "error" : format!( "{:#}" , err) ,
477471 } ) ) ,
478472 }
479473}
480474
481- fn successful_source_comparison (
475+ fn successful_source_detail ( result : & SourceRestrictionCheckResult ) -> Value {
476+ json ! ( {
477+ "restricted" : result. is_restricted( ) ,
478+ "has_authorization" : result. has_authorization,
479+ "restriction_acls" : sorted_acls_to_strings( & result. restriction_acls) ,
480+ "restriction_paths" : result
481+ . restriction_paths
482+ . as_deref( )
483+ . map( sorted_paths_to_strings) ,
484+ } )
485+ }
486+
487+ fn successful_source_result_comparison (
482488 result : Option < & SourceRestrictionResult > ,
483489) -> Option < SourceComparisonData > {
484490 let result = match result? {
485491 Ok ( result) => result,
486492 Err ( _) => return None ,
487493 } ;
488- Some ( SourceComparisonData {
494+ Some ( successful_source_comparison ( result) )
495+ }
496+
497+ fn successful_source_comparison ( result : & SourceRestrictionCheckResult ) -> SourceComparisonData {
498+ SourceComparisonData {
489499 restricted : result. is_restricted ( ) ,
490500 has_authorization : result. has_authorization ,
491501 restriction_acls : sorted_acls_to_strings ( & result. restriction_acls ) ,
492502 restriction_paths : result
493503 . restriction_paths
494504 . as_deref ( )
495505 . map ( sorted_paths_to_strings) ,
496- } )
506+ }
497507}
498508
499509fn acls_to_strings ( acls : & [ MononokeIdentity ] ) -> Vec < String > {
@@ -786,44 +796,45 @@ fn log_checked_access_to_restricted_path(
786796 // Override sampling for unauthorized SCSC accesses to restricted paths
787797 #[ cfg( fbcode_build) ]
788798 {
789- if let Some ( aggregate) = log_data. aggregate . as_ref ( ) {
790- use clientinfo:: ClientEntryPoint ;
799+ use clientinfo:: ClientEntryPoint ;
791800
792- let is_scsc = ctx
793- . metadata ( )
794- . client_request_info ( )
795- . is_some_and ( |cri| cri. entry_point == ClientEntryPoint :: ScsClient ) ;
801+ let is_scsc = ctx
802+ . metadata ( )
803+ . client_request_info ( )
804+ . is_some_and ( |cri| cri. entry_point == ClientEntryPoint :: ScsClient ) ;
796805
797- if is_scsc && !aggregate. authorization . has_authorization {
798- ctx. set_override_sampling ( ) ;
799- }
806+ if let Some ( aggregate) = log_data. aggregate . as_ref ( )
807+ && is_scsc
808+ && !aggregate. authorization . has_authorization
809+ {
810+ ctx. set_override_sampling ( ) ;
800811 }
801812 }
802813
803814 // Log to schematized logger (logs to both Scuba and Hive) if enabled via JK
804815 // Only available in fbcode builds
805816 #[ cfg( fbcode_build) ]
806817 {
807- if let Some ( aggregate ) = log_data . aggregate . as_ref ( ) {
808- let use_schematized_logger = justknobs :: eval (
809- "scm/mononoke:restricted_paths_use_schematized_logger" ,
810- None ,
811- None ,
812- ) ? ;
813-
814- if use_schematized_logger {
815- if let Err ( e ) = schematized_logger :: log_access_to_schematized_logger (
816- ctx ,
817- log_data . repo_id ,
818- aggregate . restricted_paths . unwrap_or ( & [ ] ) ,
819- & log_data . access_data ,
820- aggregate . authorization . has_authorization ,
821- aggregate. authorization . is_allowlisted_tooling ,
822- aggregate. authorization . is_rollout_allowlisted ,
823- & aggregate. acls ,
824- ) {
825- tracing :: error! ( "Failed to log to schematized logger: {:?}" , e ) ;
826- }
818+ let use_schematized_logger = justknobs :: eval (
819+ "scm/mononoke:restricted_paths_use_schematized_logger" ,
820+ None ,
821+ None ,
822+ ) ? ;
823+
824+ if let Some ( aggregate ) = log_data . aggregate . as_ref ( )
825+ && use_schematized_logger
826+ {
827+ if let Err ( e ) = schematized_logger :: log_access_to_schematized_logger (
828+ ctx ,
829+ log_data . repo_id ,
830+ aggregate . restricted_paths . unwrap_or ( & [ ] ) ,
831+ & log_data . access_data ,
832+ aggregate. authorization . has_authorization ,
833+ aggregate. authorization . is_allowlisted_tooling ,
834+ aggregate. authorization . is_rollout_allowlisted ,
835+ & aggregate . acls ,
836+ ) {
837+ tracing :: error! ( "Failed to log to schematized logger: {:?}" , e ) ;
827838 }
828839 }
829840 }
0 commit comments