Commit dec99527 authored by fago's avatar fago

Patch by klausi, fago, clemens.tolboom, japerry, helmo: Access API fix for...

Patch by klausi, fago, clemens.tolboom, japerry, helmo: Access API fix for lists of referenced entities and integration improvements for comment, node and statitics. Includes improved test coverage.
parent e01e9fd6
This diff is collapsed.
......@@ -228,10 +228,6 @@ abstract class EntityMetadataWrapper {
* If there is no access information for this property, TRUE is returned.
*/
public function access($op, $account = NULL) {
if (empty($this->info['parent']) && $this instanceof EntityDrupalWrapper) {
// If there is no parent just incorporate entity based access.
return $this->entityAccess($op == 'edit' ? 'update' : 'view', $account);
}
return !empty($this->info['parent']) ? $this->info['parent']->propertyAccess($this->info['name'], $op, $account) : TRUE;
}
......@@ -500,13 +496,9 @@ class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAg
protected function propertyAccess($name, $op, $account = NULL) {
$info = $this->getPropertyInfo($name);
// If the property should be accessed and it's an entity, make sure the user
// is allowed to view that entity.
if ($op == 'view' && $this->$name instanceof EntityDrupalWrapper && !$this->$name->entityAccess($op, $account)) {
return FALSE;
}
// If a property should be edited and this is an entity, make sure the user
// has update access for this entity.
// If a property should be edited and this is part of an entity, make sure
// the user has update access for this entity.
if ($op == 'edit') {
$entity = $this;
while (!($entity instanceof EntityDrupalWrapper) && isset($entity->info['parent'])) {
......@@ -804,6 +796,27 @@ class EntityDrupalWrapper extends EntityStructureWrapper {
return $this->type;
}
/**
* {@inheritdoc}
*
* Note that this method checks property access, but can be used for checking
* entity access *only* if the wrapper is not a property (i.e. has no parent
* wrapper).
* To be safe, better use EntityDrupalWrapper::entityAccess() for checking
* entity access.
*/
public function access($op, $account = NULL) {
if (!empty($this->info['parent'])) {
// If this is a property, make sure the user is able to view the
// currently referenced entity also.
return $this->entityAccess('view', $account) && parent::access($op, $account);
}
else {
// This is not a property, so fallback on entity access.
return $this->entityAccess($op == 'edit' ? 'update' : 'view', $account);
}
}
/**
* Checks whether the operation $op is allowed on the entity.
*
......
......@@ -206,6 +206,16 @@ function entity_metadata_statistics_node_get_properties($node, array $options, $
}
}
/**
* Access callback for restricted node statistics properties.
*/
function entity_metadata_statistics_properties_access($op, $property, $entity = NULL, $account = NULL) {
if ($property == 'views' && user_access('view post access counter', $account)) {
return TRUE;
}
return user_access('access statistics', $account);
}
/**
* Callback for getting site-wide properties.
* @see entity_metadata_system_entity_info_alter()
......@@ -733,6 +743,18 @@ function entity_metadata_comment_access($op, $entity = NULL, $account = NULL) {
return FALSE;
}
}
// Comment administrators are allowed to perform all operations on all
// comments.
if (user_access('administer comments', $account)) {
return TRUE;
}
// Unpublished comments can never be accessed by non-admins.
if (isset($entity->status) && $entity->status == COMMENT_NOT_PUBLISHED) {
return FALSE;
}
if (isset($entity) && $op == 'update') {
// Because 'comment_access' only checks the current user, we need to do our
// own access checking if an account was specified.
......@@ -740,15 +762,22 @@ function entity_metadata_comment_access($op, $entity = NULL, $account = NULL) {
return comment_access('edit', $entity);
}
else {
return ($account->uid && $account->uid == $entity->uid && $entity->status == COMMENT_PUBLISHED && user_access('edit own comments', $account)) || user_access('administer comments', $account);
return $account->uid && $account->uid == $entity->uid && user_access('edit own comments', $account);
}
}
if (user_access('administer comments', $account) || user_access('access comments', $account) && $op == 'view') {
if (user_access('access comments', $account) && $op == 'view') {
return TRUE;
}
return FALSE;
}
/**
* Access callback for restricted comment properties.
*/
function entity_metadata_comment_properties_access($op, $property, $entity = NULL, $account = NULL) {
return user_access('administer comments', $account);
}
/**
* Access callback for the taxonomy entities.
*/
......
......@@ -24,6 +24,7 @@ function entity_metadata_comment_entity_property_info() {
$properties['hostname'] = array(
'label' => t("IP Address"),
'description' => t("The IP address of the computer the comment was posted from."),
'access callback' => 'entity_metadata_comment_properties_access',
'schema field' => 'hostname',
);
$properties['name'] = array(
......@@ -40,8 +41,8 @@ function entity_metadata_comment_entity_property_info() {
'description' => t("The email address left by the comment author."),
'getter callback' => 'entity_metadata_comment_get_properties',
'setter callback' => 'entity_property_verbatim_set',
'setter permission' => 'administer comments',
'validation callback' => 'valid_email_address',
'access callback' => 'entity_metadata_comment_properties_access',
'schema field' => 'mail',
);
$properties['homepage'] = array(
......@@ -56,7 +57,6 @@ function entity_metadata_comment_entity_property_info() {
'label' => t("Subject"),
'description' => t("The subject of the comment."),
'setter callback' => 'entity_property_verbatim_set',
'setter permission' => 'administer comments',
'sanitize' => 'filter_xss',
'required' => TRUE,
'schema field' => 'subject',
......@@ -88,6 +88,7 @@ function entity_metadata_comment_entity_property_info() {
'description' => t("The comment's parent, if comment threading is active."),
'type' => 'comment',
'getter callback' => 'entity_metadata_comment_get_properties',
'setter permission' => 'administer comments',
'schema field' => 'pid',
);
$properties['node'] = array(
......@@ -116,7 +117,7 @@ function entity_metadata_comment_entity_property_info() {
// it is an integer, so we follow the schema definition.
'type' => 'integer',
'options list' => 'entity_metadata_status_options_list',
'setter permission' => 'administer comments',
'access callback' => 'entity_metadata_comment_properties_access',
'schema field' => 'status',
);
return $info;
......
......@@ -19,6 +19,7 @@ function entity_metadata_statistics_entity_property_info_alter(&$info) {
'type' => 'integer',
'getter callback' => 'entity_metadata_statistics_node_get_properties',
'computed' => TRUE,
'access callback' => 'entity_metadata_statistics_properties_access',
);
$properties['day_views'] = array(
'label' => t("Views today"),
......@@ -26,6 +27,7 @@ function entity_metadata_statistics_entity_property_info_alter(&$info) {
'type' => 'integer',
'getter callback' => 'entity_metadata_statistics_node_get_properties',
'computed' => TRUE,
'access callback' => 'entity_metadata_statistics_properties_access',
);
$properties['last_view'] = array(
'label' => t("Last view"),
......@@ -33,5 +35,6 @@ function entity_metadata_statistics_entity_property_info_alter(&$info) {
'type' => 'date',
'getter callback' => 'entity_metadata_statistics_node_get_properties',
'computed' => TRUE,
'access callback' => 'entity_metadata_statistics_properties_access',
);
}
......@@ -59,6 +59,7 @@ function entity_metadata_user_entity_property_info() {
'description' => t("The date the user last accessed the site."),
'getter callback' => 'entity_metadata_user_get_properties',
'type' => 'date',
'access callback' => 'entity_metadata_user_properties_access',
'schema field' => 'access',
);
$properties['last_login'] = array(
......@@ -66,6 +67,7 @@ function entity_metadata_user_entity_property_info() {
'description' => t("The date the user last logged in to the site."),
'getter callback' => 'entity_metadata_user_get_properties',
'type' => 'date',
'access callback' => 'entity_metadata_user_properties_access',
'schema field' => 'login',
);
$properties['created'] = array(
......@@ -73,6 +75,7 @@ function entity_metadata_user_entity_property_info() {
'description' => t("The date the user account was created."),
'type' => 'date',
'schema field' => 'created',
'setter permission' => 'administer users',
);
$properties['roles'] = array(
'label' => t("User roles"),
......@@ -80,7 +83,6 @@ function entity_metadata_user_entity_property_info() {
'type' => 'list<integer>',
'getter callback' => 'entity_metadata_user_get_properties',
'setter callback' => 'entity_metadata_user_set_properties',
'setter permission' => 'administer users',
'options list' => 'entity_metadata_user_roles',
'access callback' => 'entity_metadata_user_properties_access',
);
......@@ -92,7 +94,7 @@ function entity_metadata_user_entity_property_info() {
// it is an integer, so we follow the schema definition.
'type' => 'integer',
'options list' => 'entity_metadata_user_status_options_list',
'setter permission' => 'administer users',
'access callback' => 'entity_metadata_user_properties_access',
'schema field' => 'status',
);
$properties['theme'] = array(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment