%PDF- %PDF-
Direktori : /var/www/projetos/suporte.iigd.com.br/src/ |
Current File : /var/www/projetos/suporte.iigd.com.br/src/DomainRecordType.php |
<?php /** * --------------------------------------------------------------------- * * GLPI - Gestionnaire Libre de Parc Informatique * * http://glpi-project.org * * @copyright 2015-2024 Teclib' and contributors. * @copyright 2003-2014 by the INDEPNET Development Team. * @licence https://www.gnu.org/licenses/gpl-3.0.html * * --------------------------------------------------------------------- * * LICENSE * * This file is part of GLPI. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * * --------------------------------------------------------------------- */ class DomainRecordType extends CommonDropdown { public static $rightname = 'dropdown'; public static $knowtypes = [ [ 'id' => 1, 'name' => 'A', 'comment' => 'Host address', 'fields' => [], ], [ 'id' => 2, 'name' => 'AAAA', 'comment' => 'IPv6 host address', 'fields' => [], ], [ 'id' => 3, 'name' => 'ALIAS', 'comment' => 'Auto resolved alias', 'fields' => [], ], [ 'id' => 4, 'name' => 'CNAME', 'comment' => 'Canonical name for an alias', 'fields' => [ [ 'key' => 'target', 'label' => 'Target', 'placeholder' => 'sip.example.com.', 'is_fqdn' => true ], ], ], [ 'id' => 5, 'name' => 'MX', 'comment' => 'Mail eXchange', 'fields' => [ [ 'key' => 'priority', 'label' => 'Priority', 'placeholder' => '10', ], [ 'key' => 'server', 'label' => 'Server', 'placeholder' => 'mail.example.com.', 'is_fqdn' => true ], ], ], [ 'id' => 6, 'name' => 'NS', 'comment' => 'Name Server', 'fields' => [], ], [ 'id' => 7, 'name' => 'PTR', 'comment' => 'Pointer', 'fields' => [], ], [ 'id' => 8, 'name' => 'SOA', 'comment' => 'Start Of Authority', 'fields' => [ [ 'key' => 'primary_name_server', 'label' => 'Primary name server', 'placeholder' => 'ns1.example.com.', 'is_fqdn' => true ], [ 'key' => 'primary_contact', 'label' => 'Primary contact', 'placeholder' => 'admin.example.com.', 'is_fqdn' => true ], [ 'key' => 'serial', 'label' => 'Serial', 'placeholder' => '2020010101', ], [ 'key' => 'zone_refresh_timer', 'label' => 'Zone refresh timer', 'placeholder' => '86400', ], [ 'key' => 'failed_refresh_retry_timer', 'label' => 'Failed refresh retry timer', 'placeholder' => '7200', ], [ 'key' => 'zone_expiry_timer', 'label' => 'Zone expiry timer', 'placeholder' => '1209600', ], [ 'key' => 'minimum_ttl', 'label' => 'Minimum TTL', 'placeholder' => '300', ], ], ], [ 'id' => 9, 'name' => 'SRV', 'comment' => 'Location of service', 'fields' => [ [ 'key' => 'priority', 'label' => 'Priority', 'placeholder' => '0', ], [ 'key' => 'weight', 'label' => 'Weight', 'placeholder' => '10', ], [ 'key' => 'port', 'label' => 'Port', 'placeholder' => '5060', ], [ 'key' => 'target', 'label' => 'Target', 'placeholder' => 'sip.example.com.', 'is_fqdn' => true ], ], ], [ 'id' => 10, 'name' => 'TXT', 'comment' => 'Descriptive text', 'fields' => [ [ 'key' => 'data', 'label' => 'TXT record data', 'placeholder' => 'Your TXT record data', 'quote_value' => true, ], ], ], [ 'id' => 11, 'name' => 'CAA', 'comment' => 'Certification Authority Authorization', 'fields' => [ [ 'key' => 'flag', 'label' => 'Flag', 'placeholder' => '0', ], [ 'key' => 'tag', 'label' => 'Tag', 'placeholder' => 'issue', ], [ 'key' => 'value', 'label' => 'Value', 'placeholder' => 'letsencrypt.org', 'quote_value' => true, ], ], ] ]; public function getAdditionalFields() { return [ [ 'name' => 'fields', 'label' => __('Fields'), 'type' => 'fields', ] ]; } public function displaySpecificTypeField($ID, $field = [], array $options = []) { $field_name = $field['name']; $field_type = $field['type']; $field_value = $this->fields[$field_name]; switch ($field_type) { case 'fields': $printable = json_encode(json_decode($field_value), JSON_PRETTY_PRINT); echo '<textarea name="' . $field_name . '" cols="75" rows="25">' . $printable . '</textarea >'; break; } } public function prepareInputForAdd($input) { if (!array_key_exists('fields', $input)) { $input['fields'] = '[]'; } else { $input['fields'] = Toolbox::cleanNewLines($input['fields']); } if (!$this->validateFieldsDescriptor($input['fields'])) { return false; } return parent::prepareInputForAdd($input); } public function prepareInputForUpdate($input) { if (array_key_exists('fields', $input)) { $input['fields'] = Toolbox::cleanNewLines($input['fields']); if (!$this->validateFieldsDescriptor($input['fields'])) { return false; } } return parent::prepareInputForUpdate($input); } public function post_updateItem($history = true) { /** @var \DBmysql $DB */ global $DB; if (in_array('fields', $this->updates)) { $old_fields = self::decodeFields($this->oldvalues['fields']); $new_fields = self::decodeFields($this->fields['fields']); // Checks only for keys changes as fields order, label, placeholder or quote_value properties changes // should have no impact on object representation. $old_keys = array_column($old_fields, 'key'); $new_keys = array_column($new_fields, 'key'); sort($old_keys); sort($new_keys); if ($old_keys != $new_keys) { // Remove data stored as obj as properties changed. // Do not remove data stored as string as this representation may still be valid. $DB->update( DomainRecord::getTable(), ['data_obj' => null], [self::getForeignKeyField() => $this->fields['id']] ); } } } /** * Validate fields descriptor. * * @param string $fields_str Value of "fields" field (should be a JSON encoded string). * * @return bool */ private function validateFieldsDescriptor($fields_str): bool { if (!is_string($fields_str)) { Session::addMessageAfterRedirect(__('Invalid JSON used to define fields.'), true, ERROR); return false; } $fields = self::decodeFields($fields_str); if (!is_array($fields)) { Session::addMessageAfterRedirect(__('Invalid JSON used to define fields.'), true, ERROR); return false; } foreach ($fields as $field) { if ( !is_array($field) || !array_key_exists('key', $field) || !is_string($field['key']) || !array_key_exists('label', $field) || !is_string($field['label']) || (array_key_exists('placeholder', $field) && !is_string($field['placeholder'])) || (array_key_exists('quote_value', $field) && !is_bool($field['quote_value'])) || (array_key_exists('is_fqdn', $field) && !is_bool($field['is_fqdn'])) || count(array_diff(array_keys($field), ['key', 'label', 'placeholder', 'quote_value', 'is_fqdn'])) > 0 ) { Session::addMessageAfterRedirect( __('Valid field descriptor properties are: key (string, mandatory), label (string, mandatory), placeholder (string, optionnal), quote_value (boolean, optional), is_fqdn (boolean, optional).'), true, ERROR ); return false; } } return true; } /** * Decode JSON encoded fields. * Handle decoding of sanitized value. * Returns null if unable to decode. * * @param string $json_encoded_fields * * @return array|null */ public static function decodeFields(string $json_encoded_fields): ?array { $fields = null; if (\Toolbox::isJSON($json_encoded_fields)) { $fields = json_decode($json_encoded_fields, true); } else { $fields_str = stripslashes(preg_replace('/(\\\r|\\\n)/', '', $json_encoded_fields)); if (\Toolbox::isJSON($fields_str)) { $fields = json_decode($fields_str, true); } } if (!is_array($fields)) { return null; } return $fields; } public static function getTypeName($nb = 0) { return _n('Record type', 'Records types', $nb); } public static function getDefaults() { return array_map( function ($e) { $e['is_recursive'] = 1; $e['fields'] = json_encode($e['fields']); return $e; }, self::$knowtypes ); } /** * Display ajax form used to fill record data. * * @param string $str_input_id Id of input used to get/store record data as string. * @param string $obj_input_id Id of input used to get/store record data as object. */ public function showDataAjaxForm(string $str_input_id, string $obj_input_id) { $rand = mt_rand(); echo '<form id="domain_record_data' . $rand . '">'; echo '<table class="tab_cadre_fixe">'; $fields = json_decode($this->fields['fields'] ?? '[]', true); if (empty($fields)) { $fields = [ [ 'key' => 'data', 'label' => __('Data'), ], ]; } foreach ($fields as $field) { $placeholder = Html::entities_deep($field['placeholder'] ?? ''); $quote_value = $field['quote_value'] ?? false; $is_fqdn = $field['is_fqdn'] ?? false; echo '<tr class="tab_bg_1">'; echo '<td>' . $field['label'] . '</td>'; echo '<td>'; echo '<input name="' . $field['key'] . '" ' . 'placeholder="' . $placeholder . '" ' . 'data-quote-value="' . ($quote_value ? 'true' : 'false') . '" ' . (!$quote_value ? 'pattern="[^\s]+" ' : '') // prevent usage of spaces in unquoted values . 'data-is-fqdn="' . ($is_fqdn ? 'true' : 'false') . '" ' . ' />'; echo '</td>'; echo '</tr>'; } echo '<tr class="tab_bg_2">'; echo '<td colspan="2" class="right">'; echo Html::submit('<i class="fas fa-save"></i> ' . _x('button', 'Save')); echo '</td>'; echo '</tr>'; echo '</table>'; echo '</form>'; $js = <<<JAVASCRIPT $( function () { var form = $('#domain_record_data{$rand}'); // Put existing data into fields var data_to_copy = $('#{$str_input_id}').val(); form.find('input').each( function () { var endoffset = 0; if ($(this).data('quote-value')) { // Search for closing quote (quote inside value are escaped by a \) do { endoffset = endoffset + 1; // move to next char (ignore opening or escaped quote) endoffset = data_to_copy.indexOf('" ', endoffset); } while (endoffset !== -1 && data_to_copy.charAt(endoffset - 1) == '\\\'); if (endoffset !== -1) { endoffset += 1; // capture closing quote } } else { endoffset = data_to_copy.indexOf(' '); } if (endoffset === -1) { endoffset = data_to_copy.length; // get whole value if no separator found } var value = data_to_copy.substring(0, endoffset).trim(); if ($(this).data('quote-value')) { value = value.replace(/^"/, '').replace(/"$/, ''); // trim surrounding quotes value = value.replace('\\\"', '"'); // unescape quotes } $(this).val(value); // "endoffset + 1" to strip also ' ' separator char data_to_copy = data_to_copy.substring(endoffset + 1); } ); // Copy values into data input on submit form.on( 'submit', function(event) { event.preventDefault(); var data_tokens = []; var data_obj = {}; $(this).find('input').each( function () { var value = $(this).val(); data_obj[$(this).attr('name')] = value; // keep raw value if ($(this).data('is-fqdn') && !value.match('/^\.$/')) { value += '.'; // add ending dot } if ($(this).data('quote-value') && !value.match('/^".*"$/')) { value = '"' + value.replace('"', '\\\"') + '"'; } data_tokens.push(value); } ); $('#{$str_input_id}').val(data_tokens.join(' ')); $('#{$obj_input_id}').val(JSON.stringify(data_obj)); } ); } ); JAVASCRIPT; echo Html::scriptBlock($js); } }