@@ -343,7 +343,7 @@ impl RuntimeAuthority {
343343 webview : & str ,
344344 origin : & Origin ,
345345 ) -> String {
346- fn print_references ( resolved : Vec < & ResolvedCommand > ) -> String {
346+ fn print_references ( resolved : & [ ResolvedCommand ] ) -> String {
347347 resolved
348348 . iter ( )
349349 . map ( |r| {
@@ -356,6 +356,53 @@ impl RuntimeAuthority {
356356 . join ( " || " )
357357 }
358358
359+ fn print_allowed_on ( resolved : & [ ResolvedCommand ] ) -> String {
360+ if resolved. is_empty ( ) {
361+ "command not allowed on any window/webview/URL context" . to_string ( )
362+ } else {
363+ let mut s = "allowed on: " . to_string ( ) ;
364+
365+ let last_index = resolved. len ( ) - 1 ;
366+ for ( index, cmd) in resolved. iter ( ) . enumerate ( ) {
367+ let windows = cmd
368+ . windows
369+ . iter ( )
370+ . map ( |w| format ! ( "\" {}\" " , w. as_str( ) ) )
371+ . collect :: < Vec < _ > > ( )
372+ . join ( ", " ) ;
373+ let webviews = cmd
374+ . webviews
375+ . iter ( )
376+ . map ( |w| format ! ( "\" {}\" " , w. as_str( ) ) )
377+ . collect :: < Vec < _ > > ( )
378+ . join ( ", " ) ;
379+
380+ s. push ( '[' ) ;
381+
382+ if !windows. is_empty ( ) {
383+ s. push_str ( & format ! ( "windows: {windows}, " ) ) ;
384+ }
385+
386+ if !webviews. is_empty ( ) {
387+ s. push_str ( & format ! ( "webviews: {webviews}, " ) ) ;
388+ }
389+
390+ match & cmd. context {
391+ ExecutionContext :: Local => s. push_str ( "URL: local" ) ,
392+ ExecutionContext :: Remote { url } => s. push_str ( & format ! ( "URL: {}" , url. as_str( ) ) ) ,
393+ }
394+
395+ s. push ( ']' ) ;
396+
397+ if index != last_index {
398+ s. push_str ( ", " ) ;
399+ }
400+ }
401+
402+ s
403+ }
404+ }
405+
359406 fn has_permissions_allowing_command (
360407 manifest : & crate :: utils:: acl:: manifest:: Manifest ,
361408 set : & crate :: utils:: acl:: PermissionSet ,
@@ -393,35 +440,34 @@ impl RuntimeAuthority {
393440 format ! ( "{key}.{command_name}" )
394441 } ;
395442
396- if let Some ( resolved) = self . denied_commands . get ( & command) . map ( |r| {
397- r. iter ( )
398- . filter ( |cmd| origin. matches ( & cmd. context ) )
399- . collect ( )
400- } ) {
443+ if let Some ( resolved) = self . denied_commands . get ( & command) {
401444 format ! (
402- "{command_pretty_name} denied on origin {origin}, referenced by: {}" ,
445+ "{command_pretty_name} explicitly denied on origin {origin}\n \n referenced by: {}" ,
403446 print_references( resolved)
404447 )
405448 } else {
406449 let command_matches = self . allowed_commands . get ( & command) ;
407450
408- if let Some ( resolved) = self . allowed_commands . get ( & command) . map ( |r| {
409- r. iter ( )
451+ if let Some ( resolved) = self . allowed_commands . get ( & command) {
452+ let resolved_matching_origin = resolved
453+ . iter ( )
410454 . filter ( |cmd| origin. matches ( & cmd. context ) )
411- . collect :: < Vec < & ResolvedCommand > > ( )
412- } ) {
413- if resolved
455+ . collect :: < Vec < & ResolvedCommand > > ( ) ;
456+ if resolved_matching_origin
414457 . iter ( )
415458 . any ( |cmd| cmd. webviews . iter ( ) . any ( |w| w. matches ( webview) ) )
416- || resolved
459+ || resolved_matching_origin
417460 . iter ( )
418461 . any ( |cmd| cmd. windows . iter ( ) . any ( |w| w. matches ( window) ) )
419462 {
420463 "allowed" . to_string ( )
421464 } else {
422- format ! ( "{command_pretty_name} not allowed on window {window}, webview {webview}, allowed windows: {}, allowed webviews: {}, referenced by {}" ,
423- resolved. iter( ) . flat_map( |cmd| cmd. windows. iter( ) . map( |w| w. as_str( ) ) ) . collect:: <Vec <_>>( ) . join( ", " ) ,
424- resolved. iter( ) . flat_map( |cmd| cmd. webviews. iter( ) . map( |w| w. as_str( ) ) ) . collect:: <Vec <_>>( ) . join( ", " ) ,
465+ format ! ( "{command_pretty_name} not allowed on window \" {window}\" , webview \" {webview}\" , URL: {}\n \n {}\n \n referenced by: {}" ,
466+ match origin {
467+ Origin :: Local => "local" ,
468+ Origin :: Remote { url } => url. as_str( )
469+ } ,
470+ print_allowed_on( resolved) ,
425471 print_references( resolved)
426472 )
427473 }
@@ -451,20 +497,25 @@ impl RuntimeAuthority {
451497
452498 permissions_referencing_command. sort ( ) ;
453499
454- format ! (
455- "Permissions associated with this command: {}" ,
456- permissions_referencing_command
457- . iter( )
458- . map( |p| if key == APP_ACL_KEY {
500+ let associated_permissions = permissions_referencing_command
501+ . iter ( )
502+ . map ( |p| {
503+ if key == APP_ACL_KEY {
459504 p. to_string ( )
460505 } else {
461506 format ! ( "{key}:{p}" )
462- } )
463- . collect:: <Vec <_>>( )
464- . join( ", " )
465- )
507+ }
508+ } )
509+ . collect :: < Vec < _ > > ( )
510+ . join ( ", " ) ;
511+
512+ if associated_permissions. is_empty ( ) {
513+ "Command not found" . to_string ( )
514+ } else {
515+ format ! ( "Permissions associated with this command: {associated_permissions}" )
516+ }
466517 } else {
467- "Plugin did not define its manifest " . to_string ( )
518+ "Plugin not found " . to_string ( )
468519 } ;
469520
470521 if let Some ( resolved_cmds) = command_matches {
@@ -985,4 +1036,153 @@ mod tests {
9851036 . resolve_access( command, window, webview, & Origin :: Local )
9861037 . is_none( ) ) ;
9871038 }
1039+
1040+ #[ cfg( debug_assertions) ]
1041+ #[ test]
1042+ fn resolve_access_message ( ) {
1043+ use tauri_utils:: acl:: manifest:: Manifest ;
1044+
1045+ let plugin_name = "myplugin" ;
1046+ let command_allowed_on_window = "my-command-window" ;
1047+ let command_allowed_on_webview_window = "my-command-webview-window" ;
1048+ let window = "main-*" ;
1049+ let webview = "webview-*" ;
1050+ let remote_url = "http://localhost:8080" ;
1051+
1052+ let referenced_by = tauri_utils:: acl:: resolved:: ResolvedCommandReference {
1053+ capability : "maincap" . to_string ( ) ,
1054+ permission : "allow-command" . to_string ( ) ,
1055+ } ;
1056+
1057+ let resolved_window_cmd = ResolvedCommand {
1058+ windows : vec ! [ Pattern :: new( window) . unwrap( ) ] ,
1059+ referenced_by : referenced_by. clone ( ) ,
1060+ ..Default :: default ( )
1061+ } ;
1062+ let resolved_webview_window_cmd = ResolvedCommand {
1063+ windows : vec ! [ Pattern :: new( window) . unwrap( ) ] ,
1064+ webviews : vec ! [ Pattern :: new( webview) . unwrap( ) ] ,
1065+ referenced_by : referenced_by. clone ( ) ,
1066+ ..Default :: default ( )
1067+ } ;
1068+ let resolved_webview_window_remote_cmd = ResolvedCommand {
1069+ windows : vec ! [ Pattern :: new( window) . unwrap( ) ] ,
1070+ webviews : vec ! [ Pattern :: new( webview) . unwrap( ) ] ,
1071+ referenced_by : referenced_by. clone ( ) ,
1072+ context : ExecutionContext :: Remote {
1073+ url : remote_url. parse ( ) . unwrap ( ) ,
1074+ } ,
1075+ ..Default :: default ( )
1076+ } ;
1077+
1078+ let allowed_commands = [
1079+ (
1080+ format ! ( "plugin:{plugin_name}|{command_allowed_on_window}" ) ,
1081+ vec ! [ resolved_window_cmd] ,
1082+ ) ,
1083+ (
1084+ format ! ( "plugin:{plugin_name}|{command_allowed_on_webview_window}" ) ,
1085+ vec ! [
1086+ resolved_webview_window_cmd,
1087+ resolved_webview_window_remote_cmd,
1088+ ] ,
1089+ ) ,
1090+ ]
1091+ . into_iter ( )
1092+ . collect ( ) ;
1093+
1094+ let authority = RuntimeAuthority :: new (
1095+ [ (
1096+ plugin_name. to_string ( ) ,
1097+ Manifest {
1098+ default_permission : None ,
1099+ permissions : Default :: default ( ) ,
1100+ permission_sets : Default :: default ( ) ,
1101+ global_scope_schema : None ,
1102+ } ,
1103+ ) ]
1104+ . into_iter ( )
1105+ . collect ( ) ,
1106+ Resolved {
1107+ allowed_commands,
1108+ ..Default :: default ( )
1109+ } ,
1110+ ) ;
1111+
1112+ // unknown plugin
1113+ assert_eq ! (
1114+ authority. resolve_access_message(
1115+ "unknown-plugin" ,
1116+ command_allowed_on_window,
1117+ window,
1118+ webview,
1119+ & Origin :: Local
1120+ ) ,
1121+ "unknown-plugin.my-command-window not allowed. Plugin not found"
1122+ ) ;
1123+
1124+ // unknown command
1125+ assert_eq ! (
1126+ authority. resolve_access_message(
1127+ plugin_name,
1128+ "unknown-command" ,
1129+ window,
1130+ webview,
1131+ & Origin :: Local
1132+ ) ,
1133+ "myplugin.unknown-command not allowed. Command not found"
1134+ ) ;
1135+
1136+ // window/webview do not match
1137+ assert_eq ! (
1138+ authority. resolve_access_message(
1139+ plugin_name,
1140+ command_allowed_on_window,
1141+ "other-window" ,
1142+ "any-webview" ,
1143+ & Origin :: Local
1144+ ) ,
1145+ "myplugin.my-command-window not allowed on window \" other-window\" , webview \" any-webview\" , URL: local\n \n allowed on: [windows: \" main-*\" , URL: local]\n \n referenced by: capability: maincap, permission: allow-command"
1146+ ) ;
1147+
1148+ // window matches, but not origin
1149+ assert_eq ! (
1150+ authority. resolve_access_message(
1151+ plugin_name,
1152+ command_allowed_on_window,
1153+ window,
1154+ "any-webview" ,
1155+ & Origin :: Remote {
1156+ url: "http://localhst" . parse( ) . unwrap( )
1157+ }
1158+ ) ,
1159+ "myplugin.my-command-window not allowed on window \" main-*\" , webview \" any-webview\" , URL: http://localhst/\n \n allowed on: [windows: \" main-*\" , URL: local]\n \n referenced by: capability: maincap, permission: allow-command"
1160+ ) ;
1161+
1162+ // window/webview do not match
1163+ assert_eq ! (
1164+ authority. resolve_access_message(
1165+ plugin_name,
1166+ command_allowed_on_webview_window,
1167+ "other-window" ,
1168+ "other-webview" ,
1169+ & Origin :: Local
1170+ ) ,
1171+ "myplugin.my-command-webview-window not allowed on window \" other-window\" , webview \" other-webview\" , URL: local\n \n allowed on: [windows: \" main-*\" , webviews: \" webview-*\" , URL: local], [windows: \" main-*\" , webviews: \" webview-*\" , URL: http://localhost:8080]\n \n referenced by: capability: maincap, permission: allow-command || capability: maincap, permission: allow-command"
1172+ ) ;
1173+
1174+ // window/webview matches, but not origin
1175+ assert_eq ! (
1176+ authority. resolve_access_message(
1177+ plugin_name,
1178+ command_allowed_on_webview_window,
1179+ window,
1180+ webview,
1181+ & Origin :: Remote {
1182+ url: "http://localhost:123" . parse( ) . unwrap( )
1183+ }
1184+ ) ,
1185+ "myplugin.my-command-webview-window not allowed on window \" main-*\" , webview \" webview-*\" , URL: http://localhost:123/\n \n allowed on: [windows: \" main-*\" , webviews: \" webview-*\" , URL: local], [windows: \" main-*\" , webviews: \" webview-*\" , URL: http://localhost:8080]\n \n referenced by: capability: maincap, permission: allow-command || capability: maincap, permission: allow-command"
1186+ ) ;
1187+ }
9881188}
0 commit comments