├── .gitignore ├── airwatch.png ├── locales ├── cs_CZ.mo ├── en_GB.mo ├── fr_FR.mo ├── pt_PT.mo ├── airwatch.pot ├── en_GB.po ├── pt_PT.po ├── cs_CZ.po └── fr_FR.po ├── .tx └── config ├── composer.json ├── tools └── HEADER ├── .github └── workflows │ └── release.yml ├── front ├── detail.form.php └── config.form.php ├── README.md ├── setup.php ├── airwatch.xml ├── inc ├── compliance.class.php ├── rest.class.php ├── config.class.php ├── xml.class.php ├── airwatch.class.php └── detail.class.php ├── hook.php ├── LICENSE └── composer.lock /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | vendor/ 3 | .gh_token 4 | -------------------------------------------------------------------------------- /airwatch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InfotelGLPI/airwatch/master/airwatch.png -------------------------------------------------------------------------------- /locales/cs_CZ.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InfotelGLPI/airwatch/master/locales/cs_CZ.mo -------------------------------------------------------------------------------- /locales/en_GB.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InfotelGLPI/airwatch/master/locales/en_GB.mo -------------------------------------------------------------------------------- /locales/fr_FR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InfotelGLPI/airwatch/master/locales/fr_FR.mo -------------------------------------------------------------------------------- /locales/pt_PT.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InfotelGLPI/airwatch/master/locales/pt_PT.mo -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com 3 | 4 | [glpi-plugin-airwatch.airwatch-pot] 5 | file_filter = locales/.po 6 | source_file = locales/airwatch.pot 7 | source_lang = en 8 | type = PO 9 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "php": "^7.2", 4 | "ext-curl": "*" 5 | }, 6 | "require-dev": { 7 | "glpi-project/tools": "^0.4" 8 | }, 9 | "config": { 10 | "optimize-autoloader": true, 11 | "platform": { 12 | "php": "7.2.0" 13 | }, 14 | "sort-packages": true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tools/HEADER: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------- 2 | Airwatch plugin for GLPI 3 | ------------------------------------------------------------------------- 4 | 5 | LICENSE 6 | 7 | This file is part of Airwatch. 8 | 9 | Airwatch is free software; you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation; either version 2 of the License, or 12 | (at your option) any later version. 13 | 14 | Airwatch is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Airwatch. If not, see . 21 | ------------------------------------------------------------------------- 22 | @copyright Copyright (C) 2016-2022 by Teclib'. 23 | @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html 24 | @link https://github.com/pluginsGLPI/airwatch 25 | ------------------------------------------------------------------------- 26 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: "Plugin release" 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*' 7 | 8 | jobs: 9 | create-release: 10 | name: "Create release" 11 | runs-on: "ubuntu-latest" 12 | steps: 13 | - name: "Extract tag name" 14 | run: | 15 | echo "tag_name=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV 16 | - name: "Checkout" 17 | uses: "actions/checkout@v2" 18 | - name: "Build package" 19 | id: "build-package" 20 | uses: "glpi-project/tools/github-actions/build-package@0.1.15" 21 | with: 22 | plugin-version: ${{ env.tag_name }} 23 | - name: "Create release" 24 | id: "create-release" 25 | uses: "actions/create-release@v1" 26 | env: 27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 28 | with: 29 | tag_name: ${{ env.tag_name }} 30 | release_name: ${{ env.tag_name }} 31 | draft: true 32 | - name: "Attach package to release" 33 | uses: "actions/upload-release-asset@v1" 34 | env: 35 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 36 | with: 37 | upload_url: ${{ steps.create-release.outputs.upload_url }} 38 | asset_path: ${{ steps.build-package.outputs.package-path }} 39 | asset_name: ${{ steps.build-package.outputs.package-basename }} 40 | asset_content_type: " application/x-bzip2" 41 | -------------------------------------------------------------------------------- /front/detail.form.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @copyright Copyright (C) 2016-2022 by Teclib'. 26 | * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html 27 | * @link https://github.com/pluginsGLPI/airwatch 28 | * ------------------------------------------------------------------------- 29 | */ 30 | 31 | include ("../../../inc/includes.php"); 32 | 33 | if (isset($_POST['update']) && isset($_POST['aw_device_id'])) { 34 | PluginAirwatchAirwatch::doOneDeviceInventory($_POST['aw_device_id']); 35 | } 36 | Html::back(); 37 | -------------------------------------------------------------------------------- /front/config.form.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @copyright Copyright (C) 2016-2022 by Teclib'. 26 | * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html 27 | * @link https://github.com/pluginsGLPI/airwatch 28 | * ------------------------------------------------------------------------- 29 | */ 30 | 31 | include ("../../../inc/includes.php"); 32 | 33 | $config = new PluginAirwatchConfig(); 34 | 35 | if (isset($_POST['test'])) { 36 | $result = PluginAirwatchRest::testConnection(); 37 | if ($result['status'] == AIRWATCH_API_RESULT_OK) { 38 | Session::addMessageAfterRedirect("Connection successful", true, INFO, true); 39 | } else { 40 | $message = "Connection error: ".$result['message']; 41 | Session::addMessageAfterRedirect($message, true, ERROR, true); 42 | } 43 | Html::back(); 44 | } 45 | if (isset($_POST["update"])) { 46 | $config->update($_POST); 47 | Html::back(); 48 | } else { 49 | 50 | Html::header(__("Airwatch", "airwatch"), $_SERVER['PHP_SELF'], "plugins", "airwatch", 51 | "config"); 52 | 53 | Session::checkRight("config", UPDATE); 54 | $config->showForm(); 55 | 56 | Html::footer(); 57 | 58 | } 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Airwatch GLPi plugin 2 | 3 | Airwatch connector for GLPi made by Teclib'. 4 | 5 | This plugin imports inventory data from Airwatch to GLPi. 6 | For more information, please see http://teclib-edition.com 7 | 8 | ## Contributing to the plugin 9 | 10 | To declare issues or feature requests, please go to [Github](https://github.com/pluginsGLPI/airwatch). 11 | To help translating the plugin, please join [Transifex](http://transifex.com). 12 | 13 | ## Prerequisites 14 | 15 | * php curl extension must be installed. 16 | * GLPi 9.1 or higher is required. 17 | * FusionInventory plugin must be installed and enabled. 18 | * FI4GLPI version 0.90+1.3 or lated is required, otherwise you must patch the source code with the following commit : 19 | ``` 20 | ``` 21 | 22 | ## How does it work 23 | 24 | The plugin requests Airwatch REST API for: 25 | 26 | * general informations (name, OS, etc) 27 | * network informations 28 | * software 29 | * airwatch specific information (enrollement, compliance and comprimse checks, etc) 30 | 31 | A XML inventory file is done using the data above, and sent to FusionInventory, using curl. 32 | Computers are then created, representing Airwatch devices. 33 | 34 | For each device managed by Airwatch, an "Airwatch" tab is displayed in GLPi. This tab shows Airwatch specific informtions, and allows user to force an inventory 35 | 36 | ## Rights 37 | 38 | There's no specific right for the plugin. 39 | You need, at least, to have the right to see a computer to access Airwatch informations. 40 | To force an Airwatch inventory, you need the right to update a computer. 41 | 42 | ## Configuration 43 | 44 | Configuration options: 45 | 46 | * Service URL: URL to send inventories to FusionInventory (by default `http://glpi/plugins/fusioninventory/`) 47 | * Airwatch web service URL: the REST API URL 48 | * Airwatch console URL: Airwatch web console URL (used to generate a direct Airwatch link for each Airwatch device) 49 | * Username: Aiwatch user used to access the API 50 | * Password: the password for the user 51 | * API Key: a string defined in the Airwatch administration panel 52 | * Skip SSL checks: access REST API without checking for SSL certificate 53 | 54 | ## Contributing 55 | 56 | * Open a ticket for each bug/feature so it can be discussed 57 | * Follow [development guidelines](http://glpi-developer-documentation.readthedocs.io/en/latest/plugins/index.html) 58 | * Refer to [GitFlow](http://git-flow.readthedocs.io/) process for branching 59 | * Work on a new branch on your own fork 60 | * Open a PR that will be reviewed by a developer 61 | -------------------------------------------------------------------------------- /setup.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @copyright Copyright (C) 2016-2022 by Teclib'. 26 | * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html 27 | * @link https://github.com/pluginsGLPI/airwatch 28 | * ------------------------------------------------------------------------- 29 | */ 30 | 31 | define ('AIRWATCH_API_RESULT_OK', 'ok'); 32 | define ('AIRWATCH_API_RESULT_ERROR', 'ko'); 33 | define ('AIRWATCH_USER_AGENT', 'Airwatch-Connector-1.1'); 34 | define ('PLUGIN_AIRWATCH_VERSION', '1.5.0'); 35 | 36 | // Minimal GLPI version, inclusive 37 | define('PLUGIN_AIRWATCH_MIN_GLPI', '9.5'); 38 | // Maximum GLPI version, exclusive 39 | define('PLUGIN_AIRWATCH_MAX_GLPI', '9.6'); 40 | 41 | function plugin_init_airwatch() { 42 | global $PLUGIN_HOOKS,$CFG_GLPI,$LANG; 43 | $PLUGIN_HOOKS['csrf_compliant']['airwatch'] = true; 44 | 45 | $plugin = new Plugin(); 46 | if ($plugin->isActivated('airwatch')) { 47 | 48 | Plugin::registerClass('PluginAirwatchDetail', ['addtabon' => ['Computer']]); 49 | 50 | $PLUGIN_HOOKS['use_massive_action']['airwatch'] = 1; 51 | 52 | $PLUGIN_HOOKS['config_page']['airwatch'] = 'front/config.form.php'; 53 | $PLUGIN_HOOKS['item_purge']['order'] = [ 54 | 'Computer' => ['PluginAirwatchDetail', 'cleanOnPurge']]; 55 | $PLUGIN_HOOKS['import_item']['airwatch'] 56 | = ['Computer' => ['Plugin']]; 57 | $PLUGIN_HOOKS['autoinventory_information']['airwatch'] 58 | = ['Computer' => ['PluginAirwatchDetail', 'showInfo']]; 59 | 60 | //FusionInventory hooks 61 | $PLUGIN_HOOKS['fusioninventory_inventory']['airwatch'] 62 | = ['PluginAirwatchAirwatch', 'updateInventory']; 63 | $PLUGIN_HOOKS['fusioninventory_addinventoryinfos']['airwatch'] 64 | = ['PluginAirwatchAirwatch', 'addInventoryInfos']; 65 | } 66 | } 67 | 68 | function plugin_version_airwatch() { 69 | return [ 70 | 'name' => __("GLPi Airwatch Connector", 'airwatch'), 71 | 'version' => PLUGIN_AIRWATCH_VERSION, 72 | 'author' => "Teclib'", 73 | 'license' => 'GPLv2+', 74 | 'homepage' => 'https://github.com/pluginsglpi/airwatch', 75 | 'requirements' => [ 76 | 'glpi' => [ 77 | 'min' => PLUGIN_AIRWATCH_MIN_GLPI, 78 | 'max' => PLUGIN_AIRWATCH_MAX_GLPI, 79 | 'plugins' => [ 80 | 'fusioninventory', 81 | ], 82 | ], 83 | 'php' => [ 84 | 'exts' => [ 85 | 'curl' => [ 86 | 'required' => true, 87 | ] 88 | ] 89 | ] 90 | ] 91 | ]; 92 | } 93 | -------------------------------------------------------------------------------- /airwatch.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Airwatch connector 4 | airwatch 5 | stable 6 | https://raw.githubusercontent.com/pluginsGLPI/airwatch/master/airwatch.png 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | https://github.com/pluginsGLPI/airwatch 20 | https://github.com/pluginsGLPI/airwatch/releases 21 | https://github.com/pluginsGLPI/airwatch/issues 22 | https://raw.githubusercontent.com/pluginsGLPI/airwatch/master/README.md 23 | 24 | Teclib 25 | Walid Nouh 26 | 27 | 28 | 29 | 1.5.0 30 | ~9.5.0 31 | https://github.com/pluginsGLPI/airwatch/releases/download/1.5.0/glpi-airwatch-1.5.0.tar.bz2 32 | 33 | 34 | 1.4.1 35 | 9.2 36 | 9.3 37 | 9.4 38 | 39 | 40 | 1.4.0 41 | 9.2 42 | 9.3 43 | 9.4 44 | 45 | 46 | 1.3.0 47 | 9.2 48 | 9.3 49 | 50 | 51 | 1.2.0 52 | 9.1 53 | 54 | 55 | 0.90+1.1 56 | 0.85 57 | 0.90 58 | 9.1 59 | 60 | 61 | 0.90+1.0 62 | 0.85 63 | 0.90 64 | 9.1 65 | 66 | 67 | 68 | cs_CZ 69 | en_GB 70 | fr_FR 71 | 72 | 73 | 74 | inventory 75 | smartphone 76 | connector 77 | airwatch 78 | helpdesk 79 | loans 80 | 81 | 82 | inventář 83 | chytrý telefon 84 | connector 85 | airwatch 86 | služba podpory 87 | zápůjčky 88 | 89 | 90 | inventaire 91 | smartphone 92 | connecteur 93 | airwatch 94 | helpdesk 95 | réservations 96 | 97 | 98 | GPL v2+ 99 | 100 | -------------------------------------------------------------------------------- /locales/airwatch.pot: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: PACKAGE VERSION\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2020-07-03 13:05+0000\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "Language: \n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=CHARSET\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | 20 | #: hook.php:38 hook.php:45 hook.php:52 hook.php:60 hook.php:68 hook.php:76 21 | #: hook.php:84 hook.php:92 hook.php:100 hook.php:108 hook.php:116 hook.php:124 22 | #: hook.php:133 hook.php:142 hook.php:151 hook.php:160 hook.php:169 23 | #: hook.php:180 hook.php:190 front/config.form.php:51 inc/detail.class.php:290 24 | msgid "Airwatch" 25 | msgstr "" 26 | 27 | #: hook.php:38 inc/detail.class.php:118 28 | msgid "Airwatch ID" 29 | msgstr "" 30 | 31 | #: hook.php:45 32 | msgid "IMEI" 33 | msgstr "" 34 | 35 | #: hook.php:53 36 | msgid "Simcard serial number" 37 | msgstr "" 38 | 39 | #: hook.php:61 inc/detail.class.php:129 40 | msgid "Last seen" 41 | msgstr "" 42 | 43 | #: hook.php:69 inc/detail.class.php:171 44 | msgid "Last enrollment date" 45 | msgstr "" 46 | 47 | #: hook.php:77 48 | msgid "Last enrollment check date" 49 | msgstr "" 50 | 51 | #: hook.php:85 inc/detail.class.php:200 52 | msgid "Last compliance check date" 53 | msgstr "" 54 | 55 | #: hook.php:93 inc/detail.class.php:215 56 | msgid "Last compromised check date" 57 | msgstr "" 58 | 59 | #: hook.php:101 inc/detail.class.php:167 60 | msgid "Enrollment status" 61 | msgstr "" 62 | 63 | #: hook.php:109 hook.php:171 inc/detail.class.php:196 inc/detail.class.php:303 64 | msgid "Compliance status" 65 | msgstr "" 66 | 67 | #: hook.php:117 inc/detail.class.php:211 68 | msgid "Compromised status" 69 | msgstr "" 70 | 71 | #: hook.php:125 72 | msgid "Data encryption" 73 | msgstr "" 74 | 75 | #: hook.php:134 inc/detail.class.php:228 76 | msgid "Roaming enabled" 77 | msgstr "" 78 | 79 | #: hook.php:143 inc/detail.class.php:232 80 | msgid "Data roaming enabled" 81 | msgstr "" 82 | 83 | #: hook.php:152 inc/detail.class.php:239 84 | msgid "Voice roaming enabled" 85 | msgstr "" 86 | 87 | #: hook.php:161 hook.php:170 hook.php:181 88 | msgid "Profile" 89 | msgstr "" 90 | 91 | #: hook.php:182 inc/compliance.class.php:77 92 | msgid "Last check date" 93 | msgstr "" 94 | 95 | #: inc/detail.class.php:110 96 | msgid "General" 97 | msgstr "" 98 | 99 | #: inc/detail.class.php:126 inc/detail.class.php:295 100 | msgid "Phone number" 101 | msgstr "" 102 | 103 | #: inc/detail.class.php:140 104 | msgid "Data encryption enabled" 105 | msgstr "" 106 | 107 | #: inc/detail.class.php:144 108 | msgid "Current SIM serial number" 109 | msgstr "" 110 | 111 | #: inc/detail.class.php:160 112 | msgid "See device in Airwatch console" 113 | msgstr "" 114 | 115 | #: inc/detail.class.php:164 116 | msgid "Enrollment process" 117 | msgstr "" 118 | 119 | #: inc/detail.class.php:182 120 | msgid "Last enrollment check" 121 | msgstr "" 122 | 123 | #: inc/detail.class.php:193 124 | msgid "Other status checks" 125 | msgstr "" 126 | 127 | #: inc/detail.class.php:225 128 | msgid "Roaming" 129 | msgstr "" 130 | 131 | #: inc/config.class.php:40 setup.php:71 132 | msgid "GLPi Airwatch Connector" 133 | msgstr "" 134 | 135 | #: inc/config.class.php:53 136 | msgid "Plugin configuration" 137 | msgstr "" 138 | 139 | #: inc/config.class.php:56 inc/config.class.php:184 140 | msgid "Service URL" 141 | msgstr "" 142 | 143 | #: inc/config.class.php:63 inc/config.class.php:194 144 | msgid "Airwatch Service URL" 145 | msgstr "" 146 | 147 | #: inc/config.class.php:70 inc/config.class.php:204 148 | msgid "Airwatch Console URL" 149 | msgstr "" 150 | 151 | #: inc/config.class.php:77 152 | msgid "Username" 153 | msgstr "" 154 | 155 | #: inc/config.class.php:86 156 | msgid "Password" 157 | msgstr "" 158 | 159 | #: inc/config.class.php:95 160 | msgid "API Key" 161 | msgstr "" 162 | 163 | #: inc/config.class.php:104 164 | msgid "Skip SSL check" 165 | msgstr "" 166 | 167 | #: inc/compliance.class.php:66 168 | msgid "Compliance details" 169 | msgstr "" 170 | 171 | #: inc/airwatch.class.php:65 172 | msgid "Import devices informations from Airwatch" 173 | msgstr "" 174 | -------------------------------------------------------------------------------- /inc/compliance.class.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @copyright Copyright (C) 2016-2022 by Teclib'. 26 | * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html 27 | * @link https://github.com/pluginsGLPI/airwatch 28 | * ------------------------------------------------------------------------- 29 | */ 30 | 31 | if (!defined('GLPI_ROOT')) { 32 | die("Sorry. You can't access directly to this file"); 33 | } 34 | 35 | class PluginAirwatchCompliance extends CommonDBTM { 36 | 37 | //Do not record historical, because details are deleted and recreated at each inventory 38 | public $dohistory = false; 39 | 40 | /** 41 | * since 0.90+1.1 42 | * 43 | * Delete all profiles informations for a device 44 | * @param computers_id GLPi device ID 45 | */ 46 | static function deleteForComputer($computers_id) { 47 | global $DB; 48 | 49 | $query = "DELETE FROM `glpi_plugin_airwatch_compliances` 50 | WHERE `computers_id`='$computers_id'"; 51 | $DB->query($query); 52 | } 53 | 54 | static function showForComputer(CommonDBTM $item) { 55 | $computers_id = $item->getID(); 56 | $data = getAllDataFromTable( 57 | 'glpi_plugin_airwatch_compliances', 58 | ['computers_id' => $computers_id] 59 | ); 60 | if (empty($data)) { 61 | return true; 62 | } 63 | 64 | echo ''; 65 | echo ''.__('Compliance details', 'airwatch').''; 66 | echo ''; 67 | 68 | foreach ($data as $compliance) { 69 | echo ""; 70 | echo ""; 71 | echo $compliance['name']; 72 | echo ""; 73 | echo PluginAirwatchDetail::showYesNoNotSet($compliance['is_compliant'], true); 74 | echo ""; 75 | echo ""; 76 | echo __("Last check date", "airwatch"). ""; 77 | echo PluginAirwatchDetail::getHumanReadableDate($_SESSION['glpi_currenttime'], 78 | $compliance['date_last_check'], 79 | 1); 80 | echo ""; 81 | echo ''; 82 | } 83 | 84 | } 85 | /** 86 | * since 0.90+1.1 87 | * 88 | * Add a device compliance 89 | * @param computers_id GLPi device ID 90 | * @param name profile name 91 | * @param is_compliant compliance status 92 | * @param date_last_check last compliance check date 93 | * 94 | * @return the compliance ID 95 | */ 96 | static function addProfile($computers_id, $name, $is_compliant, $date_last_check) { 97 | $compliance = new self(); 98 | return $compliance->add(['computers_id' => $computers_id, 99 | 'name' => $name, 100 | 'is_compliant' => ($is_compliant?'1':'0'), 101 | 'date_last_check' => $date_last_check]); 102 | } 103 | 104 | static function install(Migration $migration) { 105 | global $DB; 106 | 107 | if (!$DB->tableExists('glpi_plugin_airwatch_compliances')) { 108 | $query = "CREATE TABLE `glpi_plugin_airwatch_compliances` ( 109 | `id` int(11) NOT NULL AUTO_INCREMENT, 110 | `computers_id` int(11) NOT NULL DEFAULT '0', 111 | `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, 112 | `is_compliant` tinyint(1) NOT NULL DEFAULT '0', 113 | `date_last_check` timestamp NULL DEFAULT NULL, 114 | PRIMARY KEY (`id`), 115 | KEY `computers_id` (`computers_id`), 116 | KEY `is_compliant` (`is_compliant`), 117 | KEY `date_last_check` (`date_last_check`) 118 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;"; 119 | $DB->queryOrDie($query, $DB->error()); 120 | } 121 | } 122 | 123 | static function uninstall(Migration $migration) { 124 | $migration->dropTable("glpi_plugin_airwatch_compliances"); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /locales/en_GB.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # 5 | # Translators: 6 | # Walid Nouh, 2016 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: GLPi Plugin - Airwatch\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2020-07-03 13:05+0000\n" 12 | "PO-Revision-Date: 2017-09-23 22:26+0000\n" 13 | "Last-Translator: Johan Cwiklinski \n" 14 | "Language-Team: English (United Kingdom) (http://www.transifex.com/teclib/glpi-plugin-airwatch/language/en_GB/)\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Language: en_GB\n" 19 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 20 | 21 | #: hook.php:38 hook.php:45 hook.php:52 hook.php:60 hook.php:68 hook.php:76 22 | #: hook.php:84 hook.php:92 hook.php:100 hook.php:108 hook.php:116 hook.php:124 23 | #: hook.php:133 hook.php:142 hook.php:151 hook.php:160 hook.php:169 24 | #: hook.php:180 hook.php:190 front/config.form.php:51 inc/detail.class.php:290 25 | msgid "Airwatch" 26 | msgstr "Airwatch" 27 | 28 | #: hook.php:38 inc/detail.class.php:118 29 | msgid "Airwatch ID" 30 | msgstr "Airwatch ID" 31 | 32 | #: hook.php:45 33 | msgid "IMEI" 34 | msgstr "IMEI" 35 | 36 | #: hook.php:53 37 | msgid "Simcard serial number" 38 | msgstr "Simcard serial number" 39 | 40 | #: hook.php:61 inc/detail.class.php:129 41 | msgid "Last seen" 42 | msgstr "Last seen" 43 | 44 | #: hook.php:69 inc/detail.class.php:171 45 | msgid "Last enrollment date" 46 | msgstr "Last enrollment date" 47 | 48 | #: hook.php:77 49 | msgid "Last enrollment check date" 50 | msgstr "Last enrollment check date" 51 | 52 | #: hook.php:85 inc/detail.class.php:200 53 | msgid "Last compliance check date" 54 | msgstr "Last compliance check date" 55 | 56 | #: hook.php:93 inc/detail.class.php:215 57 | msgid "Last compromised check date" 58 | msgstr "Last compromised check date" 59 | 60 | #: hook.php:101 inc/detail.class.php:167 61 | msgid "Enrollment status" 62 | msgstr "Is enrolled" 63 | 64 | #: hook.php:109 hook.php:171 inc/detail.class.php:196 inc/detail.class.php:303 65 | msgid "Compliance status" 66 | msgstr "Is compliant" 67 | 68 | #: hook.php:117 inc/detail.class.php:211 69 | msgid "Compromised status" 70 | msgstr "Is compromised" 71 | 72 | #: hook.php:125 73 | msgid "Data encryption" 74 | msgstr "Data encryption" 75 | 76 | #: hook.php:134 inc/detail.class.php:228 77 | msgid "Roaming enabled" 78 | msgstr "Roaming enabled" 79 | 80 | #: hook.php:143 inc/detail.class.php:232 81 | msgid "Data roaming enabled" 82 | msgstr "Data roaming enabled" 83 | 84 | #: hook.php:152 inc/detail.class.php:239 85 | msgid "Voice roaming enabled" 86 | msgstr "Voice roaming enabled" 87 | 88 | #: hook.php:161 hook.php:170 hook.php:181 89 | msgid "Profile" 90 | msgstr "Profile" 91 | 92 | #: hook.php:182 inc/compliance.class.php:77 93 | msgid "Last check date" 94 | msgstr "Last check date" 95 | 96 | #: inc/detail.class.php:110 97 | msgid "General" 98 | msgstr "General" 99 | 100 | #: inc/detail.class.php:126 inc/detail.class.php:295 101 | msgid "Phone number" 102 | msgstr "Phone number" 103 | 104 | #: inc/detail.class.php:140 105 | msgid "Data encryption enabled" 106 | msgstr "Data encryption enabled" 107 | 108 | #: inc/detail.class.php:144 109 | msgid "Current SIM serial number" 110 | msgstr "Current SIM serial number" 111 | 112 | #: inc/detail.class.php:160 113 | msgid "See device in Airwatch console" 114 | msgstr "See device in Airwatch console" 115 | 116 | #: inc/detail.class.php:164 117 | msgid "Enrollment process" 118 | msgstr "Enrollment process" 119 | 120 | #: inc/detail.class.php:182 121 | msgid "Last enrollment check" 122 | msgstr "Last enrollment check" 123 | 124 | #: inc/detail.class.php:193 125 | msgid "Other status checks" 126 | msgstr "Other status checks" 127 | 128 | #: inc/detail.class.php:225 129 | msgid "Roaming" 130 | msgstr "Roaming" 131 | 132 | #: inc/config.class.php:40 setup.php:71 133 | msgid "GLPi Airwatch Connector" 134 | msgstr "GLPi Airwatch Connector" 135 | 136 | #: inc/config.class.php:53 137 | msgid "Plugin configuration" 138 | msgstr "Plugin configuration" 139 | 140 | #: inc/config.class.php:56 inc/config.class.php:184 141 | msgid "Service URL" 142 | msgstr "Service URL" 143 | 144 | #: inc/config.class.php:63 inc/config.class.php:194 145 | msgid "Airwatch Service URL" 146 | msgstr "Airwatch Service URL" 147 | 148 | #: inc/config.class.php:70 inc/config.class.php:204 149 | msgid "Airwatch Console URL" 150 | msgstr "Airwatch Console URL" 151 | 152 | #: inc/config.class.php:77 153 | msgid "Username" 154 | msgstr "Username" 155 | 156 | #: inc/config.class.php:86 157 | msgid "Password" 158 | msgstr "Password" 159 | 160 | #: inc/config.class.php:95 161 | msgid "API Key" 162 | msgstr "API Key" 163 | 164 | #: inc/config.class.php:104 165 | msgid "Skip SSL check" 166 | msgstr "Skip SSL check" 167 | 168 | #: inc/compliance.class.php:66 169 | msgid "Compliance details" 170 | msgstr "Compliance details" 171 | 172 | #: inc/airwatch.class.php:65 173 | msgid "Import devices informations from Airwatch" 174 | msgstr "Import devices informations from Airwatch" 175 | -------------------------------------------------------------------------------- /locales/pt_PT.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # 5 | # Translators: 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: GLPi Plugin - Airwatch\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2020-07-03 13:05+0000\n" 11 | "PO-Revision-Date: 2019-03-01 10:57+0000\n" 12 | "Last-Translator: Rui Melo \n" 13 | "Language-Team: Portuguese (Portugal) (http://www.transifex.com/teclib/glpi-plugin-airwatch/language/pt_PT/)\n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=UTF-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Language: pt_PT\n" 18 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 19 | 20 | #: hook.php:38 hook.php:45 hook.php:52 hook.php:60 hook.php:68 hook.php:76 21 | #: hook.php:84 hook.php:92 hook.php:100 hook.php:108 hook.php:116 hook.php:124 22 | #: hook.php:133 hook.php:142 hook.php:151 hook.php:160 hook.php:169 23 | #: hook.php:180 hook.php:190 front/config.form.php:51 inc/detail.class.php:290 24 | msgid "Airwatch" 25 | msgstr "Airwatch" 26 | 27 | #: hook.php:38 inc/detail.class.php:118 28 | msgid "Airwatch ID" 29 | msgstr "IDAirwatch" 30 | 31 | #: hook.php:45 32 | msgid "IMEI" 33 | msgstr "IMEI" 34 | 35 | #: hook.php:53 36 | msgid "Simcard serial number" 37 | msgstr "Número de série Simcard" 38 | 39 | #: hook.php:61 inc/detail.class.php:129 40 | msgid "Last seen" 41 | msgstr "Última vez visto" 42 | 43 | #: hook.php:69 inc/detail.class.php:171 44 | msgid "Last enrollment date" 45 | msgstr "Última data de inscrição" 46 | 47 | #: hook.php:77 48 | msgid "Last enrollment check date" 49 | msgstr "Data da última verificação de inscrição" 50 | 51 | #: hook.php:85 inc/detail.class.php:200 52 | msgid "Last compliance check date" 53 | msgstr "Data da última verificação de conformidade" 54 | 55 | #: hook.php:93 inc/detail.class.php:215 56 | msgid "Last compromised check date" 57 | msgstr "Data da última verificação comprometida" 58 | 59 | #: hook.php:101 inc/detail.class.php:167 60 | msgid "Enrollment status" 61 | msgstr "Estado da inscrição" 62 | 63 | #: hook.php:109 hook.php:171 inc/detail.class.php:196 inc/detail.class.php:303 64 | msgid "Compliance status" 65 | msgstr "Status de conformidade" 66 | 67 | #: hook.php:117 inc/detail.class.php:211 68 | msgid "Compromised status" 69 | msgstr "Estado comprometido" 70 | 71 | #: hook.php:125 72 | msgid "Data encryption" 73 | msgstr "Criptografia de dados" 74 | 75 | #: hook.php:134 inc/detail.class.php:228 76 | msgid "Roaming enabled" 77 | msgstr "Roaming ativo" 78 | 79 | #: hook.php:143 inc/detail.class.php:232 80 | msgid "Data roaming enabled" 81 | msgstr "Roaming de dados ativo" 82 | 83 | #: hook.php:152 inc/detail.class.php:239 84 | msgid "Voice roaming enabled" 85 | msgstr "Roaming de voz ativado" 86 | 87 | #: hook.php:161 hook.php:170 hook.php:181 88 | msgid "Profile" 89 | msgstr "Perfil" 90 | 91 | #: hook.php:182 inc/compliance.class.php:77 92 | msgid "Last check date" 93 | msgstr "Última data de verificação" 94 | 95 | #: inc/detail.class.php:110 96 | msgid "General" 97 | msgstr "Geral" 98 | 99 | #: inc/detail.class.php:126 inc/detail.class.php:295 100 | msgid "Phone number" 101 | msgstr "Número de Telemóvel" 102 | 103 | #: inc/detail.class.php:140 104 | msgid "Data encryption enabled" 105 | msgstr "Criptografia de dados ativada" 106 | 107 | #: inc/detail.class.php:144 108 | msgid "Current SIM serial number" 109 | msgstr "Número de série atual do SIM" 110 | 111 | #: inc/detail.class.php:160 112 | msgid "See device in Airwatch console" 113 | msgstr "Veja o dispositivo no console do Airwatch" 114 | 115 | #: inc/detail.class.php:164 116 | msgid "Enrollment process" 117 | msgstr "Processo de inscrição" 118 | 119 | #: inc/detail.class.php:182 120 | msgid "Last enrollment check" 121 | msgstr "Última verificação de inscrição" 122 | 123 | #: inc/detail.class.php:193 124 | msgid "Other status checks" 125 | msgstr "Outras verificações de status" 126 | 127 | #: inc/detail.class.php:225 128 | msgid "Roaming" 129 | msgstr "Roaming" 130 | 131 | #: inc/config.class.php:40 setup.php:71 132 | msgid "GLPi Airwatch Connector" 133 | msgstr "Conector do Airwatch GLPI" 134 | 135 | #: inc/config.class.php:53 136 | msgid "Plugin configuration" 137 | msgstr "Configuração do plugin" 138 | 139 | #: inc/config.class.php:56 inc/config.class.php:184 140 | msgid "Service URL" 141 | msgstr "URL do serviço" 142 | 143 | #: inc/config.class.php:63 inc/config.class.php:194 144 | msgid "Airwatch Service URL" 145 | msgstr "URL do serviço do Airwatch" 146 | 147 | #: inc/config.class.php:70 inc/config.class.php:204 148 | msgid "Airwatch Console URL" 149 | msgstr "URL da Consola do Airwatch" 150 | 151 | #: inc/config.class.php:77 152 | msgid "Username" 153 | msgstr "Nome de utilizador" 154 | 155 | #: inc/config.class.php:86 156 | msgid "Password" 157 | msgstr "Senha" 158 | 159 | #: inc/config.class.php:95 160 | msgid "API Key" 161 | msgstr "Chave API" 162 | 163 | #: inc/config.class.php:104 164 | msgid "Skip SSL check" 165 | msgstr "Ignorar verificação SSL" 166 | 167 | #: inc/compliance.class.php:66 168 | msgid "Compliance details" 169 | msgstr "Detalhes de conformidade" 170 | 171 | #: inc/airwatch.class.php:65 172 | msgid "Import devices informations from Airwatch" 173 | msgstr "Informações sobre a importação de dispositivos do Airwatch" 174 | -------------------------------------------------------------------------------- /locales/cs_CZ.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # 5 | # Translators: 6 | # Pavel Borecki , 2018 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: GLPi Plugin - Airwatch\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2020-07-03 13:05+0000\n" 12 | "PO-Revision-Date: 2018-04-10 12:31+0000\n" 13 | "Last-Translator: Pavel Borecki \n" 14 | "Language-Team: Czech (Czech Republic) (http://www.transifex.com/teclib/glpi-plugin-airwatch/language/cs_CZ/)\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Language: cs_CZ\n" 19 | "Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n" 20 | 21 | #: hook.php:38 hook.php:45 hook.php:52 hook.php:60 hook.php:68 hook.php:76 22 | #: hook.php:84 hook.php:92 hook.php:100 hook.php:108 hook.php:116 hook.php:124 23 | #: hook.php:133 hook.php:142 hook.php:151 hook.php:160 hook.php:169 24 | #: hook.php:180 hook.php:190 front/config.form.php:51 inc/detail.class.php:290 25 | msgid "Airwatch" 26 | msgstr "Airwatch" 27 | 28 | #: hook.php:38 inc/detail.class.php:118 29 | msgid "Airwatch ID" 30 | msgstr "Airwatch identifikátor" 31 | 32 | #: hook.php:45 33 | msgid "IMEI" 34 | msgstr "IMEI" 35 | 36 | #: hook.php:53 37 | msgid "Simcard serial number" 38 | msgstr "Sériové číslo simkarty" 39 | 40 | #: hook.php:61 inc/detail.class.php:129 41 | msgid "Last seen" 42 | msgstr "Naposledy spatřeno" 43 | 44 | #: hook.php:69 inc/detail.class.php:171 45 | msgid "Last enrollment date" 46 | msgstr "Datum minulého nasazení" 47 | 48 | #: hook.php:77 49 | msgid "Last enrollment check date" 50 | msgstr "Datum minulé kontroly nasazení" 51 | 52 | #: hook.php:85 inc/detail.class.php:200 53 | msgid "Last compliance check date" 54 | msgstr "Datum minulé kontroly souladu" 55 | 56 | #: hook.php:93 inc/detail.class.php:215 57 | msgid "Last compromised check date" 58 | msgstr "Datum minulé kontroly kompromitace" 59 | 60 | #: hook.php:101 inc/detail.class.php:167 61 | msgid "Enrollment status" 62 | msgstr "Stav nasazení" 63 | 64 | #: hook.php:109 hook.php:171 inc/detail.class.php:196 inc/detail.class.php:303 65 | msgid "Compliance status" 66 | msgstr "Stav souladu" 67 | 68 | #: hook.php:117 inc/detail.class.php:211 69 | msgid "Compromised status" 70 | msgstr "Stav kompromitace" 71 | 72 | #: hook.php:125 73 | msgid "Data encryption" 74 | msgstr "Šifrování dat" 75 | 76 | #: hook.php:134 inc/detail.class.php:228 77 | msgid "Roaming enabled" 78 | msgstr "Roaming zapnut" 79 | 80 | #: hook.php:143 inc/detail.class.php:232 81 | msgid "Data roaming enabled" 82 | msgstr "Datový roaming zapnut" 83 | 84 | #: hook.php:152 inc/detail.class.php:239 85 | msgid "Voice roaming enabled" 86 | msgstr "Hlasový roaming zapnut" 87 | 88 | #: hook.php:161 hook.php:170 hook.php:181 89 | msgid "Profile" 90 | msgstr "Profil" 91 | 92 | #: hook.php:182 inc/compliance.class.php:77 93 | msgid "Last check date" 94 | msgstr "Datum minulé kontroly" 95 | 96 | #: inc/detail.class.php:110 97 | msgid "General" 98 | msgstr "Obecné" 99 | 100 | #: inc/detail.class.php:126 inc/detail.class.php:295 101 | msgid "Phone number" 102 | msgstr "Telefonní číslo" 103 | 104 | #: inc/detail.class.php:140 105 | msgid "Data encryption enabled" 106 | msgstr "Šifrování dat zapnuto" 107 | 108 | #: inc/detail.class.php:144 109 | msgid "Current SIM serial number" 110 | msgstr "Sériové číslo stávající SIM karty" 111 | 112 | #: inc/detail.class.php:160 113 | msgid "See device in Airwatch console" 114 | msgstr "Zobrazit zařízení v konzoli Airwatch" 115 | 116 | #: inc/detail.class.php:164 117 | msgid "Enrollment process" 118 | msgstr "Proces nasazení" 119 | 120 | #: inc/detail.class.php:182 121 | msgid "Last enrollment check" 122 | msgstr "Minulá kontrola nasazení" 123 | 124 | #: inc/detail.class.php:193 125 | msgid "Other status checks" 126 | msgstr "Ostatní kontroly stavu" 127 | 128 | #: inc/detail.class.php:225 129 | msgid "Roaming" 130 | msgstr "Roaming" 131 | 132 | #: inc/config.class.php:40 setup.php:71 133 | msgid "GLPi Airwatch Connector" 134 | msgstr "Napojení GLPi na Airwatch" 135 | 136 | #: inc/config.class.php:53 137 | msgid "Plugin configuration" 138 | msgstr "Nastavení zásuvného modulu" 139 | 140 | #: inc/config.class.php:56 inc/config.class.php:184 141 | msgid "Service URL" 142 | msgstr "URL adresa služby" 143 | 144 | #: inc/config.class.php:63 inc/config.class.php:194 145 | msgid "Airwatch Service URL" 146 | msgstr "URL adresa služby Airwatch" 147 | 148 | #: inc/config.class.php:70 inc/config.class.php:204 149 | msgid "Airwatch Console URL" 150 | msgstr "URL adresa Airwatch konzole" 151 | 152 | #: inc/config.class.php:77 153 | msgid "Username" 154 | msgstr "Uživatelské jméno" 155 | 156 | #: inc/config.class.php:86 157 | msgid "Password" 158 | msgstr "Heslo" 159 | 160 | #: inc/config.class.php:95 161 | msgid "API Key" 162 | msgstr "Klíč k API" 163 | 164 | #: inc/config.class.php:104 165 | msgid "Skip SSL check" 166 | msgstr "Přeskočit kontrolu SSL" 167 | 168 | #: inc/compliance.class.php:66 169 | msgid "Compliance details" 170 | msgstr "Podrobnosti o shodě" 171 | 172 | #: inc/airwatch.class.php:65 173 | msgid "Import devices informations from Airwatch" 174 | msgstr "Naimportovat informace o zařízeních z Airwatch" 175 | -------------------------------------------------------------------------------- /locales/fr_FR.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # 5 | # Translators: 6 | # Walid Nouh, 2016 7 | # Walid Nouh, 2016 8 | msgid "" 9 | msgstr "" 10 | "Project-Id-Version: GLPi Plugin - Airwatch\n" 11 | "Report-Msgid-Bugs-To: \n" 12 | "POT-Creation-Date: 2020-07-03 13:05+0000\n" 13 | "PO-Revision-Date: 2017-09-23 22:26+0000\n" 14 | "Last-Translator: Johan Cwiklinski \n" 15 | "Language-Team: French (France) (http://www.transifex.com/teclib/glpi-plugin-airwatch/language/fr_FR/)\n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=UTF-8\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | "Language: fr_FR\n" 20 | "Plural-Forms: nplurals=2; plural=(n > 1);\n" 21 | 22 | #: hook.php:38 hook.php:45 hook.php:52 hook.php:60 hook.php:68 hook.php:76 23 | #: hook.php:84 hook.php:92 hook.php:100 hook.php:108 hook.php:116 hook.php:124 24 | #: hook.php:133 hook.php:142 hook.php:151 hook.php:160 hook.php:169 25 | #: hook.php:180 hook.php:190 front/config.form.php:51 inc/detail.class.php:290 26 | msgid "Airwatch" 27 | msgstr "Airwatch" 28 | 29 | #: hook.php:38 inc/detail.class.php:118 30 | msgid "Airwatch ID" 31 | msgstr "Identifiant Airwatch" 32 | 33 | #: hook.php:45 34 | msgid "IMEI" 35 | msgstr "IMEI" 36 | 37 | #: hook.php:53 38 | msgid "Simcard serial number" 39 | msgstr "Numéro de série de la carte SIM" 40 | 41 | #: hook.php:61 inc/detail.class.php:129 42 | msgid "Last seen" 43 | msgstr "Dernier contact" 44 | 45 | #: hook.php:69 inc/detail.class.php:171 46 | msgid "Last enrollment date" 47 | msgstr "Date de dernier enrôlement " 48 | 49 | #: hook.php:77 50 | msgid "Last enrollment check date" 51 | msgstr "Date de dernière vérification de l'enrôlement" 52 | 53 | #: hook.php:85 inc/detail.class.php:200 54 | msgid "Last compliance check date" 55 | msgstr "Date de dernière vérfication de conformité" 56 | 57 | #: hook.php:93 inc/detail.class.php:215 58 | msgid "Last compromised check date" 59 | msgstr "Date de dernière vérification de compromission" 60 | 61 | #: hook.php:101 inc/detail.class.php:167 62 | msgid "Enrollment status" 63 | msgstr "Est enrôlé" 64 | 65 | #: hook.php:109 hook.php:171 inc/detail.class.php:196 inc/detail.class.php:303 66 | msgid "Compliance status" 67 | msgstr "Est conforme" 68 | 69 | #: hook.php:117 inc/detail.class.php:211 70 | msgid "Compromised status" 71 | msgstr "Est compromis" 72 | 73 | #: hook.php:125 74 | msgid "Data encryption" 75 | msgstr "Chiffrement des données" 76 | 77 | #: hook.php:134 inc/detail.class.php:228 78 | msgid "Roaming enabled" 79 | msgstr "Itinérance activée" 80 | 81 | #: hook.php:143 inc/detail.class.php:232 82 | msgid "Data roaming enabled" 83 | msgstr "Itinérance des données activée" 84 | 85 | #: hook.php:152 inc/detail.class.php:239 86 | msgid "Voice roaming enabled" 87 | msgstr "Itinérance de la voix activée" 88 | 89 | #: hook.php:161 hook.php:170 hook.php:181 90 | msgid "Profile" 91 | msgstr "Profil" 92 | 93 | #: hook.php:182 inc/compliance.class.php:77 94 | msgid "Last check date" 95 | msgstr "Dernière vérification" 96 | 97 | #: inc/detail.class.php:110 98 | msgid "General" 99 | msgstr "Général" 100 | 101 | #: inc/detail.class.php:126 inc/detail.class.php:295 102 | msgid "Phone number" 103 | msgstr "Numéro de téléphone" 104 | 105 | #: inc/detail.class.php:140 106 | msgid "Data encryption enabled" 107 | msgstr "Chiffrement des données activé" 108 | 109 | #: inc/detail.class.php:144 110 | msgid "Current SIM serial number" 111 | msgstr "Numéro de série de la carte SIM en utilisation" 112 | 113 | #: inc/detail.class.php:160 114 | msgid "See device in Airwatch console" 115 | msgstr "Voir le matériel dans la console Airwatch" 116 | 117 | #: inc/detail.class.php:164 118 | msgid "Enrollment process" 119 | msgstr "Processus d'enrôlement" 120 | 121 | #: inc/detail.class.php:182 122 | msgid "Last enrollment check" 123 | msgstr "Dernière vérification de l'enrôlement" 124 | 125 | #: inc/detail.class.php:193 126 | msgid "Other status checks" 127 | msgstr "Autres vérifications de statuts" 128 | 129 | #: inc/detail.class.php:225 130 | msgid "Roaming" 131 | msgstr "Itinérance" 132 | 133 | #: inc/config.class.php:40 setup.php:71 134 | msgid "GLPi Airwatch Connector" 135 | msgstr "Connecteur Airwatch pour GLPi" 136 | 137 | #: inc/config.class.php:53 138 | msgid "Plugin configuration" 139 | msgstr "Configuration du plugin" 140 | 141 | #: inc/config.class.php:56 inc/config.class.php:184 142 | msgid "Service URL" 143 | msgstr "URL du service" 144 | 145 | #: inc/config.class.php:63 inc/config.class.php:194 146 | msgid "Airwatch Service URL" 147 | msgstr "URL du service Airwatch" 148 | 149 | #: inc/config.class.php:70 inc/config.class.php:204 150 | msgid "Airwatch Console URL" 151 | msgstr "URL de la console Airwatch" 152 | 153 | #: inc/config.class.php:77 154 | msgid "Username" 155 | msgstr "Nom d'utilisateur" 156 | 157 | #: inc/config.class.php:86 158 | msgid "Password" 159 | msgstr "Mot de passe" 160 | 161 | #: inc/config.class.php:95 162 | msgid "API Key" 163 | msgstr "Clef d'API" 164 | 165 | #: inc/config.class.php:104 166 | msgid "Skip SSL check" 167 | msgstr "Passer les vérifications SSL" 168 | 169 | #: inc/compliance.class.php:66 170 | msgid "Compliance details" 171 | msgstr "Détails de conformité" 172 | 173 | #: inc/airwatch.class.php:65 174 | msgid "Import devices informations from Airwatch" 175 | msgstr "Import des matériels depuis Airwatch" 176 | -------------------------------------------------------------------------------- /inc/rest.class.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @copyright Copyright (C) 2016-2022 by Teclib'. 26 | * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html 27 | * @link https://github.com/pluginsGLPI/airwatch 28 | * ------------------------------------------------------------------------- 29 | */ 30 | 31 | if (!defined('GLPI_ROOT')) { 32 | die("Sorry. You can't access directly to this file"); 33 | } 34 | 35 | class PluginAirwatchRest { 36 | 37 | /** 38 | * @since 0.90+1.0 39 | * 40 | * Test API by calling the help page 41 | * 42 | * @return an array which contains: 43 | * - an execution status code : OK or KO 44 | * - the error message if execution fails 45 | * - data if execution is a success 46 | */ 47 | static function testConnection() { 48 | //return self::callApi('/help'); 49 | return self::callApi('/mdm/devices/search?pagesize=1'); 50 | } 51 | 52 | /** 53 | * @since 0.90+1.0 54 | * 55 | * Call Airwatch REST API 56 | * 57 | * @param endpoint endpoint to call 58 | * @return an array which contains: 59 | * - an execution status code : OK or KO 60 | * - the error message if execution fails 61 | * - data if execution is a success 62 | */ 63 | static function callApi($endpoint) { 64 | 65 | //Array to return API call informations 66 | $result = []; 67 | set_time_limit(0); 68 | //Get airwatch access configuration 69 | $config = new PluginAirwatchConfig(); 70 | $config->getFromDB(1); 71 | 72 | if (!isset($config->fields['airwatch_service_url']) 73 | || $config->fields['airwatch_service_url'] == '') { 74 | return false; 75 | } 76 | 77 | //Encode auth informations in base64 78 | $basic_auth = base64_encode($config->fields['username'].':'.$config->fields['password']); 79 | $ch = curl_init(); 80 | 81 | //Build full endpoit URL 82 | $url = $config->fields['airwatch_service_url'].$endpoint; 83 | curl_setopt($ch, CURLOPT_URL, $url); 84 | 85 | $headers = ['aw-tenant-code: '.$config->fields['api_key'], 86 | 'Authorization: Basic '.$basic_auth, 87 | 'Accept: application/json']; 88 | curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 89 | curl_setopt($ch, CURLOPT_VERBOSE, 1); 90 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 91 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 92 | curl_setopt($ch, CURLOPT_TIMEOUT,5000); 93 | curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"); 94 | 95 | //Skip SSL check if requested in the plugin's configuration 96 | if ($config->fields['skip_ssl_check']) { 97 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 98 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); 99 | } 100 | 101 | $ch_result = curl_exec($ch); 102 | //Get curl informations about the last call 103 | $infos = curl_getinfo($ch); 104 | 105 | //If http_code is not 200, then there's an error 106 | if ($infos['http_code'] != 200) { 107 | $result['status'] = AIRWATCH_API_RESULT_ERROR; 108 | $result['error'] = $infos['http_code']; 109 | } else { 110 | $result['status'] = AIRWATCH_API_RESULT_OK; 111 | $result['data'] = $ch_result; 112 | } 113 | curl_close($ch); 114 | 115 | return $result; 116 | } 117 | 118 | /** 119 | * @since 0.90+1.1 120 | * 121 | * Get profies for a device using the Airwatch rest API 122 | * @param the Airwatch Device ID 123 | * @return profiles informations as an array 124 | */ 125 | static function getDeviceProfiles($device_id) { 126 | return self::callApiAndGetData('/mdm/devices/'.$device_id.'/profiles'); 127 | } 128 | 129 | /** 130 | * @since 0.90+1.1 131 | * 132 | * Get profile compliance for a device using the Airwatch rest API 133 | * @param the Airwatch Device ID 134 | * @return compliance informations as an array 135 | */ 136 | static function getDeviceCompliance($device_id) { 137 | return self::callApiAndGetData('/mdm/devices/'.$device_id.'/compliance'); 138 | } 139 | 140 | /** 141 | * @since 0.90+1.0 142 | * 143 | * Get all devices using the Airwatch rest API 144 | * @return devices informations as an array 145 | */ 146 | static function getDevices() { 147 | return self::callApiAndGetData('/mdm/devices/search?pagesize=3000'); 148 | } 149 | 150 | /** 151 | * @since 0.90+1.0 152 | * 153 | * Get a device informations using the Airwatch rest API 154 | * @param the Airwatch Device ID 155 | * @return device informations as an array 156 | */ 157 | static function getDevice($device_id) { 158 | return self::callApiAndGetData('/mdm/devices/'.$device_id); 159 | } 160 | 161 | /** 162 | * @since 0.90+1.0 163 | * 164 | * Get a device network informations using the Airwatch rest API 165 | * @param the Airwatch Device ID 166 | * @return network informations as an array 167 | */ 168 | static function getDeviceNetworkInfo($device_id) { 169 | return self::callApiAndGetData('/mdm/devices/'.$device_id.'/network'); 170 | } 171 | 172 | /** 173 | * @since 0.90+1.0 174 | * 175 | * Get a device applications using the Airwatch rest API 176 | * @param the Airwatch Device ID 177 | * @return applications as an array 178 | */ 179 | static function getDeviceApplications($device_id) { 180 | return self::callApiAndGetData('/mdm/devices/'.$device_id.'/apps'); 181 | } 182 | 183 | /** 184 | * @since 0.90+1.0 185 | * 186 | * Get details for one device using the Airwatch rest API 187 | * @return the device informations as an array 188 | */ 189 | static function callApiAndGetData($endpoint) { 190 | 191 | $results = self::callApi($endpoint); 192 | if ($results['status'] == AIRWATCH_API_RESULT_OK 193 | && isset($results['data']) && !empty($results['data'])) { 194 | $data = json_decode($results['data'], true); 195 | $results['array_data'] = $data; 196 | } else { 197 | $results['array_data'] = []; 198 | } 199 | return $results; 200 | } 201 | 202 | } 203 | -------------------------------------------------------------------------------- /inc/config.class.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @copyright Copyright (C) 2016-2022 by Teclib'. 26 | * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html 27 | * @link https://github.com/pluginsGLPI/airwatch 28 | * ------------------------------------------------------------------------- 29 | */ 30 | 31 | if (!defined('GLPI_ROOT')) { 32 | die("Sorry. You can't access directly to this file"); 33 | } 34 | 35 | class PluginAirwatchConfig extends CommonDBTM { 36 | static $rightname = 'config'; 37 | 38 | public static function getTypeName($nb = 0) { 39 | return __("GLPi Airwatch Connector", 'airwatch'); 40 | } 41 | 42 | public function showForm() { 43 | $this->getFromDB(1); 44 | 45 | echo "
"; 46 | echo "
"; 47 | 48 | echo ""; 49 | 50 | echo ""; 51 | 52 | echo ""; 53 | 54 | echo ""; 55 | echo ""; 56 | echo ""; 59 | echo ""; 60 | 61 | echo ""; 62 | echo ""; 63 | echo ""; 66 | echo ""; 67 | 68 | echo ""; 69 | echo ""; 70 | echo ""; 73 | echo ""; 74 | 75 | echo ""; 76 | echo ""; 77 | echo ""; 82 | echo ""; 83 | 84 | echo ""; 85 | echo ""; 86 | echo ""; 91 | echo ""; 92 | 93 | echo ""; 94 | echo ""; 95 | echo ""; 100 | echo ""; 101 | 102 | echo ""; 103 | echo ""; 104 | echo ""; 107 | echo ""; 108 | 109 | echo ""; 110 | echo ""; 114 | echo ""; 115 | 116 | echo "
" . __("Plugin configuration", "airwatch") . "
" . __("Service URL", "fusioninventory") . ""; 57 | Html::autocompletionTextField($this, "fusioninventory_url"); 58 | echo "
" . __("Airwatch Service URL", "airwatch") . ""; 64 | Html::autocompletionTextField($this, "airwatch_service_url"); 65 | echo "
" . __("Airwatch Console URL", "airwatch") . ""; 71 | Html::autocompletionTextField($this, "airwatch_console_url"); 72 | echo "
" . __("Username", "airwatch") . ""; 78 | // FIXME This is a credential field so it is not in autocomplete whitelist 79 | // Replace with a simple text input. 80 | Html::autocompletionTextField($this, "username"); 81 | echo "
" . __("Password", "airwatch") . ""; 87 | // FIXME This is a credential field so it is not in autocomplete whitelist 88 | // Replace with a password text input, crypt it, and handle ability to "blank" it. 89 | Html::autocompletionTextField($this, "password"); 90 | echo "
" . __("API Key", "airwatch") . ""; 96 | // FIXME This is a credential field so it is not in autocomplete whitelist 97 | // Replace with a simple text input. 98 | Html::autocompletionTextField($this, "api_key"); 99 | echo "
" . __("Skip SSL check", "airwatch") . ""; 105 | Dropdown::showYesNo("skip_ssl_check", $this->fields['skip_ssl_check']); 106 | echo "
"; 111 | echo ""; 112 | echo " "; 113 | echo"
"; 117 | Html::closeForm(); 118 | echo "
"; 119 | } 120 | 121 | 122 | //----------------- Install & uninstall -------------------// 123 | public static function install(Migration $migration) { 124 | global $DB; 125 | 126 | $config = new self(); 127 | 128 | //This class is available since version 1.3.0 129 | if (!$DB->tableExists("glpi_plugin_airwatch_configs")) { 130 | $migration->displayMessage("Install glpi_plugin_airwatch_configs"); 131 | 132 | //Install 133 | $query = "CREATE TABLE `glpi_plugin_airwatch_configs` ( 134 | `id` int(11) NOT NULL auto_increment, 135 | `fusioninventory_url` varchar(255) character set utf8 collate utf8_unicode_ci NOT NULL, 136 | `airwatch_service_url` varchar(255) character set utf8 collate utf8_unicode_ci NOT NULL, 137 | `airwatch_console_url` varchar(255) character set utf8 collate utf8_unicode_ci NOT NULL, 138 | `username` varchar(255) character set utf8 collate utf8_unicode_ci NOT NULL, 139 | `password` varchar(255) character set utf8 collate utf8_unicode_ci NOT NULL, 140 | `api_key` varchar(255) character set utf8 collate utf8_unicode_ci NOT NULL, 141 | `skip_ssl_check` tinyint(1) NOT NULL default '0', 142 | PRIMARY KEY (`id`), 143 | KEY `fusioninventory_url` (`fusioninventory_url`), 144 | KEY `airwatch_service_url` (`airwatch_service_url`), 145 | KEY `airwatch_console_url` (`airwatch_console_url`), 146 | KEY `username` (`username`), 147 | KEY `password` (`password`), 148 | KEY `api_key` (`api_key`), 149 | KEY `skip_ssl_check` (`skip_ssl_check`) 150 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;"; 151 | $DB->query($query) or die ($DB->error()); 152 | 153 | $tmp = ['id' => 1, 154 | 'fusioninventory_url' => 'http://localhost/glpi/plugins/fusioninventory/', 155 | 'airwatch_service_url' => '', 156 | 'airwatch_console_url' => '', 157 | 'username' => '', 158 | 'password' => '', 159 | 'api_key' => '', 160 | 'skip_ssl_check' => 0]; 161 | $config->add($tmp); 162 | } 163 | } 164 | 165 | public static function uninstall() { 166 | global $DB; 167 | $DB->query("DROP TABLE IF EXISTS `glpi_plugin_airwatch_configs`"); 168 | } 169 | 170 | function rawSearchOptions() { 171 | 172 | $tab = []; 173 | 174 | $tab[] = [ 175 | 'id' => 'common', 176 | 'name' => __('Characteristics') 177 | ]; 178 | 179 | $tab[] = [ 180 | 'id' => '2', 181 | 'table' => $this->getTable(), 182 | 'field' => 'fusioninventory_url', 183 | 'name' => __('Service URL', 'fusioninventory'), 184 | 'datatype' => 'string', 185 | 'massiveaction' => false, 186 | 'autocomplete' => true, 187 | ]; 188 | 189 | $tab[] = [ 190 | 'id' => '3', 191 | 'table' => $this->getTable(), 192 | 'field' => 'airwatch_service_url', 193 | 'name' => __('Airwatch Service URL', 'airwatch'), 194 | 'datatype' => 'string', 195 | 'massiveaction' => false, 196 | 'autocomplete' => true, 197 | ]; 198 | 199 | $tab[] = [ 200 | 'id' => '4', 201 | 'table' => $this->getTable(), 202 | 'field' => 'airwatch_console_url', 203 | 'name' => __('Airwatch Console URL', 'airwatch'), 204 | 'datatype' => 'string', 205 | 'massiveaction' => false, 206 | 'autocomplete' => true, 207 | ]; 208 | 209 | return $tab; 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /inc/xml.class.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @copyright Copyright (C) 2016-2022 by Teclib'. 26 | * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html 27 | * @link https://github.com/pluginsGLPI/airwatch 28 | * ------------------------------------------------------------------------- 29 | */ 30 | 31 | if (!defined('GLPI_ROOT')) { 32 | die("Sorry. You can't access directly to this file"); 33 | } 34 | 35 | /** 36 | * Methods to generate an XML file compliant with the FusionInventory format 37 | */ 38 | class PluginAirwatchXml { 39 | 40 | var $data; 41 | var $sxml; 42 | var $agentbuildnumber; 43 | var $deviceid; 44 | var $username; 45 | 46 | /** 47 | * @since 0.90+1.0 48 | * 49 | * Export Airwatch specific informations in XML format 50 | */ 51 | function PluginAirwatchXml($data) { 52 | $this->data = $data; 53 | 54 | $this->deviceid = $data['DEVICEID']; 55 | $this->agentbuildnumber = $data['VERSIONCLIENT']; 56 | 57 | $SXML=" \n\n"; 58 | $SXML.="{$this->agentbuildnumber}\n"; 59 | $SXML.="\n"; 60 | $SXML.="{$this->deviceid}\nINVENTORY\n"; 61 | $SXML.="\n"; 62 | 63 | $this->sxml = new SimpleXMLElement($SXML); 64 | $this->setAccessLog(); 65 | $this->setAccountInfos(); 66 | $this->setBios(); 67 | $this->setHardware(); 68 | $this->setOS(); 69 | //$this->setSoftwares(); 70 | $this->setNetwork(); 71 | $this->setAirwatchInfos(); 72 | //$this->setCompliance(); 73 | } 74 | 75 | /** 76 | * @since 0.90+1.0 77 | * 78 | * Export access informations in XML format 79 | */ 80 | function setAccessLog() { 81 | $CONTENT = $this->sxml->CONTENT[0]; 82 | $CONTENT->addChild('ACCESSLOG'); 83 | 84 | $ACCESSLOG = $this->sxml->CONTENT[0]->ACCESSLOG; 85 | $ACCESSLOG->addChild('LOGDATE', date('Y-m-d h:i:s')); 86 | 87 | if (isset($this->data['userid']) && !empty($this->data['userid'])) { 88 | $this->username = $this->data['userid']; 89 | $ACCESSLOG->addChild('USERID', $this->username); 90 | } 91 | } 92 | 93 | /** 94 | * @since 0.90+1.0 95 | * 96 | * Export network informations in XML format 97 | */ 98 | function setNetwork() { 99 | $CONTENT = $this->sxml->CONTENT[0]; 100 | $i = 0; 101 | 102 | if (isset($this->data['wifi_ipaddress']) || isset($this->data['wifi_macaddress'])) { 103 | $CONTENT->addChild('NETWORKS'); 104 | $NETWORK = $this->sxml->CONTENT[$i]->NETWORKS; 105 | if (isset($this->data['wifi_ipaddress'])) { 106 | $NETWORK->addChild('IPADDRESS', $this->data['wifi_ipaddress']); 107 | } 108 | if (isset($this->data['wifi_macaddress'])) { 109 | $NETWORK->addChild('MACADDR', $this->data['wifi_macaddress']); 110 | } 111 | $NETWORK->addChild('TYPE', 'wifi'); 112 | $i++; 113 | } 114 | if (isset($this->data['cellular_ipaddress'])) { 115 | $CONTENT->addChild('NETWORKS'); 116 | 117 | $NETWORK = $this->sxml->CONTENT[$i]->NETWORKS; 118 | $NETWORK->addChild('IPADDRESS', $this->data['cellular_ipaddress']); 119 | $NETWORK->addChild('TYPE', 'ethernet'); 120 | } 121 | } 122 | 123 | /** 124 | * @since 0.90+1.0 125 | * 126 | * Export TAG in XML format 127 | */ 128 | function setAccountInfos() { 129 | 130 | //Use the LocationGroupName as TAG 131 | if (isset($this->data['tag'])) { 132 | $CONTENT = $this->sxml->CONTENT[0]; 133 | $CONTENT->addChild('ACCOUNTINFO'); 134 | 135 | $ACCOUNTINFO = $this->sxml->CONTENT[0]->ACCOUNTINFO; 136 | $ACCOUNTINFO->addChild('KEYNAME', 'TAG'); 137 | $ACCOUNTINFO->addChild('KEYVALUE', $this->data['tag']); 138 | } 139 | } 140 | 141 | /** 142 | * @since 0.90+1.0 143 | * 144 | * Export Hardware informations in XML format 145 | */ 146 | function setHardware() { 147 | $CONTENT = $this->sxml->CONTENT[0]; 148 | $CONTENT->addChild('HARDWARE'); 149 | 150 | $HARDWARE = $this->sxml->CONTENT[0]->HARDWARE; 151 | $HARDWARE->addChild('NAME', $this->data['name']); 152 | if (isset($this->username)) { 153 | $HARDWARE->addChild('LASTLOGGEDUSER', $this->username); 154 | } 155 | $HARDWARE->addChild('UUID', $this->data['uuid']); 156 | $HARDWARE->addChild('CHASSIS_TYPE', $this->data['type']); 157 | } 158 | 159 | /** 160 | * @since 0.90+1.0 161 | * 162 | * Export OS informations in XML format 163 | */ 164 | function setOS() { 165 | $HARDWARE = $this->sxml->CONTENT[0]->HARDWARE; 166 | $HARDWARE->addChild('OSNAME', $this->data['osname']); 167 | $HARDWARE->addChild('OSVERSION', $this->data['osversion']); 168 | } 169 | 170 | /** 171 | * @since 0.90+1.0 172 | * 173 | * Export Bios informations in XML format 174 | */ 175 | function setBios() { 176 | $CONTENT = $this->sxml->CONTENT[0]; 177 | $CONTENT->addChild('BIOS'); 178 | 179 | $BIOS = $this->sxml->CONTENT[0]->BIOS; 180 | $BIOS->addChild('SMODEL', $this->data['model']); 181 | $BIOS->addChild('SMANUFACTURER', $this->data['manufacturer']); 182 | $BIOS->addChild('SSN', $this->data['serial']); 183 | } 184 | 185 | /** 186 | * @since 0.90+1.0 187 | * 188 | * Export softwares informations in XML format 189 | */ 190 | function setSoftwares() { 191 | $i = 0; 192 | $CONTENT = $this->sxml->CONTENT[0]; 193 | foreach ($this->data['applications'] as $application) { 194 | $application = Toolbox::addslashes_deep($application); 195 | //If, for one reason or another the name is not set 196 | //do not export the software in the XML file 197 | if (!isset($application['name']) || ! isset($application['version'])) { 198 | continue; 199 | } 200 | $CONTENT->addChild('SOFTWARES'); 201 | $SOFTWARES = $this->sxml->CONTENT[0]->SOFTWARES[$i]; 202 | $SOFTWARES->addChild('NAME', $application['name']); 203 | $SOFTWARES->addChild('VERSION', $application['version']); 204 | $SOFTWARES->addChild('PUBLISHER', ''); 205 | $SOFTWARES->addChild('DATEINSTALL', ''); 206 | $i++; 207 | } 208 | } 209 | 210 | /** 211 | * @since 0.90+1.0 212 | * 213 | * Export Airwatch specific informations in XML format 214 | */ 215 | function setAirwatchInfos() { 216 | 217 | if (isset($this->data['tag'])) { 218 | $CONTENT = $this->sxml->CONTENT[0]; 219 | $CONTENT->addChild('AIRWATCH'); 220 | 221 | $fields = ['PHONENUMBER', 'LASTSEEN', 'ISENROLLED', "LASTENROLLEDON", 222 | 'ISCOMPLIANT', 'ISCOMPROMISED', 'IMEI', 'airwatchid', 223 | 'CURRENTSIM', 'LASTENROLLMENTCHECKEDON', 'LASTCOMPLIANCECHECKEDON', 224 | 'LASTCOMPROMISEDCHECKEDON', 'DATAENCRYPTION', 'ROAMINGSTATUS', 225 | 'DATAROAMINGENABLED', 'VOICEROAMINGENABLED']; 226 | 227 | $ACCOUNTINFO = $this->sxml->CONTENT[0]->AIRWATCH; 228 | 229 | foreach ($fields as $field) { 230 | if (isset($this->data[$field])) { 231 | $ACCOUNTINFO->addChild($field, $this->data[$field]); 232 | } 233 | } 234 | } 235 | } 236 | 237 | /** 238 | * @since 0.90+1.1 239 | * 240 | * Export profiles informations in XML format 241 | */ 242 | function setCompliance() { 243 | $i = 0; 244 | $CONTENT = $this->sxml->CONTENT[0]; 245 | foreach ($this->data['AIRWATCHCOMPLIANCE'] as $profile) { 246 | $profile = Toolbox::addslashes_deep($profile); 247 | if (!isset($profile['PolicyName']) || ! isset($profile['CompliantStatus'])) { 248 | continue; 249 | } 250 | $CONTENT->addChild('AIRWATCHCOMPLIANCE'); 251 | $AIRWATCHCOMPLIANCE = $this->sxml->CONTENT[0]->AIRWATCHCOMPLIANCE[$i]; 252 | $AIRWATCHCOMPLIANCE->addChild('NAME', $profile['PolicyName']); 253 | $AIRWATCHCOMPLIANCE->addChild('LASTCHECK', $profile['LastComplianceCheck']); 254 | $AIRWATCHCOMPLIANCE->addChild('COMPLIANCESTATUS', $profile['CompliantStatus']); 255 | $i++; 256 | } 257 | } 258 | 259 | } 260 | -------------------------------------------------------------------------------- /hook.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @copyright Copyright (C) 2016-2022 by Teclib'. 26 | * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html 27 | * @link https://github.com/pluginsGLPI/airwatch 28 | * ------------------------------------------------------------------------- 29 | */ 30 | 31 | function plugin_airwatch_getAddSearchOptions($itemtype) { 32 | 33 | $sopt = []; 34 | if ($itemtype == 'Computer') { 35 | $sopt[6000]['table'] = 'glpi_plugin_airwatch_details'; 36 | $sopt[6000]['field'] = 'aw_device_id'; 37 | $sopt[6000]['name'] = __('Airwatch', 'airwatch').'-'.__('Airwatch ID', 'airwatch'); 38 | $sopt[6000]['datatype'] = 'integer'; 39 | $sopt[6000]['joinparams'] = ['jointype' => 'child']; 40 | $sopt[6000]['massiveaction'] = false; 41 | 42 | $sopt[6001]['table'] = 'glpi_plugin_airwatch_details'; 43 | $sopt[6001]['field'] = 'imei'; 44 | $sopt[6001]['name'] = __('Airwatch', 'airwatch').'-'.__('IMEI', 'airwatch'); 45 | $sopt[6001]['datatype'] = 'integer'; 46 | $sopt[6001]['joinparams'] = ['jointype' => 'child']; 47 | $sopt[6001]['massiveaction'] = false; 48 | 49 | $sopt[6002]['table'] = 'glpi_plugin_airwatch_details'; 50 | $sopt[6002]['field'] = 'simcard_serial'; 51 | $sopt[6002]['name'] = __('Airwatch', 'airwatch').'-'. 52 | __('Simcard serial number', 'airwatch'); 53 | $sopt[6002]['datatype'] = 'integer'; 54 | $sopt[6002]['joinparams'] = ['jointype' => 'child']; 55 | $sopt[6002]['massiveaction'] = false; 56 | 57 | $sopt[6003]['table'] = 'glpi_plugin_airwatch_details'; 58 | $sopt[6003]['field'] = 'date_last_seen'; 59 | $sopt[6003]['name'] = __('Airwatch', 'airwatch').'-'. 60 | __('Last seen', 'airwatch'); 61 | $sopt[6003]['datatype'] = 'datetime'; 62 | $sopt[6003]['joinparams'] = ['jointype' => 'child']; 63 | $sopt[6003]['massiveaction'] = false; 64 | 65 | $sopt[6004]['table'] = 'glpi_plugin_airwatch_details'; 66 | $sopt[6004]['field'] = 'date_last_enrollment'; 67 | $sopt[6004]['name'] = __('Airwatch', 'airwatch').'-'. 68 | __('Last enrollment date', 'airwatch'); 69 | $sopt[6004]['datatype'] = 'datetime'; 70 | $sopt[6004]['joinparams'] = ['jointype' => 'child']; 71 | $sopt[6004]['massiveaction'] = false; 72 | 73 | $sopt[6005]['table'] = 'glpi_plugin_airwatch_details'; 74 | $sopt[6005]['field'] = 'date_last_enrollment_check'; 75 | $sopt[6005]['name'] = __('Airwatch', 'airwatch').'-'. 76 | __('Last enrollment check date', 'airwatch'); 77 | $sopt[6005]['datatype'] = 'datetime'; 78 | $sopt[6005]['joinparams'] = ['jointype' => 'child']; 79 | $sopt[6005]['massiveaction'] = false; 80 | 81 | $sopt[6006]['table'] = 'glpi_plugin_airwatch_details'; 82 | $sopt[6006]['field'] = 'date_last_compliance_check'; 83 | $sopt[6006]['name'] = __('Airwatch', 'airwatch').'-'. 84 | __('Last compliance check date', 'airwatch'); 85 | $sopt[6006]['datatype'] = 'datetime'; 86 | $sopt[6006]['joinparams'] = ['jointype' => 'child']; 87 | $sopt[6006]['massiveaction'] = false; 88 | 89 | $sopt[6007]['table'] = 'glpi_plugin_airwatch_details'; 90 | $sopt[6007]['field'] = 'date_last_compromised_check'; 91 | $sopt[6007]['name'] = __('Airwatch', 'airwatch').'-'. 92 | __('Last compromised check date', 'airwatch'); 93 | $sopt[6007]['datatype'] = 'datetime'; 94 | $sopt[6007]['joinparams'] = ['jointype' => 'child']; 95 | $sopt[6007]['massiveaction'] = false; 96 | 97 | $sopt[6008]['table'] = 'glpi_plugin_airwatch_details'; 98 | $sopt[6008]['field'] = 'is_enrolled'; 99 | $sopt[6008]['name'] = __('Airwatch', 'airwatch').'-'. 100 | __('Enrollment status', 'airwatch'); 101 | $sopt[6008]['datatype'] = 'bool'; 102 | $sopt[6008]['joinparams'] = ['jointype' => 'child']; 103 | $sopt[6008]['massiveaction'] = false; 104 | 105 | $sopt[6009]['table'] = 'glpi_plugin_airwatch_details'; 106 | $sopt[6009]['field'] = 'is_compliant'; 107 | $sopt[6009]['name'] = __('Airwatch', 'airwatch').'-'. 108 | __('Compliance status', 'airwatch'); 109 | $sopt[6009]['datatype'] = 'bool'; 110 | $sopt[6009]['joinparams'] = ['jointype' => 'child']; 111 | $sopt[6009]['massiveaction'] = false; 112 | 113 | $sopt[6010]['table'] = 'glpi_plugin_airwatch_details'; 114 | $sopt[6010]['field'] = 'is_compromised'; 115 | $sopt[6010]['name'] = __('Airwatch', 'airwatch').'-'. 116 | __('Compromised status', 'airwatch'); 117 | $sopt[6010]['datatype'] = 'bool'; 118 | $sopt[6010]['joinparams'] = ['jointype' => 'child']; 119 | $sopt[6010]['massiveaction'] = false; 120 | 121 | $sopt[6011]['table'] = 'glpi_plugin_airwatch_details'; 122 | $sopt[6011]['field'] = 'is_dataencryption'; 123 | $sopt[6011]['name'] = __('Airwatch', 'airwatch').'-'. 124 | __('Data encryption', 'airwatch'); 125 | $sopt[6011]['datatype'] = 'bool'; 126 | $sopt[6011]['joinparams'] = ['jointype' => 'child']; 127 | $sopt[6011]['massiveaction'] = false; 128 | $sopt[6011]['searchtype'] = ['equals', 'notequals']; 129 | 130 | $sopt[6012]['table'] = 'glpi_plugin_airwatch_details'; 131 | $sopt[6012]['field'] = 'is_roaming_enabled'; 132 | $sopt[6012]['name'] = __('Airwatch', 'airwatch').'-'. 133 | __('Roaming enabled', 'airwatch'); 134 | $sopt[6012]['datatype'] = 'bool'; 135 | $sopt[6012]['joinparams'] = ['jointype' => 'child']; 136 | $sopt[6012]['massiveaction'] = false; 137 | $sopt[6012]['searchtype'] = ['equals', 'notequals']; 138 | 139 | $sopt[6013]['table'] = 'glpi_plugin_airwatch_details'; 140 | $sopt[6013]['field'] = 'is_data_roaming_enabled'; 141 | $sopt[6013]['name'] = __('Airwatch', 'airwatch').'-'. 142 | __('Data roaming enabled', 'airwatch'); 143 | $sopt[6013]['datatype'] = 'bool'; 144 | $sopt[6013]['joinparams'] = ['jointype' => 'child']; 145 | $sopt[6013]['massiveaction'] = false; 146 | $sopt[6013]['searchtype'] = ['equals', 'notequals']; 147 | 148 | $sopt[6014]['table'] = 'glpi_plugin_airwatch_details'; 149 | $sopt[6014]['field'] = 'is_voice_roaming_enabled'; 150 | $sopt[6014]['name'] = __('Airwatch', 'airwatch').'-'. 151 | __('Voice roaming enabled', 'airwatch'); 152 | $sopt[6014]['datatype'] = 'bool'; 153 | $sopt[6014]['joinparams'] = ['jointype' => 'child']; 154 | $sopt[6014]['massiveaction'] = false; 155 | $sopt[6014]['searchtype'] = ['equals', 'notequals']; 156 | 157 | $sopt[6015]['table'] = 'glpi_plugin_airwatch_compliances'; 158 | $sopt[6015]['field'] = 'name'; 159 | $sopt[6015]['name'] = __('Airwatch', 'airwatch').'-'. 160 | __('Profile', 'airwatch'); 161 | $sopt[6015]['datatype'] = 'string'; 162 | $sopt[6015]['joinparams'] = ['jointype' => 'child']; 163 | $sopt[6015]['massiveaction'] = false; 164 | $sopt[6015]['forcegroupby'] = true; 165 | 166 | $sopt[6016]['table'] = 'glpi_plugin_airwatch_compliances'; 167 | $sopt[6016]['field'] = 'is_compliant'; 168 | $sopt[6016]['name'] = __('Airwatch', 'airwatch').'-'. 169 | __('Profile', 'airwatch').'-'. 170 | __('Compliance status', 'airwatch'); 171 | $sopt[6016]['datatype'] = 'airwatch_bool'; 172 | $sopt[6016]['joinparams'] = ['jointype' => 'child']; 173 | $sopt[6016]['massiveaction'] = false; 174 | $sopt[6016]['forcegroupby'] = true; 175 | $sopt[6016]['searchtype'] = ['equals', 'notequals']; 176 | 177 | $sopt[6017]['table'] = 'glpi_plugin_airwatch_compliances'; 178 | $sopt[6017]['field'] = 'date_last_check'; 179 | $sopt[6017]['name'] = __('Airwatch', 'airwatch').'-'. 180 | __('Profile', 'airwatch').'-'. 181 | __('Last check date', 'airwatch'); 182 | $sopt[6017]['datatype'] = 'datetime'; 183 | $sopt[6017]['joinparams'] = ['jointype' => 'child']; 184 | $sopt[6017]['forcegroupby'] = false; 185 | $sopt[6017]['massiveaction'] = true; 186 | 187 | $sopt[6018]['table'] = 'glpi_plugin_airwatch_details'; 188 | $sopt[6018]['field'] = 'phone_number'; 189 | $sopt[6018]['name'] = __('Airwatch', 'airwatch').'-'.__('Phone number'); 190 | $sopt[6018]['joinparams'] = ['jointype' => 'child']; 191 | $sopt[6018]['massiveaction'] = false; 192 | $sopt[6018]['forcegroupby'] = true; 193 | 194 | } 195 | 196 | return $sopt; 197 | } 198 | 199 | function plugin_airwatch_giveItem($type, $ID, $data, $num) { 200 | global $CFG_GLPI; 201 | $searchopt = &Search::getOptions($type); 202 | $table = $searchopt[$ID]["table"]; 203 | $field = $searchopt[$ID]["field"]; 204 | 205 | switch ($table . '.' . $field) { 206 | case "glpi_plugin_airwatch_details.is_enrolled": 207 | case "glpi_plugin_airwatch_details.is_compromised": 208 | case "glpi_plugin_airwatch_details.is_compliant": 209 | case "glpi_plugin_airwatch_compliances.is_compliant": 210 | $message = ""; 211 | if ($data['raw']["ITEM_" . $num]) { 212 | $message = PluginAirwatchDetail::showYesNoNotSet($data['raw']["ITEM_" . $num]); 213 | } 214 | return $message; 215 | } 216 | } 217 | 218 | function plugin_airwatch_searchOptionsValues($type, $ID, $data, $num) { 219 | global $CFG_GLPI; 220 | $searchopt = &Search::getOptions($type); 221 | $table = $searchopt[$ID]["table"]; 222 | $field = $searchopt[$ID]["field"]; 223 | 224 | switch ($table . '.' . $field) { 225 | case "glpi_plugin_airwatch_details.is_enrolled": 226 | case "glpi_plugin_airwatch_details.is_compromised": 227 | case "glpi_plugin_airwatch_details.is_compliant": 228 | case "glpi_plugin_airwatch_compliances.is_compliant": 229 | switch ($data['raw']["ITEM_" . $num]) { 230 | case -1: 231 | return __('None'); 232 | case 0: 233 | return __('No'); 234 | case 1: 235 | return __('Yes'); 236 | } 237 | return ''; 238 | } 239 | } 240 | 241 | /***************** Install / uninstall functions **************/ 242 | 243 | function plugin_airwatch_install() { 244 | $airwatch_dir = Plugin::getPhpDir('airwatch'); 245 | 246 | $migration = new Migration(PLUGIN_AIRWATCH_VERSION); 247 | include ($airwatch_dir."/inc/config.class.php"); 248 | include ($airwatch_dir."/inc/airwatch.class.php"); 249 | include ($airwatch_dir."/inc/detail.class.php"); 250 | include ($airwatch_dir."/inc/compliance.class.php"); 251 | PluginairwatchConfig::install($migration); 252 | PluginAirwatchAirwatch::install($migration); 253 | PluginAirwatchDetail::install($migration); 254 | PluginAirwatchCompliance::install($migration); 255 | return true; 256 | } 257 | 258 | function plugin_airwatch_uninstall() { 259 | $airwatch_dir = Plugin::getPhpDir('airwatch'); 260 | 261 | $migration = new Migration(PLUGIN_AIRWATCH_VERSION); 262 | include ($airwatch_dir."/inc/config.class.php"); 263 | include ($airwatch_dir."/inc/detail.class.php"); 264 | include ($airwatch_dir."/inc/compliance.class.php"); 265 | PluginairwatchConfig::uninstall($migration); 266 | PluginairwatchDetail::uninstall($migration); 267 | PluginAirwatchCompliance::uninstall($migration); 268 | return true; 269 | } 270 | -------------------------------------------------------------------------------- /inc/airwatch.class.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @copyright Copyright (C) 2016-2022 by Teclib'. 26 | * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html 27 | * @link https://github.com/pluginsGLPI/airwatch 28 | * ------------------------------------------------------------------------- 29 | */ 30 | 31 | if (!defined('GLPI_ROOT')) { 32 | die("Sorry. You can't access directly to this file"); 33 | } 34 | 35 | class PluginAirwatchAirwatch extends CommonDBTM { 36 | 37 | //Do not record historical, because details are deleted and recreated at each inventory 38 | public $dohistory = false; 39 | 40 | /** 41 | * Cron method to export devices to XML files 42 | */ 43 | static function cronairwatchImport($task) { 44 | 45 | //Total of export lines 46 | $index = 0; 47 | 48 | $results = PluginAirwatchRest::getDevices(); 49 | if ($results['status'] == AIRWATCH_API_RESULT_OK 50 | && !empty($results['array_data']) && isset($results['array_data']['Devices'])) { 51 | foreach ($results['array_data']['Devices'] as $device) { 52 | if (empty($device)) { 53 | continue; 54 | } 55 | self::importDevice($device); 56 | $index++; 57 | } 58 | } 59 | $task->addVolume($index); 60 | return true; 61 | } 62 | 63 | static function cronInfo($name) { 64 | return ['description' => __("Import devices informations from Airwatch", "airwatch")]; 65 | } 66 | 67 | /** 68 | * @since 0.90+1.0 69 | * 70 | * Perform an inventory for one device 71 | * 72 | * @param aw_device_id the device's Airwatch ID 73 | */ 74 | static function doOneDeviceInventory($aw_device_id) { 75 | $results = PluginAirwatchRest::getDevice($aw_device_id); 76 | if ($results['status'] == AIRWATCH_API_RESULT_OK) { 77 | self::importDevice($results['array_data']); 78 | } else { 79 | Session::addMessageAfterRedirect(__("Error on executing the action"), true, ERROR, true); 80 | } 81 | } 82 | 83 | /** 84 | * @since 0.90+1.0 85 | * 86 | * Build the inventory and send it to FusionInventory for import and update 87 | * @param aw_data device infomations, as sent by the REST API 88 | * @return 89 | */ 90 | static function importDevice($aw_data = []) { 91 | //Array to store device inventory, as requested by FusionInventory 92 | $inventory = []; 93 | 94 | $inventory['VERSIONCLIENT'] = AIRWATCH_USER_AGENT; 95 | $inventory['type'] = 'Smartphone'; 96 | 97 | $fields = ['LocationGroupName' => 'tag', 98 | 'Platform' => 'manufacturer', 99 | 'Model' => 'model', 100 | 'SerialNumber' => 'serial', 101 | 'PhoneNumber' => 'PHONENUMBER', 102 | 'LastSeen' => 'LASTSEEN', 103 | "LastEnrolledOn" => 'LASTENROLLEDON', 104 | "LastCompromisedCheckOn" => 'LASTCOMPROMISEDCHECKEDON', 105 | "LastEnrollmentCheckOn" => 'LASTENROLLMENTCHECKEDON', 106 | "LastComplianceCheckOn" => 'LASTCOMPLIANCECHECKEDON', 107 | 'DataEncryptionYN' => 'DATAENCRYPTION', 108 | 'Imei' => 'IMEI', 109 | 'DeviceFriendlyName' => 'name', 110 | 'OperatingSystem' => 'osversion', 111 | 'UserName' => 'userid', 112 | 'Udid' => 'uuid']; 113 | foreach ($fields as $aw => $fusion) { 114 | if (isset($aw_data[$aw])) { 115 | //Check if data is encodeded in utf8. 116 | //If not, let's encode it ! 117 | if (!Toolbox::seems_utf8($aw_data[$aw])) { 118 | $aw_data[$aw] = Toolbox::encodeInUtf8($aw_data[$aw]); 119 | } 120 | $inventory[$fusion] = $aw_data[$aw]; 121 | } else { 122 | $inventory[$fusion] = ''; 123 | } 124 | } 125 | 126 | $inventory['DEVICEID'] = $inventory['IMEI']; 127 | 128 | if (isset($aw_data['EnrollmentStatus'])) { 129 | if ($aw_data['EnrollmentStatus'] == 'Enrolled') { 130 | $inventory['ISENROLLED'] = 1; 131 | } else { 132 | $inventory['ISENROLLED'] = 0; 133 | } 134 | } 135 | 136 | if (isset($aw_data['CompromisedStatus'])) { 137 | if ($aw_data['CompromisedStatus'] == 'true') { 138 | $inventory['ISCOMPROMISED'] = 1; 139 | } else { 140 | $inventory['ISCOMPROMISED'] = 0; 141 | } 142 | } 143 | 144 | if (isset($aw_data['ComplianceStatus'])) { 145 | if ($aw_data['ComplianceStatus'] == 'Compliant') { 146 | $inventory['ISCOMPLIANT'] = 1; 147 | } else { 148 | $inventory['ISCOMPLIANT'] = 0; 149 | } 150 | } 151 | 152 | if (isset($aw_data['OperatingSystem'])) { 153 | switch ($aw_data['Platform']) { 154 | case 'Apple': 155 | $inventory['osname'] = 'iOS'; 156 | break; 157 | case 'Android': 158 | $inventory['osname'] = 'Android'; 159 | if (preg_match('/^(.*) (.*)$/', $aw_data['Model'], $results)) { 160 | $inventory['manufacturer'] = $results[1]; 161 | $inventory['model'] = $results[2]; 162 | } 163 | break; 164 | 165 | } 166 | } 167 | 168 | if (is_array($aw_data['Id'])) { 169 | $inventory['airwatchid'] = $aw_data['Id']['Value']; 170 | } 171 | 172 | $inventory['applications'] = []; 173 | 174 | //Get applications from Airwatch 175 | $applications = PluginAirwatchRest::getDeviceApplications($inventory['airwatchid']); 176 | if ($applications['status'] == AIRWATCH_API_RESULT_OK) { 177 | if (isset($applications['array_data']['DeviceApps']) 178 | && is_array($applications['array_data']['DeviceApps'])) { 179 | foreach ($applications['array_data']['DeviceApps'] as $application) { 180 | if (!Toolbox::seems_utf8($application['ApplicationName'])) { 181 | $application['ApplicationName'] = Toolbox::encodeInUtf8($application['ApplicationName']); 182 | } 183 | if (!Toolbox::seems_utf8($application['Version'])) { 184 | $application['Version'] = Toolbox::encodeInUtf8($application['Version']); 185 | } 186 | $inventory['applications'][] = ['name' => $application['ApplicationName'], 187 | 'version' => $application['Version']]; 188 | } 189 | } 190 | } 191 | 192 | //Get Network informations 193 | $networks = PluginAirwatchRest::getDeviceNetworkInfo($inventory['airwatchid']); 194 | if ($networks['status'] == AIRWATCH_API_RESULT_OK) { 195 | $network = $networks['array_data']; 196 | $fields = ['RoamingStatus', 'DataRoamingEnabled', 'VoiceRoamingEnabled']; 197 | foreach ($fields as $field) { 198 | if (isset($network[$field])) { 199 | $inventory[strtoupper($field)] = $network[$field]; 200 | } 201 | } 202 | //Get the wifi card mac address 203 | if (isset($network['WifiInfo']) 204 | && !empty($network['WifiInfo']) 205 | && isset($network['WifiInfo']['WifiMacAddress'])) { 206 | $inventory['wifi_macaddress'] = $network['WifiInfo']['WifiMacAddress']; 207 | } 208 | //Get the current simcard serial number 209 | if (isset($network['CellularNetworkInfo']['CurrentSIM'])) { 210 | $inventory['CURRENTSIM'] = $network['CellularNetworkInfo']['CurrentSIM']; 211 | } 212 | //Get ID addresses available 213 | if (isset($network['IPAddress']) && !empty($network['IPAddress'])) { 214 | if (isset($network['IPAddress']['WifiIPAddress'])) { 215 | $inventory['wifi_ipaddress'] = $network['IPAddress']['WifiIPAddress']; 216 | } 217 | if (isset($network['IPAddress']['CellularIPAddress'])) { 218 | $inventory['wifi_ipaddress'] = $network['IPAddress']['CellularIPAddress']; 219 | } 220 | } 221 | } 222 | 223 | //Get Network informations 224 | $compliances = PluginAirwatchRest::getDeviceCompliance($inventory['airwatchid']); 225 | if ($compliances['status'] == AIRWATCH_API_RESULT_OK) { 226 | if (isset($compliances['array_data']['DeviceCompliance']) 227 | && is_array($compliances['array_data']['DeviceCompliance'])) { 228 | foreach ($compliances['array_data']['DeviceCompliance'] as $compliance) { 229 | $inventory['AIRWATCHCOMPLIANCE'][] = $compliance; 230 | } 231 | } 232 | } 233 | 234 | //Generate an inventory XML file 235 | $aw_xml = new PluginAirwatchXml($inventory); 236 | 237 | //Send the file to FusionInventory 238 | self::sendInventoryToPlugin($aw_xml->sxml); 239 | } 240 | 241 | /** 242 | * @since 0.90+1.0 243 | * 244 | * Send an XML inventory to FusionInventory over HTTP 245 | * @param confg plugin configuration 246 | * @param xml_data inventory in XML format 247 | */ 248 | static function sendInventoryToPlugin($xml_data) { 249 | $config = new PluginAirwatchConfig(); 250 | $config->getFromDB(1); 251 | 252 | //Do not send inventory if no service url defined 253 | if (!$config->getField('fusioninventory_url')) { 254 | return true; 255 | } 256 | $ch = curl_init(); 257 | curl_setopt($ch, CURLOPT_URL, $config->getField('fusioninventory_url')); 258 | curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: text/xml']); 259 | curl_setopt($ch, CURLOPT_USERAGENT, AIRWATCH_USER_AGENT); 260 | curl_setopt($ch, CURLOPT_HEADER, 0); 261 | curl_setopt($ch, CURLOPT_POST, 1); 262 | curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_data->asXML()); 263 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); 264 | curl_setopt($ch, CURLOPT_REFERER, $config->getField('fusioninventory_url')); 265 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 266 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 267 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); 268 | $ch_result = curl_exec($ch); 269 | //Get curl error 270 | $error = curl_error($ch); 271 | if($error){ 272 | Toolbox::logWarning($error); 273 | } 274 | curl_close($ch); 275 | } 276 | 277 | 278 | /** 279 | * @since 0.90+1.0 280 | * 281 | * Convert Airwatch date to GLPi DB format 282 | * @param airwatch date 283 | * @return date in Y-m-d H:i:s format 284 | */ 285 | static function convertAirwatchDate($aw_date) { 286 | //Do not process this kind of dates coming from Airwatch : not representative 287 | if (preg_match("/^0001/", $aw_date)) { 288 | return ''; 289 | } else { 290 | $date = new DateTime($aw_date); 291 | return date_format($date, 'Y-m-d H:i:s'); 292 | } 293 | } 294 | 295 | /************** FusionInventory hooks ***************/ 296 | 297 | /** 298 | * @since 0.90+1.0 299 | * 300 | * Add Airwatch informations coming from the XML inventory 301 | * @param params Airwatch section in the XML file 302 | */ 303 | static function updateInventory($params = []) { 304 | //Toolbox::logDebug("updateInventory", $params); 305 | global $DB; 306 | 307 | if (!empty($params) 308 | && isset($params['inventory_data']) && !empty($params['inventory_data'])) { 309 | 310 | //Get data to be processed 311 | $data = $params['inventory_data']; 312 | $computers_id = $params['computers_id']; 313 | 314 | //Always delete details 315 | $detail = new PluginAirwatchDetail(); 316 | $detail->deletebyCriteria(['computers_id' => $computers_id]); 317 | 318 | //Delete airwatch profiles 319 | PluginAirwatchCompliance::deleteForComputer($computers_id); 320 | 321 | $tmp['computers_id'] = $computers_id; 322 | $fields = ['ROAMINGSTATUS' => 'is_roaming_enabled', 323 | 'DATAROAMINGENABLED' => 'is_data_roaming_enabled', 324 | 'VOICEROAMINGENABLED' => 'is_voice_roaming_enabled', 325 | 'CURRENTSIM' => 'simcard_serial', 326 | 'IMEI' => 'imei', 327 | 'PHONENUMBER' => 'phone_number', 328 | 'ISCOMPLIANT' => 'is_compliant', 329 | 'ISCOMPROMISED' => 'is_compromised', 330 | 'ISENROLLED' => 'is_enrolled', 331 | 'AIRWATCHID' => 'aw_device_id']; 332 | foreach ($fields as $xml_field => $glpifield) { 333 | if (isset($data['AIRWATCH'][$xml_field]) && $data['AIRWATCH'][$xml_field]) { 334 | $tmp[$glpifield] = $data['AIRWATCH'][$xml_field]; 335 | } else { 336 | if (preg_match('/is_/', $glpifield)) { 337 | $tmp[$glpifield] = '-1'; 338 | } else { 339 | $tmp[$glpifield] = ''; 340 | } 341 | } 342 | } 343 | 344 | if (isset($data['AIRWATCH']['DATAENCRYPTION'])) { 345 | if ($data['AIRWATCH']['DATAENCRYPTION'] == 'Y') { 346 | $tmp['is_dataencryption'] = '1'; 347 | } else { 348 | $tmp['is_dataencryption'] = '0'; 349 | } 350 | } 351 | $dates = ['LASTSEEN' => 'date_last_seen', 352 | 'LASTENROLLEDON' => 'date_last_enrollment', 353 | 'LASTENROLLMENTCHECKEDON' => 'date_last_enrollment_check', 354 | 'LASTCOMPLIANCECHECKEDON' => 'date_last_compliance_check', 355 | 'LASTCOMPROMISEDCHECKEDON' => 'date_last_compromised_check']; 356 | foreach ($dates as $xmldate => $glpidate) { 357 | if (isset($data['AIRWATCH'][$xmldate])) { 358 | $tmpdate = self::convertAirwatchDate($data['AIRWATCH'][$xmldate]); 359 | if ($tmpdate) { 360 | $tmp[$glpidate] = $tmpdate; 361 | } 362 | } 363 | } 364 | $detail->add($tmp); 365 | 366 | if (isset($data['AIRWATCHCOMPLIANCE'])) { 367 | $compliances = []; 368 | $go = true; 369 | 370 | if (isset($data['AIRWATCHCOMPLIANCE']['NAME'])) { 371 | $compliances = [$data['AIRWATCHCOMPLIANCE']]; 372 | } else if (is_array($data['AIRWATCHCOMPLIANCE'])) { 373 | $compliances = $data['AIRWATCHCOMPLIANCE']; 374 | } else { 375 | $go = false; 376 | } 377 | 378 | if ($go) { 379 | foreach ($compliances as $compliance) { 380 | $tmpdate = self::convertAirwatchDate($compliance['LASTCHECK']); 381 | 382 | PluginAirwatchCompliance::addProfile($computers_id, 383 | $compliance['NAME'], 384 | $compliance['COMPLIANCESTATUS'], 385 | $tmpdate); 386 | } 387 | } 388 | } 389 | } 390 | } 391 | 392 | static function addInventoryInfos($params = []) { 393 | $values = []; 394 | if (isset($params['source']) 395 | && isset($params['source']['AIRWATCH']) 396 | && is_array($params['source']['AIRWATCH']) 397 | && !empty($params['source']['AIRWATCH'])) { 398 | //Add airwatch info to the list of data to be processed 399 | foreach ($params['source']['AIRWATCH'] as $field => $value) { 400 | $values['AIRWATCH'][$field] = $value; 401 | } 402 | if (isset($params['source']['AIRWATCHCOMPLIANCE'])) { 403 | foreach ($params['source']['AIRWATCHCOMPLIANCE'] as $field => $value) { 404 | $values['AIRWATCHCOMPLIANCE'][$field] = $value; 405 | } 406 | } 407 | } 408 | return $values; 409 | } 410 | 411 | static function install(Migration $migration) { 412 | $cron = new CronTask; 413 | if (!$cron->getFromDBbyName(__CLASS__, 'airwatchImport')) { 414 | CronTask::Register(__CLASS__, 'airwatchImport', DAY_TIMESTAMP, 415 | ['param' => 24, 'mode' => CronTask::MODE_EXTERNAL]); 416 | } 417 | } 418 | } 419 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /inc/detail.class.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @copyright Copyright (C) 2016-2022 by Teclib'. 26 | * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html 27 | * @link https://github.com/pluginsGLPI/airwatch 28 | * ------------------------------------------------------------------------- 29 | */ 30 | 31 | if (!defined('GLPI_ROOT')) { 32 | die("Sorry. You can't access directly to this file"); 33 | } 34 | 35 | /** 36 | * Store and display Airwatch informations for a device 37 | */ 38 | class PluginAirwatchDetail extends CommonDBTM { 39 | 40 | //Do not record historical, because details are deleted and recreated at each inventory 41 | public $dohistory = false; 42 | 43 | 44 | static function getTypeName($nb = 0) { 45 | return __('Airwatch'); 46 | } 47 | 48 | /** 49 | * @see CommonGLPI::getTabNameForItem() 50 | **/ 51 | function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) { 52 | 53 | // can exists for template 54 | if (($item->getType() == 'Computer') 55 | && Computer::canView()) { 56 | $nb = countElementsInTable( 57 | 'glpi_plugin_airwatch_details', 58 | ['computers_id' => $item->getID()] 59 | ); 60 | if (!$nb) { 61 | return ''; 62 | } else { 63 | return self::createTabEntry(self::getTypeName(Session::getPluralNumber()), $nb); 64 | } 65 | } 66 | return ''; 67 | } 68 | 69 | 70 | /** 71 | * @param $item CommonGLPI object 72 | * @param $tabnum (default 1) 73 | * @param $withtemplate (default 0) 74 | */ 75 | static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) { 76 | self::showForComputer($item, $withtemplate); 77 | return true; 78 | } 79 | 80 | 81 | function getFromDBbComputerID($computers_id) { 82 | global $DB; 83 | 84 | $query = "SELECT `id` FROM `glpi_plugin_airwatch_details` 85 | WHERE `computers_id`='$computers_id'"; 86 | 87 | $result = $DB->query($query); 88 | if ($DB->numrows($result)) { 89 | $id = $DB->result($result, 0, 'id'); 90 | $this->getFromDB($id); 91 | return true; 92 | } else { 93 | return false; 94 | } 95 | } 96 | 97 | static function showForComputer(CommonDBTM $item, $withtemplate = '') { 98 | 99 | $detail = new self(); 100 | if (!$detail->getFromDBbComputerID($item->getID())) { 101 | return true; 102 | } 103 | 104 | echo "
"; 105 | echo ""; 106 | 107 | echo ""; 108 | 109 | echo ""; 110 | 111 | echo ""; 112 | echo ""; 113 | echo ""; 116 | 117 | echo ""; 118 | echo ""; 122 | echo ""; 123 | 124 | echo ""; 125 | echo ""; 126 | echo ""; 129 | echo ""; 136 | echo ""; 137 | 138 | echo ""; 139 | echo ""; 140 | echo ""; 143 | echo ""; 144 | echo ""; 147 | echo ""; 148 | 149 | //If airwatch console url is set, display a link 150 | $config = new PluginAirwatchConfig(); 151 | $config->getFromDB(1); 152 | if ($config->fields['airwatch_console_url'] > '' && $detail->fields['aw_device_id'] > 0) { 153 | echo ""; 154 | $url = $config->fields['airwatch_console_url']. 155 | '/#/Airwatch/Device/Details/Summary/'. 156 | $detail->fields['aw_device_id']; 157 | echo ""; 160 | echo ""; 161 | } 162 | 163 | echo ""; 164 | 165 | echo ""; 166 | echo ""; 167 | echo ""; 170 | echo ""; 171 | echo ""; 178 | echo ""; 179 | 180 | echo ""; 181 | echo ""; 182 | echo ""; 189 | echo ""; 190 | echo ""; 191 | 192 | echo ""; 193 | 194 | echo ""; 195 | echo ""; 196 | echo ""; 199 | echo ""; 200 | echo ""; 207 | echo ""; 208 | 209 | echo ""; 210 | echo ""; 211 | echo ""; 214 | echo ""; 215 | echo ""; 222 | echo ""; 223 | 224 | echo ""; 225 | 226 | echo ""; 227 | echo ""; 228 | echo ""; 231 | echo ""; 232 | echo ""; 235 | echo ""; 236 | 237 | echo ""; 238 | echo ""; 239 | echo ""; 242 | echo ""; 244 | echo ""; 245 | 246 | PluginAirwatchCompliance::showForComputer($item, $withtemplate); 247 | 248 | //To refresh an inventory, you must be able to update a computer 249 | if (self::canRefresh()) { 250 | echo ""; 251 | echo ""; 255 | echo ""; 256 | } 257 | 258 | echo "
" . __("General", "airwatch") . "
" . __("Serial number") . ""; 114 | echo $detail->fields['imei']; 115 | echo "" . __("Airwatch ID", "airwatch") . ""; 119 | echo $detail->fields['aw_device_id']; 120 | echo ""; 121 | echo "
" . __("Phone number", "airwatch") . ""; 127 | echo $detail->fields['phone_number']; 128 | echo "" . __("Last seen", "airwatch") . ""; 130 | if ($detail->fields['date_last_seen']) { 131 | echo self::getHumanReadableDate($_SESSION['glpi_currenttime'], 132 | $detail->fields['date_last_seen'], 133 | 1); 134 | } 135 | echo "
" . __("Data encryption enabled", "airwatch") . ""; 141 | echo self::showYesNoNotSet($detail->fields['is_dataencryption']); 142 | echo "" . __("Current SIM serial number", "airwatch") . ""; 145 | echo $detail->fields['simcard_serial']; 146 | echo "
"; 158 | echo "" 159 | .__("See device in Airwatch console", "airwatch")."
" . __("Enrollment process", "airwatch") . "
" . __("Enrollment status", "airwatch") . ""; 168 | echo self::showYesNoNotSet($detail->fields['is_enrolled']); 169 | echo "" . __("Last enrollment date", "airwatch") . ""; 172 | if ($detail->fields['date_last_enrollment']) { 173 | echo self::getHumanReadableDate($_SESSION['glpi_currenttime'], 174 | $detail->fields['date_last_enrollment'], 175 | 1); 176 | } 177 | echo "
" . __("Last enrollment check", "airwatch") . ""; 183 | if ($detail->fields['date_last_enrollment_check']) { 184 | echo self::getHumanReadableDate($_SESSION['glpi_currenttime'], 185 | $detail->fields['date_last_enrollment_check'], 186 | 1); 187 | } 188 | echo "
" . __("Other status checks", "airwatch") . "
" . __("Compliance status", "airwatch") . ""; 197 | echo self::showYesNoNotSet($detail->fields['is_compliant'], true); 198 | echo "" . __("Last compliance check date", "airwatch") . ""; 201 | if ($detail->fields['date_last_compliance_check']) { 202 | echo self::getHumanReadableDate($_SESSION['glpi_currenttime'], 203 | $detail->fields['date_last_compliance_check'], 204 | 1); 205 | } 206 | echo "
" . __("Compromised status", "airwatch") . ""; 212 | echo self::showYesNoNotSet($detail->fields['is_compromised']); 213 | echo "" . __("Last compromised check date", "airwatch") . ""; 216 | if ($detail->fields['date_last_compromised_check']) { 217 | echo self::getHumanReadableDate($_SESSION['glpi_currenttime'], 218 | $detail->fields['date_last_compromised_check'], 219 | 1); 220 | } 221 | echo "
" . __("Roaming", "airwatch") . "
" . __("Roaming enabled", "airwatch") . ""; 229 | echo self::showYesNoNotSet($detail->fields['is_roaming_enabled']); 230 | echo "" . __("Data roaming enabled", "airwatch") . ""; 233 | echo self::showYesNoNotSet($detail->fields['is_data_roaming_enabled']); 234 | echo "
" . __("Voice roaming enabled", "airwatch") . ""; 240 | echo self::showYesNoNotSet($detail->fields['is_voice_roaming_enabled']); 241 | echo ""; 243 | echo "
"; 252 | echo ""; 254 | echo"
"; 259 | Html::closeForm(); 260 | echo "
"; 261 | } 262 | 263 | /** 264 | * @since 0.90+1.0 265 | * 266 | * Delete airwatch details when a computer is purged 267 | * @param computer the Computer object 268 | */ 269 | static function cleanOnPurge(Computer $computer) { 270 | $detail = new self(); 271 | $detail->deleteByCriteria(['computers_id' => $computer->getID()]); 272 | } 273 | 274 | /** 275 | * Display informations about computer (bios...) 276 | * 277 | * @param type $computers_id 278 | */ 279 | static function showInfo($item) { 280 | global $CFG_GLPI; 281 | 282 | $detail = new self(); 283 | if (!$detail->getFromDBbComputerID($item->getID())) { 284 | return true; 285 | } 286 | 287 | echo ''; 288 | echo ''; 289 | echo ''; 290 | echo ''; 291 | 292 | echo ''; 293 | echo ''; 296 | echo ''; 299 | echo ''; 300 | 301 | echo ""; 302 | echo ""; 303 | echo ""; 306 | echo ''; 307 | 308 | echo '
'.__('Airwatch', 'airwatch').'
'; 294 | echo __('Phone number', 'airwatch'); 295 | echo ''; 297 | echo $detail->fields['phone_number']; 298 | echo '
" . __("Compliance status", "airwatch") . ""; 304 | echo self::showYesNoNotSet($detail->fields['is_compliant']); 305 | echo "
'; 309 | } 310 | 311 | /** 312 | * Get human readable time difference between 2 dates 313 | * 314 | * Return difference between 2 dates in year, month, hour, minute or second 315 | * The $precision caps the number of time units used: for instance if 316 | * $time1 - $time2 = 3 days, 4 hours, 12 minutes, 5 seconds 317 | * - with precision = 1 : 3 days 318 | * - with precision = 2 : 3 days, 4 hours 319 | * - with precision = 3 : 3 days, 4 hours, 12 minutes 320 | * 321 | * From: http://www.if-not-true-then-false.com/2010/php-calculate-real-differences-between-two-dates-or-timestamps/ 322 | * 323 | * @param mixed $time1 a time (string or timestamp) 324 | * @param mixed $time2 a time (string or timestamp) 325 | * @param integer $precision Optional precision 326 | * @return string time difference 327 | */ 328 | static function getHumanReadableDate($time1, $time2, $precision = 2) { 329 | // If not numeric then convert timestamps 330 | if (!is_int( $time1 )) { 331 | $time1 = strtotime( $time1 ); 332 | } 333 | if (!is_int( $time2 )) { 334 | $time2 = strtotime( $time2 ); 335 | } 336 | 337 | // If time1 > time2 then swap the 2 values 338 | if ($time1 > $time2) { 339 | list( $time1, $time2 ) = [ $time2, $time1 ]; 340 | } 341 | 342 | // Set up intervals and diffs arrays 343 | $intervals = ['year', 'month', 'day', 'hour', 'minute', 'second' ]; 344 | $diffs = []; 345 | 346 | foreach ($intervals as $interval) { 347 | // Create temp time from time1 and interval 348 | $ttime = strtotime( '+1 ' . $interval, $time1 ); 349 | // Set initial values 350 | $add = 1; 351 | $looped = 0; 352 | // Loop until temp time is smaller than time2 353 | while ($time2 >= $ttime) { 354 | // Create new temp time from time1 and interval 355 | $add++; 356 | $ttime = strtotime( "+" . $add . " " . $interval, $time1 ); 357 | $looped++; 358 | } 359 | 360 | $time1 = strtotime( "+" . $looped . " " . $interval, $time1 ); 361 | $diffs[ $interval ] = $looped; 362 | } 363 | 364 | $count = 0; 365 | $times = []; 366 | foreach ($diffs as $interval => $value) { 367 | // Break if we have needed precission 368 | if ($count >= $precision) { 369 | break; 370 | } 371 | // Add value and interval if value is bigger than 0 372 | if ($value > 0) { 373 | // Add value and interval to times array 374 | $times[] = Dropdown::getValueWithUnit($value, $interval); 375 | $count++; 376 | } 377 | } 378 | 379 | // Return string with times 380 | return implode( ", ", $times ); 381 | } 382 | 383 | /** 384 | * since 0.90+1.1 385 | * 386 | * Delete all profiles informations for a device 387 | * @param computers_id GLPi device ID 388 | */ 389 | static function deleteForComputer($computers_id) { 390 | global $DB; 391 | 392 | $query = "DELETE FROM `glpi_plugin_airwatch_airwatchprofiles` 393 | WHERE `computers_id`='$computers_id'"; 394 | $DB->query($query); 395 | } 396 | 397 | static function canRefresh() { 398 | return (PluginAirwatchRest::testConnection() && Computer::canUpdate()); 399 | } 400 | 401 | static function showYesNoNotSet($value, $show_warning = false) { 402 | switch ($value) { 403 | case -1: 404 | return ""; 405 | case 0: 406 | if ($show_warning) { 407 | return ""; 408 | } 409 | return ""; 410 | case 1: 411 | return ""; 412 | } 413 | } 414 | 415 | //----------------- Install & uninstall -------------------// 416 | public static function install(Migration $migration) { 417 | global $DB; 418 | 419 | $config = new self(); 420 | 421 | //This class is available since version 1.3.0 422 | if (!$DB->tableExists("glpi_plugin_airwatch_details")) { 423 | $migration->displayMessage("Install glpi_plugin_airwatch_details"); 424 | 425 | //Install 426 | $query = "CREATE TABLE `glpi_plugin_airwatch_details` ( 427 | `id` int(11) NOT NULL auto_increment, 428 | `computers_id` int(11) NOT NULL DEFAULT '0', 429 | `aw_device_id` int(11) NOT NULL DEFAULT '0', 430 | `imei` varchar(255) character set utf8 collate utf8_unicode_ci NOT NULL DEFAULT '', 431 | `simcard_serial` varchar(255) character set utf8 collate utf8_unicode_ci NOT NULL DEFAULT '', 432 | `phone_number` varchar(255) character set utf8 collate utf8_unicode_ci NOT NULL DEFAULT '', 433 | `date_mod` timestamp NULL DEFAULT NULL, 434 | `date_creation` timestamp NULL DEFAULT NULL, 435 | `date_last_seen` timestamp NULL DEFAULT NULL, 436 | `date_last_enrollment` timestamp NULL DEFAULT NULL, 437 | `date_last_enrollment_check` timestamp NULL DEFAULT NULL, 438 | `date_last_compliance_check` timestamp NULL DEFAULT NULL, 439 | `date_last_compromised_check` timestamp NULL DEFAULT NULL, 440 | `is_enrolled` tinyint(1) NOT NULL DEFAULT '0', 441 | `is_compliant` tinyint(1) NOT NULL DEFAULT '-1', 442 | `is_compromised` tinyint(1) NOT NULL DEFAULT '-1', 443 | `is_dataencryption` tinyint(1) NOT NULL DEFAULT '-1', 444 | `is_roaming_enabled` tinyint(1) NOT NULL DEFAULT '-1', 445 | `is_data_roaming_enabled` tinyint(1) NOT NULL DEFAULT '-1', 446 | `is_voice_roaming_enabled` tinyint(1) NOT NULL DEFAULT '-1', 447 | PRIMARY KEY (`id`), 448 | KEY `computers_id` (`computers_id`), 449 | KEY `aw_device_id` (`aw_device_id`), 450 | KEY `imei` (`imei`), 451 | KEY `simcard_serial` (`simcard_serial`), 452 | KEY `date_last_seen` (`date_last_seen`), 453 | KEY `date_last_enrollment` (`date_last_enrollment`), 454 | KEY `date_last_enrollment_check` (`date_last_enrollment_check`), 455 | KEY `date_last_compliance_check` (`date_last_compliance_check`), 456 | KEY `date_last_compromised_check` (`date_last_compromised_check`), 457 | KEY `is_enrolled` (`is_enrolled`), 458 | KEY `is_compliant` (`is_compliant`), 459 | KEY `is_compromised` (`is_compromised`), 460 | KEY `is_dataencryption` (`is_dataencryption`), 461 | KEY `is_roaming_enabled` (`is_roaming_enabled`), 462 | KEY `is_data_roaming_enabled` (`is_data_roaming_enabled`), 463 | KEY `is_voice_roaming_enabled` (`is_voice_roaming_enabled`) 464 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;"; 465 | $DB->query($query) or die ($DB->error()); 466 | } else { 467 | $migration->changeField('glpi_plugin_airwatch_details', 'is_compliant', 'is_compliant', 468 | 'TINYINT(1) NOT NULL DEFAULT \'-1\''); 469 | $migration->changeField('glpi_plugin_airwatch_details', 'is_compromised', 'is_compromised', 470 | 'TINYINT(1) NOT NULL DEFAULT \'-1\''); 471 | $migration->changeField('glpi_plugin_airwatch_details', 'is_dataencryption', 472 | 'is_dataencryption', 'TINYINT(1) NOT NULL DEFAULT \'-1\''); 473 | $migration->changeField('glpi_plugin_airwatch_details', 'is_roaming_enabled', 474 | 'is_roaming_enabled', 'TINYINT(1) NOT NULL DEFAULT \'-1\''); 475 | $migration->changeField('glpi_plugin_airwatch_details', 'is_data_roaming_enabled', 476 | 'is_data_roaming_enabled', 'TINYINT(1) NOT NULL DEFAULT \'-1\''); 477 | $migration->changeField('glpi_plugin_airwatch_details', 'is_voice_roaming_enabled', 478 | 'is_voice_roaming_enabled', 'TINYINT(1) NOT NULL DEFAULT \'-1\''); 479 | $migration->migrationOneTable('glpi_plugin_airwatch_details'); 480 | } 481 | } 482 | 483 | public static function uninstall(Migration $migration) { 484 | $migration->dropTable("glpi_plugin_airwatch_details"); 485 | } 486 | 487 | } 488 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "2423e28867b21bcd55a6f0940e60ed90", 8 | "packages": [], 9 | "packages-dev": [ 10 | { 11 | "name": "glpi-project/tools", 12 | "version": "0.4.2", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/glpi-project/tools.git", 16 | "reference": "34369dd85cc99c18c3b8cf441bba11ec32173f2d" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/glpi-project/tools/zipball/34369dd85cc99c18c3b8cf441bba11ec32173f2d", 21 | "reference": "34369dd85cc99c18c3b8cf441bba11ec32173f2d", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "symfony/console": "^4.4 || ^5.0" 26 | }, 27 | "bin": [ 28 | "bin/extract-locales", 29 | "bin/licence-headers-check", 30 | "tools/extract_template.sh", 31 | "tools/plugin-release" 32 | ], 33 | "type": "library", 34 | "autoload": { 35 | "psr-4": { 36 | "Glpi\\": "src/" 37 | } 38 | }, 39 | "notification-url": "https://packagist.org/downloads/", 40 | "license": [ 41 | "GPL-3.0-or-later" 42 | ], 43 | "authors": [ 44 | { 45 | "name": "Teclib'", 46 | "email": "glpi@teclib.com", 47 | "homepage": "http://teclib-group.com" 48 | } 49 | ], 50 | "description": "Various tools for GLPI and its plugins", 51 | "keywords": [ 52 | "glpi", 53 | "plugins", 54 | "tools" 55 | ], 56 | "support": { 57 | "issues": "https://github.com/glpi-project/tools/issues", 58 | "source": "https://github.com/glpi-project/tools" 59 | }, 60 | "time": "2022-01-28T13:44:12+00:00" 61 | }, 62 | { 63 | "name": "psr/container", 64 | "version": "1.1.1", 65 | "source": { 66 | "type": "git", 67 | "url": "https://github.com/php-fig/container.git", 68 | "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" 69 | }, 70 | "dist": { 71 | "type": "zip", 72 | "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", 73 | "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", 74 | "shasum": "" 75 | }, 76 | "require": { 77 | "php": ">=7.2.0" 78 | }, 79 | "type": "library", 80 | "autoload": { 81 | "psr-4": { 82 | "Psr\\Container\\": "src/" 83 | } 84 | }, 85 | "notification-url": "https://packagist.org/downloads/", 86 | "license": [ 87 | "MIT" 88 | ], 89 | "authors": [ 90 | { 91 | "name": "PHP-FIG", 92 | "homepage": "https://www.php-fig.org/" 93 | } 94 | ], 95 | "description": "Common Container Interface (PHP FIG PSR-11)", 96 | "homepage": "https://github.com/php-fig/container", 97 | "keywords": [ 98 | "PSR-11", 99 | "container", 100 | "container-interface", 101 | "container-interop", 102 | "psr" 103 | ], 104 | "support": { 105 | "issues": "https://github.com/php-fig/container/issues", 106 | "source": "https://github.com/php-fig/container/tree/1.1.1" 107 | }, 108 | "time": "2021-03-05T17:36:06+00:00" 109 | }, 110 | { 111 | "name": "symfony/console", 112 | "version": "v4.4.37", 113 | "source": { 114 | "type": "git", 115 | "url": "https://github.com/symfony/console.git", 116 | "reference": "0259f01dbf9d77badddbbf4c2abb681f24c9cac6" 117 | }, 118 | "dist": { 119 | "type": "zip", 120 | "url": "https://api.github.com/repos/symfony/console/zipball/0259f01dbf9d77badddbbf4c2abb681f24c9cac6", 121 | "reference": "0259f01dbf9d77badddbbf4c2abb681f24c9cac6", 122 | "shasum": "" 123 | }, 124 | "require": { 125 | "php": ">=7.1.3", 126 | "symfony/polyfill-mbstring": "~1.0", 127 | "symfony/polyfill-php73": "^1.8", 128 | "symfony/polyfill-php80": "^1.16", 129 | "symfony/service-contracts": "^1.1|^2" 130 | }, 131 | "conflict": { 132 | "psr/log": ">=3", 133 | "symfony/dependency-injection": "<3.4", 134 | "symfony/event-dispatcher": "<4.3|>=5", 135 | "symfony/lock": "<4.4", 136 | "symfony/process": "<3.3" 137 | }, 138 | "provide": { 139 | "psr/log-implementation": "1.0|2.0" 140 | }, 141 | "require-dev": { 142 | "psr/log": "^1|^2", 143 | "symfony/config": "^3.4|^4.0|^5.0", 144 | "symfony/dependency-injection": "^3.4|^4.0|^5.0", 145 | "symfony/event-dispatcher": "^4.3", 146 | "symfony/lock": "^4.4|^5.0", 147 | "symfony/process": "^3.4|^4.0|^5.0", 148 | "symfony/var-dumper": "^4.3|^5.0" 149 | }, 150 | "suggest": { 151 | "psr/log": "For using the console logger", 152 | "symfony/event-dispatcher": "", 153 | "symfony/lock": "", 154 | "symfony/process": "" 155 | }, 156 | "type": "library", 157 | "autoload": { 158 | "psr-4": { 159 | "Symfony\\Component\\Console\\": "" 160 | }, 161 | "exclude-from-classmap": [ 162 | "/Tests/" 163 | ] 164 | }, 165 | "notification-url": "https://packagist.org/downloads/", 166 | "license": [ 167 | "MIT" 168 | ], 169 | "authors": [ 170 | { 171 | "name": "Fabien Potencier", 172 | "email": "fabien@symfony.com" 173 | }, 174 | { 175 | "name": "Symfony Community", 176 | "homepage": "https://symfony.com/contributors" 177 | } 178 | ], 179 | "description": "Eases the creation of beautiful and testable command line interfaces", 180 | "homepage": "https://symfony.com", 181 | "support": { 182 | "source": "https://github.com/symfony/console/tree/v4.4.37" 183 | }, 184 | "funding": [ 185 | { 186 | "url": "https://symfony.com/sponsor", 187 | "type": "custom" 188 | }, 189 | { 190 | "url": "https://github.com/fabpot", 191 | "type": "github" 192 | }, 193 | { 194 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 195 | "type": "tidelift" 196 | } 197 | ], 198 | "time": "2022-01-26T16:15:26+00:00" 199 | }, 200 | { 201 | "name": "symfony/polyfill-mbstring", 202 | "version": "v1.24.0", 203 | "source": { 204 | "type": "git", 205 | "url": "https://github.com/symfony/polyfill-mbstring.git", 206 | "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" 207 | }, 208 | "dist": { 209 | "type": "zip", 210 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", 211 | "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", 212 | "shasum": "" 213 | }, 214 | "require": { 215 | "php": ">=7.1" 216 | }, 217 | "provide": { 218 | "ext-mbstring": "*" 219 | }, 220 | "suggest": { 221 | "ext-mbstring": "For best performance" 222 | }, 223 | "type": "library", 224 | "extra": { 225 | "branch-alias": { 226 | "dev-main": "1.23-dev" 227 | }, 228 | "thanks": { 229 | "name": "symfony/polyfill", 230 | "url": "https://github.com/symfony/polyfill" 231 | } 232 | }, 233 | "autoload": { 234 | "psr-4": { 235 | "Symfony\\Polyfill\\Mbstring\\": "" 236 | }, 237 | "files": [ 238 | "bootstrap.php" 239 | ] 240 | }, 241 | "notification-url": "https://packagist.org/downloads/", 242 | "license": [ 243 | "MIT" 244 | ], 245 | "authors": [ 246 | { 247 | "name": "Nicolas Grekas", 248 | "email": "p@tchwork.com" 249 | }, 250 | { 251 | "name": "Symfony Community", 252 | "homepage": "https://symfony.com/contributors" 253 | } 254 | ], 255 | "description": "Symfony polyfill for the Mbstring extension", 256 | "homepage": "https://symfony.com", 257 | "keywords": [ 258 | "compatibility", 259 | "mbstring", 260 | "polyfill", 261 | "portable", 262 | "shim" 263 | ], 264 | "support": { 265 | "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0" 266 | }, 267 | "funding": [ 268 | { 269 | "url": "https://symfony.com/sponsor", 270 | "type": "custom" 271 | }, 272 | { 273 | "url": "https://github.com/fabpot", 274 | "type": "github" 275 | }, 276 | { 277 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 278 | "type": "tidelift" 279 | } 280 | ], 281 | "time": "2021-11-30T18:21:41+00:00" 282 | }, 283 | { 284 | "name": "symfony/polyfill-php73", 285 | "version": "v1.24.0", 286 | "source": { 287 | "type": "git", 288 | "url": "https://github.com/symfony/polyfill-php73.git", 289 | "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" 290 | }, 291 | "dist": { 292 | "type": "zip", 293 | "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", 294 | "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", 295 | "shasum": "" 296 | }, 297 | "require": { 298 | "php": ">=7.1" 299 | }, 300 | "type": "library", 301 | "extra": { 302 | "branch-alias": { 303 | "dev-main": "1.23-dev" 304 | }, 305 | "thanks": { 306 | "name": "symfony/polyfill", 307 | "url": "https://github.com/symfony/polyfill" 308 | } 309 | }, 310 | "autoload": { 311 | "psr-4": { 312 | "Symfony\\Polyfill\\Php73\\": "" 313 | }, 314 | "files": [ 315 | "bootstrap.php" 316 | ], 317 | "classmap": [ 318 | "Resources/stubs" 319 | ] 320 | }, 321 | "notification-url": "https://packagist.org/downloads/", 322 | "license": [ 323 | "MIT" 324 | ], 325 | "authors": [ 326 | { 327 | "name": "Nicolas Grekas", 328 | "email": "p@tchwork.com" 329 | }, 330 | { 331 | "name": "Symfony Community", 332 | "homepage": "https://symfony.com/contributors" 333 | } 334 | ], 335 | "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", 336 | "homepage": "https://symfony.com", 337 | "keywords": [ 338 | "compatibility", 339 | "polyfill", 340 | "portable", 341 | "shim" 342 | ], 343 | "support": { 344 | "source": "https://github.com/symfony/polyfill-php73/tree/v1.24.0" 345 | }, 346 | "funding": [ 347 | { 348 | "url": "https://symfony.com/sponsor", 349 | "type": "custom" 350 | }, 351 | { 352 | "url": "https://github.com/fabpot", 353 | "type": "github" 354 | }, 355 | { 356 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 357 | "type": "tidelift" 358 | } 359 | ], 360 | "time": "2021-06-05T21:20:04+00:00" 361 | }, 362 | { 363 | "name": "symfony/polyfill-php80", 364 | "version": "v1.24.0", 365 | "source": { 366 | "type": "git", 367 | "url": "https://github.com/symfony/polyfill-php80.git", 368 | "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" 369 | }, 370 | "dist": { 371 | "type": "zip", 372 | "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", 373 | "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", 374 | "shasum": "" 375 | }, 376 | "require": { 377 | "php": ">=7.1" 378 | }, 379 | "type": "library", 380 | "extra": { 381 | "branch-alias": { 382 | "dev-main": "1.23-dev" 383 | }, 384 | "thanks": { 385 | "name": "symfony/polyfill", 386 | "url": "https://github.com/symfony/polyfill" 387 | } 388 | }, 389 | "autoload": { 390 | "psr-4": { 391 | "Symfony\\Polyfill\\Php80\\": "" 392 | }, 393 | "files": [ 394 | "bootstrap.php" 395 | ], 396 | "classmap": [ 397 | "Resources/stubs" 398 | ] 399 | }, 400 | "notification-url": "https://packagist.org/downloads/", 401 | "license": [ 402 | "MIT" 403 | ], 404 | "authors": [ 405 | { 406 | "name": "Ion Bazan", 407 | "email": "ion.bazan@gmail.com" 408 | }, 409 | { 410 | "name": "Nicolas Grekas", 411 | "email": "p@tchwork.com" 412 | }, 413 | { 414 | "name": "Symfony Community", 415 | "homepage": "https://symfony.com/contributors" 416 | } 417 | ], 418 | "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", 419 | "homepage": "https://symfony.com", 420 | "keywords": [ 421 | "compatibility", 422 | "polyfill", 423 | "portable", 424 | "shim" 425 | ], 426 | "support": { 427 | "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0" 428 | }, 429 | "funding": [ 430 | { 431 | "url": "https://symfony.com/sponsor", 432 | "type": "custom" 433 | }, 434 | { 435 | "url": "https://github.com/fabpot", 436 | "type": "github" 437 | }, 438 | { 439 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 440 | "type": "tidelift" 441 | } 442 | ], 443 | "time": "2021-09-13T13:58:33+00:00" 444 | }, 445 | { 446 | "name": "symfony/service-contracts", 447 | "version": "v1.1.11", 448 | "source": { 449 | "type": "git", 450 | "url": "https://github.com/symfony/service-contracts.git", 451 | "reference": "633df678bec3452e04a7b0337c9bcfe7354124b3" 452 | }, 453 | "dist": { 454 | "type": "zip", 455 | "url": "https://api.github.com/repos/symfony/service-contracts/zipball/633df678bec3452e04a7b0337c9bcfe7354124b3", 456 | "reference": "633df678bec3452e04a7b0337c9bcfe7354124b3", 457 | "shasum": "" 458 | }, 459 | "require": { 460 | "php": ">=7.1.3", 461 | "psr/container": "^1.0" 462 | }, 463 | "suggest": { 464 | "symfony/service-implementation": "" 465 | }, 466 | "type": "library", 467 | "extra": { 468 | "branch-alias": { 469 | "dev-main": "1.1-dev" 470 | }, 471 | "thanks": { 472 | "name": "symfony/contracts", 473 | "url": "https://github.com/symfony/contracts" 474 | } 475 | }, 476 | "autoload": { 477 | "psr-4": { 478 | "Symfony\\Contracts\\Service\\": "" 479 | } 480 | }, 481 | "notification-url": "https://packagist.org/downloads/", 482 | "license": [ 483 | "MIT" 484 | ], 485 | "authors": [ 486 | { 487 | "name": "Nicolas Grekas", 488 | "email": "p@tchwork.com" 489 | }, 490 | { 491 | "name": "Symfony Community", 492 | "homepage": "https://symfony.com/contributors" 493 | } 494 | ], 495 | "description": "Generic abstractions related to writing services", 496 | "homepage": "https://symfony.com", 497 | "keywords": [ 498 | "abstractions", 499 | "contracts", 500 | "decoupling", 501 | "interfaces", 502 | "interoperability", 503 | "standards" 504 | ], 505 | "support": { 506 | "source": "https://github.com/symfony/service-contracts/tree/v1.1.11" 507 | }, 508 | "funding": [ 509 | { 510 | "url": "https://symfony.com/sponsor", 511 | "type": "custom" 512 | }, 513 | { 514 | "url": "https://github.com/fabpot", 515 | "type": "github" 516 | }, 517 | { 518 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 519 | "type": "tidelift" 520 | } 521 | ], 522 | "time": "2021-11-04T13:32:43+00:00" 523 | } 524 | ], 525 | "aliases": [], 526 | "minimum-stability": "stable", 527 | "stability-flags": [], 528 | "prefer-stable": false, 529 | "prefer-lowest": false, 530 | "platform": { 531 | "php": "^7.2", 532 | "ext-curl": "*" 533 | }, 534 | "platform-dev": [], 535 | "platform-overrides": { 536 | "php": "7.2.0" 537 | }, 538 | "plugin-api-version": "2.1.0" 539 | } 540 | --------------------------------------------------------------------------------