Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add E2E for Password Protected Post #2864

Merged
merged 12 commits into from
Jun 6, 2023
Prev Previous commit
Next Next commit
Add new ep_pre_kill_sync_for_password_protected filter
  • Loading branch information
felipeelia committed Jun 5, 2023
commit 23632db9019c4673a4b061fc8fa0c93e5cb27c9d
13 changes: 13 additions & 0 deletions includes/classes/Feature/ProtectedContent/ProtectedContent.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public function setup() {
add_filter( 'ep_post_sync_args', [ $this, 'remove_fields_from_password_protected' ], 11, 2 );
add_filter( 'ep_search_post_return_args', [ $this, 'return_post_password' ] );
add_filter( 'ep_skip_autosave_sync', '__return_false' );
add_filter( 'ep_pre_kill_sync_for_password_protected', [ $this, 'sync_password_protected' ], 10, 2 );

if ( is_admin() ) {
add_filter( 'ep_admin_wp_query_integration', '__return_true' );
Expand Down Expand Up @@ -413,4 +414,16 @@ public function requirements_status() {

return $status;
}

/**
* Bypass the default check for password protected posts.
*
* @since 4.6.0
* @param null|bool $new_skip Short-circuit flag
* @param bool $skip Current value of $skip
* @return bool
*/
public function sync_password_protected( $new_skip, bool $skip ) : bool {
return $skip;
}
}
39 changes: 39 additions & 0 deletions includes/classes/Indexable/Post/SyncManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ public function setup() {
add_action( 'added_post_meta', [ $this, 'clear_meta_keys_db_per_post_type_cache_by_meta' ], 10, 2 );
add_action( 'deleted_post_meta', [ $this, 'clear_meta_keys_db_per_post_type_cache_by_meta' ], 10, 2 );
add_action( 'delete_post_metadata', [ $this, 'clear_meta_keys_db_per_post_type_cache_by_meta' ], 10, 2 );

// Prevents password protected posts from being indexed
add_filter( 'ep_post_sync_kill', [ $this, 'kill_sync_for_password_protected' ], 10, 2 );
}

/**
Expand All @@ -106,6 +109,7 @@ public function tear_down() {
remove_action( 'wp_initialize_site', array( $this, 'action_create_blog_index' ) );
remove_filter( 'ep_sync_insert_permissions_bypass', array( $this, 'filter_bypass_permission_checks_for_machines' ) );
remove_filter( 'ep_sync_delete_permissions_bypass', array( $this, 'filter_bypass_permission_checks_for_machines' ) );
remove_filter( 'ep_post_sync_kill', [ $this, 'kill_sync_for_password_protected' ] );
}

/**
Expand Down Expand Up @@ -884,4 +888,39 @@ protected function is_tax_max_count_bigger_than_items_per_cycle( \WP_Taxonomy $t

return $is_max_count_bigger;
}

/**
* Prevent a password protected post from being indexed.
*
* @since 4.6.0
* @param bool $skip Whether should skip or not before checking for a password
* @param int $object_id The Post ID
* @return bool New value of $skip
*/
public function kill_sync_for_password_protected( $skip, $object_id ) {
/**
* Short-circuits the process of checking if a post should be indexed or not depending on its password.
*
* Returning a non-null value will effectively short-circuit the function.
*
* @since 4.6.0
* @hook ep_pre_kill_sync_for_password_protected
* @param {null} $new_skip Whether should skip or not before checking for a password
* @param {bool} $current_skip Current value
* @param {int} $object_id The Post ID
* @return {null|bool} New value of $skip or `null` to keep default behavior.
*/
$skip_filter = apply_filters( 'ep_pre_kill_sync_for_password_protected', null, $skip, $object_id );
burhandodhy marked this conversation as resolved.
Show resolved Hide resolved
if ( ! is_null( $skip_filter ) ) {
return $skip_filter;
}

if ( $skip ) {
return $skip;
}

$post = get_post( $object_id );

return ! empty( $post->post_password );
}
}
32 changes: 32 additions & 0 deletions tests/cypress/integration/features/protected-content.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,36 @@ describe('Protected Content Feature', () => {
cy.visitAdminPage('edit.php?post_status=draft&post_type=post');
cy.getTotal(1);
});

it('Can search password protected post', () => {
cy.login();
cy.maybeEnableFeature('protected_content');

cy.publishPost({
title: 'Password Protected',
password: 'password',
});

// Admin can see post on front and search page.
cy.visit('/');
cy.contains('.site-content article h2', 'Password Protected').should('exist');
cy.visit('/?s=Password+Protected');
cy.contains('.site-content article h2', 'Password Protected').should('exist');

cy.logout();

// Logout user can see the post on front but not on search page.
cy.visit('/');
cy.contains('.site-content article h2', 'Password Protected').should('exist');
cy.visit('/?s=Password+Protected');
cy.contains('.site-content article h2', 'Password Protected').should('not.exist');

cy.createUser({ login: true });

// subscriber can see the post on front and on search page.
cy.visit('/');
cy.contains('.site-content article h2', 'Password Protected').should('exist');
cy.visit('/?s=Password+Protected');
cy.contains('.site-content article h2', 'Password Protected').should('exist');
});
});
42 changes: 2 additions & 40 deletions tests/cypress/integration/features/search/search.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,55 +122,17 @@ describe('Post Search Feature', { tags: '@slow' }, () => {
cy.get('.ep-highlight').should('be.visible');
});

it('Can search password protected post', () => {
it('Can not see any password protected post', () => {
cy.login();

cy.publishPost({
title: 'Password Protected',
password: 'password',
});

// Admin can see post on front and search page.
cy.visit('/');
cy.contains('.site-content article h2', 'Password Protected').should('exist');
cy.visit('/?s=Password+Protected');
cy.contains('.site-content article h2', 'Password Protected').should('exist');

cy.logout();

// Logout user can see the post on front but not on search page.
cy.visit('/');
cy.contains('.site-content article h2', 'Password Protected').should('exist');
cy.visit('/?s=Password+Protected');
cy.contains('.site-content article h2', 'Password Protected').should('not.exist');

cy.createUser();

// subscriber can see the post on front and on search page.
cy.visit('/');
cy.contains('.site-content article h2', 'Password Protected').should('exist');
cy.visit('/?s=Password+Protected');
cy.contains('.site-content article h2', 'Password Protected').should('exist');
});

it('Can Search Product by Variation SKU', () => {
cy.login();
cy.activatePlugin('woocommerce', 'wpCli');
cy.maybeEnableFeature('woocommerce');

cy.updateWeighting({
product: {
'meta._variations_skus.value': {
weight: 1,
enabled: true,
},
},
}).then(() => {
cy.wpCli('elasticpress index --setup --yes');
cy.visit('/?s=awesome-aluminum-shoes-variation-sku');
cy.contains('.site-content article:nth-of-type(1) h2', 'Awesome Aluminum Shoes').should(
'exist',
);
});
cy.contains('.site-content article h2', 'Password Protected').should('not.exist');
});
});
30 changes: 30 additions & 0 deletions tests/php/indexables/TestPost.php
Original file line number Diff line number Diff line change
Expand Up @@ -8848,4 +8848,34 @@ public function testNegativeMenuOrder() {
$this->assertEquals( $post_negative, $query->posts[0] );
$this->assertEquals( $post_positive, $query->posts[1] );
}

/**
* Test the `kill_sync_for_password_protected` method
*
* @since 4.6.0
* @group post
*/
public function testKillSyncForPasswordProtected() {
$pw_post = $this->ep_factory->post->create( [ 'post_password' => 'password' ] );
$no_pw_post = $this->ep_factory->post->create( [] );

ElasticPress\Elasticsearch::factory()->refresh_indices();

$sync_manager = ElasticPress\Indexables::factory()->get( 'post' )->sync_manager;

$this->assertTrue( $sync_manager->kill_sync_for_password_protected( false, $pw_post ) );
$this->assertFalse( $sync_manager->kill_sync_for_password_protected( false, $no_pw_post ) );

/**
* Test the `ep_pre_kill_sync_for_password_protected` filter
*/
$dont_kill_pw_post = function ( $short_circuit, $skip, $object_id ) use ( $pw_post ) {
$this->assertNull( $short_circuit );
$this->assertFalse( $skip );
$this->assertSame( $pw_post, $object_id );
return false;
};
add_filter( 'ep_pre_kill_sync_for_password_protected', $dont_kill_pw_post, 10, 3 );
$this->assertFalse( $sync_manager->kill_sync_for_password_protected( false, $pw_post ) );
}
}