Automattic / jetpack

Security, performance, marketing, and design tools — Jetpack is made by WordPress experts to make WP sites safer and faster, and help you grow your traffic.
https://jetpack.com/
Other
1.59k stars 798 forks source link

Search: add support for membership sites #17116

Open gibrown opened 4 years ago

gibrown commented 4 years ago

Membership sites are some combination of public and private content that need to allow end users to search both logged in and not. Currently we don't have a consistent way to differentiate that content, and we don't have a way to correctly authorize access to the search. It is very easy to leak data.

For private sites we are proxying through the main site. Maybe all membership sites need to proxy and then we add the filters as we proxy the request? So we treat the site as fully private for search, but allow authenticated searches. This reduces the speed of the API, but maybe the tradeoff is worth it.

gibrown commented 1 week ago

One workaround for sites with gated/member/restricted content is to intercept the content before Syncing it. This could potentially break other features, but is an OK workaround for Search.

// add_filter( 'jetpack_sync_before_send_jetpack_sync_save_post', array( $this, 'modify_jetpack_sync_post' ), 20, 1 );

/**
     * Modify post data before it's synced to Jetpack to not show protected content.
     *
     * @param array $args The arguments passed to the jetpack_sync_save_post action.
     *
     * @return array Modified arguments
     */
    public function modify_jetpack_sync_post( $args ) {
        list( $post_id, $post, $update, $previous_state ) = $args;

        $restricted_post_types = Option::get_restricted_post_types();

        $has_restricted_content = has_block( 'passport/restricted-content', $post->post_content );

        if ( ! $has_restricted_content && ! in_array( $post->post_type, $restricted_post_types, true ) ) {
            return array( $post_id, $post, $update, $previous_state );
        }

        $passport_public = get_post_meta( $post->ID, 'passport_public', true );
        $public_access   = 'public' === $passport_public;

        // Check if the article is public
        if ( empty( $passport_public ) || $public_access ) {
            // Remove Restricted Content blocks
            if ( $has_restricted_content ) {
                $post->post_content = $this->remove_restricted_content_blocks( $post->post_content );
            }

            return array( $post_id, $post, $update, $previous_state );
        }

        $post->post_content = __( 'Your search matches member-only content from this post.', 'passport' );

        $post_excerpt = get_the_excerpt( $post_id );

        if ( ! empty( $post_excerpt ) ) {
            $post->post_content = $post_excerpt;
        }

        return array( $post_id, $post, $update, $previous_state );
    }
gibrown commented 1 week ago

https://github.com/Automattic/jetpack/pull/39053 also has a workaround that switches the UI from displaying the post content to only displaying the excerpt from the posts. This has the downside of losing highlighting of the results though.