pfefferle / wordpress-webfinger

A WebFinger plugin for WordPress

Home Page:https://wordpress.org/plugins/webfinger/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

plugin is entirely user centric

willnorris opened this issue · comments

Right now, the plugin assumes that all WebFinger queries are for users. This is probably fine for now, but it's worth noting that the WebFinger spec itself provides an example where the query is for a webpage: http://tools.ietf.org/html/rfc7033#section-3.2

I think it's actually fine to consider this out of scope for now (though it wouldn't take too much work to remedy this), but I wanted to at least track it here.

I love this idea! It is a nice way to return the short URL or the license of the article.

I think we should add some actions (for example before checking the user) to enable completely custom outputs

The more I think about this feature the more convinced I am that we should start with that even if it is only conceptual. The resource is the first call and everything else depends on it, so it could result in a complete refactoring process if we implement it at last.

I tried to implement this in a first draft and I am curious what you think about https://github.com/pfefferle/wordpress-webfinger/tree/resource-centric

  • I added a pre_render action, so users can write there own resource specific outputs
  • I postfixed (<- I hope this is a word) the new webfinger hooks with webfinger_user_output and webfinger_post_output because webfinger_user should be used to filter the user (perhaps in the get_user_by_uri function)
  • I added a generic hook webfinger_generic_output to enable an object independent (if the resource is no post or user) output

It would also be possible to only use one filter and pass the post or user-object or null (for custum/generic outputs)

if ($user = self::get_user_by_uri($wp->query_vars['resource'])) {
  $object = $user;
} else if ($post = self::get_post_by_uri($wp->query_vars['resource'])) {
  $object = $post;
} else {
  $object = null;
}

$webfinger = apply_filters('webfinger_output', $webfinger, $object, $wp->query_vars['resource']);

...but that means that the implementor has to use something linke get_class to get knowledge about the resource type. We have to do the check anyways (to get the post or user) so I thought it would be a more comfortable way to add several filters.

I think we have to rethink the use of the webfinger filter nevertheless... the filter should be working if there is a user or not.

what do you think about

// find matching user
$user = self::get_user_by_uri($wp->query_vars['resource']);

// filter webfinger array
$webfinger = apply_filters('webfinger_output', array(), $user, $wp->query_vars['resource'], $wp->query_vars);

// check if there is a output
if (empty($webfinger)) {
  status_header(404);
  header('Content-Type: text/plain; charset=' . get_bloginfo('charset'), true);
  echo 'no user found';
  exit;
}

do_action('webfinger_render', $webfinger);

That would allow us to pass the user if there is one or null if not. That would allow extensions that focuses on post-urls etc. To be downwards compatible we have to rename the filter and have hook the old filter into the new one like I did here: https://github.com/pfefferle/wordpress-webfinger/blob/resource-centric/plugin.php#L334 because the old filter always expects a user.

the alternative would be to add a general filter without the user param in addition to the current filter like

// find matching user
$user = self::get_user_by_uri($wp->query_vars['resource']);

$webfinger = array();

if ($user) {
  // filter webfinger array
  $webfinger = apply_filters('webfinger', $webfinger, $user, $wp->query_vars['resource'], $wp->query_vars);
} else {
  $webfinger = apply_filters('webfinger_general', $webfinger, $wp->query_vars['resource'], $wp->query_vars);
}

// check if there is a output
if (empty($webfinger)) {
  status_header(404);
  header('Content-Type: text/plain; charset=' . get_bloginfo('charset'), true);
  echo 'no user found';
  exit;
}

do_action('webfinger_render', $webfinger);

I am not sure if it is good to parse a param that could be null as used in the first example

I implemented the mentioned in a branch: https://github.com/pfefferle/wordpress-webfinger/tree/generic-filter

The changes:

  • the WP_User can be null
  • the 404 check checks if the array is filled

Extensibility

  • to add data for all users in the system you have to check if $user is not null
  • to add user-specific entries you have to check the $user id
  • to add for example post-specific entries you have to check if $user is null and check the url...

I experimented with another version. A generic filter and the user stuff hooks into this filter and provides a second, user specific filter. It's in the main branch right now. Not sure if it like it though...

changed it once again.

  • parse request adds a generic "webfinger_data" filter
  • the user stuff hooks into this filter and provides a separate "webfinger_user_data" filter
  • the user is set via a "webfinger_user" filter to replace it with some custom code