Skip to content

Commit

Permalink
Add filter vip_files_acl_is_valid_path_for_site to is_valid_path_for_…
Browse files Browse the repository at this point in the history
…site ACL function (#6033)
  • Loading branch information
rbcorrales authored Dec 13, 2024
1 parent 3b7ecd5 commit 611f574
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 14 deletions.
35 changes: 21 additions & 14 deletions files/acl/acl.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,25 +72,32 @@ function get_option_as_bool_if_exists( $option_name ) {
/**
* Check if the path is allowed for the current context.
*
* @param string $file_path Path to the file, minus the `/wp-content/uploads/` bit. It's the second portion returned by `Pre_Wp_Utils\prepare_request()`
* @param string $file_path Path to the file, minus the `/wp-content/uploads/` bit.
* This is the second portion returned by `Pre_Wp_Utils\prepare_request()`.
* @return bool True if the file path is valid for the current site, false otherwise.
*/
function is_valid_path_for_site( $file_path ) {
if ( ! is_multisite() ) {
return true;
}

// If main site, don't allow access to /sites/ subdirectories.
if ( is_main_network() && is_main_site() ) {
if ( 0 === strpos( $file_path, 'sites/' ) ) {
return false;
$is_valid = true;

if ( is_multisite() ) {
// If main site, don't allow access to `/sites/` subdirectories.
if ( is_main_network() && is_main_site() ) {
$is_valid = ! str_starts_with( $file_path, 'sites/' );
} else {
// Check if the file path matches the current site ID's directory.
$base_path = sprintf( 'sites/%d', get_current_blog_id() );
$is_valid = str_starts_with( $file_path, $base_path );
}

return true;
}

$base_path = sprintf( 'sites/%d', get_current_blog_id() );

return 0 === strpos( $file_path, $base_path );
/**
* Filter the result of the path validation for the current site.
* Allows to override the logic used to determine if a file path is valid for the current site.
*
* @param bool $is_valid Whether the file path is valid for the current site.
* @param string $file_path Path to the file, minus the `/wp-content/uploads/` bit.
*/
return apply_filters( 'vip_files_acl_is_valid_path_for_site', $is_valid, $file_path );
}

/**
Expand Down
55 changes: 55 additions & 0 deletions tests/files/acl/test-acl.php
Original file line number Diff line number Diff line change
Expand Up @@ -366,4 +366,59 @@ public function test__is_valid_path_for_site__multisite_subsite_cannot_access_an

$this->assertEquals( $expected_is_allowed, $actual_is_allowed );
}

public function test__is_valid_path_for_site__multisite_subsite_can_access_other_subsite_with_filter() {
if ( ! is_multisite() ) {
$this->markTestSkipped();
}

$expected_is_allowed = true;

add_filter( 'vip_files_acl_is_valid_path_for_site', '__return_true' );

// Create two subsites
$first_subsite_id = $this->factory()->blog->create();
$second_subsite_id = $this->factory()->blog->create();

// Get file path from second
$file_path = sprintf( 'sites/%d/2021/01/parakeets.gif', $second_subsite_id );

// Restore first subsite
switch_to_blog( $first_subsite_id );

$actual_is_allowed = is_valid_path_for_site( $file_path );

$this->assertEquals( $expected_is_allowed, $actual_is_allowed );
}

public function test__is_valid_path_for_site__multisite_subsite_can_access_other_paths_with_filter() {
if ( ! is_multisite() ) {
$this->markTestSkipped();
}

$expected_is_allowed = true;

add_filter(
'vip_files_acl_is_valid_path_for_site',
function ( $is_valid, $file_path ) {
// Allow access to any file path starting with 'custom-uploads/'.
if ( str_starts_with( $file_path, 'custom-uploads/' ) ) {
return true;
}

// Return the original validation result for other paths.
return $is_valid;
},
10,
2
);

$this->factory()->blog->create();

$file_path = 'custom-uploads/parakeets.gif';

$actual_is_allowed = is_valid_path_for_site( $file_path );

$this->assertEquals( $expected_is_allowed, $actual_is_allowed );
}
}

0 comments on commit 611f574

Please sign in to comment.