humanmade / protected-embeds

A drop-in replacement for WordPress.com protected embeds
11 stars 4 forks source link

Allow filterable use of embeds domain for other content #8

Open goldenapples opened 8 years ago

goldenapples commented 8 years ago

Here's another modification we made for our purposes: now that we have an embeds domain available, we've found a number of other uses for it.

This pull adds a filter around the behavior of dying when a request for something other than a protected embed is recieved on the embeds domain. This can be used to serve other types of embeds which need to be served on a different domain from the main site.

In our theme, we've added some rules like this in order to serve iframes inside Google AMP articles:

/**
 * Allow the theme to use the protected embeds domain to serve iframes
 * using the endpoint `/cta/{name}/`.
 */
add_filter( 'protected_embeds_allow_embeds_domain', function( $allow ) {
    global $wp;

    // Allow serving CTAs from embeds domain
    if ( ! empty( $wp->query_vars['cta'] ) ) {
        $allow = true;
    }

    return $allow;
} );

See #2

goldenapples commented 8 years ago

@roborourke @joehoyle I'm wondering if you can merge this into version 1.0 as well. We're currently using the embeds domain for a few other purposes that require a cookieless domain, and if we update to version 1.0 we'd like to be able to preserve that functionality. Thanks!

roborourke commented 8 years ago

@goldenapples only thing here is I'm not sure it makes sense for the scope of this plugin as after the check to see if the domain is allowed it'll just return from that function if there's no protected-iframe query var. You could achieve the same using a simple separate plugin that references the PROTECTED_EMBEDS_DOMAIN constant just on an earlier priority eg:

/**
Plugin name: Protected embeds domain requests
*/

add_action( 'parse_request', function( WP $wp ) {
    $server = $_SERVER['HTTP_HOST'];

    // Ignore requests to other hostnames
    if ( PROTECTED_EMBEDS_DOMAIN !== $server ) {
        return;
    }

    $allow = apply_filters( 'protected_embeds_domain_allow', false, $wp );

    // Make sure if this hook is used we don't continue to the protected-embeds plugin output
    if ( $allow && has_action( 'protected_embeds_domain_request' ) ) {
        do_action( 'protected_embeds_domain_request', $wp );
        exit;
    }
}, 9  );

Maybe your solution along with this generic approach could be worked in thinking about it. @joehoyle any thoughts?

goldenapples commented 8 years ago

You could achieve the same using a simple separate plugin that references the PROTECTED_EMBEDS_DOMAIN constant just on an earlier priority.

Oh, that makes some sense. But in our case there are some times where we want to go through the whole WP setup to serve a request through the protected embeds domain.

An example: In Google AMP templates the main file must be served from the primary site domain, but any interactive iframes must be served from a separate domain if you want to avoid the allow-same-origin sandbox. We're using the protected embeds domain to embed any interactive forms, etc, onto these views through the <amp-iframe> element. But because those are dependant on the current post, we need to let the main WordPress query run and all the globals be set up. If the plugin throws a wp_die() in the parse_request hook, then that doesn't work.

I think your solution could still work - it would just mean removing this plugin's action if we determine we want to serve something else on a request to the embeds domain. But I'm not sure which is cleaner or less hacky.

roborourke commented 8 years ago

I see your point. If the above (or something like it) is the same mechanism used to add the default protected iframe handling then you could register / unregister hooks as you like. Or we could just resort to wp_die() if there are no hooks on the proposed action or $allow is false. That way we could remove that bit of code from the display iframe function.

roborourke commented 8 years ago

Could perhaps use it as a single point to remove any WP auth cookies that might be there. I have that potential use case in #12 with multisite SSO.