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

WIP Give ability to update an existing agent #762

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 58 additions & 1 deletion inc/agent.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,22 @@ public function canViewItem() {
return $_SESSION['glpiID'] == $computer->getField('users_id');
}

public function canUpdateItem() {
// Check the active profile
$config = Config::getConfigurationValues('flyvemdm', ['guest_profiles_id']);
if ($_SESSION['glpiactiveprofile']['id'] != $config['guest_profiles_id']) {
return parent::canUpdateItem();
}

// The user has a guest profile
if (!$this->checkEntity(true)) {
return false;
}

// Only the account of the device can update
return $_SESSION['glpiID'] == $this->fields[User::getForeignKeyField()];
}

/**
* Sends a wipe command to the agent
*/
Expand Down Expand Up @@ -469,6 +485,13 @@ public function prepareInputForAdd($input) {
}

public function prepareInputForUpdate($input) {
$config = Config::getConfigurationValues('flyvemdm', ['guest_profiles_id']);
if ($_SESSION['glpiactiveprofile']['id'] == $config['guest_profiles_id']) {
// a guest profile is the device itself.
// @see self::canUpdateItem()
return $this->prepareInputForUpdateFromDevice($input);
}

if (isset($input['plugin_flyvemdm_fleets_id'])) {
// Update MQTT ACL for the fleet
$oldFleet = new PluginFlyvemdmFleet();
Expand Down Expand Up @@ -547,6 +570,31 @@ public function prepareInputForUpdate($input) {
return $input;
}

/**
* Prepare input for update from the agent itseld
*
* @param array $input
* @return array
*/
private function prepareInputForUpdateFromDevice($input) {
//Sanitize input
unset($input[Computer::getForeignKeyField()]);
unset($input[User::getForeignKeyField()]);
unset($input[Entity::getForeignKeyField()]);
unset($input[PluginFlyvemdmFleet::getForeignKeyField()]);
unset($input['name']);
unset($input['wipe']);
unset($input['lock']);
unset($input['enroll_status']);
unset($input['last_report']);
unset($input['last_contact']);
unset($input['is_online']);
unset($input['certificate']);
unset($input['mdm_type']);

return $input;
}

public function post_addItem() {
// Notify the agent about its fleets
$this->updateSubscription();
Expand Down Expand Up @@ -1294,6 +1342,15 @@ protected function enrollByInvitationToken($input) {
}
$computerId = $pfAgent->getField(Computer::getForeignKeyField());

// Check no Flyvemdm agent is linked to this computer
$agent = new self();
if ($agent->getFromDBByCrit(['computers_id' => $computerId])) {
// Save the agent ID in session to allow the device to find it
// and update it. Give up creation
$_SESSION['plugin_flyvemdm_agents_id'] = $agent->getID();
return false;
}

if ($computerId === 0) {
$event = __("Cannot create the device", 'flyvemdm');
$this->filterMessages($event);
Expand Down Expand Up @@ -1355,7 +1412,7 @@ protected function enrollByInvitationToken($input) {
// Create the agent
$defaultFleet = PluginFlyvemdmFleet::getDefaultFleet();
if ($defaultFleet === null) {
$event = __("No default fleet available for the device", 'flyvemdm');
$event = __('No default fleet available for the device', 'flyvemdm');
$this->filterMessages($event);
$this->logInvitationEvent($invitation, $event);
return false;
Expand Down
2 changes: 1 addition & 1 deletion install/install.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ protected function createGuestProfileAccess() {
Config::setConfigurationValues('flyvemdm', ['guest_profiles_id' => $profileId]);
$profileRight = new ProfileRight();
$profileRight->updateProfileRights($profileId, [
PluginFlyvemdmAgent::$rightname => READ | CREATE,
PluginFlyvemdmAgent::$rightname => READ | CREATE | UPDATE,
PluginFlyvemdmFile::$rightname => READ,
PluginFlyvemdmPackage::$rightname => READ,
]);
Expand Down
11 changes: 9 additions & 2 deletions install/upgrade_to_dev.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,21 @@ function upgrade(Migration $migration) {

$migration->setVersion(PLUGIN_FLYVEMDM_VERSION);

$profileRight = new ProfileRight();

$config = Config::getConfigurationValues('flyvemdm');
if (!isset($config['mqtt_broker_port_backend'])) {
// Split port setting for client in one hand and backend in the other hand
$config['mqtt_broker_tls_port_backend'] = $config['mqtt_broker_tls_port'];
$config['mqtt_broker_port_backend'] = $config['mqtt_broker_port'];
Config::setConfigurationValues('flyvemdm', $config);
}

// Merge new rights into guest profile
$profileId = $config['guest_profiles_id'];
$currentRights = ProfileRight::getProfileRights($profileId);
$newRights = array_merge($currentRights, [
PluginFlyvemdmAgent::$rightname => CREATE| READ | UPDATE ,
]);
$profileRight = new ProfileRight();
$profileRight->updateProfileRights($profileId, $newRights);
}
}
12 changes: 7 additions & 5 deletions tests/before_script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,20 @@ mkdir plugins/fusioninventory && git clone --depth=35 $FI_SOURCE -b $FI_BRANCH p
IFS=/ read -a repo <<< $TRAVIS_REPO_SLUG
mv ../${repo[1]} plugins/flyvemdm

# patch settings
PATCH_ARGS="-p1 -N --batch"

# patch Fusion Inventory when needed
cd plugins/fusioninventory
if [[ $FI_BRANCH == "master" ]] ; then patch -p1 --batch < ../flyvemdm/tests/patches/fusioninventory/fi-raise-max-version.patch; fi
if [[ $FI_BRANCH == "master" ]] ; then patch -p1 --batch < ../flyvemdm/tests/patches/fusioninventory/compat-glpi-9-3-2.diff; fi
if [[ $FI_BRANCH == "glpi9.3" ]] ; then patch -p1 --batch < ../flyvemdm/tests/patches/fusioninventory/compat-glpi-9-3-2.diff; fi
if [[ $FI_BRANCH == "master" ]] ; then patch $PATCH_ARGS < ../flyvemdm/tests/patches/fusioninventory/fi-raise-max-version.patch; fi
if [[ $FI_BRANCH == "master" ]] ; then patch $PATCH_ARGS < ../flyvemdm/tests/patches/fusioninventory/compat-glpi-9-3-2.diff; fi
if [[ $FI_BRANCH == "glpi9.3" ]] ; then patch $PATCH_ARGS < ../flyvemdm/tests/patches/fusioninventory/compat-glpi-9-3-2.diff; fi
cd ../..

# patch GLPI when needed
# if [[ $GLPI_BRANCH == "9.2.1" ]] ; then patch -p1 --batch < plugins/flyvemdm/tests/patches/glpi/10f8dabfc5e20bb5a4e7d4ba4b93706871156a8a.diff; fi

# prepare plugin to test
cd plugins/flyvemdm
if [[ $GLPI_BRANCH == "master" ]] ; then patch -p1 --batch < tests/patches/allow-test-on-master-branch.patch; fi
if [[ $GLPI_BRANCH == "master" ]] ; then patch $PATCH_ARGS < tests/patches/allow-test-on-master-branch.patch; fi
composer install --no-interaction

8 changes: 8 additions & 0 deletions tests/src/Flyvemdm/Tests/CommonTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -688,4 +688,12 @@ protected function asserLastMqttlog(
}
return 0;
}

protected function assertInvitationLogHasMessage(\PluginFlyvemdmInvitation $invitation, $message) {
$invitationId = $invitation->getID();
$fk = \PluginFlyvemdmInvitation::getForeignKeyField();
$invitationLog = new \PluginFlyvemdmInvitationLog();
$found = $invitationLog->find("`$fk` = '$invitationId' AND `event` = '$message'");
return count($found);
}
}
39 changes: 28 additions & 11 deletions tests/suite-integration/PluginFlyvemdmAgent.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,37 +127,43 @@ protected function providerInvalidEnrollAgent() {
'invitationToken' => 'bad token',
],
'expected' => 'Invitation token invalid',
'invitationlog' => false,
],
'without MDM type' => [
'data' => [
'mdmType' => null,
],
'expected' => 'MDM type missing',
'invitationlog' => true,
],
'with bad MDM type' => [
'data' => [
'mdmType' => 'alien MDM',
],
'expected' => 'unknown MDM type',
'invitationlog' => true,
],
'with bad version' => [
'data' => [
'version' => 'bad version',
],
'expected' => 'Bad agent version',
'invitationlog' => true,
],
'with a too low version' => [
'data' => [
'version' => '1.9.0',
],
'expected' => 'The agent version is too low',
'invitationlog' => true,
],
'without inventory' => [
'data' => [
'version' => $version,
'inventory' => '',
],
'expected' => 'Device inventory XML is mandatory',
'invitationlog' => true,
],
'with invalid inventory' => [
'data' => [
Expand All @@ -166,6 +172,7 @@ protected function providerInvalidEnrollAgent() {
'inventory' => $inventory,
],
'expected' => 'Inventory XML is not well formed',
'invitationlog' => true,
],
];
}
Expand All @@ -175,12 +182,17 @@ protected function providerInvalidEnrollAgent() {
* @tags testInvalidEnrollAgent
* @param array $data
* @param string $expected
* @param boolean $invitationlog Is an invitation log entry expected ?
*/
public function testInvalidEnrollAgent(array $data, $expected) {
public function testInvalidEnrollAgent(array $data, $expected, $invitationlog) {
$dbUtils = new \DbUtils;
$invitationlogTable = \PluginFlyvemdmInvitationlog::getTable();
$expectedLogCount = $dbUtils->countElementsInTable($invitationlogTable);
list($user, $serial, $guestEmail, $invitation) = $this->createUserInvitation(\User::getForeignKeyField());

//Check there is no event for the invitation
$this->integer($this->assertInvitationLogHasMessage($invitation, $expected))->isEqualTo(0);

$invitationToken = (isset($data['invitationToken'])) ? $data['invitationToken'] : $invitation->getField('invitation_token');
$serial = (key_exists('serial', $data)) ? $data['serial'] : $serial;
$mdmType = (key_exists('mdmType', $data)) ? $data['mdmType'] : 'android';
Expand All @@ -194,15 +206,10 @@ public function testInvalidEnrollAgent(array $data, $expected) {
->isTrue(json_encode($_SESSION['MESSAGE_AFTER_REDIRECT'], JSON_PRETTY_PRINT));
$this->array($_SESSION['MESSAGE_AFTER_REDIRECT'][ERROR])->contains($expected);

// Check registered log
// previous enrolment could generate a new log
$invitationLog = new \PluginFlyvemdmInvitationlog();
$fk = \PluginFlyvemdmInvitation::getForeignKeyField();
$inviationId = $invitation->getID();
$expectedLogCount += count($invitationLog->find("`$fk` = '$inviationId'"));

$total = $dbUtils->countElementsInTable($invitationlogTable);
$this->integer($total)->isEqualTo($expectedLogCount);
// Check that an event was created for the invitation
if ($invitationlog) {
$this->integer($this->assertInvitationLogHasMessage($invitation, $expected))->isGreaterThan(0);
}
}

/**
Expand Down Expand Up @@ -382,7 +389,7 @@ public function testUnenrollAgent() {
$this->boolean($agent->isNewItem())
->isFalse(json_encode($_SESSION['MESSAGE_AFTER_REDIRECT'], JSON_PRETTY_PRINT));

sleep(2);
$this->login('glpi', 'glpi');

// Find the last existing ID of logged MQTT messages
$log = new \PluginFlyvemdmMqttlog();
Expand Down Expand Up @@ -446,6 +453,8 @@ public function testDeviceOnlineChange() {
$this->boolean($agent->isNewItem())
->isFalse(json_encode($_SESSION['MESSAGE_AFTER_REDIRECT'], JSON_PRETTY_PRINT));

$this->login('glpi', 'glpi');

$this->deviceOnlineStatus($agent, 'true', 1);

$this->deviceOnlineStatus($agent, 'false', 0);
Expand Down Expand Up @@ -581,6 +590,8 @@ public function testPingRequest() {
// Get enrolment data to enable the agent's MQTT account
$this->boolean($agent->getFromDB($agent->getID()))->isTrue();

$this->login('glpi', 'glpi');

// Find the last existing ID of logged MQTT messages
$log = new \PluginFlyvemdmMqttlog();
$lastLogId = \PluginFlyvemdmCommon::getMax($log, '', 'id');
Expand Down Expand Up @@ -616,6 +627,8 @@ public function testGeolocateRequest() {
// Get enrolment data to enable the agent's MQTT account
$this->boolean($agent->getFromDB($agent->getID()))->isTrue();

$this->login('glpi', 'glpi');

// Find the last existing ID of logged MQTT messages
$log = new \PluginFlyvemdmMqttlog();
$lastLogId = \PluginFlyvemdmCommon::getMax($log, '', 'id');
Expand Down Expand Up @@ -647,6 +660,8 @@ public function testInventoryRequest() {
$this->boolean($agent->isNewItem())
->isFalse(json_encode($_SESSION['MESSAGE_AFTER_REDIRECT'], JSON_PRETTY_PRINT));

$this->login('glpi', 'glpi');

// Get enrolment data to enable the agent's MQTT account
$this->boolean($agent->getFromDB($agent->getID()))->isTrue();

Expand Down Expand Up @@ -684,6 +699,8 @@ public function testLockAndWipe() {
$this->boolean($agent->isNewItem())
->isFalse(json_encode($_SESSION['MESSAGE_AFTER_REDIRECT'], JSON_PRETTY_PRINT));

$this->login('glpi', 'glpi');

// Test lock and wipe are unset after enrollment
$this->integer((int) $agent->getField('lock'))->isEqualTo(0);
$this->integer((int) $agent->getField('wipe'))->isEqualTo(0);
Expand Down
2 changes: 1 addition & 1 deletion tests/suite-integration/ProfileRight.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public function testGuestProfileRights() {
$profileId = $config['guest_profiles_id'];
// Expected rights
$rightsSet = [
\PluginFlyvemdmAgent::$rightname => READ | CREATE,
\PluginFlyvemdmAgent::$rightname => READ | CREATE | UPDATE,
\PluginFlyvemdmPackage::$rightname => READ,
\PluginFlyvemdmFile::$rightname => READ,
];
Expand Down
Loading