/* Authors: * Adam Young * Petr Vobornik * * Copyright (C) 2010 Red Hat * see file 'COPYING' for use and warranty information * * 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 . */ define([ './ipa', './jquery', './net', './navigation', './menu', './phases', './reg', './text', './details', './search', './association', './entity'], function(IPA, $, NET, navigation, menu, phases, reg, text) { var exp = IPA.dns = { zone_permission_name: 'Manage DNS zone ${dnszone}' }; var make_config_spec = function() { return { name: 'dnsconfig', defines_key: false, enable_test: function() { return IPA.dns_enabled; }, facets: [ { $type: 'details', title: '@mo:config.label', sections: [ { name: 'options', label: '@i18n:objects.dnsconfig.options', fields: [ { $type: 'checkbox', name: 'idnsallowsyncptr' }, { $type: 'multivalued', name: 'idnsforwarders', validators: [ 'dnsforwarder'] }, { $type: 'radio', name: 'idnsforwardpolicy', default_value: 'first', options: [ { value: 'first', label: '@i18n:objects.dnsconfig.forward_first' }, { value: 'only', label: '@i18n:objects.dnsconfig.forward_only' }, { value: 'none', label: '@i18n:objects.dnsconfig.forward_none' } ] }, 'idnszonerefresh' ] } ], needs_update: true } ] };}; var make_zone_spec = function() { return { name: 'dnszone', enable_test: function() { return IPA.dns_enabled; }, facet_groups: [ 'dnsrecord', 'settings' ], facets: [ { $type: 'search', row_enabled_attribute: 'idnszoneactive', title: '@mo:dnszone.label', columns: [ 'idnsname', { name: 'idnszoneactive', label: '@i18n:status.label', formatter: 'boolean_status' } ], actions: [ 'batch_disable', 'batch_enable' ], control_buttons: [ { name: 'disable', label: '@i18n:buttons.disable', icon: 'disabled-icon' }, { name: 'enable', label: '@i18n:buttons.enable', icon: 'enabled-icon' } ] }, { $type: 'details', $factory: IPA.dnszone_details_facet, command_mode: 'info', sections: [ { name: 'identity', fields: [ 'idnsname', 'idnssoamname', 'idnssoarname', 'idnssoaserial', 'idnssoarefresh', 'idnssoaretry', 'idnssoaexpire', 'idnssoaminimum', 'dnsttl', { $type: 'combobox', name: 'dnsclass', options: [ 'IN', 'CS', 'CH', 'HS' ] }, { $type: 'radio', name: 'idnsallowdynupdate', options: [ { value: 'TRUE', label: '@i18n:true' }, { value: 'FALSE', label: '@i18n:false' } ] }, { $type: 'textarea', name: 'idnsupdatepolicy' }, { $type: 'netaddr', name: 'idnsallowquery', validators: [ { $type: 'network', specials: ['any', 'none', 'localhost', 'localnets'], allow_negation: true, allow_host_address: true }] }, { $type: 'netaddr', name: 'idnsallowtransfer', validators: [ { $type: 'network', specials: ['any', 'none', 'localhost', 'localnets'], allow_negation: true, allow_host_address: true }] }, { $type: 'multivalued', name: 'idnsforwarders', validators: [ 'dnsforwarder'] }, { $type: 'radio', name: 'idnsforwardpolicy', default_value: 'first', options: [ { value: 'first', label: '@i18n:objects.dnsconfig.forward_first' }, { value: 'only', label: '@i18n:objects.dnsconfig.forward_only' }, { value: 'none', label: '@i18n:objects.dnsconfig.forward_none' } ] }, { $type: 'checkbox', name: 'idnsallowsyncptr' } ] }], actions: [ 'select', 'enable', 'disable', 'delete', 'dns_add_permission', 'dns_remove_permission' ], header_actions: ['select_action', 'enable', 'disable', 'delete', 'add_permission', 'remove_permission'], state: { evaluators: [ { $factory: IPA.enable_state_evaluator, field: 'idnszoneactive' }, { $factory: IPA.acl_state_evaluator, attribute: 'managedby' }, IPA.dns.zone_has_permission_evaluator ], summary_conditions: [ IPA.enabled_summary_cond, IPA.disabled_summary_cond ] } }, { $type: 'nested_search', $factory: IPA.dns.record_search_facet, facet_group: 'dnsrecord', nested_entity : 'dnsrecord', name: 'records', deleter_dialog: IPA.dns.record_search_deleter_dialog, title: '@mo:dnszone.label_singular', label: '@mo:dnsrecord.label', tab_label: '@mo:dnsrecord.label', columns: [ { name: 'idnsname', label: '@mo-param:dnsrecord:idnsname:label', primary_key: true }, { name: 'type', label: '@i18n:objects.dnsrecord.type' }, { name: 'data', label: '@i18n:objects.dnsrecord.data' } ] } ], standard_association_facets: true, adder_dialog: { $factory: IPA.dnszone_adder_dialog, height: 300, sections: [ { $factory: IPA.dnszone_name_section, name: 'name', fields: [ { $type: 'dnszone_name', name: 'idnsname', required: false, radio_name: 'dnszone_name_type' }, { $type: 'dnszone_name', name: 'name_from_ip', radio_name: 'dnszone_name_type', validators: ['network'] } ] }, { name: 'other', fields: [ 'idnssoamname', { name: 'ip_address', validators: [ 'ip_address' ], metadata: '@mc-opt:dnszone_add:ip_address' }, { name: 'idnssoarname', required: false }, { $type: 'force_dnszone_add_checkbox', name: 'force', metadata: '@mc-opt:dnszone_add:force' } ] } ], policies: [ IPA.add_dns_zone_name_policy ] } };}; IPA.dnszone_details_facet = function(spec, no_init) { spec = spec || {}; var that = IPA.details_facet(spec, true); that.permission_load = IPA.observer(); that.permission_status = 'unknown'; // [unknown, set, none] that.refresh_on_success = function(data, text_status, xhr) { // do not load data from batch that.show_content(); }; that.create_refresh_command = function() { var pkey = that.get_pkey(); var batch = IPA.batch_command({ name: 'dnszone_details_refresh' }); var dnszone_command = that.details_facet_create_refresh_command(); dnszone_command.on_success = function(data, text_status, xhr) { // create data that mimics dnszone-show output var dnszone_data = {}; dnszone_data.result = data; that.load(dnszone_data); }; batch.add_command(dnszone_command); var permission_name = IPA.dns.zone_permission_name.replace('${dnszone}', pkey); var permission_command = IPA.command({ entity: 'permission', method: 'show', args: [permission_name], options: {}, retry: false }); permission_command.on_success = function(data, text_status, xhr) { that.permission_status = 'set'; that.permission_load.notify([that.permission_status], that); }; permission_command.on_error = function(xhr, text_status, error_thrown) { if (error_thrown && error_thrown.code === 4001) { //NotFound error that.permission_status = 'none'; } else { that.permission_status = 'unknown'; } that.permission_load.notify([that.permission_status], that); }; batch.add_command(permission_command); return batch; }; that.update_on_success = function(data, text_status, xhr) { that.refresh(); that.on_update.notify(); that.nofify_update_success(); }; that.update_on_error = function(xhr, text_status, error_thrown) { that.refresh(); }; if (!no_init) that.init_details_facet(); return that; }; IPA.dnszone_name_section = function(spec) { spec = spec || {}; var that = IPA.details_table_section(spec); that.create = function(container) { that.container = container; that.message_container = $('
', { style: 'display: none', 'class': 'dialog-message ui-state-highlight ui-corner-all' }).appendTo(that.container); var table = $('', { 'class': 'section-table' }).appendTo(that.container); var idnsname = that.widgets.get_widget('idnsname'); var tr = $('').appendTo(table); var td = $('').appendTo(table); td = $('
', { 'class': 'section-cell-label', title: idnsname.label }).appendTo(tr); var label = $('', { 'class': 'section-cell-field', title: idnsname.label }).appendTo(tr); var widget_cont = $('
', { name: 'idnsname', 'class': 'field' }).appendTo(td); idnsname.create(widget_cont); var idnsname_input = $('input', widget_cont); var name_from_ip = that.widgets.get_widget('name_from_ip'); tr = $('
', { 'class': 'section-cell-label', title: name_from_ip.label }).appendTo(tr); label = $('', { 'class': 'section-cell-field', title: name_from_ip.label }).appendTo(tr); widget_cont = $('
', { name: 'name_from_ip', 'class': 'field' }).appendTo(td); name_from_ip.create(widget_cont); idnsname.radio.click(); }; return that; }; IPA.add_dns_zone_name_policy = function() { var that = IPA.facet_policy(); that.init = function() { var idnsname_w = this.container.widgets.get_widget('name.idnsname'); var name_from_ip_w = this.container.widgets.get_widget('name.name_from_ip'); var idnsname_f = this.container.fields.get_field('idnsname'); var name_from_ip_f = this.container.fields.get_field('name_from_ip'); idnsname_w.radio_clicked.attach(function() { idnsname_w.input.prop('disabled', false); name_from_ip_w.input.prop('disabled', true); idnsname_f.set_required(true); name_from_ip_f.set_required(false); name_from_ip_f.reset(); }); name_from_ip_w.radio_clicked.attach(function() { idnsname_w.input.prop('disabled', true); name_from_ip_w.input.prop('disabled', false); idnsname_f.set_required(false); name_from_ip_f.set_required(true); idnsname_f.reset(); }); }; return that; }; IPA.dnszone_name_widget = function(spec) { spec = spec || {}; var that = IPA.text_widget(spec); that.radio_name = spec.radio_name; that.radio_clicked = IPA.observer(); that.text_save = that.save; that.radio_id = IPA.html_util.get_next_id(that.radio_name); that.save = function() { var values = []; if (that.radio.is(':checked')) { values = that.text_save(); } return values; }; that.create_radio = function(container) { that.radio = $('', { type: 'radio', id: that.radio_id, name: that.radio_name, value: that.name, click: function() { that.radio_clicked.notify([], that); } }).appendTo(container); }; return that; }; IPA.force_dnszone_add_checkbox_widget = function(spec) { var metadata = IPA.get_command_option('dnszone_add', spec.name); spec.label = metadata.label; spec.tooltip = metadata.doc; return IPA.checkbox_widget(spec); }; IPA.dnszone_adder_dialog = function(spec) { spec = spec || {}; var that = IPA.entity_adder_dialog(spec); function ends_with(str, suffix) { return str.indexOf(suffix, str.length - suffix.length) !== -1; } var init = function() { var zone_w = that.fields.get_field('idnsname').widget; var reverse_zone_w = that.fields.get_field('name_from_ip').widget; var ns_w = that.fields.get_field('idnssoamname').widget; zone_w.value_changed.attach(that.check_ns_ip); reverse_zone_w.value_changed.attach(that.check_ns_ip); ns_w.value_changed.attach(that.check_ns_ip); }; that.check_ns_ip = function() { var ip_address_f = that.fields.get_field('ip_address'); var zone_w = that.fields.get_field('idnsname').widget; var ns_w = that.fields.get_field('idnssoamname').widget; var zone = zone_w.save()[0] || ''; var ns = ns_w.save()[0] || ''; var zone_is_reverse = !zone_w.is_enabled() || ends_with(zone, '.in-addr.arpa.') || ends_with(zone, '.ip6.arpa.'); var relative_ns = true; var ns_in_zone = false; if (ns && ns[ns.length-1] === '.') { relative_ns = false; ns = ns.slice(0, -1); } if (zone && zone[zone.length-1] === '.') { zone = zone.slice(0, -1); } if (ns && zone && ends_with(ns, '.' + zone)) { ns_in_zone = true; } if (!zone_is_reverse && (relative_ns || ns_in_zone)) { ip_address_f.set_enabled(true); ip_address_f.set_required(true); } else { ip_address_f.reset(); ip_address_f.set_required(false); ip_address_f.set_enabled(false); } }; that.create = function() { that.entity_adder_dialog_create(); that.container.addClass('dnszone-adder-dialog'); }; init(); return that; }; IPA.dns.add_permission_action = function(spec) { spec = spec || {}; spec.name = spec.name || 'add_permission'; spec.label = spec.label || '@i18n:objects.dnszone.add_permission'; spec.enable_cond = spec.enable_cond || ['permission-none', 'managedby_w']; var that = IPA.action(spec); that.execute_action = function(facet) { var pkey = facet.get_pkey(); var command = IPA.command({ entity: 'dnszone', method: 'add_permission', args: [pkey], options: {}, on_success: function(data, text_status, xhr) { facet.refresh(); IPA.notify_success(data.result.summary); } }); command.execute(); }; return that; }; IPA.dns.remove_permission_action = function(spec) { spec = spec || {}; spec.name = spec.name || 'remove_permission'; spec.label = spec.label || '@i18n:objects.dnszone.remove_permission'; spec.enable_cond = spec.enable_cond || ['permission-set', 'managedby_w']; var that = IPA.action(spec); that.execute_action = function(facet) { var pkey = facet.get_pkey(); var command = IPA.command({ entity: 'dnszone', method: 'remove_permission', args: [pkey], options: {}, on_success: function(data, text_status, xhr) { facet.refresh(); IPA.notify_success(data.result.summary); } }); command.execute(); }; return that; }; IPA.dns.zone_has_permission_evaluator = function(spec) { spec = spec || {}; spec.event = spec.event || 'permission_load'; var that = IPA.state_evaluator(spec); that.on_event = function(permission_status) { var old_state = that.state; that.state = [ 'permission-'+permission_status ]; that.notify_on_change(old_state); }; return that; }; IPA.dns.record_search_facet = function(spec) { var that = IPA.nested_search_facet(spec); that.get_records = function(pkeys, on_success, on_error) { var batch = IPA.batch_command({ name: that.get_records_command_name(), on_success: on_success, on_error: on_error }); var zone = that.get_pkey(); for (var i=0; i 0) { $('input[name="'+that.table.name+'"]', tr).remove(); } } }; return that; }; IPA.dns.record_search_deleter_dialog = function(spec) { spec = spec || {}; var that = IPA.search_deleter_dialog(spec); that.create_command = function() { var batch = that.search_deleter_dialog_create_command(); for (var i=0; i', { 'text': text.get('@i18n:objects.dnsrecord.deleted_no_data') }).appendTo(that.container); $('

', { 'text': text.get('@i18n:objects.dnsrecord.redirection_dnszone') }).appendTo(that.container); }; that.on_ok = function() { navigation.show_entity_page('dnszone','default'); }; return that; }; /* * Spec preparation methods */ IPA.dns.record_prepare_spec = function(spec, type_prepare_method) { var metadata = IPA.dns.get_record_metadata(); var fields = []; var widgets = []; for (var i=0; i -1) continue; //create field var field = {}; field.name = attribute.name; field.label = attribute.label || IPA.dns.record_get_attr_label(attribute.name); set_defined(attribute.$type, field, '$type'); set_defined(attribute.validators, field, 'validators'); set_defined(attribute.required, field, 'required'); copy_obj(widget, attribute.field_opt); field.widget = type.name+'.'+field.name; fields.push(field); //create editor widget var widget = {}; if (typeof attribute === 'string') { widget.name = attribute; } else { widget.name = attribute.name; set_defined(attribute.$type, widget, '$type'); set_defined(attribute.options, widget, 'options'); copy_obj(widget, attribute.widget_opt); } section.widgets.push(widget); } }; IPA.dns.record_prepare_details_spec = function(spec, type_prepare_method) { var metadata = IPA.dns.get_record_metadata(); var fields = []; var widgets = []; var standard_record_section = { name: 'standard_types', $type: 'details_table_section', label: '@i18n:objects.dnsrecord.standard', widgets: [] }; var other_record_section = { name: 'other_types', $type: 'details_table_section', label: '@i18n:objects.dnsrecord.other', widgets: [] }; widgets.push(standard_record_section); widgets.push(other_record_section); var standard_types = ['arecord', 'aaaarecord', 'ptrrecord', 'srvrecord', 'txtrecord', 'cnamerecord', 'mxrecord', 'nsrecord']; for (var i=0; i -1) { IPA.dns.record_prepare_details_for_type(type, fields, standard_record_section); } else { IPA.dns.record_prepare_details_for_type(type, fields, other_record_section); } } IPA.dns.extend_spec(spec, fields, widgets); }; IPA.dns.record_prepare_details_for_type = function(type, fields, container) { var index = type.name.search('record$'); var dnstype = type.name.substring(0, index).toUpperCase(); var type_widget = { name: type.name, $type: 'dnsrecord_type_table', record_type: type.name, value_attribute: 'dnsdata', dnstype: dnstype, columns: type.columns }; container.widgets.push(type_widget); var field = { name: type.name, $type: 'dnsrecord_type_table', dnstype: dnstype, label: dnstype, widget: container.name+'.'+type.name }; fields.push(field); }; /* * Widgets and policies */ IPA.dnsrecord_host_link_field = function(spec) { var that = IPA.link_field(spec); that.other_pkeys = function() { var pkey = that.facet.get_pkeys(); return [pkey[1]+'.'+pkey[0]]; }; return that; }; IPA.dns_record_types = function() { //only supported var attrs = ['A', 'AAAA', 'A6', 'AFSDB', 'CERT', 'CNAME', 'DNAME', 'DS','KEY', 'KX', 'LOC', 'MX', 'NAPTR', 'NS', 'NSEC', 'PTR', 'RRSIG', 'SRV', 'SIG', 'SSHFP', 'TXT']; var record_types = []; for (var i=0; i -1) { label = label.substring(label.indexOf(' ')); } else if (part_name.indexOf('_extra_') > -1) { label = label.substring(label.indexOf(' ')); } return label; }; IPA.dnsrecord_type_field = function(spec) { spec = spec || {}; var that = IPA.field(spec); that.type_changed = IPA.observer(); that.get_type = function() { return that.widget.save()[0]; }; that.on_type_change = function() { that.type_changed.notify([], that); }; that.widgets_created = function() { that.field_widgets_created(); that.widget.value_changed.attach(that.on_type_change); }; that.reset = function() { that.field_reset(); that.on_type_change(); }; return that; }; IPA.dnsrecord_type_widget = function(spec) { spec.options = IPA.dns_record_types(); var that = IPA.select_widget(spec); return that; }; IPA.dnsrecord_adder_dialog_type_policy = function(spec) { spec = spec || {}; var that = IPA.facet_policy(spec); that.type_field_name = spec.type_field; that.post_create = function() { that.type_field = that.container.fields.get_field(that.type_field_name); that.type_field.type_changed.attach(that.on_type_change); that.on_type_change(); }; that.on_type_change = function() { var type = that.type_field.get_type(); that.allow_fields_for_type(type); that.show_widgets_for_type(type); }; that.allow_fields_for_type = function(type) { type = type.substring(0, type.indexOf('record')); var fields = that.container.fields.get_fields(); for (var i=0; i -1) { fieldtype = field.name.substring(0, index); break; } } field.enabled = (field.name === 'idnsname' || field.name === that.type_field_name || fieldtype === type); } }; that.show_widgets_for_type = function(type) { var widgets = that.container.widgets.get_widgets(); for (var i=0; i', { href: '#'+that.text, text: that.text, style: 'float: right;', click: function() { return that.link_handler(value); } }).appendTo(container); }; return that; }; IPA.dns.ptr_redirection_column = function(spec) { spec = spec || {}; var that = IPA.column(spec); that.link = true; that.link_handler = function(value) { var address = NET.ip_address(value); var pkeys = that.facet.get_pkeys(); var record = { zone: pkeys[0], name: pkeys[1] }; var dialog = IPA.dns.ptr_redirection_dialog({ address: address, dns_record: record }); dialog.open(); return false; }; return that; }; IPA.dns.ptr_redirection_dialog = function(spec) { spec = spec || {}; spec.title = spec.title || '@i18n:objects.dnsrecord.ptr_redir_title'; var that = IPA.dialog(spec); that.dns_record = spec.dns_record; that.address = spec.address; that.create = function() { that.status_div = $('

', { 'class': 'redirection-status' }).appendTo(that.container); }; that.create_buttons = function() { that.create_button({ name: 'close', label: '@i18n:buttons.close', click: function() { that.close(); } }); }; that.create_add_record_button = function() { $('', { text: text.get('@i18n:objects.dnsrecord.ptr_redir_create'), href: '#create_record', click: function() { that.create_record(); return false; } }).appendTo(that.container); }; that.append_status = function(message) { $('
', { text: message }).appendTo(that.status_div); }; that.open = function() { that.dialog_open(); that.start_redirect(); }; //step 0 - preparation that.start_redirect = function() { if (!that.address.valid) { that.append_status(text.get('@i18n:objects.dnsrecord.ptr_redir_address_err')); } else { that.reverse_address = that.address.get_reverse().toLowerCase()+'.'; that.get_zones(); } }; //1st step: get all zones that.get_zones = function() { that.append_status(text.get('@i18n:objects.dnsrecord.ptr_redir_zones')); var command = IPA.command({ entity: 'dnszone', method: 'find', options: { pkey_only: true }, on_success: that.find_zone, on_error: function() { that.append_status(text.get('@i18n:objects.dnsrecord.ptr_redir_zones_err')); } }); command.execute(); }; //2nd step: find target zone that.find_zone = function(data) { var zones = data.result.result; var target_zone = null; for (var i=0; i -1) { var msg = text.get('@i18n:objects.dnsrecord.ptr_redir_zone'); msg = msg.replace('${zone}', zone_name); that.append_status(msg); if (!target_zone || (target_zone && zone_name.length > target_zone.length)) { target_zone = zone_name; } break; } } if (target_zone) { that.zone = target_zone; that.check_record(); } else { that.append_status(text.get('@i18n:objects.dnsrecord.ptr_redir_zone_err')); } }; //3rd step: check record existance that.check_record = function(zone) { that.append_status(text.get('@i18n:objects.dnsrecord.ptr_redir_record')); var i1 = that.reverse_address.indexOf(that.zone); var record_name = that.reverse_address.substring(0,i1 - 1); that.record_keys = [that.zone, record_name]; var command = IPA.command({ entity: 'dnsrecord', method: 'show', args: that.record_keys, on_success: function() { that.redirect(); }, on_error: function() { that.append_status(text.get('@i18n:objects.dnsrecord.ptr_redir_record_err')); if (that.dns_record) { that.create_add_record_button(); } }, retry: false }); command.execute(); }; //4th-a step: actual redirect that.redirect = function() { navigation.show_entity( 'dnsrecord', 'default', that.record_keys); that.close(); }; //4th-b optional step: create PTR record that.create_record = function() { that.append_status(text.get('@i18n:objects.dnsrecord.ptr_redir_creating')); var ptr = that.dns_record.name +'.' + that.dns_record.zone; var command = IPA.command({ entity: 'dnsrecord', method: 'add', args: that.record_keys, options: { ptrrecord: [ptr] }, on_success: function() { that.redirect(); }, on_error: function() { that.append_status(text.get('@i18n:objects.dnsrecord.ptr_redir_creating_err')); } }); command.execute(); }; that.create_buttons(); return that; }; IPA.ip_address_validator = function(spec) { spec = spec || {}; spec.message = spec.message || '@i18n:widget.validation.ip_address'; var that = IPA.validator(spec); that.address_type = spec.address_type; that.validate = function(value) { if (IPA.is_empty(value)) return that.true_result(); var address = NET.ip_address(value); if (!address.valid || !that.is_type_match(address.type)) { return that.false_result(); } return that.true_result(); }; that.is_type_match = function(net_type) { return (!that.address_type || (that.address_type === 'IPv4' && (net_type === 'v4-quads' || net_type === 'v4-int')) || (that.address_type === 'IPv6' && net_type === 'v6')); }; that.ip_address_validate = that.validate; return that; }; IPA.ip_v4_address_validator = function(spec) { spec = spec || {}; spec.address_type = 'IPv4'; spec.message = spec.message || '@i18n:widget.validation.ip_v4_address'; return IPA.ip_address_validator(spec); }; IPA.ip_v6_address_validator = function(spec) { spec = spec || {}; spec.address_type = 'IPv6'; spec.message = spec.message || '@i18n:widget.validation.ip_v6_address'; return IPA.ip_address_validator(spec); }; IPA.dnsforwarder_validator = function(spec) { spec = spec || {}; var that = IPA.ip_address_validator(spec); that.validate = function(value) { var address_part = value; if (value.indexOf(' ') > - 1) { var parts = value.split(' '); if (parts.length !== 3 || parts[1] !== 'port') return that.false_result(); address_part = parts[0]; var port = parts[2]; if (!port.match(/^[1-9]\d*$|^0$/) || port < 0 || port > 65535) { var message = text.get('@i18n:widget.validation.port'); message = message.replace('${port}', port); return that.false_result(message); } } return that.ip_address_validate(address_part); }; return that; }; IPA.network_validator = function(spec) { spec = spec || {}; spec.message = spec.message || '@i18n:widget.validation.net_address'; var that = IPA.validator(spec); that.allow_negation = spec.allow_negation; that.allow_host_address = spec.allow_host_address; that.specials = spec.specials || []; that.validate = function(value) { if (IPA.is_empty(value)) return that.true_result(); if (typeof value !== 'string') return that.false_result(); if (that.specials.indexOf(value) > -1) { return that.true_result(); } var address_part, mask; if (value.indexOf('/') > -1) { var parts = value.split('/'); if (parts.length === 2) { address_part = parts[0]; mask = parts[1]; if (mask === '') return that.false_result(); } else { return that.false_result(); } } else if (that.allow_host_address) { address_part = value; } else { return that.false_result(); } if (that.allow_negation && address_part.indexOf('!') === 0) { address_part = address_part.substring(1); } var address = NET.ip_address(address_part); if (!address.valid) return that.false_result(); if (mask) { var mask_length = 32; if (address.type === 'v6') mask_length = 128; if (!mask.match(/^[1-9]\d*$/) || mask < 8 || mask > mask_length) { return that.false_result(); } } return that.true_result(); }; return that; }; exp.remove_menu_item = function() { if (!IPA.dns_enabled) { menu.remove_item('identity/dns'); } }; exp.config_spec = make_config_spec(); exp.zone_spec = make_zone_spec(); exp.record_spec = make_record_spec(); exp.register = function() { var e = reg.entity; var w = reg.widget; var f = reg.field; var v = reg.validator; var a = reg.action; e.register({type: 'dnsconfig', spec: exp.config_spec}); e.register({type: 'dnszone', spec: exp.zone_spec}); e.register({type: 'dnsrecord', spec: exp.record_spec}); w.register('dnszone_name', IPA.dnszone_name_widget); w.register('force_dnszone_add_checkbox', IPA.force_dnszone_add_checkbox_widget); f.register('force_dnszone_add_checkbox', IPA.checkbox_field); w.register('dnsrecord_host_link', IPA.link_widget); f.register('dnsrecord_host_link', IPA.dnsrecord_host_link_field); w.register('dnsrecord_type', IPA.dnsrecord_type_widget); f.register('dnsrecord_type', IPA.dnsrecord_type_field); w.register('dnsrecord_type_table', IPA.dns.record_type_table_widget); f.register('dnsrecord_type_table', IPA.dns.record_type_table_field); w.register('netaddr', IPA.multivalued_widget); f.register('netaddr', IPA.dns.netaddr_field); v.register('ip_address', IPA.ip_address_validator); v.register('ip_v4_address', IPA.ip_v4_address_validator); v.register('ip_v6_address', IPA.ip_v6_address_validator); v.register('dnsforwarder', IPA.dnsforwarder_validator); v.register('network', IPA.network_validator); a.register('dns_add_permission', IPA.dns.add_permission_action); a.register('dns_remove_permission', IPA.dns.remove_permission_action); }; phases.on('registration', exp.register); phases.on('profile', exp.remove_menu_item, 20); return exp; });