diff --git a/front/fdroidapplication.form.php b/front/fdroidapplication.form.php
new file mode 100644
index 00000000..457e6edf
--- /dev/null
+++ b/front/fdroidapplication.form.php
@@ -0,0 +1,77 @@
+isActivated('flyvemdm')) {
+ Html::displayNotFoundError();
+}
+
+Session::checkRight('flyvemdm:flyvemdm', PluginFlyvemdmProfile::RIGHT_FLYVEMDM_USE);
+
+if (!isset($_GET['id'])) {
+ $_GET['id'] = '';
+}
+
+if (!isset($_GET['withtemplate'])) {
+ $_GET['withtemplate'] = '';
+}
+
+$fdroidApplication = new PluginFlyvemdmFDroidApplication();
+if (isset($_POST['import'])) {
+ unset($_POST['_skip_checks']);
+ $fdroidApplication->update(['id' => $_POST['id'], 'import_status' => 'to_import']);
+ Html::back();
+} else {
+ $fdroidApplication->check($_GET['id'], READ);
+ Html::header(
+ PluginFlyvemdmFDroidApplication::getTypeName(Session::getPluralNumber()),
+ '',
+ 'admin',
+ PluginFlyvemdmMenu::class,
+ 'fdroid application'
+ );
+
+ $menu = new PluginFlyvemdmMenu();
+ $menu->displayMenu('mini');
+
+ $fdroidApplication->display([
+ 'id' => $_GET['id'],
+ 'withtemplate' => $_GET['withtemplate']
+ ]);
+
+ // Footer
+ if (strstr($_SERVER['PHP_SELF'], 'popup')) {
+ Html::popFooter();
+ } else {
+ Html::footer();
+ }
+}
diff --git a/front/fdroidapplication.php b/front/fdroidapplication.php
new file mode 100644
index 00000000..8e972122
--- /dev/null
+++ b/front/fdroidapplication.php
@@ -0,0 +1,54 @@
+isActivated('flyvemdm')) {
+ Html::displayNotFoundError();
+}
+
+Session::checkRight("flyvemdm:flyvemdm", PluginFlyvemdmProfile::RIGHT_FLYVEMDM_USE);
+Session::checkRight("flyvemdm:fdroidapplication", READ);
+
+Html::header(
+ PluginFlyvemdmFDroidApplication::getTypeName(Session::getPluralNumber()),
+ '',
+ 'admin',
+ PluginFlyvemdmMenu::class,
+ 'fdroid application'
+);
+
+$menu = new PluginFlyvemdmMenu();
+$menu->displayMenu('mini');
+
+Search::show(PluginFlyvemdmFDroidApplication::class);
+
+Html::footer();
diff --git a/front/fdroidmarket.form.php b/front/fdroidmarket.form.php
new file mode 100644
index 00000000..b101694d
--- /dev/null
+++ b/front/fdroidmarket.form.php
@@ -0,0 +1,100 @@
+isActivated('flyvemdm')) {
+ Html::displayNotFoundError();
+}
+
+Session::checkRight('flyvemdm:flyvemdm', PluginFlyvemdmProfile::RIGHT_FLYVEMDM_USE);
+
+if (!isset($_GET['id'])) {
+ $_GET['id'] = '';
+}
+
+if (!isset($_GET['withtemplate'])) {
+ $_GET['withtemplate'] = '';
+}
+
+$market = new PluginFlyvemdmFDroidMarket();
+if (isset($_POST["add"])) {
+ $market->check(-1, CREATE, $_POST);
+ if ($newID = $market->add($_POST)) {
+ if ($_SESSION['glpibackcreated']) {
+ Html::redirect($market->getFormURL() . "?id=" . $newID);
+ }
+ }
+ Html::back();
+} else if (isset($_POST["update"])) {
+ $market->check($_POST['id'], UPDATE);
+ $market->update($_POST);
+ Html::back();
+} else if (isset($_POST["purge"])) {
+ $market->check($_POST['id'], PURGE);
+ $market->delete($_POST, 1);
+ $market->redirectToList();
+} else if (isset($_POST['refresh'])) {
+ $fdroidMarket = new PluginFlyvemdmFDroidMarket();
+ $fdroidMarket->getFromDB((int) $_POST['id']);
+ $volume = $fdroidMarket->updateRepository();
+ Html::back();
+} else {
+ if (isset($_GET['search'])) {
+ $criterias = array_intersect_key($_GET, ['criteria' => null, 'metacriteria' => null]);
+ $_SESSION['glpisearch'][PluginFlyvemdmFDroidApplication::class] = $criterias;
+ } else if (isset($_GET['reset'])) {
+ unset($_SESSION['glpisearch'][PluginFlyvemdmFDroidApplication::class]);
+ }
+ $market->check($_GET['id'], READ);
+ Html::header(
+ PluginFlyvemdmFDroidApplication::getTypeName(Session::getPluralNumber()),
+ '',
+ 'admin',
+ PluginFlyvemdmMenu::class,
+ 'fdroid market'
+ );
+
+ $menu = new PluginFlyvemdmMenu();
+ $menu->displayMenu('mini');
+
+ $market->display([
+ 'id' => $_GET['id'],
+ 'withtemplate' => $_GET['withtemplate']
+ ]);
+
+ // Footer
+ if (strstr($_SERVER['PHP_SELF'], 'popup')) {
+ Html::popFooter();
+ } else {
+ Html::footer();
+ }
+}
diff --git a/front/fdroidmarket.php b/front/fdroidmarket.php
new file mode 100644
index 00000000..13435763
--- /dev/null
+++ b/front/fdroidmarket.php
@@ -0,0 +1,54 @@
+isActivated('flyvemdm')) {
+ Html::displayNotFoundError();
+}
+
+Session::checkRight('flyvemdm:flyvemdm', PluginFlyvemdmProfile::RIGHT_FLYVEMDM_USE);
+Session::checkRight('flyvemdm:fdroidmarket', READ);
+
+Html::header(
+ PluginFlyvemdmFDroidMarket::getTypeName(Session::getPluralNumber()),
+ '',
+ 'admin',
+ PluginFlyvemdmMenu::class,
+ 'fdroid market');
+
+$menu = new PluginFlyvemdmMenu();
+$menu->displayMenu('mini');
+
+Search::show(PluginFlyvemdmFDroidMarket::class);
+
+Html::footer();
+
diff --git a/hook.php b/hook.php
index 0ad828eb..bda7d3c9 100644
--- a/hook.php
+++ b/hook.php
@@ -33,12 +33,15 @@
* 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();
+ $version = plugin_version_flyvemdm();
+ $migration = new Migration($version['version']);
+ require_once(PLUGIN_FLYVEMDM_ROOT . "/install/install.class.php");
+ spl_autoload_register([PluginFlyvemdmInstall::class, 'autoload']);
+ $install = new PluginFlyvemdmInstall();
+ if (!$install->isPluginInstalled()) {
+ return $install->install($migration);
+ }
+ return $install->upgrade($migration);
}
/**
@@ -46,10 +49,10 @@ function plugin_flyvemdm_install() {
* @return boolean True if success
*/
function plugin_flyvemdm_uninstall() {
- require_once(PLUGIN_FLYVEMDM_ROOT . "/install/installer.class.php");
- $installer = new PluginFlyvemdmInstaller();
+ require_once(PLUGIN_FLYVEMDM_ROOT . "/install/install.class.php");
+ $install = new PluginFlyvemdmInstall();
- return $installer->uninstall();
+ return $install->uninstall();
}
/**
@@ -129,13 +132,16 @@ function plugin_flyvemdm_addDefaultSelect($itemtype) {
* @param string $itemtype Itemtype
* @return string
*/
-function plugin_Flyvemdm_addDefaultJoin($itemtype) {
+function plugin_Flyvemdm_addDefaultJoin($itemtype, $ref_table, &$already_link_tables) {
switch ($itemtype) {
case PluginFlyvemdmGeolocation::class:
- return PluginFlyvemdmGeolocation::addDefaultJoin();
+ return PluginFlyvemdmGeolocation::addDefaultJoin($ref_table, $already_link_tables);
case PluginFlyvemdmAgent::class:
- return PluginFlyvemdmAgent::addDefaultJoin();
+ return PluginFlyvemdmAgent::addDefaultJoin($ref_table, $already_link_tables);
+
+ case PluginFlyvemdmFDroidApplication::class:
+ return PluginFlyvemdmFDroidApplication::addDefaultJoin($ref_table, $already_link_tables);
}
}
@@ -151,6 +157,10 @@ function plugin_Flyvemdm_addDefaultWhere($itemtype) {
case PluginFlyvemdmAgent::class:
return PluginFlyvemdmAgent::addDefaultWhere();
+
+ case PluginFlyvemdmFDroidApplication::class: {
+ return PluginFlyvemdmFDroidApplication::addDefaultWhere();
+ }
}
}
diff --git a/inc/entityconfig.class.php b/inc/entityconfig.class.php
index 78a1088f..7ab6075a 100644
--- a/inc/entityconfig.class.php
+++ b/inc/entityconfig.class.php
@@ -86,6 +86,17 @@ static function canUpdate() {
}
}
+ function getRights($interface = 'central') {
+ $values = [
+ READ => __('Read'),
+ self::RIGHT_FLYVEMDM_DEVICE_COUNT_LIMIT => __('Write device limit'),
+ self::RIGHT_FLYVEMDM_APP_DOWNLOAD_URL => __('Set agent download URL'),
+ self::RIGHT_FLYVEMDM_INVITATION_TOKEN_LIFE => __('Set invitation tiken lifetime'),
+ ];
+
+ return $values;
+ }
+
/**
* Actions done after the getFromDB method
*/
diff --git a/inc/fdroidapplication.class.php b/inc/fdroidapplication.class.php
new file mode 100644
index 00000000..e74353dd
--- /dev/null
+++ b/inc/fdroidapplication.class.php
@@ -0,0 +1,380 @@
+ __('No import', 'flyvemdm'),
+ 'to_import' => __('To import', 'flyvemdm'),
+ 'imported' => __('Imported', 'flyvemdm'),
+ ];
+ }
+
+ /**
+ * Return the picture file for the menu
+ * @return string
+ */
+ public static function getMenuPicture() {
+ return '';
+ }
+
+ /**
+ * Returns the name of the type
+ * @param integer $count
+ * @return string
+ */
+ static function getTypeName($count = 0) {
+ return _n('F-Droid application', 'F-Droid applications', $count);
+ }
+
+ /**
+ * @see CommonGLPI::getTabNameForItem()
+ *
+ * @since version 9.1
+ * @param CommonGLPI $item
+ * @param integer $withtemplate
+ * @return array|string
+ */
+ public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) {
+ if (static::canView()) {
+ switch ($item->getType()) {
+ case PluginFlyvemdmFDroidMarket::class:
+ if (!$withtemplate) {
+ $nb = 0;
+ $fleetId = $item->getID();
+ $pluralNumber = Session::getPluralNumber();
+ if ($_SESSION['glpishow_count_on_tabs']) {
+ $DbUtil = new DbUtils();
+ $nb = $DbUtil->countElementsInTable(static::getTable(), ['plugin_flyvemdm_fdroidmarkets_id' => $fleetId]);
+ }
+ return self::createTabEntry(self::getTypeName($pluralNumber), $nb);
+ }
+ break;
+ }
+ }
+
+ return '';
+ }
+
+ static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) {
+ switch (get_class($item)) {
+ case PluginFlyvemdmFDroidMarket::class:
+ self::showForFDroidMarket($item);
+ return true;
+ break;
+ }
+
+ return false;
+ }
+
+ public function getAdditionalLinks() {
+ return [];
+ }
+
+ function getRights($interface = 'central') {
+ $values = [
+ READ => __('Read'),
+ UPDATE => __('Update'),
+ ];
+
+ return $values;
+ }
+
+ /**
+ * get Cron description parameter for this class
+ * @param $name string name of the task
+ * @return array of string
+ **/
+ static function cronInfo($name) {
+ switch ($name) {
+ case 'DownloadApplications' :
+ return ['description' => __('download applications from the market')];
+ }
+ }
+
+ /**
+ * Maitnains a local list of all apps available in the repository
+ * This algorithm is limited and cannot handle a huge quantity of applications
+ * @param CronTask $cronTask
+ * @return number
+ */
+ public static function cronDownloadApplications(CronTask $cronTask) {
+ global $DB;
+
+ $cronStatus = 0;
+
+ $cronTask->log('Download applications to import from F-Droid');
+
+ $fDroidApplication = new PluginFlyvemdmFDroidApplication();
+ $request = [
+ 'FROM' => PluginFlyvemdmFDroidApplication::getTable(),
+ 'WHERE' => ['import_status' => 'to_import']
+ ];
+ $package = new PluginFlyvemdmPackage();
+ $market = new PluginFlyvemdmFDroidMarket();
+ foreach ($DB->request($request) as $row) {
+ if ($package->getFromDBByCrit(['name' => $row['name']])) {
+ continue;
+ }
+ $market->getFromDB($row[$market::getForeignKeyField()]);
+ $baseUrl = dirname($market->getField('url'));
+
+ $file = GLPI_TMP_DIR . "/" . $row['filename'];
+ file_put_contents($file, file_get_contents("$baseUrl/" . $row['filename']));
+ $_POST['_file'][0] = $row['filename'];
+ if ($package->add($row)) {
+ $fDroidApplication->update([
+ 'id' => $row['id'],
+ 'import_status' => 'imported',
+ ]);
+ } else {
+ Toolbox::logInFile('php-errors', 'Failed to import an application from a F-Droid like market');
+ }
+ $cronStatus = 1;
+ }
+
+ return $cronStatus;
+ }
+
+ /**
+ * Imports an application in the database, or updates an existing one
+ * @param array $input
+ * @return integer|false ID of the imported item or false on error
+ */
+ public static function import($input) {
+ $marketFk = PluginFlyvemdmFDroidMarket::getForeignKeyField();
+ if (!isset($input['name']) || !isset($input[$marketFk])) {
+ return false;
+ }
+
+ $application = new self();
+ $application->getFromDBByCrit([
+ 'name' => $input['name'],
+ $marketFk => $input[$marketFk],
+ ]);
+ if ($application->isNewItem()) {
+ return $application->add($input);
+ }
+
+ $input['id'] = $application->getID();
+ $input['is_available'] = '1';
+ if ($application->update($input) === false) {
+ return false;
+ }
+ return $application->getID();
+ }
+
+ public function prepareInputForUpdate($input) {
+ if (isset($input['_skip_checks'])) {
+ return $input;
+ }
+
+ if (!isset($input['import_status'])) {
+ $input['import_status'] = 'no_import';
+ }
+
+ return $input;
+ }
+
+ public function showForm($ID, $options = []) {
+ $options['canUpdate'] = (!$this->isNewID($ID)) && ($this->canUpdate() > 0);
+ $this->initForm($ID, $options);
+ $this->showFormHeader($options);
+ $fields = $this->fields;
+
+ $importStatuses = static::getEnumImportStatus();
+ $fields['import_status'] = $importStatuses[$fields['import_status']];
+
+ $data = [
+ 'withTemplate' => (isset($options['withtemplate']) && $options['withtemplate'] ? '*' : ''),
+ 'isNewID' => $this->isNewID($ID),
+ 'canUpdate' => $options['canUpdate'],
+ 'fdroidapplication' => $fields,
+ ];
+
+ $twig = plugin_flyvemdm_getTemplateEngine();
+ echo $twig->render('fdroidapplication.html.twig', $data);
+
+ if (PluginFlyvemdmPackage::canCreate()) {
+ $options['addbuttons'] = [
+ 'import' => __('Import the package', 'flyvemdm'),
+ ];
+ }
+ $this->showFormButtons($options);
+ }
+
+ public static function showForFDroidMarket(CommonDBTM $item, $withtemplate = '') {
+ global $CFG_GLPI, $DB;
+
+ if (!$item->canView()) {
+ return false;
+ }
+
+ $searchParams = [];
+ if (isset($_SESSION['glpisearch'][PluginFlyvemdmFDroidApplication::class])) {
+ $searchParams = $_SESSION['glpisearch'][PluginFlyvemdmFDroidApplication::class];
+ }
+ $searchParams = Search::manageParams(PluginFlyvemdmApplication::class, $searchParams);
+ $searchParams['showbookmark'] = false;
+ $searchParams['target'] = PluginFlyvemdmFDroidMarket::getFormUrlWithID($item->getID());
+ $searchParams['addhidden'] = [
+ 'id' => $item->getID(),
+ PluginFlyvemdmFDroidMarket::getForeignKeyField() => $item->getID(),
+ ];
+ Search::showGenericSearch(PluginFlyvemdmFDroidApplication::class, $searchParams);
+
+ Search::showList(PluginFlyvemdmFDroidApplication::class, $searchParams);
+ }
+
+ public function getSearchOptionsNew() {
+ return $this->rawSearchOptions();
+ }
+
+ public function rawSearchOptions() {
+ if (method_exists('CommonDBTM', 'rawSearchOptions')) {
+ $tab = parent::rawSearchOptions();
+ } else {
+ $tab = parent::getSearchOptionsNew();
+ }
+
+ $tab[] = [
+ 'id' => '2',
+ 'table' => $this->getTable(),
+ 'field' => 'id',
+ 'name' => __('ID'),
+ 'massiveaction' => false,
+ 'datatype' => 'number'
+ ];
+
+ $tab[] = [
+ 'id' => '3',
+ 'table' => $this->getTable(),
+ 'field' => 'alias',
+ 'name' => __('Alias', 'flyvemdm'),
+ 'massiveaction' => false,
+ 'datatype' => 'string'
+ ];
+
+ $tab[] = [
+ 'id' => '4',
+ 'table' => $this->getTable(),
+ 'field' => 'version',
+ 'name' => __('Version', 'flyvemdm'),
+ 'massiveaction' => false,
+ 'datatype' => 'string'
+ ];
+
+ $tab[] = [
+ 'id' => '6',
+ 'table' => $this->getTable(),
+ 'field' => 'filesize',
+ 'name' => __('Size'),
+ 'massiveaction' => false,
+ 'datatype' => 'number'
+ ];
+
+ $tab[] = [
+ 'id' => '7',
+ 'table' => $this->getTable(),
+ 'field' => 'import_status',
+ 'name' => __('Import status', 'flyvemdm'),
+ 'searchtype' => ['equals', 'notequals'],
+ 'massiveaction' => false,
+ 'datatype' => 'specific'
+ ];
+
+ $tab[] = [
+ 'id' => '8',
+ 'table' => $this::getTable(),
+ 'field' => PluginFlyvemdmFDroidMarket::getForeignKeyField(),
+ 'name' => __('FDroid market', 'flyvemdm'),
+ 'massiveaction' => false,
+ ];
+
+ return $tab;
+ }
+
+ public static function addDefaultJoin($ref_table, $already_link_tables) {
+ $join = '';
+
+ $table = PluginFlyvemdmFDroidMarket::getTable();
+ $fkTable = PluginFlyvemdmFDroidMarket::getForeignKeyField();
+ $join = "LEFT JOIN `$table` ON `$table`.`id`=`$ref_table`.`$fkTable` ";
+
+ return $join;
+ }
+
+ public static function addDefaultWhere() {
+ $where = '';
+
+ $fkFDroidMarket = PluginFlyvemdmFDroidMarket::getForeignKeyField();
+ if (isset($_GET['id'])) {
+ $fDfroidMarketId = (int) $_GET['id'];
+ $where = " `$fkFDroidMarket` = '$fDfroidMarketId'";
+ }
+ return $where;
+ }
+
+ public static function getSpecificValueToSelect($field, $name = '', $values = '', array $options = []) {
+ if (!is_array($values)) {
+ $values = [$field => $values];
+ }
+ switch ($field) {
+ case 'import_status':
+ $elements = self::getEnumImportStatus();
+ $output = Dropdown::showFromArray(
+ $name,
+ $elements,
+ [
+ 'display' => false,
+ 'value' => $values[$field]
+ ]
+ );
+ return $output;
+ break;
+ }
+ return parent::getSpecificValueToSelect($field, $name, $values, $options);
+ }
+}
diff --git a/inc/fdroidmarket.class.php b/inc/fdroidmarket.class.php
new file mode 100644
index 00000000..824f7dc4
--- /dev/null
+++ b/inc/fdroidmarket.class.php
@@ -0,0 +1,207 @@
+addDefaultFormTab($tab);
+ if (!$this->isNewItem()) {
+ $this->addStandardTab(PluginFlyvemdmFDroidApplication::class, $tab, $options);
+ }
+ $this->addStandardTab(Notepad::class, $tab, $options);
+ $this->addStandardTab(Log::class, $tab, $options);
+
+ return $tab;
+ }
+
+ /**
+ * get Cron description parameter for this class
+ * @param $name string name of the task
+ * @return array of string
+ */
+ static function cronInfo($name) {
+ switch ($name) {
+ case 'UpdateRepositories' :
+ return ['description' => __('Updates the list of applications')];
+ }
+ }
+
+ /**
+ * Maitnains a local list of all apps available in the repository
+ * This algorithm is limited and cannot handle a huge quantity of applications
+ * @param CronTask $cronTask
+ * @return integer
+ */
+ public static function cronUpdateRepositories(CronTask $cronTask) {
+ global $DB;
+
+ $cronStatus = 0;
+ $cronTask->log('Update the list of applications available from F-Droid like repositories');
+
+ $request = [
+ 'FROM' => static::getTable(),
+ ];
+ foreach ($DB->request($request) as $row) {
+ $fdroidMarket = new static();
+ $fdroidMarket->getFromResultSet($row);
+ $volume = $fdroidMarket->updateRepository();
+ $cronTask->addVolume($volume);
+ $cronStatus = 1;
+ }
+
+ return $cronStatus;
+ }
+
+ /**
+ * Updates the list of applications from a F Droid like repository
+ * @return integer
+ */
+ private function updateRepository() {
+ global $DB;
+
+ $volume = 0;
+ $xml = file_get_contents($this->fields['url']);
+ $fdroid = simplexml_load_string($xml);
+ unset($xml);
+
+ if (isset($fdroid->application)) {
+ $marketFk = $this::getForeignKeyField();
+ $fdroidApplication = new PluginFlyvemdmFDroidApplication();
+ $DB->query("UPDATE `" . PluginFlyvemdmFDroidApplication::getTable() . "` SET `is_available` = '0' WHERE `$marketFk`=" . $this->getID());
+ foreach ($fdroid->application as $application) {
+ $input = [
+ 'name' => Toolbox::addslashes_deep($application->name),
+ 'package_name' => Toolbox::addslashes_deep($application->id),
+ 'entities_id' => $this->fields['entities_id'],
+ 'is_recursive' => $this->fields['is_recursive'],
+ $marketFk => $this->getID(),
+ 'alias' => Toolbox::addslashes_deep($application->name),
+ 'version' => Toolbox::addslashes_deep($application->package[0]->version),
+ 'version_code' => Toolbox::addslashes_deep($application->package[0]->versioncode),
+ 'filesize' => Toolbox::addslashes_deep($application->package[0]->size),
+ 'filename' => Toolbox::addslashes_deep($application->package[0]->apkname),
+ 'desc' => Toolbox::addslashes_deep($application->desc),
+ ];
+ if (isCommandline()) {
+ // TRANS: %1$s is the name of the application being updated %2$s is the name of the repository
+ echo sprintf(__('Updating application %1$s in repository %2$s', 'flyvemdm'), $input['name'], $this->getField('name')) . PHP_EOL;
+ }
+ PluginFlyvemdmFDroidApplication::import($input);
+ }
+
+ // Delete applications vanished from the repo
+ $criteria = [$marketFk => $this->getID(), 'is_available' => '0'];
+ if (isCommandline()) {
+ $dbUtils = new DbUtils();
+ $deleteCount = $dbUtils->countElementsInTable(PluginFlyvemdmFDroidApplication::getTable(), $criteria);
+ }
+ $fdroidApplication->deleteByCriteria($criteria);
+ $volume = count($fdroid->application) + $deleteCount;
+ }
+
+ return $volume;
+ }
+
+ public function showForm($ID, $options = []) {
+ $this->initForm($ID, $options);
+ $this->showFormHeader($options);
+ $fields = $this->fields;
+
+ $data = [
+ 'withTemplate' => (isset($options['withtemplate']) && $options['withtemplate'] ? '*' : ''),
+ 'isNewID' => $this->isNewID($ID),
+ 'fdroidmarket' => $fields,
+ 'importButton' => Html::submit(_x('button', 'Import'), ['name' => 'import']),
+ 'canImport' => PluginFlyvemdmPackage::canCreate(),
+ ];
+
+ $twig = plugin_flyvemdm_getTemplateEngine();
+ echo $twig->render('fdroidmarket.html.twig', $data);
+
+ if (!$this->isNewID($ID)) {
+ $options['addbuttons'] = [
+ 'refresh' => _x('button', 'Import'),
+ ];
+ }
+ $this->showFormButtons($options);
+ }
+
+ public function getSearchOptionsNew() {
+ $tab = parent::getSearchOptionsNew();
+
+ $tab[] = [
+ 'id' => '2',
+ 'table' => $this->getTable(),
+ 'field' => 'id',
+ 'name' => __('ID'),
+ 'massiveaction' => false,
+ 'datatype' => 'number'
+ ];
+
+ return $tab;
+
+ }
+}
\ No newline at end of file
diff --git a/inc/file.class.php b/inc/file.class.php
index 89eeaf46..dc031db7 100644
--- a/inc/file.class.php
+++ b/inc/file.class.php
@@ -70,6 +70,10 @@ public static function getMenuPicture() {
return 'fa-file';
}
+ public function getAdditionalLinks() {
+ return [];
+ }
+
public function addNeededInfoToInput($input) {
$input['entities_id'] = $_SESSION['glpiactive_entity'];
@@ -253,9 +257,6 @@ public function pre_deleteItem() {
]);
}
- /**
- * Actions done after the getFromFB method
- */
public function post_getFromDB() {
// Check the user can view this itemtype and can view this item
if ($this->canView() && $this->canViewItem()) {
@@ -304,7 +305,6 @@ public function showForm($ID, array $options = []) {
$this->initForm($ID, $options);
$this->showFormHeader($options);
- $twig = plugin_flyvemdm_getTemplateEngine();
$fields = $this->fields;
$fields['filesize'] = '';
if (!$this->isNewID($ID)) {
@@ -319,6 +319,7 @@ public function showForm($ID, array $options = []) {
'upload' => Html::file(['name' => 'file', 'display' => false]),
'comment' => $fields['comment'],
];
+ $twig = plugin_flyvemdm_getTemplateEngine();
echo $twig->render('file.html.twig', $data);
$this->showFormButtons($options);
diff --git a/inc/fleet.class.php b/inc/fleet.class.php
index 4d866087..fbe34f49 100644
--- a/inc/fleet.class.php
+++ b/inc/fleet.class.php
@@ -84,6 +84,10 @@ public static function getMenuPicture() {
return 'fa-group';
}
+ public function getAdditionalLinks() {
+ return [];
+ }
+
/**
* @see CommonGLPI::defineTabs()
*/
@@ -122,7 +126,6 @@ public function showForm($ID, array $options = []) {
$this->initForm($ID, $options);
$this->showFormHeader($options);
- $twig = plugin_flyvemdm_getTemplateEngine();
$fields = $this->fields;
$objectName = $DbUtil->autoName($this->fields["name"], "name",
(isset($options['withtemplate']) && $options['withtemplate'] == 2),
@@ -131,10 +134,12 @@ public function showForm($ID, array $options = []) {
['value' => $objectName, 'display' => false]);
$fields['is_default'] = $fields['is_default'] ? __('No') : __('Yes');
$data = [
- 'withTemplate' => (isset($options['withtemplate']) && $options['withtemplate'] ? "*" : ""),
- 'fleet' => $fields,
+ 'withTemplate' => (isset($options['withtemplate']) && $options['withtemplate'] ? "*" : ""),
+ 'isNewID' => $this->isNewID($ID),
+ 'fleet' => $fields,
];
+ $twig = plugin_flyvemdm_getTemplateEngine();
echo $twig->render('fleet.html.twig', $data);
$this->showFormButtons($options);
diff --git a/inc/menu.class.php b/inc/menu.class.php
index b7ab5d1a..6e076520 100644
--- a/inc/menu.class.php
+++ b/inc/menu.class.php
@@ -112,6 +112,12 @@ public function displayMenu($type = 'dashboard') {
'pic' => PluginFlyvemdmFile::getMenuPicture(),
],
],
+ __('Markets', 'flyvemdm') => [
+ PluginFlyvemdmFDroidMarket::getTypeName($pluralNumber) => [
+ 'link' => Toolbox::getItemTypeSearchURL(PluginFlyvemdmFDroidMarket::class),
+ 'pic' => PluginFlyvemdmFDroidMarket::getMenuPicture(),
+ ],
+ ],
__('Configuration', 'flyvemdm') => [
__('General') => [
'link' => Toolbox::getItemTypeFormURL(PluginFlyvemdmConfig::class) . '?forcetab='.PluginFlyvemdmConfig::class.'$2',
@@ -134,17 +140,20 @@ public function displayMenu($type = 'dashboard') {
*/
public static function getMenuContent() {
$front_flyvemdm = "/plugins/flyvemdm/front";
+ $pics_flyvemdm = "/plugins/flyvemdm/pics";
$menu = [];
$menu['title'] = self::getMenuName();
$menu['page'] = "$front_flyvemdm/menu.php";
$itemtypes = [
- PluginFlyvemdmAgent::class => 'agent',
- PluginFlyvemdmPackage::class => 'package',
- PluginFlyvemdmFile::class => 'file',
- PluginFlyvemdmFleet::class => 'fleet',
- PluginFlyvemdmInvitation::class => 'invitation',
+ PluginFlyvemdmAgent::class => 'agent',
+ PluginFlyvemdmPackage::class => 'package',
+ PluginFlyvemdmFile::class => 'file',
+ PluginFlyvemdmFleet::class => 'fleet',
+ PluginFlyvemdmInvitation::class => 'invitation',
+ PluginFlyvemdmFDroidMarket::class => 'fdroid market',
+ PluginFlyvemdmFDroidApplication::class => 'fdroid application',
];
$pluralNumber = Session::getPluralNumber();
@@ -155,6 +164,17 @@ public static function getMenuContent() {
if ($itemtype::canCreate()) {
$menu['options'][$option]['links']['add'] = $itemtype::getFormURL(false);
}
+
+ // MenuInterface not yet used
+ // Issue: cannot use font awesome because GLPI escapes the picture
+ // if the picture string does not starts with "getAdditionalLinks();
+ foreach ($links as $link) {
+ $image = $link['pic'];
+ $menu['options'][$option]['links'][$image] = $link['link'];
+ }
+ }
}
return $menu;
}
diff --git a/inc/menuinterface.class.php b/inc/menuinterface.class.php
new file mode 100644
index 00000000..17d403bd
--- /dev/null
+++ b/inc/menuinterface.class.php
@@ -0,0 +1,41 @@
+deleteByCriteria([
'itemtype' => $this->getType(),
'items_id' => $this->getID(),
]);
+
+ // Reset import status in the linked F-Droid store
+ $fDroidApplication = new PluginFlyvemdmFDroidApplication();
+ if ($fDroidApplication->getFromDBByCrit(['name' => $this->fields['name']])) {
+ $fDroidApplication->update([
+ 'id' => $fDroidApplication->getID(),
+ 'import_status' => 'no_import',
+ ]);
+ }
}
/**
diff --git a/inc/profile.class.php b/inc/profile.class.php
index e3edc3eb..41decf0e 100644
--- a/inc/profile.class.php
+++ b/inc/profile.class.php
@@ -54,9 +54,12 @@ public static function purgeProfiles(Profile $prof) {
$plugprof->deleteByCriteria(['profiles_id' => $prof->getField("id")]);
}
- /**
- * @see Profile::showForm()
- */
+ function getRights($interface = 'central') {
+ $values = [self::RIGHT_FLYVEMDM_USE => __('Use Flyve MDM')];
+
+ return $values;
+ }
+
public function showForm($ID, $options = []) {
if (!Profile::canView()) {
return false;
@@ -92,9 +95,6 @@ public function showForm($ID, $options = []) {
$this->showLegend();
}
- /**
- * @see Profile::getTabNameForItem()
- */
public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) {
if ($item->getType() == 'Profile') {
return __('Flyve MDM', 'flyvemdm');
@@ -102,9 +102,6 @@ public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) {
return '';
}
- /**
- * @see Profile::displayTabContentForItem
- */
public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) {
if ($item->getType() == 'Profile') {
$profile = new self();
@@ -161,6 +158,8 @@ public function getAssetsRights() {
PluginFlyvemdmPolicy::class,
PluginFlyvemdmPolicyCategory::class,
PluginFlyvemdmWellknownpath::class,
+ PluginFlyvemdmFDroidMarket::class,
+ PluginFlyvemdmFDroidApplication::class,
];
$rights = [];
diff --git a/install/installer.class.php b/install/install.class.php
similarity index 90%
rename from install/installer.class.php
rename to install/install.class.php
index 5544b88d..0440c933 100644
--- a/install/installer.class.php
+++ b/install/install.class.php
@@ -39,36 +39,12 @@
* @since 0.1.0
*
*/
-class PluginFlyvemdmInstaller {
+class PluginFlyvemdmInstall {
const DEFAULT_CIPHERS_LIST = 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK';
const BACKEND_MQTT_USER = 'flyvemdm-backend';
- // Order of this array is mandatory due tu dependancies on install and uninstall
- protected static $itemtypesToInstall = [
- 'mqttuser',
- // Must be before config because config creates a mqtt user for the plugin
- 'mqttacl',
- // Must be before config because config creates a mqtt ACL for the plugin
- 'config',
- 'entityconfig',
- 'mqttlog',
- 'agent',
- 'package',
- 'file',
- 'fleet',
- 'profile',
- 'notificationtargetinvitation',
- 'geolocation',
- 'policy',
- 'policycategory',
- 'fleet_policy',
- 'wellknownpath',
- 'invitation',
- 'invitationlog',
- ];
-
protected static $currentVersion = null;
protected $migration;
@@ -78,7 +54,7 @@ class PluginFlyvemdmInstaller {
* @param string $classname
* @return bool
*/
- public function autoload($classname) {
+ public static function autoload($classname) {
// useful only for installer GLPI autoloader already handles inc/ folder
$filename = dirname(__DIR__) . '/inc/' . strtolower(str_replace('PluginFlyvemdm', '',
$classname)) . '.class.php';
@@ -95,52 +71,34 @@ public function autoload($classname) {
* @return boolean true (assume success, needs enhancement)
*
*/
- public function install() {
+ public function install(Migration $migration) {
global $DB;
+ $this->migration = $migration;
spl_autoload_register([__CLASS__, 'autoload']);
- $this->migration = new Migration(PLUGIN_FLYVEMDM_VERSION);
- $this->migration->setVersion(PLUGIN_FLYVEMDM_VERSION);
-
- // adding DB model from sql file
- // TODO : migrate in-code DB model setup here
- if (self::getCurrentVersion() == '') {
- // Setup DB model
- $dbFile = PLUGIN_FLYVEMDM_ROOT . "/install/mysql/plugin_flyvemdm_empty.sql";
- if (!$DB->runFile($dbFile)) {
- $this->migration->displayWarning("Error creating tables : " . $DB->error(), true);
- return false;
- }
+ $this->installSchema();
+ $this->createInitialConfig();
+ $this->migration->executeMigration();
+ $this->installUpgradeCommonTasks();
- $this->createInitialConfig();
- } else {
- if (PluginFlyvemdmCommon::endsWith(PLUGIN_FLYVEMDM_VERSION,
- "-dev") || (version_compare(self::getCurrentVersion(),
- PLUGIN_FLYVEMDM_VERSION) != 0)) {
- // TODO : Upgrade (or downgrade)
- $this->upgrade(self::getCurrentVersion());
- }
- }
+ return true;
+ }
- $this->migration->executeMigration();
+ protected function installSchema() {
+ global $DB;
+
+ $this->migration->displayMessage("create database schema");
+
+ $dbFile = __DIR__ . '/mysql/plugin_flyvemdm_empty.sql';
+ if (!$DB->runFile($dbFile)) {
+ $this->migration->displayWarning("Error creating tables : " . $DB->error(), true);
+ return false;
+ }
if (version_compare(GLPI_VERSION, '9.3.0') >= 0) {
$this->migrateToInnodb();
}
- $this->createDirectories();
- $this->createFirstAccess();
- $this->createGuestProfileAccess();
- $this->createAgentProfileAccess();
- $this->createDefaultFleet();
- $this->createPolicies();
- $this->createNotificationTargetInvitation();
- $this->createJobs();
- $this->createRootEntityConfig();
- $this->createDisplayPreferences();
-
- Config::setConfigurationValues('flyvemdm', ['version' => PLUGIN_FLYVEMDM_VERSION]);
-
return true;
}
@@ -198,25 +156,45 @@ public function createDirectories() {
}
// Create cache directory for the template engine
- PluginFlyvemdmCommon::recursiveRmdir(FLYVEMDM_TEMPLATE_CACHE_PATH);
- if (!mkdir(FLYVEMDM_TEMPLATE_CACHE_PATH, 0770, true)) {
- $this->migration->displayWarning("Cannot create " . FLYVEMDM_TEMPLATE_CACHE_PATH . " directory");
+ if (!file_exists(FLYVEMDM_TEMPLATE_CACHE_PATH)) {
+ if (!mkdir(FLYVEMDM_TEMPLATE_CACHE_PATH, 0770, true)) {
+ $this->migration->displayWarning("Cannot create " . FLYVEMDM_TEMPLATE_CACHE_PATH . " directory");
+ }
}
}
/**
* @return null|string
*/
- public static function getCurrentVersion() {
- if (self::$currentVersion === null) {
- $config = \Config::getConfigurationValues('flyvemdm', ['version']);
- if (!isset($config['version'])) {
- self::$currentVersion = '';
- } else {
- self::$currentVersion = $config['version'];
+ public function getSchemaVersion() {
+ if ($this->isPluginInstalled()) {
+ $config = Config::getConfigurationValues('flyvemdm', ['schema_version']);
+ if (!isset($config['schema_version'])) {
+ return '0.0';
}
+ return $config['schema_version'];
}
- return self::$currentVersion;
+
+ return null;
+ }
+
+ /**
+ * is the plugin already installed ?
+ *
+ * @return boolean
+ */
+ public function isPluginInstalled() {
+ global $DB;
+
+ // Check tables of the plugin between 1.1 and 2.0 releases
+ $result = $DB->query("SHOW TABLES LIKE 'glpi_plugin_flyvemdm_%'");
+ if ($result) {
+ if ($DB->numrows($result) > 0) {
+ return true;
+ }
+ }
+
+ return false;
}
protected function createRootEntityConfig() {
@@ -257,6 +235,8 @@ protected function createFirstAccess() {
PluginFlyvemdmInvitation::$rightname => ALLSTANDARDRIGHT,
PluginFlyvemdmInvitationLog::$rightname => READ,
PluginFlyvemdmTaskstatus::$rightname => READ,
+ PluginFlyvemdmFDroidApplication::$rightname => READ | UPDATE | READNOTE | UPDATENOTE,
+ PluginFlyvemdmFDroidMarket::$rightname => ALLSTANDARDRIGHT | READNOTE | UPDATENOTE,
];
$profileRight->updateProfileRights($_SESSION['glpiactiveprofile']['id'], $newRights);
@@ -495,22 +475,53 @@ public function createNotificationTargetInvitation() {
/**
* Upgrade the plugin to the current code version
*
- * @param string $fromVersion
+ * @param string version to upgrade from
*/
- protected function upgrade($fromVersion) {
- switch ($fromVersion) {
- case '2.0.0':
- // Example : upgrade to version 3.0.0
- // $this->upgradeOneStep('3.0.0');
- case '3.0.0':
- // Example : upgrade to version 4.0.0
- // $this->upgradeOneStep('4.0.0');
-
- default:
+ public function upgrade(Migration $migration) {
+ spl_autoload_register([__CLASS__, 'autoload']);
+
+ $this->migration = $migration;
+ $fromSchemaVersion = $this->getSchemaVersion();
+
+ switch ($fromSchemaVersion) {
+ case '0.0':
+ // Upgrade to 2.0
+ $this->upgradeOneStep('2.0');
+
+ case '2.0':
+ // Example : upgrade to version 2.1
+ // $this->upgradeOneStep('2.1');
+
+ case '3.0':
+ // Example : upgrade to version 3.0
+ // $this->upgradeOneStep('3.0');
+
}
- if (PluginFlyvemdmCommon::endsWith(PLUGIN_FLYVEMDM_VERSION, "-dev")) {
- $this->upgradeOneStep('dev');
+ if (!PLUGIN_FLYVEMDM_IS_OFFICIAL_RELEASE) {
+ $this->upgradeOneStep('develop');
}
+ $this->installUpgradeCommonTasks();
+ return true;
+ }
+
+ private function installUpgradeCommonTasks() {
+ $this->createDirectories();
+ $this->createFirstAccess();
+ $this->createGuestProfileAccess();
+ $this->createAgentProfileAccess();
+ $this->createDefaultFleet();
+ $this->createPolicies();
+ $this->createNotificationTargetInvitation();
+ $this->createJobs();
+ $this->createRootEntityConfig();
+ $this->createDisplayPreferences();
+
+ Config::setConfigurationValues(
+ 'flyvemdm', [
+ 'version' => PLUGIN_FLYVEMDM_VERSION,
+ 'schema_version' => PLUGIN_FLYVEMDM_SCHEMA_VERSION,
+ ]
+ );
}
/**
@@ -519,21 +530,19 @@ protected function upgrade($fromVersion) {
* @param string $toVersion
*/
protected function upgradeOneStep($toVersion) {
-
ini_set("max_execution_time", "0");
ini_set("memory_limit", "-1");
$suffix = str_replace('.', '_', $toVersion);
- $includeFile = __DIR__ . "/upgrade/update_to_$suffix.php";
+ $includeFile = __DIR__ . "/update_to_$suffix.php";
if (is_readable($includeFile) && is_file($includeFile)) {
include_once $includeFile;
- $updateFunction = "plugin_flyvemdm_update_to_$suffix";
- if (function_exists($updateFunction)) {
- $this->migration->addNewMessageArea("Upgrade to $toVersion");
- $updateFunction($this->migration);
- $this->migration->executeMigration();
- $this->migration->displayMessage('Done');
- }
+ $updateClass = "PluginFlyvemdmUpgradeTo$suffix";
+ $this->migration->addNewMessageArea("Upgrade to $toVersion");
+ $upgradeStep = new $updateClass();
+ $upgradeStep->upgrade($this->migration);
+ $this->migration->executeMigration();
+ $this->migration->displayMessage('Done');
}
}
@@ -543,6 +552,18 @@ protected function createJobs() {
'comment' => __('Parse uploaded applications to collect metadata', 'flyvemdm'),
'mode' => CronTask::MODE_EXTERNAL,
]);
+
+ CronTask::Register(PluginFlyvemdmFDroidMarket::class, 'UpdateRepositories', DAY_TIMESTAMP,
+ [
+ 'comment' => __('Update the list of applications available from F-Droid like repositories', 'flyvemdm'),
+ 'mode' => CronTask::MODE_EXTERNAL
+ ]);
+
+ CronTask::Register(PluginFlyvemdmFDroidApplication::class, 'DownloadApplications', DAY_TIMESTAMP,
+ [
+ 'comment' => __('Imports applications for deployment', 'flyvemdm'),
+ 'mode' => CronTask::MODE_EXTERNAL
+ ]);
}
/**
@@ -812,6 +833,8 @@ protected function deleteTables() {
PluginFlyvemdmPolicyCategory::getTable(),
PluginFlyvemdmWellknownpath::getTable(),
PluginFlyvemdmTaskstatus::getTable(),
+ PluginFlyvemdmFDroidApplication::getTable(),
+ PluginFlyvemdmFDroidMarket::getTable(),
];
foreach ($tables as $table) {
diff --git a/install/mysql/plugin_flyvemdm_empty.sql b/install/mysql/plugin_flyvemdm_empty.sql
index 4afebbb3..e778cc3a 100644
--- a/install/mysql/plugin_flyvemdm_empty.sql
+++ b/install/mysql/plugin_flyvemdm_empty.sql
@@ -259,3 +259,40 @@ CREATE TABLE `glpi_plugin_flyvemdm_taskstatuses` (
INDEX `plugin_flyvemdm_agents_id` (`plugin_flyvemdm_agents_id`),
INDEX `plugin_flyvemdm_tasks_id` (`plugin_flyvemdm_tasks_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+-- Export de la structure de table glpi-flyvemdm. glpi_plugin_flyvemdm_fdroidapplications
+DROP TABLE IF EXISTS `glpi_plugin_flyvemdm_fdroidapplications`;
+CREATE TABLE `glpi_plugin_flyvemdm_fdroidapplications` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `name` varchar(255) NOT NULL DEFAULT '',
+ `package_name` varchar(255) NOT NULL DEFAULT '',
+ `entities_id` int(11) NOT NULL DEFAULT '0',
+ `is_recursive` tinyint(1) NOT NULL DEFAULT '0',
+ `plugin_flyvemdm_fdroidmarkets_id` int(11) NOT NULL DEFAULT '0',
+ `plugin_flyvemdm_packages_id` int(11) NOT NULL DEFAULT '0',
+ `alias` varchar(255) NOT NULL DEFAULT '',
+ `version` varchar(255) NOT NULL DEFAULT '',
+ `version_code` varchar(255) NOT NULL DEFAULT '',
+ `date_mod` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `desc` text NOT NULL,
+ `filename` varchar(255) NOT NULL DEFAULT '',
+ `filesize` int(11) NOT NULL DEFAULT '0',
+ `import_status` enum('no_import','to_import','imported') NOT NULL DEFAULT 'no_import',
+ `is_available` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Does the application exists in the store ?',
+ PRIMARY KEY (`id`),
+ KEY `entities_id` (`entities_id`),
+ KEY `plugin_flyvemdm_fdroidmarkets_id` (`plugin_flyvemdm_fdroidmarkets_id`),
+ KEY `plugin_flyvemdm_packages_id` (`plugin_flyvemdm_packages_id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+-- Export de la structure de table glpi-flyvemdm. glpi_plugin_flyvemdm_fdroidmarkets
+DROP TABLE IF EXISTS `glpi_plugin_flyvemdm_fdroidmarkets`;
+CREATE TABLE `glpi_plugin_flyvemdm_fdroidmarkets` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `name` varchar(255) NOT NULL DEFAULT '',
+ `entities_id` int(11) NOT NULL DEFAULT '0',
+ `is_recursive` tinyint(1) NOT NULL DEFAULT '0',
+ `url` varchar(255) NOT NULL DEFAULT '' COMMENT 'URL to index.xml of the market',
+ PRIMARY KEY (`id`),
+ KEY `entities_id` (`entities_id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
diff --git a/install/update_to_develop.php b/install/update_to_develop.php
new file mode 100644
index 00000000..dc735ebf
--- /dev/null
+++ b/install/update_to_develop.php
@@ -0,0 +1,122 @@
+setVersion(PLUGIN_FLYVEMDM_VERSION);
+
+ $profileRight = new ProfileRight();
+ // Merge new rights into current profile
+ $profiles_id = $_SESSION['glpiactiveprofile']['id'];
+ $currentRights = ProfileRight::getProfileRights($profiles_id);
+ $newRights = array_merge($currentRights, [
+ PluginFlyvemdmFDroidMarket::$rightname => ALLSTANDARDRIGHT | READNOTE | UPDATENOTE,
+ PluginFlyvemdmFDroidApplication::$rightname => READ | UPDATE | READNOTE | UPDATENOTE,
+ ]);
+ $profileRight->updateProfileRights($profiles_id, $newRights);
+
+ // Create table for F-Droid application
+ $query = "CREATE TABLE IF NOT EXISTS `glpi_plugin_flyvemdm_fdroidapplications` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `name` varchar(255) NOT NULL DEFAULT '',
+ `package_name` varchar(255) NOT NULL DEFAULT '',
+ `entities_id` int(11) NOT NULL DEFAULT '0',
+ `is_recursive` tinyint(1) NOT NULL DEFAULT '0',
+ `plugin_flyvemdm_fdroidmarkets_id` int(11) NOT NULL DEFAULT '0',
+ `plugin_flyvemdm_packages_id` int(11) NOT NULL DEFAULT '0',
+ `alias` varchar(255) NOT NULL DEFAULT '',
+ `version` varchar(255) NOT NULL DEFAULT '',
+ `version_code` varchar(255) NOT NULL DEFAULT '',
+ `date_mod` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `desc` text NOT NULL,
+ `filename` varchar(255) NOT NULL DEFAULT '',
+ `filesize` int(11) NOT NULL DEFAULT '0',
+ `import_status` enum('no_import','to_import','imported') NOT NULL DEFAULT 'no_import',
+ `is_available` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Does the applciation e xists in the store ?',
+ PRIMARY KEY (`id`),
+ KEY `entities_id` (`entities_id`),
+ KEY `plugin_flyvemdm_fdroidmarkets_id` (`plugin_flyvemdm_fdroidmarkets_id`),
+ KEY `plugin_flyvemdm_packages_id` (`plugin_flyvemdm_packages_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+ ";
+ $DB->query($query) or plugin_flyvemdm_upgrade_error($migration);
+
+ // Update enum if needed
+ $table = 'glpi_plugin_flyvemdm_fdroidapplications';
+ $enumImportStatus = PluginFlyvemdmFDroidApplication::getEnumImportStatus();
+ $currentEnumImportStatus = PluginFlyvemdmCommon::getEnumValues($table, 'import_status');
+ if (count($currentEnumImportStatus) > 0) {
+ // The field exists
+ if (count($currentEnumImportStatus) != count($enumImportStatus)) {
+ reset($enumImportStatus);
+ $defaultValue = key($enumImportStatus);
+ $enumImportStatus = "'" . implode("', '", array_keys($enumImportStatus)) . "'";
+ $query = "ALTER TABLE `$table`
+ CHANGE COLUMN `import_status` `import_status`
+ ENUM($enumImportStatus)
+ NOT NULL DEFAULT '$defaultValue'";
+ $DB->query($query) or plugin_flyvemdm_upgrade_error($migration);
+ }
+ } else {
+ // The field does not exists
+ reset($enumImportStatus);
+ $defaultValue = key($enumImportStatus);
+ $enumImportStatus = "'" . implode("', '", array_keys($enumImportStatus)) . "'";
+ $query = "ALTER TABLE `$table`
+ ADD COLUMN `import_status`
+ ENUM($enumImportStatus)
+ NOT NULL DEFAULT '$defaultValue'";
+ $DB->query($query) or plugin_flyvemdm_upgrade_error($migration);
+ }
+
+ // Create table for F-Droid
+ $query = "CREATE TABLE IF NOT EXISTS `glpi_plugin_flyvemdm_fdroidmarkets` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `name` varchar(255) NOT NULL DEFAULT '',
+ `entities_id` int(11) NOT NULL DEFAULT '0',
+ `is_recursive` tinyint(1) NOT NULL DEFAULT '0',
+ `url` varchar(255) NOT NULL DEFAULT '' COMMENT 'URL to index.xml of the market',
+ PRIMARY KEY (`id`),
+ KEY `entities_id` (`entities_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+ ";
+ $DB->query($query) or plugin_flyvemdm_upgrade_error($migration);
+ }
+}
\ No newline at end of file
diff --git a/install/upgrade/update_to_dev.php b/install/upgrade/update_to_dev.php
deleted file mode 100644
index ad05392d..00000000
--- a/install/upgrade/update_to_dev.php
+++ /dev/null
@@ -1,491 +0,0 @@
-setVersion(PLUGIN_FLYVEMDM_VERSION);
-
- $profileRight = new ProfileRight();
-
- // Merge new rights into current profile
- $profiles_id = $_SESSION['glpiactiveprofile']['id'];
- $currentRights = ProfileRight::getProfileRights($profiles_id);
- $newRights = array_merge($currentRights, [
- PluginFlyvemdmInvitation::$rightname => ALLSTANDARDRIGHT ,
- PluginFlyvemdmInvitationlog::$rightname => READ,
- PluginFlyvemdmGeolocation::$rightname => ALLSTANDARDRIGHT | READNOTE | UPDATENOTE,
- ]);
- $profileRight->updateProfileRights($profiles_id, $newRights);
-
- $migration->setContext('flyvemdm');
- $migration->addConfig([
- 'default_agent_url' => PLUGIN_FLYVEMDM_AGENT_DOWNLOAD_URL,
- 'show_wizard' => '0',
- 'debug_save_inventory' => '0',
- 'android_bugcollecctor_url' => '',
- 'android_bugcollector_login' => '',
- 'android_bugcollector_passwd' => '',
- 'invitation_deeplink' => PLUGIN_FLYVEMDM_DEEPLINK,
- ]);
-
- $config = Config::getConfigurationValues('flyvemdm', ['mqtt_broker_tls']);
- if (isset($config['mqtt_broker_tls'])) {
- if ($config['mqtt_broker_tls'] !== '0') {
- $config['mqtt_broker_tls_port'] = $config['mqtt_broker_port'];
- $config['mqtt_broker_port'] = '1883';
- } else {
- $config['mqtt_broker_tls_port'] = '8883';
- }
- // Split TLS setting for client in one hand and backend in the other hand
- $config['mqtt_tls_for_clients'] = $config['mqtt_broker_tls'];
- $config['mqtt_tls_for_backend'] = $config['mqtt_broker_tls'];
- Config::setConfigurationValues('flyvemdm', $config);
- Config::deleteConfigurationValues('flyvemdm', ['mqtt_broker_tls']);
- }
-
- // remove download base URL setting
- Config::deleteConfigurationValues('flyvemdm', ['deploy_base_url']);
-
- // update Entity config table
- $table = 'glpi_plugin_flyvemdm_entityconfigs';
- $migration->addField($table, 'support_name', 'text', ['after' => 'agent_token_life']);
- $migration->addField($table, 'support_phone', 'string', ['after' => 'support_name']);
- $migration->addField($table, 'support_website', 'string', ['after' => 'support_phone']);
- $migration->addField($table, 'support_email', 'string', ['after' => 'support_website']);
- $migration->addField($table, 'support_address', 'text', ['after' => 'support_email']);
- $migration->addKey($table, 'entities_id', 'entities_id');
-
- // update Agent table
- $table = 'glpi_plugin_flyvemdm_agents';
- if (!$DB->fieldExists($table, 'enroll_status')) {
- $query = "ALTER TABLE `$table`
- ADD COLUMN `enroll_status` ENUM('enrolled', 'unenrolling', 'unenrolled') NOT NULL DEFAULT 'enrolled' AFTER `lock`";
- $DB->query($query) or plugin_flyvemdm_upgrade_error($migration);
- }
- $migration->addField($table, 'version', 'string', ['after' => 'name']);
- $migration->addField($table, 'users_id', 'integer', ['after' => 'computers_id']);
- $migration->addField($table, 'is_online', 'integer', ['after' => 'last_contact']);
- $migration->addField($table, 'has_system_permission', 'bool', ['after' => 'mdm_type']);
- $migration->addKey($table, 'computers_id', 'computers_id');
- $migration->addKey($table, 'users_id', 'users_id');
- $migration->addKey($table, 'entities_id', 'entities_id');
- $migration->changeField($table, 'wipe', 'wipe', 'bool');
- $migration->changeField($table, 'lock', 'lock', 'bool');
-
- $enumMdmType = PluginFlyvemdmAgent::getEnumMdmType();
- $currentEnumMdmType = PluginFlyvemdmCommon::getEnumValues($table, 'mdm_type');
- if (count($currentEnumMdmType) > 0) {
- // The field exists
- if (count($currentEnumMdmType) != count($enumMdmType)) {
- reset($enumMdmType);
- $defaultValue = key($enumMdmType);
- $enumMdmType = "'" . implode("', '", array_keys($enumMdmType)) . "'";
- $query = "ALTER TABLE `$table`
- CHANGE COLUMN `mdm_type` `mdm_type`
- ENUM($enumMdmType)
- NOT NULL DEFAULT '$defaultValue'";
- $DB->query($query) or plugin_flyvemdm_upgrade_error($migration);
- }
- } else {
- // The field does not exists
- reset($enumMdmType);
- $defaultValue = key($enumMdmType);
- $enumMdmType = "'" . implode("', '", array_keys($enumMdmType)) . "'";
- $query = "ALTER TABLE `$table`
- ADD COLUMN `mdm_type`
- ENUM($enumMdmType)
- NOT NULL DEFAULT '$defaultValue'";
- $DB->query($query) or plugin_flyvemdm_upgrade_error($migration);
- }
-
- // Create task status table
- $table = 'glpi_plugin_flyvemdm_taskstatuses';
- $query = "CREATE TABLE IF NOT EXISTS `$table` (
- `id` INT(11) NOT NULL AUTO_INCREMENT,
- `name` VARCHAR(255) NOT NULL DEFAULT '',
- `date_creation` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
- `date_mod` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
- `plugin_flyvemdm_agents_id` INT(11) NOT NULL DEFAULT '0',
- `plugin_flyvemdm_tasks_id` INT(11) NOT NULL DEFAULT '0',
- `status` VARCHAR(255) NOT NULL DEFAULT '',
- PRIMARY KEY (`id`),
- KEY `plugin_flyvemdm_agents_id` (`plugin_flyvemdm_agents_id`),
- KEY `plugin_flyvemdm_tasks_id` (`plugin_flyvemdm_tasks_id`)
- ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";
- $DB->query($query) or plugin_flyvemdm_upgrade_error($migration);
-
- $migration->addKey($table, 'plugin_flyvemdm_agents_id', 'plugin_flyvemdm_agents_id');
- $migration->addKey($table, 'plugin_flyvemdm_tasks_id', 'plugin_flyvemdm_tasks_id');
-
- // update Policy table
- $table = 'glpi_plugin_flyvemdm_policies';
- $migration->addField($table, 'recommended_value', 'string', ['after' => 'default_value']);
- $migration->addField($table, 'is_android_system', 'bool', ['after' => 'recommended_value']);
- $migration->addField($table, 'android_min_version', 'string', ['after' => 'is_android_system', 'value' => '0']);
- $migration->addField($table, 'android_max_version', 'string', ['after' => 'android_min_version', 'value' => '0']);
- $migration->addField($table, 'apple_min_version', 'string', ['after' => 'android_max_version', 'value' => '0']);
- $migration->addField($table, 'apple_max_version', 'string', ['after' => 'apple_min_version', 'value' => '0']);
- $migration->addKey($table, 'group', 'group');
- $migration->addKey($table, 'plugin_flyvemdm_policycategories_id', 'plugin_flyvemdm_policycategories_id');
- $migration->dropField($table, 'is_android_policy');
- $migration->dropField($table, 'is_apple_policy');
-
- // Rename and update fleet_policy into task
- $table = 'glpi_plugin_flyvemdm_tasks';
- $migration->renameTable('glpi_plugin_flyvemdm_fleets_policies', $table);
- $migration->changeField($table, 'plugin_flyvemdm_fleets_policies_id', 'plugin_flyvemdm_tasks_id',
- 'integer');
- $migration->addKey($table, 'plugin_flyvemdm_policies_id', 'plugin_flyvemdm_policies_id');
-
- // Upgrade schema to apply policies on fleets and agents
- if (!$DB->fieldExists($table, 'items_id_applied')) {
- $migration->changeField($table, 'plugin_flyvemdm_fleets_id', 'items_id_applied', 'integer');
- $migration->dropKey($table, 'plugin_flyvemdm_fleets_id');
- $migration->addField($table, 'itemtype_applied', 'string', ['after' => 'id']);
- $migration->addKey($table, ['itemtype_applied', 'items_id_applied'], 'FK_applied');
- // All tasks already created were applied on fleets
- $migration->addPostQuery("UPDATE `$table` SET `itemtype_applied` = 'PluginFlyvemdmFleet'");
- $migration->executeMigration();
- }
-
- $table = 'glpi_plugin_flyvemdm_policies';
- $policies = [
- 'disableFmRadio',
- 'disableVoiceMail',
- 'disableCallAutoAnswer',
- 'disableVoiceDictation',
- 'disableUsbOnTheGo',
- 'resetPassword',
- 'inventoryFrequency',
- 'disableSmsMms',
- 'disableStreamVoiceCall',
- 'disableCreateVpnProfiles',
- ];
- $tasksTable = 'glpi_plugin_flyvemdm_tasks';
- $fleetTable = 'glpi_plugin_flyvemdm_fleets';
- $agentsTable = 'glpi_plugin_flyvemdm_agents';
- $request = [
- 'FIELDS' => [
- $table => ['symbol'],
- $tasksTable => ['id', 'itemtype_applied', 'items_id_applied'],
- $fleetTable => ['entities_id'],
- ],
- 'FROM' => $table,
- 'INNER JOIN' => [
- $tasksTable => [
- 'FKEY' => [
- $tasksTable => 'plugin_flyvemdm_policies_id',
- $table => 'id',
- ],
- ],
- ],
- 'LEFT JOIN' => [
- $fleetTable => [
- 'itemtype_applied' => 'PluginFlyvemdmFleet',
- 'FKEY' => [
- $tasksTable => 'items_id_applied',
- $fleetTable => 'id',
- ],
- ],
- $agentsTable => [
- 'itemtype_applied' => 'PluginFlyvemdmAgent',
- 'FKEY' => [
- $tasksTable => 'items_id_applied',
- $agentsTable => 'id',
- ],
- ],
- ],
- 'WHERE' => [
- 'symbol' => $policies,
- ],
- ];
- $result = $DB->request($request);
- if (count($result) > 0) {
- $mqttClient = PluginFlyvemdmMqttclient::getInstance();
- foreach ($result as $data) {
- switch ($data['itemtype_applied']) {
- case PluginFlyvemdmFleet::class:
- $type = 'fleet';
- $entityId = $data['entities_id'];
- break;
-
- case PluginFlyvemdmAgent::class:
- $agent = new PluginFlyvemdmAgent();
- $agent->getFromDB($data['items_id_applied']);
- $type = 'agent';
- $entityId = $agent->getEntityID();
- break;
-
- default:
- $type = '';
- }
- if ($type === '') {
- continue;
- }
- $topic = implode('/', [
- '/',
- $entityId,
- $type,
- $data['items_id_applied'],
- 'Policy',
- $data['symbol'],
- 'Task',
- $data['id']
- ]);
- $mqttClient->publish($topic, null, 0, 1);
- }
- }
- $policiesStr = implode("','", $policies);
- $migration->addPostQuery("DELETE FROM `$table` WHERE `symbol` IN ('" . $policiesStr . "')");
-
- // update Applications table
- $table = 'glpi_plugin_flyvemdm_packages';
- $migration->addField($table, 'parse_status', "enum('pending', 'parsed', 'failed') NOT NULL DEFAULT 'pending'",
- ['after' => 'dl_filename', 'default' => 'pending']);
- $migration->addfield($table, 'plugin_orion_tasks_id', 'integer', ['after' => 'dl_filename']);
- $migration->changeField($table, 'name', 'package_name', 'string');
- $migration->migrationOneTable($table);
- $migration->dropField($table, 'filesize');
- $migration->addField($table, 'name', 'string', ['after' => 'id']);
- $migration->addKey($table, 'entities_id', 'entities_id');
- $migration->addPostQuery("UPDATE `$table` SET `parse_status` = 'parsed'");
- $migration->addPostQuery("UPDATE `$table` SET `name` = `package_name`");
-
- $result = $DB->request(['FROM' => $table, 'LIMIT' => '1']);
- if ($result->count() > 0) {
- $result->rewind();
- $row = $result->current();
- if (strpos($row['filename'], 'flyvemdm/package/') !== 0) {
- // If there is at least one package and the path does starts with the new prefix, then update all the table
- $migration->addPostQuery("UPDATE `$table` SET `filename` = CONCAT('flyvemdm/package/', `filename`)");
- }
- }
-
- $table = 'glpi_plugin_flyvemdm_files';
- $migration->addKey($table, 'entities_id', 'entities_id');
- $migration->addField($table, 'comment', 'text');
-
- // Add display preferences for PluginFlyvemdmFile
- $query = "SELECT * FROM `glpi_displaypreferences`
- WHERE `itemtype` = 'PluginFlyvemdmFile'
- AND `users_id`='0'";
- $result=$DB->query($query);
- if ($DB->numrows($result) == '0') {
- $query = "INSERT INTO `glpi_displaypreferences` (`id`, `itemtype`, `num`, `rank`, `users_id`)
- VALUES (NULL, 'PluginFlyvemdmFile', '1', '1', '0'),
- (NULL, 'PluginFlyvemdmFile', '4', '2', '0');";
- $DB->query($query);
- }
-
- $table = 'glpi_plugin_flyvemdm_fleets';
- $migration->addField($table, 'is_recursive', 'bool');
- $migration->addKey($table, 'entities_id', 'entities_id');
-
- $table = 'glpi_plugin_flyvemdm_geolocations';
- $migration->addKey($table, 'computers_id', 'computers_id');
-
- $table = 'glpi_plugin_flyvemdm_mqttacls';
- $migration->addKey($table, 'plugin_flyvemdm_mqttusers_id', 'plugin_flyvemdm_mqttusers_id');
-
- $table = 'glpi_plugin_flyvemdm_policycategories';
- $migration->addKey($table, 'plugin_flyvemdm_policycategories_id', 'plugin_flyvemdm_policycategories_id');
-
- // Create invitation log table
- $table = 'glpi_plugin_flyvemdm_invitationlogs';
- $query = "CREATE TABLE IF NOT EXISTS `$table` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `plugin_flyvemdm_invitations_id` int(11) NOT NULL DEFAULT '0',
- `date_creation` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
- `event` varchar(255) NOT NULL DEFAULT '',
- PRIMARY KEY (`id`),
- INDEX `plugin_flyvemdm_invitations_id` (`plugin_flyvemdm_invitations_id`),
- INDEX `date_creation` (`date_creation`)
- ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";
- $DB->query($query) or plugin_flyvemdm_upgrade_error($migration);
- $migration->addKey($table, 'plugin_flyvemdm_invitations_id', 'plugin_flyvemdm_invitations_id');
-
- $table = 'glpi_plugin_flyvemdm_invitations';
- if (!$DB->fieldExists($table, 'name')) {
- $invitationName = _n('Invitation', 'Invitations', 1, 'flyvemdm');
- $migration->addField($table, 'name', 'string', ['after' => 'id']);
- $migration->addPostQuery("UPDATE `$table` SET `name` = '$invitationName'");
- }
- $migration->addKey($table, 'users_id', 'users_id');
- $migration->addKey($table, 'entities_id', 'entities_id');
- $migration->addKey($table, 'documents_id', 'documents_id');
-
- // drop Mqtt Update queue
- $cronTask = new CronTask();
- $cronTask->deleteByCriteria(['itemtype' => 'PluginFlyvemdmMqttupdatequeue']);
- $table = 'glpi_plugin_flyvemdm_mqttupdatequeues';
- $migration->dropTable($table);
-
- // Fix PascalCase symbols
- $query = "UPDATE `glpi_plugin_flyvemdm_policies`
- SET `symbol` = 'maximumFailedPasswordsForWipe'
- WHERE `symbol`='MaximumFailedPasswordsForWipe'";
- $DB->query($query);
- $query = "UPDATE `glpi_plugin_flyvemdm_policies`
- SET `symbol` = 'maximumTimeToLock'
- WHERE `symbol`='MaximumTimeToLock'";
- $DB->query($query);
-
- // change MQTT topics tree layout : remove leading slash
- $mqttClient = PluginFlyvemdmMqttclient::getInstance();
- $request = [
- 'FIELDS' => [
- 'glpi_plugin_flyvemdm_agents' => ['entities_id'],
- 'glpi_computers' => ['serial'],
- ],
- 'FROM' => 'glpi_plugin_flyvemdm_agents',
- 'INNER JOIN' => [
- 'glpi_computers' => ['FKEY' => [
- 'glpi_plugin_flyvemdm_agents' => 'computers_id',
- 'glpi_computers' => 'id'
- ]]
- ],
- 'WHERE' => ['lock' => ['<>' => '0']]
- ];
- $mqttMessage = ['lock' => 'now'];
- $mqttMessage = json_encode($mqttMessage, JSON_UNESCAPED_SLASHES);
- foreach ($DB->request($request) as $row) {
- $topic = implode('/', [
- $row['entities_id'],
- 'agent',
- $row['serial'],
- 'Command',
- 'Lock',
- ]);
- $mqttClient->publish($topic, $mqttMessage, 0, 1);
- $mqttClient->publish('/' . $topic, null, 0, 1);
- }
-
- // re-use previous request array
- $request['WHERE'] = ['wipe' => ['<>' => '0']];
- $mqttMessage = ['wipe' => 'now'];
- $mqttMessage = json_encode($mqttMessage, JSON_UNESCAPED_SLASHES);
- foreach ($DB->request($request) as $row) {
- $topic = implode('/', [
- $row['entities_id'],
- 'agent',
- $row['serial'],
- 'Command',
- 'Wipe',
- ]);
- $mqttClient->publish($topic, $mqttMessage, 0, 1);
- $mqttClient->publish('/' . $topic, null, 0, 1);
- }
-
- // re-use previous request array
- $request['WHERE'] = ['enroll_status' => ['=' => 'unenrolling']];
- $mqttMessage = ['unenroll' => 'now'];
- $mqttMessage = json_encode($mqttMessage, JSON_UNESCAPED_SLASHES);
- foreach ($DB->request($request) as $row) {
- $topic = implode('/', [
- $row['entities_id'],
- 'agent',
- $row['serial'],
- 'Command',
- 'Unenroll',
- ]);
- $mqttClient->publish($topic, $mqttMessage, 0, 1);
- $mqttClient->publish('/' . $topic, null, 0, 1);
- }
-
- $request = [
- 'FIELDS' => [
- 'glpi_plugin_flyvemdm_tasks' => ['id', 'itemtype_applied', 'items_id_applied', 'plugin_flyvemdm_policies_id', 'itemtype', 'items_id', 'value'],
- 'glpi_plugin_flyvemdm_policies' => ['symbol'],
- 'glpi_plugin_flyvemdm_fleets' => ['entities_id']
- ],
- 'FROM' => 'glpi_plugin_flyvemdm_tasks',
- 'INNER JOIN' => [
- 'glpi_plugin_flyvemdm_policies' => [
- 'FKEY' => [
- 'glpi_plugin_flyvemdm_tasks' => 'plugin_flyvemdm_policies_id',
- 'glpi_plugin_flyvemdm_policies' => 'id'
- ]
- ],
- 'glpi_plugin_flyvemdm_fleets' => [
- 'FKEY' => [
- 'glpi_plugin_flyvemdm_tasks' => 'items_id_applied',
- 'glpi_plugin_flyvemdm_fleets' => 'id'
- ]
- ]
- ],
- 'WHERE' => [
- 'glpi_plugin_flyvemdm_tasks.itemtype_applied' => 'PluginFlyvemdmFleet'
- ]
- ];
- foreach ($DB->request($request) as $row) {
- switch ($row['itemtype_applied']) {
- case PluginFlyvemdmFleet::class:
- $type = 'fleet';
- break;
-
- case PluginFlyvemdmAgent::class:
- $type = 'agent';
- break;
-
- default:
- $type = '';
- }
- if ($type === '') {
- continue;
- }
- $topic = implode('/', [
- $row['entities_id'],
- 'fleet',
- $row['items_id_applied'],
- 'Policy',
- $row['symbol'],
- ]);
- $policyFactory = new PluginFlyvemdmPolicyFactory();
- $appliedPolicy = $policyFactory->createFromDBByID($row['plugin_flyvemdm_policies_id']);
- $policyMessage = $appliedPolicy->getMqttMessage(
- $row['value'],
- $row['itemtype'],
- $row['items_id']
- );
- $policyMessage['taskId'] = $row['id'];
- $encodedMessage = json_encode($policyMessage, JSON_UNESCAPED_SLASHES);
- $mqttClient->publish("$topic/Task/" . $row['id'], $encodedMessage, 0, 1);
- $mqttClient->publish('/' . $topic, null, 0, 1);
- }
-}
diff --git a/install/upgrade_to_2.0.php b/install/upgrade_to_2.0.php
new file mode 100644
index 00000000..920191f2
--- /dev/null
+++ b/install/upgrade_to_2.0.php
@@ -0,0 +1,490 @@
+ ALLSTANDARDRIGHT ,
+ PluginFlyvemdmInvitationlog::$rightname => READ,
+ PluginFlyvemdmGeolocation::$rightname => ALLSTANDARDRIGHT | READNOTE | UPDATENOTE,
+ ]);
+ $profileRight->updateProfileRights($profiles_id, $newRights);
+
+ $migration->setContext('flyvemdm');
+ $migration->addConfig([
+ 'default_agent_url' => PLUGIN_FLYVEMDM_AGENT_DOWNLOAD_URL,
+ 'show_wizard' => '0',
+ 'debug_save_inventory' => '0',
+ 'android_bugcollecctor_url' => '',
+ 'android_bugcollector_login' => '',
+ 'android_bugcollector_passwd' => '',
+ 'invitation_deeplink' => PLUGIN_FLYVEMDM_DEEPLINK,
+ ]);
+
+ $config = Config::getConfigurationValues('flyvemdm', ['mqtt_broker_tls']);
+ if (isset($config['mqtt_broker_tls'])) {
+ if ($config['mqtt_broker_tls'] !== '0') {
+ $config['mqtt_broker_tls_port'] = $config['mqtt_broker_port'];
+ $config['mqtt_broker_port'] = '1883';
+ } else {
+ $config['mqtt_broker_tls_port'] = '8883';
+ }
+ // Split TLS setting for client in one hand and backend in the other hand
+ $config['mqtt_tls_for_clients'] = $config['mqtt_broker_tls'];
+ $config['mqtt_tls_for_backend'] = $config['mqtt_broker_tls'];
+ Config::setConfigurationValues('flyvemdm', $config);
+ Config::deleteConfigurationValues('flyvemdm', ['mqtt_broker_tls']);
+ }
+
+ // remove download base URL setting
+ Config::deleteConfigurationValues('flyvemdm', ['deploy_base_url']);
+
+ // update Entity config table
+ $table = 'glpi_plugin_flyvemdm_entityconfigs';
+ $migration->addField($table, 'support_name', 'text', ['after' => 'agent_token_life']);
+ $migration->addField($table, 'support_phone', 'string', ['after' => 'support_name']);
+ $migration->addField($table, 'support_website', 'string', ['after' => 'support_phone']);
+ $migration->addField($table, 'support_email', 'string', ['after' => 'support_website']);
+ $migration->addField($table, 'support_address', 'text', ['after' => 'support_email']);
+ $migration->addKey($table, 'entities_id', 'entities_id');
+
+ // update Agent table
+ $table = 'glpi_plugin_flyvemdm_agents';
+ if (!$DB->fieldExists($table, 'enroll_status')) {
+ $query = "ALTER TABLE `$table`
+ ADD COLUMN `enroll_status` ENUM('enrolled', 'unenrolling', 'unenrolled') NOT NULL DEFAULT 'enrolled' AFTER `lock`";
+ $DB->query($query) or plugin_flyvemdm_upgrade_error($migration);
+ }
+ $migration->addField($table, 'version', 'string', ['after' => 'name']);
+ $migration->addField($table, 'users_id', 'integer', ['after' => 'computers_id']);
+ $migration->addField($table, 'is_online', 'integer', ['after' => 'last_contact']);
+ $migration->addField($table, 'has_system_permission', 'bool', ['after' => 'mdm_type']);
+ $migration->addKey($table, 'computers_id', 'computers_id');
+ $migration->addKey($table, 'users_id', 'users_id');
+ $migration->addKey($table, 'entities_id', 'entities_id');
+ $migration->changeField($table, 'wipe', 'wipe', 'bool');
+ $migration->changeField($table, 'lock', 'lock', 'bool');
+
+ $enumMdmType = PluginFlyvemdmAgent::getEnumMdmType();
+ $currentEnumMdmType = PluginFlyvemdmCommon::getEnumValues($table, 'mdm_type');
+ if (count($currentEnumMdmType) > 0) {
+ // The field exists
+ if (count($currentEnumMdmType) != count($enumMdmType)) {
+ reset($enumMdmType);
+ $defaultValue = key($enumMdmType);
+ $enumMdmType = "'" . implode("', '", array_keys($enumMdmType)) . "'";
+ $query = "ALTER TABLE `$table`
+ CHANGE COLUMN `mdm_type` `mdm_type`
+ ENUM($enumMdmType)
+ NOT NULL DEFAULT '$defaultValue'";
+ $DB->query($query) or plugin_flyvemdm_upgrade_error($migration);
+ }
+ } else {
+ // The field does not exists
+ reset($enumMdmType);
+ $defaultValue = key($enumMdmType);
+ $enumMdmType = "'" . implode("', '", array_keys($enumMdmType)) . "'";
+ $query = "ALTER TABLE `$table`
+ ADD COLUMN `mdm_type`
+ ENUM($enumMdmType)
+ NOT NULL DEFAULT '$defaultValue'";
+ $DB->query($query) or plugin_flyvemdm_upgrade_error($migration);
+ }
+
+ // Create task status table
+ $table = 'glpi_plugin_flyvemdm_taskstatuses';
+ $query = "CREATE TABLE IF NOT EXISTS `$table` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `name` VARCHAR(255) NOT NULL DEFAULT '',
+ `date_creation` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `date_mod` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `plugin_flyvemdm_agents_id` INT(11) NOT NULL DEFAULT '0',
+ `plugin_flyvemdm_tasks_id` INT(11) NOT NULL DEFAULT '0',
+ `status` VARCHAR(255) NOT NULL DEFAULT '',
+ PRIMARY KEY (`id`),
+ KEY `plugin_flyvemdm_agents_id` (`plugin_flyvemdm_agents_id`),
+ KEY `plugin_flyvemdm_tasks_id` (`plugin_flyvemdm_tasks_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";
+ $DB->query($query) or plugin_flyvemdm_upgrade_error($migration);
+
+ $migration->addKey($table, 'plugin_flyvemdm_agents_id', 'plugin_flyvemdm_agents_id');
+ $migration->addKey($table, 'plugin_flyvemdm_tasks_id', 'plugin_flyvemdm_tasks_id');
+
+ // update Policy table
+ $table = 'glpi_plugin_flyvemdm_policies';
+ $migration->addField($table, 'recommended_value', 'string', ['after' => 'default_value']);
+ $migration->addField($table, 'is_android_system', 'bool', ['after' => 'recommended_value']);
+ $migration->addField($table, 'android_min_version', 'string', ['after' => 'is_android_system', 'value' => '0']);
+ $migration->addField($table, 'android_max_version', 'string', ['after' => 'android_min_version', 'value' => '0']);
+ $migration->addField($table, 'apple_min_version', 'string', ['after' => 'android_max_version', 'value' => '0']);
+ $migration->addField($table, 'apple_max_version', 'string', ['after' => 'apple_min_version', 'value' => '0']);
+ $migration->addKey($table, 'group', 'group');
+ $migration->addKey($table, 'plugin_flyvemdm_policycategories_id', 'plugin_flyvemdm_policycategories_id');
+ $migration->dropField($table, 'is_android_policy');
+ $migration->dropField($table, 'is_apple_policy');
+
+ // Rename and update fleet_policy into task
+ $table = 'glpi_plugin_flyvemdm_tasks';
+ $migration->renameTable('glpi_plugin_flyvemdm_fleets_policies', $table);
+ $migration->changeField($table, 'plugin_flyvemdm_fleets_policies_id', 'plugin_flyvemdm_tasks_id',
+ 'integer');
+ $migration->addKey($table, 'plugin_flyvemdm_policies_id', 'plugin_flyvemdm_policies_id');
+
+ // Upgrade schema to apply policies on fleets and agents
+ if (!$DB->fieldExists($table, 'items_id_applied')) {
+ $migration->changeField($table, 'plugin_flyvemdm_fleets_id', 'items_id_applied', 'integer');
+ $migration->dropKey($table, 'plugin_flyvemdm_fleets_id');
+ $migration->addField($table, 'itemtype_applied', 'string', ['after' => 'id']);
+ $migration->addKey($table, ['itemtype_applied', 'items_id_applied'], 'FK_applied');
+ // All tasks already created were applied on fleets
+ $migration->addPostQuery("UPDATE `$table` SET `itemtype_applied` = 'PluginFlyvemdmFleet'");
+ $migration->executeMigration();
+ }
+
+ $table = 'glpi_plugin_flyvemdm_policies';
+ $policies = [
+ 'disableFmRadio',
+ 'disableVoiceMail',
+ 'disableCallAutoAnswer',
+ 'disableVoiceDictation',
+ 'disableUsbOnTheGo',
+ 'resetPassword',
+ 'inventoryFrequency',
+ 'disableSmsMms',
+ 'disableStreamVoiceCall',
+ 'disableCreateVpnProfiles',
+ ];
+ $tasksTable = 'glpi_plugin_flyvemdm_tasks';
+ $fleetTable = 'glpi_plugin_flyvemdm_fleets';
+ $agentsTable = 'glpi_plugin_flyvemdm_agents';
+ $request = [
+ 'FIELDS' => [
+ $table => ['symbol'],
+ $tasksTable => ['id', 'itemtype_applied', 'items_id_applied'],
+ $fleetTable => ['entities_id'],
+ ],
+ 'FROM' => $table,
+ 'INNER JOIN' => [
+ $tasksTable => [
+ 'FKEY' => [
+ $tasksTable => 'plugin_flyvemdm_policies_id',
+ $table => 'id',
+ ],
+ ],
+ ],
+ 'LEFT JOIN' => [
+ $fleetTable => [
+ 'itemtype_applied' => 'PluginFlyvemdmFleet',
+ 'FKEY' => [
+ $tasksTable => 'items_id_applied',
+ $fleetTable => 'id',
+ ],
+ ],
+ $agentsTable => [
+ 'itemtype_applied' => 'PluginFlyvemdmAgent',
+ 'FKEY' => [
+ $tasksTable => 'items_id_applied',
+ $agentsTable => 'id',
+ ],
+ ],
+ ],
+ 'WHERE' => [
+ 'symbol' => $policies,
+ ],
+ ];
+ $result = $DB->request($request);
+ if (count($result) > 0) {
+ $mqttClient = PluginFlyvemdmMqttclient::getInstance();
+ foreach ($result as $data) {
+ switch ($data['itemtype_applied']) {
+ case PluginFlyvemdmFleet::class:
+ $type = 'fleet';
+ $entityId = $data['entities_id'];
+ break;
+
+ case PluginFlyvemdmAgent::class:
+ $agent = new PluginFlyvemdmAgent();
+ $agent->getFromDB($data['items_id_applied']);
+ $type = 'agent';
+ $entityId = $agent->getEntityID();
+ break;
+
+ default:
+ $type = '';
+ }
+ if ($type === '') {
+ continue;
+ }
+ $topic = implode('/', [
+ '/',
+ $entityId,
+ $type,
+ $data['items_id_applied'],
+ 'Policy',
+ $data['symbol'],
+ 'Task',
+ $data['id']
+ ]);
+ $mqttClient->publish($topic, null, 0, 1);
+ }
+ }
+ $policiesStr = implode("','", $policies);
+ $migration->addPostQuery("DELETE FROM `$table` WHERE `symbol` IN ('" . $policiesStr . "')");
+
+ // update Applications table
+ $table = 'glpi_plugin_flyvemdm_packages';
+ $migration->addField($table, 'parse_status', "enum('pending', 'parsed', 'failed') NOT NULL DEFAULT 'pending'",
+ ['after' => 'dl_filename', 'default' => 'pending']);
+ $migration->addfield($table, 'name', 'string', ['after' => 'id']);
+ $migration->migrationOneTable($table);
+ $migration->dropField($table, 'filesize');
+ $migration->addField($table, 'name', 'string', ['after' => 'id']);
+ $migration->addKey($table, 'entities_id', 'entities_id');
+ $migration->addPostQuery("UPDATE `$table` SET `parse_status` = 'parsed'");
+ $migration->addPostQuery("UPDATE `$table` SET `name` = `package_name`");
+
+ $result = $DB->request(['FROM' => $table, 'LIMIT' => '1']);
+ if ($result->count() > 0) {
+ $result->rewind();
+ $row = $result->current();
+ if (strpos($row['filename'], 'flyvemdm/package/') !== 0) {
+ // If there is at least one package and the path does starts with the new prefix, then update all the table
+ $migration->addPostQuery("UPDATE `$table` SET `filename` = CONCAT('flyvemdm/package/', `filename`)");
+ }
+ }
+
+ $table = 'glpi_plugin_flyvemdm_files';
+ $migration->addKey($table, 'entities_id', 'entities_id');
+ $migration->addField($table, 'comment', 'text');
+
+ // Add display preferences for PluginFlyvemdmFile
+ $query = "SELECT * FROM `glpi_displaypreferences`
+ WHERE `itemtype` = 'PluginFlyvemdmFile'
+ AND `users_id`='0'";
+ $result=$DB->query($query);
+ if ($DB->numrows($result) == '0') {
+ $query = "INSERT INTO `glpi_displaypreferences` (`id`, `itemtype`, `num`, `rank`, `users_id`)
+ VALUES (NULL, 'PluginFlyvemdmFile', '1', '1', '0'),
+ (NULL, 'PluginFlyvemdmFile', '4', '2', '0');";
+ $DB->query($query);
+ }
+
+ $table = 'glpi_plugin_flyvemdm_fleets';
+ $migration->addField($table, 'is_recursive', 'bool');
+ $migration->addKey($table, 'entities_id', 'entities_id');
+
+ $table = 'glpi_plugin_flyvemdm_geolocations';
+ $migration->addKey($table, 'computers_id', 'computers_id');
+
+ $table = 'glpi_plugin_flyvemdm_mqttacls';
+ $migration->addKey($table, 'plugin_flyvemdm_mqttusers_id', 'plugin_flyvemdm_mqttusers_id');
+
+ $table = 'glpi_plugin_flyvemdm_policycategories';
+ $migration->addKey($table, 'plugin_flyvemdm_policycategories_id', 'plugin_flyvemdm_policycategories_id');
+
+ // Create invitation log table
+ $table = 'glpi_plugin_flyvemdm_invitationlogs';
+ $query = "CREATE TABLE IF NOT EXISTS `$table` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `plugin_flyvemdm_invitations_id` int(11) NOT NULL DEFAULT '0',
+ `date_creation` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `event` varchar(255) NOT NULL DEFAULT '',
+ PRIMARY KEY (`id`),
+ INDEX `plugin_flyvemdm_invitations_id` (`plugin_flyvemdm_invitations_id`),
+ INDEX `date_creation` (`date_creation`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";
+ $DB->query($query) or plugin_flyvemdm_upgrade_error($migration);
+ $migration->addKey($table, 'plugin_flyvemdm_invitations_id', 'plugin_flyvemdm_invitations_id');
+
+ $table = 'glpi_plugin_flyvemdm_invitations';
+ if (!$DB->fieldExists($table, 'name')) {
+ $invitationName = _n('Invitation', 'Invitations', 1, 'flyvemdm');
+ $migration->addField($table, 'name', 'string', ['after' => 'id']);
+ $migration->addPostQuery("UPDATE `$table` SET `name` = '$invitationName'");
+ }
+ $migration->addKey($table, 'users_id', 'users_id');
+ $migration->addKey($table, 'entities_id', 'entities_id');
+ $migration->addKey($table, 'documents_id', 'documents_id');
+
+ // drop Mqtt Update queue
+ $cronTask = new CronTask();
+ $cronTask->deleteByCriteria(['itemtype' => 'PluginFlyvemdmMqttupdatequeue']);
+ $table = 'glpi_plugin_flyvemdm_mqttupdatequeues';
+ $migration->dropTable($table);
+
+ // Fix PascalCase symbols
+ $query = "UPDATE `glpi_plugin_flyvemdm_policies`
+ SET `symbol` = 'maximumFailedPasswordsForWipe'
+ WHERE `symbol`='MaximumFailedPasswordsForWipe'";
+ $DB->query($query);
+ $query = "UPDATE `glpi_plugin_flyvemdm_policies`
+ SET `symbol` = 'maximumTimeToLock'
+ WHERE `symbol`='MaximumTimeToLock'";
+ $DB->query($query);
+
+ // change MQTT topics tree layout : remove leading slash
+ $mqttClient = PluginFlyvemdmMqttclient::getInstance();
+ $request = [
+ 'FIELDS' => [
+ 'glpi_plugin_flyvemdm_agents' => ['entities_id'],
+ 'glpi_computers' => ['serial'],
+ ],
+ 'FROM' => 'glpi_plugin_flyvemdm_agents',
+ 'INNER JOIN' => [
+ 'glpi_computers' => ['FKEY' => [
+ 'glpi_plugin_flyvemdm_agents' => 'computers_id',
+ 'glpi_computers' => 'id'
+ ]]
+ ],
+ 'WHERE' => ['lock' => ['<>' => '0']]
+ ];
+ $mqttMessage = ['lock' => 'now'];
+ $mqttMessage = json_encode($mqttMessage, JSON_UNESCAPED_SLASHES);
+ foreach ($DB->request($request) as $row) {
+ $topic = implode('/', [
+ $row['entities_id'],
+ 'agent',
+ $row['serial'],
+ 'Command',
+ 'Lock',
+ ]);
+ $mqttClient->publish($topic, $mqttMessage, 0, 1);
+ $mqttClient->publish('/' . $topic, null, 0, 1);
+ }
+
+ // re-use previous request array
+ $request['WHERE'] = ['wipe' => ['<>' => '0']];
+ $mqttMessage = ['wipe' => 'now'];
+ $mqttMessage = json_encode($mqttMessage, JSON_UNESCAPED_SLASHES);
+ foreach ($DB->request($request) as $row) {
+ $topic = implode('/', [
+ $row['entities_id'],
+ 'agent',
+ $row['serial'],
+ 'Command',
+ 'Wipe',
+ ]);
+ $mqttClient->publish($topic, $mqttMessage, 0, 1);
+ $mqttClient->publish('/' . $topic, null, 0, 1);
+ }
+
+ // re-use previous request array
+ $request['WHERE'] = ['enroll_status' => ['=' => 'unenrolling']];
+ $mqttMessage = ['unenroll' => 'now'];
+ $mqttMessage = json_encode($mqttMessage, JSON_UNESCAPED_SLASHES);
+ foreach ($DB->request($request) as $row) {
+ $topic = implode('/', [
+ $row['entities_id'],
+ 'agent',
+ $row['serial'],
+ 'Command',
+ 'Unenroll',
+ ]);
+ $mqttClient->publish($topic, $mqttMessage, 0, 1);
+ $mqttClient->publish('/' . $topic, null, 0, 1);
+ }
+
+ $request = [
+ 'FIELDS' => [
+ 'glpi_plugin_flyvemdm_tasks' => ['id', 'itemtype_applied', 'items_id_applied', 'plugin_flyvemdm_policies_id', 'itemtype', 'items_id', 'value'],
+ 'glpi_plugin_flyvemdm_policies' => ['symbol'],
+ 'glpi_plugin_flyvemdm_fleets' => ['entities_id']
+ ],
+ 'FROM' => 'glpi_plugin_flyvemdm_tasks',
+ 'INNER JOIN' => [
+ 'glpi_plugin_flyvemdm_policies' => [
+ 'FKEY' => [
+ 'glpi_plugin_flyvemdm_tasks' => 'plugin_flyvemdm_policies_id',
+ 'glpi_plugin_flyvemdm_policies' => 'id'
+ ]
+ ],
+ 'glpi_plugin_flyvemdm_fleets' => [
+ 'FKEY' => [
+ 'glpi_plugin_flyvemdm_tasks' => 'items_id_applied',
+ 'glpi_plugin_flyvemdm_fleets' => 'id'
+ ]
+ ]
+ ],
+ 'WHERE' => [
+ 'glpi_plugin_flyvemdm_tasks.itemtype_applied' => 'PluginFlyvemdmFleet'
+ ]
+ ];
+ foreach ($DB->request($request) as $row) {
+ switch ($row['itemtype_applied']) {
+ case PluginFlyvemdmFleet::class:
+ $type = 'fleet';
+ break;
+
+ case PluginFlyvemdmAgent::class:
+ $type = 'agent';
+ break;
+
+ default:
+ $type = '';
+ }
+ if ($type === '') {
+ continue;
+ }
+ $topic = implode('/', [
+ $row['entities_id'],
+ 'fleet',
+ $row['items_id_applied'],
+ 'Policy',
+ $row['symbol'],
+ ]);
+ $policyFactory = new PluginFlyvemdmPolicyFactory();
+ $appliedPolicy = $policyFactory->createFromDBByID($row['plugin_flyvemdm_policies_id']);
+ $policyMessage = $appliedPolicy->getMqttMessage(
+ $row['value'],
+ $row['itemtype'],
+ $row['items_id']
+ );
+ $policyMessage['taskId'] = $row['id'];
+ $encodedMessage = json_encode($policyMessage, JSON_UNESCAPED_SLASHES);
+ $mqttClient->publish("$topic/Task/" . $row['id'], $encodedMessage, 0, 1);
+ $mqttClient->publish('/' . $topic, null, 0, 1);
+ }
+ }
+}
\ No newline at end of file
diff --git a/setup.php b/setup.php
index a097266c..2e62b0ff 100644
--- a/setup.php
+++ b/setup.php
@@ -29,7 +29,10 @@
* ------------------------------------------------------------------------------
*/
+// Version of the plugin
define('PLUGIN_FLYVEMDM_VERSION', 'develop');
+// Schema version of this version
+define('PLUGIN_FLYVEMDM_SCHEMA_VERSION', '2.0');
// is or is not an official release of the plugin
define('PLUGIN_FLYVEMDM_IS_OFFICIAL_RELEASE', false);
// Minimal GLPI version, inclusive
diff --git a/tests/src/Flyvemdm/Tests/CommonTestCase.php b/tests/src/Flyvemdm/Tests/CommonTestCase.php
index cbfa8f5c..6ad77356 100644
--- a/tests/src/Flyvemdm/Tests/CommonTestCase.php
+++ b/tests/src/Flyvemdm/Tests/CommonTestCase.php
@@ -186,6 +186,56 @@ protected function createFleet($input) {
return $fleet;
}
+ /**
+ * @param array $input input data
+ * @return \PluginFlyvemdmTask
+ */
+ protected function createTask($input) {
+ $task = $this->newMockInstance(\PluginFlyvemdmTask::class, '\MyMock');
+ $task->getMockController()->post_addItem = function () {};
+ $taskId = $task->add($input);
+ $this->boolean($task->isNewItem())->isFalse();
+
+ $task = new \PluginFlyvemdmTask();
+ $task->getFromDB($taskId);
+
+ return $task;
+ }
+
+ /**
+ * @param string $policySymbol
+ * @return array
+ */
+ protected function createFleetAndTask($policySymbol = 'storageEncryption') {
+ $fleet = $this->createFleet(['name' => $this->getUniqueString()]);
+ $policy = $this->newMockInstance(\PluginFlyvemdmPolicy::class, '\MyMock');
+ $policy->getFromDbBySymbol($policySymbol);
+ $task = $this->createTask([
+ 'value' => '0',
+ 'plugin_flyvemdm_policies_id' => $policy->getID(),
+ 'itemtype_applied' => \PluginFlyvemdmFleet::class,
+ 'items_id_applied' => $fleet->getID(),
+ 'itemtype' => '',
+ 'items_id' => '',
+ ]);
+ return [$fleet, $task];
+ }
+
+ /**
+ * @return array
+ */
+ protected function createAgentTaskstatus() {
+ list($fleet, $task) = $this->createFleetAndTask();
+ $agent = $this->createAgent();
+ $agent->update([\PluginFlyvemdmFleet::getForeignKeyField() => $fleet->getID()]);
+ $taskStatus = $this->newMockInstance(\PluginFlyvemdmTaskStatus::class, '\MyMock');
+ $taskStatus->getFromDBByCrit([
+ \PluginFlyvemdmAgent::getForeignKeyField() => $agent->getID(),
+ \PluginFlyvemdmTask::getForeignKeyField() => $task->getID(),
+ ]);
+ return [$taskStatus, $fleet, $task];
+ }
+
/**
* Create a new enrolled agent in the database
*
diff --git a/tests/suite-install/Config.php b/tests/suite-install/Config.php
index c77b154e..c6490f82 100644
--- a/tests/suite-install/Config.php
+++ b/tests/suite-install/Config.php
@@ -50,7 +50,8 @@ public function beforeTestMethod($method) {
case 'testUpgradePlugin':
$this->olddb = new \DB();
- $this->olddb->dbdefault = 'glpiupgradetest';
+ $this->string(getenv('OLDDBNAME'));
+ $this->olddb->dbdefault = getenv('OLDDBNAME');
$this->olddb->connect();
$this->boolean($this->olddb->connected)->isTrue();
break;
@@ -113,6 +114,16 @@ public function testInstallPlugin() {
$plugin->activate($plugin->fields['id']);
$this->boolean($plugin->isActivated($pluginName))->isTrue('Cannot enable the plugin');
+ // Check version and schema version are in the configuration
+ $config = \Config::getConfigurationValues(
+ $pluginName, [
+ 'version',
+ 'schema_version'
+ ]
+ );
+ $this->string($config['version']);
+ $this->string($config['schema_version']);
+
// Enable debug mode for enrollment messages
\Config::setConfigurationValues($pluginName, ['debug_enrolment' => '1']);
diff --git a/tests/suite-integration/ProfileRight.php b/tests/suite-integration/ProfileRight.php
index e32186d4..cf18d42a 100644
--- a/tests/suite-integration/ProfileRight.php
+++ b/tests/suite-integration/ProfileRight.php
@@ -94,6 +94,8 @@ public function testSuperAdminProfileRights() {
\PluginFlyvemdmInvitation::$rightname => ALLSTANDARDRIGHT,
\PluginFlyvemdmInvitationLog::$rightname => READ,
\PluginFlyvemdmTaskstatus::$rightname => READ,
+ \PluginFlyvemdmFDroidApplication::$rightname => READ | UPDATE | READNOTE | UPDATENOTE,
+ \PluginFlyvemdmFDroidMarket::$rightname => ALLSTANDARDRIGHT | READNOTE | UPDATENOTE,
];
$profileRight = $this->newTestedInstance();
diff --git a/tests/suite-uninstall/Config.php b/tests/suite-uninstall/Config.php
index 4be84def..6b001826 100644
--- a/tests/suite-uninstall/Config.php
+++ b/tests/suite-uninstall/Config.php
@@ -37,7 +37,6 @@ class Config extends CommonTestCase
{
public function beforeTestMethod($method) {
- $this->resetState();
parent::beforeTestMethod($method);
$this->setupGLPIFramework();
}
diff --git a/tests/suite-unit/PluginFlyvemdmFdroidApplication.php b/tests/suite-unit/PluginFlyvemdmFdroidApplication.php
new file mode 100644
index 00000000..3955e7f6
--- /dev/null
+++ b/tests/suite-unit/PluginFlyvemdmFdroidApplication.php
@@ -0,0 +1,290 @@
+login('glpi', 'glpi');
+ break;
+ }
+ }
+
+ public function afterTestMethod($method) {
+ switch ($method) {
+ case 'testPrepareInputForAdd':
+ case 'testPrepareInputForUpdate':
+ case 'testDisplayTabContentForItem':
+ case 'testGetTabNameForItem':
+ parent::afterTestMethod($method);
+ \Session::destroy();
+ break;
+ }
+ }
+
+ /**
+ * @tags testGetEnumImportStatus
+ */
+ public function testGetEnumImportStatus() {
+ $output = \PluginFlyvemdmFDroidApplication::getEnumImportStatus();
+ $this->array($output)->size->isEqualTo(3);
+ $this->array($output)->hasKeys([
+ 'no_import',
+ 'to_import',
+ 'imported',
+ ]);
+ }
+
+ /**
+ * @tags testGetMenuPicture
+ */
+ public function testGetMenuPicture() {
+ $output = \PluginFlyvemdmFDroidApplication::getMenuPicture();
+ $this->string($output)->isEqualTo('');
+ }
+
+ public function providerGetTypeName() {
+ return [
+ 'none' => [
+ 0,
+ 'F-Droid applications',
+ ],
+ 'singular' => [
+ 1,
+ 'F-Droid application',
+ ],
+ 'plural' => [
+ 2,
+ 'F-Droid applications',
+ ],
+ ];
+ }
+
+ /**
+ * @tags testGetTypeName
+ * @dataProvider providerGetTypeName
+ */
+ public function testGetTypeName($count, $expected) {
+ $output = \PluginFlyvemdmFDroidApplication::getTypeName($count);
+ $this->string($output)->isEqualTo($expected);
+ }
+
+ public function providerGetTabNameForItem() {
+ return [
+ [
+ new \PluginFlyvemdmFDroidMarket(),
+ 0,
+ 'F-Droid applications',
+ ],
+ [
+ new \PluginFlyvemdmFDroidMarket(),
+ 1,
+ '',
+ ],
+ [
+ new \PluginFlyvemdmInvitation(),
+ 0,
+ '',
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider providerGetTabNameForItem
+ * @tags testGetTabNameForItem
+ */
+ public function testGetTabNameForItem($item, $withTemplate, $expected) {
+ $instance = $this->newTestedInstance();
+ $output = $instance->getTabNameForItem($item, $withTemplate);
+ $this->string($output)->isEqualTo($expected);
+ }
+
+ public function providerDisplayTabContentForItem() {
+ return [
+ 'no app for a market' => [
+ 'item' => new \PluginFlyvemdmFDroidMarket(),
+ 'expected' => 'There is no application yet',
+ ],
+ ];
+ }
+
+ /**
+ * @tags testGetAdditionalLinks
+ */
+ public function testGetAdditionalLinks() {
+ $instance = $this->newTestedInstance();
+ $output = $instance->getAdditionalLinks();
+ $this->array($output)->size->isEqualTo(0);
+ }
+
+ /**
+ * @tags testGetRights
+ */
+ public function testGetRights() {
+ $instance = $this->newTestedInstance();
+ $result = $instance->getRights();
+ $this->array($result)->containsValues([
+ 'Read',
+ 'Update',
+ ])
+ ->hasKeys([READ, UPDATE]);
+ }
+
+ public function providerCronInfo() {
+ return [
+ [
+ 'DownloadApplications',
+ ['description' => __('download applications from the market')],
+ ],
+ [
+ 'SomethingElse',
+ null,
+ ],
+ ];
+ }
+
+ /**
+ * @tags testCronInfo
+ * @dataProvider providerCronInfo
+ */
+ public function testCronInfo($name, $expected) {
+ $output = \PluginFlyvemdmFDroidApplication::cronInfo($name);
+ if ($expected !== null) {
+ $this->array($output)->size->isEqualTo(1);
+ $this->array($output)
+ ->hasKey('description')
+ ->contains('download applications from the market');
+ } else {
+ $this->variable($output)->isNull();
+ }
+ }
+
+ public function providerTestImport() {
+ $instance = $this->newTestedInstance();
+ $applicationName = 'I exist' . $this->getUniqueString();
+ $applicationName2 = 'I miss' . $this->getUniqueString();
+ $id = $instance->add([
+ 'name' => $applicationName
+ ]);
+ $this->boolean($instance->isNewItem())->isFalse();
+ $market = new \PluginFlyvemdmFDroidMarket();
+ $market->add([
+ 'name' => $this->getUniqueString(),
+ ]);
+ $this->boolean($market->isNewItem())->isFalse();
+ return [
+ 'no name' => [
+ 'input' => [
+ 'plugin_flyvemdm_fdroidmarkets_id' => $market->getID(),
+ ],
+ 'expected' => false,
+ ],
+ 'no repository' => [
+ 'input' => [
+ 'name' => 'something',
+ ],
+ 'expected' => false,
+ ],
+ 'existing item' => [
+ 'input' => [
+ 'name' => $applicationName,
+ 'plugin_flyvemdm_fdroidmarkets_id' => $market->getID(),
+ ],
+ 'expected' => $id,
+ ],
+ 'not existing item' => [
+ 'input' => [
+ 'name' => $applicationName2,
+ 'plugin_flyvemdm_fdroidmarkets_id' => $market->getID(),
+ ],
+ 'expected' => $id,
+ ],
+ ];
+ }
+
+ /**
+ * @tags testImport
+ * @dataProvider providerTestImport
+ */
+ public function testImport($input, $expected) {
+ $output = \PluginFlyvemdmFDroidApplication::import($input);
+ if ($expected === false) {
+ $this->variable($output)->isEqualTo($expected);
+ $this->boolean($output);
+ } else {
+ $this->integer($output);
+ $instance = $this->newTestedInstance();
+ $this->boolean($instance->getFromDB($output))->isTrue();
+ }
+ }
+
+ public function providerPrepareInputForUpdate() {
+ return [
+ 'no checks' => [
+ 'input' => [
+ '_skip_checks' => '',
+ 'something' => 'random',
+ ],
+ 'expected' => [
+ '_skip_checks' => '',
+ 'something' => 'random',
+ ]
+ ],
+ 'checks' => [
+ 'input' => [
+ 'something' => 'random',
+ ],
+ 'expected' => [
+ 'something' => 'random',
+ 'import_status' => 'no_import',
+ ]
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider providerPrepareInputForUpdate
+ */
+ public function testPrepareInputForUpdate($input, $expected) {
+ $instance = $this->newTestedInstance();
+ $output = $instance->prepareInputForUpdate($input);
+ $this->array($output)->size->isEqualTo(count($expected));
+ $this->array($output)->hasKeys(array_keys($expected));
+ }
+}
\ No newline at end of file
diff --git a/tests/suite-unit/PluginFlyvemdmPackage.php b/tests/suite-unit/PluginFlyvemdmPackage.php
index 01b34cd8..dc0e6e8d 100644
--- a/tests/suite-unit/PluginFlyvemdmPackage.php
+++ b/tests/suite-unit/PluginFlyvemdmPackage.php
@@ -138,4 +138,12 @@ public function testPostGetFromDB($argument) {
}
}
-}
\ No newline at end of file
+ public function testGetSpecificValueToDisplay() {
+ // @see http://png-pixel.com/
+ $png = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==';
+
+ $instance = $this->newTestedInstance();
+ $output = $instance::getSpecificValueToDisplay('icon', ['icon' => $png]);
+ $this->string($output)->isEqualTo('
');
+ }
+}
diff --git a/tpl/agentComputerInfo.html.twig b/tpl/agentComputerInfo.html.twig
index 29a8b6fc..013b8596 100644
--- a/tpl/agentComputerInfo.html.twig
+++ b/tpl/agentComputerInfo.html.twig
@@ -1,6 +1,6 @@
{{ __('Flyve MDM') }} | +{{ __('Flyve MDM', 'flyvemdm') }} |
---|