Skip to content
This repository has been archived by the owner on Aug 9, 2021. It is now read-only.

Commit

Permalink
feat(task): apply policies on agents
Browse files Browse the repository at this point in the history
Signed-off-by: Thierry Bugier <tbugier@teclib.com>
  • Loading branch information
btry committed May 4, 2018
1 parent 504ca06 commit 4036d42
Show file tree
Hide file tree
Showing 15 changed files with 212 additions and 104 deletions.
5 changes: 3 additions & 2 deletions ajax/policyValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,15 @@
}

$policyId = (int) $_POST['value'];
$mode = (isset($_POST['mode'])) ? $_POST['mode'] : null;
$mode = (isset($_POST['mode'])) ? $_POST['mode'] : 'add';

$factory = new PluginFlyvemdmPolicyFactory();
$policy = $factory->createFromDBByID($policyId);
if ($policy !== null) {
echo $policy->formGenerator($mode, [
'policyId' => $policyId,
'task' => (int) ((isset($_POST['task'])) ? $_POST['task'] : 0),
'fleet' => (int) ((isset($_POST['fleet'])) ? $_POST['fleet'] : 0),
'itemtype_applied' => ((isset($_POST['itemtype_applied'])) ? $_POST['itemtype_applied'] : ''),
'items_id_applied' => (int) ((isset($_POST['items_id_applied'])) ? $_POST['items_id_applied'] : 0),
]);
}
8 changes: 0 additions & 8 deletions hook.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,23 @@
* Entry point for installation process
*/
function plugin_flyvemdm_install() {

global $DB;

require_once(PLUGIN_FLYVEMDM_ROOT . "/install/installer.class.php");
$installer = new PluginFlyvemdmInstaller();

return $installer->install();

}

/**
* Uninstalls the plugin
* @return boolean True if success
*/
function plugin_flyvemdm_uninstall() {

require_once(PLUGIN_FLYVEMDM_ROOT . "/install/installer.class.php");
$installer = new PluginFlyvemdmInstaller();

return $installer->uninstall();

}

/**
Expand Down Expand Up @@ -106,7 +102,6 @@ function plugin_flyvemdm_hook_pre_profileuser_purge(CommonDBTM $item) {
* @return array
*/
function plugin_flyvemdm_getDropdown() {

$plugin = new Plugin();
if ($plugin->isActivated('flyvemdm')) {
// Table => Name
Expand All @@ -117,7 +112,6 @@ function plugin_flyvemdm_getDropdown() {
} else {
return [];
}

}

/**
Expand All @@ -136,7 +130,6 @@ function plugin_flyvemdm_addDefaultSelect($itemtype) {
* @return string
*/
function plugin_Flyvemdm_addDefaultJoin($itemtype) {

switch ($itemtype) {
case PluginFlyvemdmGeolocation::class:
return PluginFlyvemdmGeolocation::addDefaultJoin();
Expand All @@ -152,7 +145,6 @@ function plugin_Flyvemdm_addDefaultJoin($itemtype) {
* @return string
*/
function plugin_Flyvemdm_addDefaultWhere($itemtype) {

switch ($itemtype) {
case PluginFlyvemdmGeolocation::class:
return PluginFlyvemdmGeolocation::addDefaultWhere();
Expand Down
9 changes: 9 additions & 0 deletions inc/agent.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -1741,6 +1741,10 @@ protected function setupMqttAccess() {
'topic' => $this->getTopic() . '/Command/#',
'access_level' => PluginFlyvemdmMqttacl::MQTTACL_READ
],
[
'topic' => $this->getTopic() . '/Policy/#',
'access_level' => PluginFlyvemdmMqttacl::MQTTACL_READ
],
[
'topic' => $this->getTopic() . '/FlyvemdmManifest/#',
'access_level' => PluginFlyvemdmMqttacl::MQTTACL_WRITE
Expand Down Expand Up @@ -1933,6 +1937,11 @@ public function refreshPersistedNotifications() {
}
}

/**
* Is the agent notifiable ?
*
* @return boolean
*/
public function isNotifiable() {
return true;
}
Expand Down
5 changes: 5 additions & 0 deletions inc/fleet.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,11 @@ public function refreshPersistedNotifications() {
}
}

/**
* Is the fleet notifiable ?
*
* @return boolean
*/
public function isNotifiable() {
if ($this->isNewItem()) {
return false;
Expand Down
2 changes: 1 addition & 1 deletion inc/mqtthandler.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ protected function updateTaskStatus($topic, $message) {
if ($agent->getField('plugin_flyvemdm_fleets_id') != $task->getField('items_id_applied')) {
return;
}
} elseif ($task->getField('itemtype_applied') === PluginFlyvemdmAgent::class) {
} else if ($task->getField('itemtype_applied') === PluginFlyvemdmAgent::class) {
if ($agent->getID() != $task->getField('items_id_applied')) {
return;
}
Expand Down
2 changes: 1 addition & 1 deletion inc/notifiableinterface.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,5 @@ public function refreshPersistedNotifications();
* is the notifiable actually notifiable ?
* @return boolean True if message may be sent
*/
public function isNotifiable();
public function isNotifiable();
}
9 changes: 8 additions & 1 deletion inc/policybase.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ public static final function getEnumBaseTaskStatus() {
'done' => __('Done', 'flyvemdm'),
'failed' => __('Failed', 'flyvemdm'),
'canceled' => __('Canceled', 'flyvemdm'),

// when a policy is applied on a fleet and an agent in the fleet
// only the policy on the agent must apply
// the conflicting policy on the fleet won't apply, and the agent
// must feedback the status 'overriden'
'overriden' => __('Overriden', 'flyvemdm'),
];
}

Expand Down Expand Up @@ -287,7 +293,8 @@ public function formGenerator(
$form['rand'] = mt_rand();
$form['taskId'] = $_input['task'];
$form['policyId'] = $_input['policyId'];
$form['fleetId'] = $_input['fleet'];
$form['itemtype_applied'] = $_input['itemtype_applied'];
$form['items_id_applied'] = $_input['items_id_applied'];
$form['_csrf'] = (GLPI_USE_CSRF_CHECK) ? Html::hidden('_glpi_csrf_token',
['value' => Session::getNewCSRFToken()]) : '';
}
Expand Down
81 changes: 40 additions & 41 deletions inc/task.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class PluginFlyvemdmTask extends CommonDBRelation {
*/
protected $silent;

public static function getTypeName() {
public static function getTypeName($nb = 0) {
return _n('Task', 'Tasks', $nb, 'flyvemdm');
}

Expand Down Expand Up @@ -262,20 +262,23 @@ public function prepareInputForUpdate($input) {
}

//Check the fleet exists
$fleetId = $this->fields['plugin_flyvemdm_fleets_id'];
if (isset($input['plugin_flyvemdm_fleets_id'])) {
$fleetId = $input['plugin_flyvemdm_fleets_id'];
$notifiableType = $this->fields['itemtype_applied'];
$notifiableId = $this->fields['items_id_applied'];
if (isset($input['items_id_applied'])) {
$notifiableId = $input['items_id_applied'];
}
$this->notifiable = new PluginFlyvemdmFleet();
if (!$this->notifiable->getFromDB($fleetId)) {
Session::addMessageAfterRedirect(__('Cannot find the target fleet', 'flyvemdm'), false,
$this->notifiable = new $notifiableType();
if (!$this->notifiable->getFromDB($notifiableId)) {
// TRANS: %1$s is the type of the item on which a policy is applied
Session::addMessageAfterRedirect(sprintf(__('Cannot find the target %1$s', 'flyvemdm'), $this->notifiable->getTypeName()), false,
ERROR);
return false;
}

// default fleet check
if ($this->notifiable->getField('is_default')) {
Session::addMessageAfterRedirect(__('Cannot apply a policy on a not managed fleet',
// Check the notifiable can receive tasks
if (!$this->notifiable->isNotifiable()) {
// TRANS: %1$s is the type of the item on which one attempds to apply a policy
Session::addMessageAfterRedirect(sprintf(__('Cannot apply a policy on this %1$s', $this->notifiable->getTypeName()),
'flyvemdm'), false, ERROR);
return false;
}
Expand Down Expand Up @@ -332,7 +335,7 @@ public function pre_deleteItem() {
$notifiableType = $this->fields['itemtype_applied'];
$this->notifiable = new $notifiableType();
if (!$this->notifiable->getFromDB($this->fields['items_id_applied'])) {
Session::addMessageAfterRedirect(__('Fleet not found', 'flyvemdm'), false, ERROR);
Session::addMessageAfterRedirect(sprintf(__('%1$s not found', 'flyvemdm'), $this->notifiable->getTypeName()), false, ERROR);
return false;
}
return $this->policy->pre_unapply($this->fields['value'], $this->fields['itemtype'],
Expand Down Expand Up @@ -371,16 +374,6 @@ public function publishPolicy(PluginFlyvemdmNotifiableInterface $item) {
return;
}

$fleet = $item->getFleet();
if ($fleet === null || $fleet->getField('is_default') != '0') {
$notifiableItemtype = get_class($item);
$exceptionMessage = "Plugin Flyvemdm : no fleet for the notifiable item $notifiableItemtype, or has a default fleet";
Toolbox::logInFile('php-errors', $exceptionMessage . PHP_EOL);
throw new TaskPublishPolicyBadFleetException($exceptionMessage);
}

$topic = $item->getTopic();

$policy = new PluginFlyvemdmPolicy();
$policyFk = $policy::getForeignKeyField();
$policyFactory = new PluginFlyvemdmPolicyFactory();
Expand All @@ -401,24 +394,28 @@ public function publishPolicy(PluginFlyvemdmNotifiableInterface $item) {
);
$policyMessage['taskId'] = $this->getID();
$encodedMessage = json_encode($policyMessage, JSON_UNESCAPED_SLASHES);
$fleet->notify("$topic/Policy/$policyName/Task/$taskId", $encodedMessage, 0, 1);
$topic = $item->getTopic();
$item->notify("$topic/Policy/$policyName/Task/$taskId", $encodedMessage, 0, 1);
}

/**
* Creates task status for all agents in the fleet linked to this task
* @param PluginFlyvemdmNotifiableInterface $item
*/
public function createTaskStatuses(PluginFlyvemdmNotifiableInterface $item) {
$fleet = $item->getFleet();
if ($fleet === null || $fleet->getField('is_default') != '0') {
if (!$item->isNotifiable()) {
return;
}

// Initialize a task status for each agent in the fleet
$fleetId = $fleet->getID();
$notifiableId = $item->getID();
$agent = new PluginFlyvemdmAgent();
$fleetFk = $fleet::getForeignKeyField();
$rows = $agent->find("`$fleetFk` = '$fleetId'");
if ($item instanceof PluginFlyvemdmFleet) {
$fleetFk = PluginFlyvemdmFleet::getForeignKeyField();
$rows = $agent->find("`$fleetFk` = '$notifiableId'");
} else if ($item instanceof PluginFlyvemdmAgent) {
$rows = $agent->find("`id` = '$notifiableId'");
}
foreach ($rows as $row) {
$agent = new PluginFlyvemdmAgent();
if ($agent->getFromDB($row['id'])) {
Expand All @@ -442,16 +439,17 @@ public function unpublishPolicy(PluginFlyvemdmNotifiableInterface $item) {
return;
}

$fleet = $item->getFleet();
if ($fleet !== null && $fleet->getField('is_default') == '0') {
$topic = $item->getTopic();

$policy = new PluginFlyvemdmPolicy();
$taskId = $this->getID();
$policy->getFromDB($this->fields['plugin_flyvemdm_policies_id']);
$policyName = $policy->getField('symbol');
$fleet->notify("$topic/Policy/$policyName/Task/$taskId", null, 0, 1);
if (!$item->isNotifiable()) {
return;
}

$topic = $item->getTopic();

$policy = new PluginFlyvemdmPolicy();
$taskId = $this->getID();
$policy->getFromDB($this->fields['plugin_flyvemdm_policies_id']);
$policyName = $policy->getField('symbol');
$item->notify("$topic/Policy/$policyName/Task/$taskId", null, 0, 1);
}

/**
Expand Down Expand Up @@ -683,6 +681,7 @@ public function getSearchOptionsNew() {
static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) {
switch (get_class($item)) {
case PluginFlyvemdmFleet::class:
case PluginFlyvemdmAgent::class:
static::showForFleet($item, $withtemplate);
break;
}
Expand All @@ -693,13 +692,12 @@ static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtem
*
* @param CommonDBTM $item
* @param string $withtemplate
* @return bool
*/
static function showForFleet(CommonDBTM $item, $withtemplate = '') {
global $CFG_GLPI;

if (!$item->canView()) {
return false;
return;
}

$itemtype = $item->getType();
Expand Down Expand Up @@ -772,9 +770,10 @@ static function showForFleet(CommonDBTM $item, $withtemplate = '') {
. Html::closeForm(false),
],
'checkAll' => Html::getCheckAllAsCheckbox('mass' . __CLASS__ . $rand),
'fleet_policy' => [
'policy' => $policyDropdown,
'plugin_flyvemdm_fleets_id' => $itemId,
'task' => [
'policy' => $policyDropdown,
'itemtype_applied' => $itemtype,
'items_id_applied' => $itemId,
],
'policies' => $appliedPolicies,
];
Expand Down
2 changes: 1 addition & 1 deletion inc/taskstatus.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ public static function showForFleet(CommonDBTM $item, $withTemplate = '') {
global $DB;

if (!$item->canView()) {
return false;
return;
}

if (isset($_GET["start"])) {
Expand Down
30 changes: 29 additions & 1 deletion tests/src/Flyvemdm/Tests/CommonTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,40 @@ protected function agentFromInvitation(
protected function createFleet($input) {
$fleet = $this->newMockInstance(\PluginFlyvemdmFleet::class, '\MyMock');
$fleet->getMockController()->post_addItem = function () {};
$fleet->add($input);
$fleetId = $fleet->add($input);
$this->boolean($fleet->isNewItem())->isFalse();

$fleet = new \PluginFlyvemdmFleet();
$fleet->getFromDB($fleetId);

return $fleet;
}

public function createAgent($input) {
$guestEmail = $this->getUniqueEmail();
$invitation = $this->createInvitation($guestEmail);
$this->variable($invitation)->isNotNull();
$user = new \User();
$user->getFromDB($invitation->getField(\User::getForeignKeyField()));
$serial = $this->getUniqueString();
$input = [
'_email' => $guestEmail,
'_invitation_token' => $invitation->getField('invitation_token'),
'_serial' => $serial,
'csr' => '',
'firstname' => 'John',
'lastname' => 'Doe',
'version' => \PluginFlyvemdmAgent::MINIMUM_ANDROID_VERSION . '.0',
'type' => 'android',
'inventory' => CommonTestCase::AgentXmlInventory($serial),
] + $input;
$agent = $this->enrollFromInvitation($user, $input);
$this->boolean($agent->isNewItem())
->isFalse(json_encode($_SESSION['MESSAGE_AFTER_REDIRECT'], JSON_PRETTY_PRINT));

return $agent;
}

/**
* Create a file directly on DB and return the object and the filename generated
*
Expand Down
6 changes: 5 additions & 1 deletion tests/suite-integration/PluginFlyvemdmAgent.php
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ public function testEnrollAgent() {

// Check the user has ACLs
$mqttACLs = $mqttUser->getACLs();
$this->integer(count($mqttACLs))->isEqualTo(4);
$this->integer(count($mqttACLs))->isEqualTo(5);

// Check the ACLs
$validated = 0;
Expand All @@ -306,6 +306,10 @@ public function testEnrollAgent() {
$this->integer((int) $acl->getField('access_level'))
->isEqualTo(\PluginFlyvemdmMqttacl::MQTTACL_WRITE);
$validated++;
} else if (preg_match("~/agent/$serial/Policy/#$~", $acl->getField('topic')) == 1) {
$this->integer((int) $acl->getField('access_level'))
->isEqualTo(\PluginFlyvemdmMqttacl::MQTTACL_READ);
$validated++;
} else if (preg_match("~^/FlyvemdmManifest/#$~", $acl->getField('topic')) == 1) {
$this->integer((int) $acl->getField('access_level'))
->isEqualTo(\PluginFlyvemdmMqttacl::MQTTACL_READ);
Expand Down
Loading

0 comments on commit 4036d42

Please sign in to comment.