humanmade / authorship

A modern approach to author attribution in WordPress.
GNU General Public License v3.0
66 stars 7 forks source link

Adding attribute_post_type does not allow you to attribute_post_type #111

Open tomjn opened 1 year ago

tomjn commented 1 year ago

Because of a user cap meta filter, this capability is never actually checked for and is overriden by:

https://github.com/humanmade/authorship/blob/ad162b111f778d51d66ea6412887ffe258407225/inc/namespace.php#L267

This means it's not possible for an author to write a post with guest authors, even if they have the attribute_post_type capability

tomjn commented 1 year ago

I've attempted to work around this with a filter but it should be unnecessary, and it's sub-optimal:

add_filter( 'user_has_cap', __NAMESPACE__ . '\\author_filter_user_has_cap', 11, 4 );

/**
 * Filters attribute_post_type
 *
 * @param bool[]   $user_caps     Array of key/value pairs where keys represent a capability name and boolean values
 *                                represent whether the user has that capability.
 * @param string[] $required_caps Array of required primitive capabilities for the requested capability.
 * @param mixed[]  $args {
 *     Arguments that accompany the requested capability check.
 *
 *     @type string    $0 Requested capability.
 *     @type int       $1 Concerned user ID.
 *     @type mixed  ...$2 Optional second and further parameters.
 * }
 * @param WP_User  $user          Concerned user object.
 * @return bool[] Array of concerned user's capabilities.
 */
function author_filter_user_has_cap( array $user_caps, array $required_caps, array $args, WP_User $user ) : array {
    $cap = $args[0];

    if ( ( $cap === 'attribute_post_type' ) && ( in_array( 'author', $user->roles, true ) ) ){
        $user_caps['attribute_post_type'] = true;
    }

    return $user_caps;
}
tomjn commented 1 year ago

Noting the above workaround does not work 😞

johnbillion commented 1 year ago

There should be test coverage for this in TestCapabilities. What's missing from the tests?

tomjn commented 1 year ago

Not sure, but a client is struggling pretty badly to get authors to be able to assign guest authors on their posts, and they've confirmed via WP CLI that attribute_post_type is indeed added to the author role. Despite this they're unable to assign guest authors.

It should be noted they also do not want authors to be able to create new guest authors

tomjn commented 1 year ago

in theory #113 would fix this by handling this more logically, and adds commenting so it's clearer. It also fixes that it falls back to edit others posts but does not pass the post ID when it performs that check

johnbillion commented 1 year ago

I would expect the testGuestPostAttributionCanBeGranted() and testGuestAuthorCreationCanBeDenied() to handle both of these situations, but those tests only test the capabilities, not the actual functionality, so there might be something missing there.

tomjn commented 1 year ago

As noted in https://github.com/humanmade/authorship/pull/113#issuecomment-1353513249 I tracked this down further, and this issue is specific to users that do not have the edit_others_posts capability, so author roles are the most likely role to have this issue.

The concern is that the client I'm working with expects that an author can add guest authors to their posts, but this isn't possible, even when they have the capability. This is due to how Authorship adds the capability to the REST response which depends on detecting then removing the ability to assign an author that requires edit_others_posts.

One thing that could be done and is implemented via the workaround is to change the check to instead call current_user_can. The downside of this is that without edit_others_posts an author can remove themselves, and the post disappears as they can no longer edit it.