Skip to content
Snippets Groups Projects
Commit 7100732c authored by baldwinlouie's avatar baldwinlouie
Browse files

Issue #3000978 by baldwinlouie: Enhance access control for aws instances

parent 2a2920e2
No related branches found
No related tags found
No related merge requests found
......@@ -8,11 +8,12 @@
*
*/
use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Entity;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\Core\Entity\EntityInterface;
/**
......@@ -184,20 +185,44 @@ function aws_cloud_entity_operation(EntityInterface $entity) {
$operations = [];
if ($entity->getEntityTypeId() == 'aws_cloud_instance') {
if ($entity->instance_state() == 'running') {
$operations['stop'] = [
'title' => t('Stop'),
'url' => $entity->toUrl('stop-form'),
'weight' => 20,
];
}
else if ($entity->instance_state() == 'stopped') {
$operations['start'] = [
'title' => t('Start'),
'url' => $entity->toUrl('start-form'),
'weight' => 20,
];
$account = \Drupal::currentUser();
if ($account->hasPermission('edit any aws cloud instance') || ($account->hasPermission('edit own aws cloud instance') && $account->id() == $entity->getOwner()->id())) {
if ($entity->instance_state() == 'running') {
$operations['stop'] = [
'title' => t('Stop'),
'url' => $entity->toUrl('stop-form'),
'weight' => 20,
];
}
else {
if ($entity->instance_state() == 'stopped') {
$operations['start'] = [
'title' => t('Start'),
'url' => $entity->toUrl('start-form'),
'weight' => 20,
];
}
}
}
}
return $operations;
}
/**
* Implements hook_query_TAG_Alter().
*
* Alter the query for users that can only view their own instances.
*/
function aws_cloud_query_aws_cloud_instance_access_alter(AlterableInterface $query) {
if (!$account = $query->getMetaData('account')) {
$account = \Drupal::currentUser();
}
if ($account->hasPermission('view any aws cloud instance')) {
return;
}
if ($account->hasPermission('view own aws cloud instance')) {
// add a user_id condition
$query->condition('user_id', $account->id());
}
}
\ No newline at end of file
......@@ -41,16 +41,23 @@ add aws cloud instance:
list aws cloud instance:
title: 'List AWS Cloud instance'
description: 'Allow to list instance'
view aws cloud instance:
title: 'View AWS Cloud instance'
view any aws cloud instance:
title: 'View any AWS Cloud instance'
description: 'Allow to view instance'
edit aws cloud instance:
title: 'Edit AWS Cloud instance'
edit any aws cloud instance:
title: 'Edit any AWS Cloud instance'
description: 'Allow to edit instance'
delete aws cloud instance:
title: 'Terminate AWS Cloud instance'
delete any aws cloud instance:
title: 'Terminate any AWS Cloud instance'
description: 'Allow to terminate instance'
view own aws cloud instance:
title: 'View own AWS Cloud instance'
edit own aws cloud instance:
title: 'Edit own AWS Cloud instance'
delete own aws cloud instance:
title: 'Terminate own AWS Cloud instance'
#################
# AWS Cloud Image
......
......@@ -21,14 +21,33 @@ class InstanceAccessControlHandler extends EntityAccessControlHandler {
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
// first check for cloud_context access
if (!AccessResult::allowedIfHasPermission($account, 'view ' . $entity->cloud_context())->isAllowed()) {
return AccessResult::neutral();
}
switch ($operation) {
case 'view':
return AccessResult::allowedIfHasPermissions($account, ['view aws cloud instance', 'view ' . $entity->cloud_context()]);
if ($account->hasPermission('view any aws cloud instance')) {
return AccessResult::allowed();
}
else {
return AccessResult::allowedIf($account->hasPermission('view own aws cloud instance') && ($account->id() == $entity->getOwner()->id()));
}
case 'update':
case 'edit':
return AccessResult::allowedIfHasPermissions($account, ['edit aws cloud instance', 'view ' . $entity->cloud_context()]);
if ($account->hasPermission('edit any aws cloud instance')) {
return AccessResult::allowed();
}
else {
return AccessResult::allowedIf($account->hasPermission('edit own aws cloud instance') && ($account->id() == $entity->getOwner()->id()));
}
case 'delete':
return AccessResult::allowedIfHasPermissions($account, ['delete aws cloud instance', 'view ' . $entity->cloud_context()]);
if ($account->hasPermission('delete any aws cloud instance')) {
return AccessResult::allowed();
}
else {
return AccessResult::allowedIf($account->hasPermission('delete own aws cloud instance') && ($account->id() == $entity->getOwner()->id()));
}
}
// Unknown operation, no opinion.
return AccessResult::neutral();
......
......@@ -37,7 +37,8 @@ class InstanceViewsData extends Ec2BaseViewsData {
'title' => t('AWS Cloud Instance'),
'help' => t('The AWC Cloud Instance entity ID.'),
];
// add an access query tag
$data[$table_name]['table']['base']['access query tag'] = 'aws_cloud_instance_access';
$this->addDropdownSelector($data, $table_name, $fields, $selectable);
return $data;
......
......@@ -186,6 +186,10 @@ class InstanceEditForm extends AwsCloudContentForm {
'Key' => 'Name',
'Value' => $this->entity->get('name')->value
],
[
'Key' => 'cloud_launched_by_uid',
'Value' => $this->entity->getOwner()->id()
]
]
];
$this->awsEc2Service->setCloudContext($this->entity->get('cloud_context')->value);
......
......@@ -476,6 +476,10 @@ class AwsEc2Service implements AwsEc2ServiceInterface {
'Key' => 'cloud_launched_by',
'Value' => $this->currentUser->getAccountName(),
],
[
'Key' => 'cloud_launched_by_uid',
'Value' => $this->currentUser->id(),
]
],
],
];
......@@ -537,10 +541,14 @@ class AwsEc2Service implements AwsEc2ServiceInterface {
}
$instanceName = '';
$uid = 0;
foreach ($instance['Tags'] as $tag) {
if ($tag['Key'] == 'Name') {
$instanceName = $tag['Value'];
}
if ($tag['Key'] == 'cloud_launched_by_uid') {
$uid = $tag['Value'];
}
}
// default to instance_id.
......@@ -557,12 +565,16 @@ class AwsEc2Service implements AwsEc2ServiceInterface {
// Skip if $entity already exists, by updating 'refreshed' time.
if (!empty($entity_id)) {
/* @var \Drupal\aws_cloud\Entity\Ec2\Instance $entity */
$entity = Instance::load($entity_id);
$entity->setName($instanceName);
$entity->setInstanceState($instance['State']['Name']);
$entity->setElasticIp($instance['elastic_ip']);
$entity->setRefreshed($timestamp);
$entity->set_launch_time($instance['LaunchTime']->__toString());
if ($uid != 0) {
$entity->setOwnerById($uid);
}
$entity->save();
continue;
}
......@@ -602,6 +614,7 @@ class AwsEc2Service implements AwsEc2ServiceInterface {
'created' => strtotime($instance['LaunchTime']->__toString()),
'changed' => $timestamp,
'refreshed' => $timestamp,
'uid' => $uid,
]);
$entity->save();
}
......
......@@ -27,7 +27,7 @@ define('AWS_CLOUD_CONFIG_REPEAT_COUNT', 1);
* @group AWS Cloud
*/
class InstanceTest extends WebTestBase {
/* @FIXME extends AwsCloudTestCase { */
//@FIXME extends AwsCloudTestCase {
/**
* Modules to enable.
......@@ -70,7 +70,7 @@ class InstanceTest extends WebTestBase {
'add aws cloud instance',
'list aws cloud instance',
'view aws cloud instance',
'view all aws cloud instance',
'edit aws cloud instance',
'delete aws cloud instance',
]);
......
......@@ -70,6 +70,10 @@ class CloudContentEntityBase extends ContentEntityBase implements EntityOwnerInt
return $this->set('user_id', $account->id());
}
public function setOwnerById($id) {
return $this->set('user_id', $id);
}
/**
* {@inheritdoc}
*/
......
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