Skip to content
Snippets Groups Projects
Commit a538c20e authored by Chris Leppanen's avatar Chris Leppanen
Browse files

Port authorization from 6.x to 7.x.

parent 6ea41915
No related branches found
Tags 4.4.0
No related merge requests found
......@@ -77,6 +77,39 @@ class FeedsNodeProcessor extends FeedsProcessor {
return $node;
}
/**
* Check that the user has permission to save a node.
*/
protected function entitySaveAccess($entity) {
// The check will be skipped for anonymous nodes.
if ($this->config['authorize'] && !empty($entity->uid)) {
$author = user_load($entity->uid);
// If the uid was mapped directly, rather than by email or username, it
// could be invalid.
if (!$author) {
$message = 'User %uid is not a valid user.';
throw new FeedsAccessException(t($message, array('%uid' => $entity->uid)));
}
if (empty($entity->nid) || !empty($entity->is_new)) {
$op = 'create';
$access = node_access($op, $entity->type, $author);
}
else {
$op = 'update';
$access = node_access($op, $entity, $author);
}
if (!$access) {
$message = 'User %name is not authorized to %op content type %content_type.';
throw new FeedsAccessException(t($message, array('%name' => $author->name, '%op' => $op, '%content_type' => $entity->type)));
}
}
}
/**
* Save a node.
*/
......@@ -137,6 +170,7 @@ class FeedsNodeProcessor extends FeedsProcessor {
'content_type' => $type,
'expire' => FEEDS_EXPIRE_NEVER,
'author' => 0,
'authorize' => TRUE,
) + parent::configDefaults();
}
......@@ -162,6 +196,12 @@ class FeedsNodeProcessor extends FeedsProcessor {
'#autocomplete_path' => 'user/autocomplete',
'#default_value' => empty($author->name) ? 'anonymous' : check_plain($author->name),
);
$form['authorize'] = array(
'#type' => 'checkbox',
'#title' => t('Authorize'),
'#description' => t('Check that the author has permission to create the node.'),
'#default_value' => $this->config['authorize'],
);
$period = drupal_map_assoc(array(FEEDS_EXPIRE_NEVER, 3600, 10800, 21600, 43200, 86400, 259200, 604800, 2592000, 2592000 * 3, 2592000 * 6, 31536000), 'feeds_format_expire');
$form['expire'] = array(
'#type' => 'select',
......
......@@ -19,6 +19,11 @@ define('FEEDS_PROCESS_LIMIT', 50);
*/
class FeedsValidationException extends Exception {}
/**
* Thrown if a an access check fails.
*/
class FeedsAccessException extends Exception {}
/**
* Abstract class, defines interface for processors.
*/
......@@ -64,11 +69,22 @@ abstract class FeedsProcessor extends FeedsPlugin {
*/
protected function entityValidate($entity) {}
/**
* Access check for saving an enity.
*
* @param $entity
* Entity to be saved.
*
* @throws FeedsAccessException $e
* If the access check fails.
*/
protected function entitySaveAccess($entity) {}
/**
* Save an entity.
*
* @param $entity
* Entity to b saved.
* Entity to be saved.
*/
protected abstract function entitySave($entity);
......@@ -159,6 +175,8 @@ abstract class FeedsProcessor extends FeedsPlugin {
continue;
}
// This will throw an exception on failure.
$this->entitySaveAccess($entity);
$this->entitySave($entity);
// Track progress.
......
......@@ -144,9 +144,9 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
$this->assertText('Deleted 10 nodes');
$this->assertFeedItemCount(0);
// Change author.
// Change author and turn off authorization.
$this->auth_user = $this->drupalCreateUser(array('access content'));
$this->setSettings('syndication', 'FeedsNodeProcessor', array('author' => $this->auth_user->name));
$this->setSettings('syndication', 'FeedsNodeProcessor', array('author' => $this->auth_user->name, 'authorize' => FALSE));
// Change input format.
$this->setSettings('syndication', 'FeedsNodeProcessor', array('input_format' => 'plain_text'));
......@@ -406,4 +406,53 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
$this->drupalGet('node/add/article');
$this->assertNoFieldByName('feeds[FeedsHTTPFetcher][source]');
}
/**
* Test that nodes will not be created if the user is unauthorized to create
* them.
*/
public function testAuthorize() {
// Create a user with limited permissions. We can't use
// $this->drupalCreateUser here because we need to to set a specific user
// name.
$edit = array(
'name' => 'Development Seed',
'mail' => 'devseed@example.com',
'pass' => user_password(),
'status' => 1,
);
$account = user_save(drupal_anonymous_user(), $edit);
// Adding a mapping to the user_name will invoke authorization.
$this->addMappings('syndication',
array(
5 => array(
'source' => 'author_name',
'target' => 'user_name',
),
)
);
$nid = $this->createFeedNode();
$this->assertText('Failed importing 10 nodes.');
$this->assertText('User ' . $account->name . ' is not authorized to create content type article.');
$node_count = db_query("SELECT COUNT(*) FROM {node}")->fetchField();
// We should have 1 node, the feed node.
$this->assertEqual($node_count, 1, t('Correct number of nodes in the database.'));
// Give the user our admin powers.
$edit = array(
'roles' => $this->admin_user->roles,
);
$account = user_save($account, $edit);
$this->drupalPost("node/$nid/import", array(), 'Import');
$this->assertText('Created 10 nodes.');
$node_count = db_query("SELECT COUNT(*) FROM {node}")->fetchField();
$this->assertEqual($node_count, 11, t('Correct number of nodes in the database.'));
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment