fix permission check for items considering collection #241
This commit is contained in:
parent
8234540ec8
commit
f30365c9b9
|
@ -27,6 +27,7 @@ class Items extends Repository {
|
|||
add_filter( 'posts_where', array( &$this, 'content_in_posts_where' ), 10, 2 );
|
||||
add_filter( 'comments_open', [$this, 'hook_comments_open'], 10, 2);
|
||||
add_action( 'tainacan-api-item-updated', array( &$this, 'hook_api_updated_item' ), 10, 2 );
|
||||
add_filter( 'map_meta_cap', array( $this, 'map_meta_cap' ), 10, 4 );
|
||||
}
|
||||
|
||||
public function get_map() {
|
||||
|
@ -552,4 +553,82 @@ class Items extends Repository {
|
|||
return $open_comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter to handle special permissions
|
||||
*
|
||||
* @see https://developer.wordpress.org/reference/hooks/map_meta_cap/
|
||||
*
|
||||
*/
|
||||
public function map_meta_cap( $caps, $cap, $user_id, $args ) {
|
||||
|
||||
// Filters meta caps edit_tainacan-collection and check if user is moderator
|
||||
|
||||
if ( $cap == 'read_post' && is_array( $args ) && array_key_exists( 0, $args ) ) {
|
||||
|
||||
$entity = $args[0];
|
||||
|
||||
if ( is_numeric( $entity ) || $entity instanceof Entities\Item ) {
|
||||
|
||||
if ( is_numeric( $entity ) ) {
|
||||
$entity = $this->fetch( (int) $entity );
|
||||
}
|
||||
|
||||
if ( $entity instanceof Entities\Item ) {
|
||||
|
||||
$collection = $entity->get_collection();
|
||||
|
||||
if ( $collection instanceof Entities\Collection ) {
|
||||
$status_obj = get_post_status_object( $collection->get_status() );
|
||||
if ( ! $status_obj->public ) {
|
||||
$caps[] = $entity->get_capabilities()->read_private_posts;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $caps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if $user can read the item
|
||||
*
|
||||
* @param Entities\Entity $entity
|
||||
* @param int|\WP_User|null $user default is null for the current user
|
||||
*
|
||||
* @return boolean
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function can_read( Entities\Entity $entity, $user = null ) {
|
||||
|
||||
if ( ! $entity instanceof Entities\Item) {
|
||||
throw new InvalidArgumentException('Items::can_read() expects an Item entity as the first parameter');
|
||||
}
|
||||
|
||||
$can_read = parent::can_read($entity, $user);
|
||||
|
||||
if ( $can_read ) {
|
||||
$collection = $entity->get_collection();
|
||||
$status_obj = get_post_status_object( $collection->get_status() );
|
||||
|
||||
if ( $status_obj->public ) {
|
||||
return $can_read;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( is_null( $user ) ) {
|
||||
return false;
|
||||
} elseif ( is_object( $user ) ) {
|
||||
$user = $user->ID;
|
||||
}
|
||||
|
||||
$entity_cap = $entity->get_capabilities();
|
||||
|
||||
return user_can( $user, $entity_cap->read_private_posts, $entity->get_id() );
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -693,7 +693,7 @@ abstract class Repository {
|
|||
* @return boolean
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function can_read( $entity, $user = null ) {
|
||||
public function can_read( Entities\Entity $entity, $user = null ) {
|
||||
|
||||
if ( is_null( $user ) ) {
|
||||
$user = get_current_user_id();
|
||||
|
@ -716,7 +716,7 @@ abstract class Repository {
|
|||
return false;
|
||||
}
|
||||
|
||||
return user_can( $user, $entity_cap->read, $entity->get_id() );
|
||||
return user_can( $user, $entity_cap->read_post, $entity->get_id() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,6 +24,7 @@ class Permissions extends TAINACAN_UnitTestCase {
|
|||
array(
|
||||
'name' => 'testePerms',
|
||||
'description' => 'adasdasdsa',
|
||||
'status' => 'publish'
|
||||
),
|
||||
true
|
||||
);
|
||||
|
@ -63,10 +64,11 @@ class Permissions extends TAINACAN_UnitTestCase {
|
|||
true
|
||||
);
|
||||
|
||||
$this->assertTrue(user_can($new_admin_user, $collection->cap->read_post, $collection->get_id()), 'admin should be able read private collection');
|
||||
$this->assertTrue(user_can($new_admin_user, $collection->cap->read_post, $privateCollection->get_id()), 'admin should be able read private collection');
|
||||
|
||||
// subsciber should not be able to
|
||||
$this->assertFalse(user_can($new_user, $collection->cap->read_post, $collection->get_id()), 'subscriber should not be able read private collection');
|
||||
$x = user_can($new_user, $collection->cap->read_post, $collection->get_id());
|
||||
$this->assertFalse(user_can($new_user, $collection->cap->read_post, $privateCollection->get_id()), 'subscriber should not be able read private collection');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -205,4 +207,57 @@ class Permissions extends TAINACAN_UnitTestCase {
|
|||
|
||||
}
|
||||
|
||||
function test_read_item() {
|
||||
|
||||
$ItemRepo = \Tainacan\Repositories\Items::get_instance();
|
||||
$ColRepo = \Tainacan\Repositories\Collections::get_instance();
|
||||
|
||||
$collection = $this->tainacan_entity_factory->create_entity(
|
||||
'collection',
|
||||
array(
|
||||
'name' => 'teste1',
|
||||
'description' => 'adasdasdsa',
|
||||
'status' => 'publish'
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
$item = $this->tainacan_entity_factory->create_entity(
|
||||
'item',
|
||||
array(
|
||||
'title' => 'testeItem',
|
||||
'collection' => $collection,
|
||||
'status' => 'publish'
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
$subscriber = $this->factory()->user->create(array( 'role' => 'subscriber' ));
|
||||
wp_set_current_user($subscriber);
|
||||
|
||||
wp_logout();
|
||||
|
||||
$this->assertTrue($item->can_read());
|
||||
|
||||
$item->set_status('private');
|
||||
$item->validate();
|
||||
$item = $ItemRepo->insert($item);
|
||||
|
||||
$this->assertFalse($item->can_read());
|
||||
|
||||
$item->set_status('publish');
|
||||
$item->validate();
|
||||
$item = $ItemRepo->insert($item);
|
||||
|
||||
$this->assertTrue($item->can_read());
|
||||
|
||||
$collection->set_status('private');
|
||||
$collection->validate();
|
||||
$collection = $ColRepo->insert($collection);
|
||||
|
||||
$this->assertFalse($item->can_read());
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue