From 61a0a9ae94d68d6ca030abab68a5f999bc6554a9 Mon Sep 17 00:00:00 2001 From: Matt Zagrabelny Date: Fri, 7 Feb 2020 15:37:05 -0600 Subject: [PATCH 1/6] Whitespace changes for RR::_validate_args Convert all tabs to 4 spaces for subroutine _validate_args. Remove trailing whitespace and canonicalize things according to Perl Best Practices. This is in anticipation of further changes coming. --- lib/Netdot/Model/RR.pm | 132 ++++++++++++++++++++++------------------- 1 file changed, 72 insertions(+), 60 deletions(-) diff --git a/lib/Netdot/Model/RR.pm b/lib/Netdot/Model/RR.pm index 4f1521f1c..86c07e52d 100644 --- a/lib/Netdot/Model/RR.pm +++ b/lib/Netdot/Model/RR.pm @@ -718,76 +718,88 @@ sub add_alias { ############################################################################ # _validate_args - Validate arguments to insert and update # -# Args: +# Args: # hashref -# Returns: +# Returns: # True, or throws exception if validation fails # Examples: # $class->_validate_args($argv); # sub _validate_args { my ($self, $argv) = @_; - + my $zone; - if (ref($self)){ - $zone = $self->zone; + if (ref($self)) { + $zone = $self->zone; } - if ( defined $argv->{zone} ){ - if ( ref($argv->{zone}) ){ - # We're being passed an object - $zone = $argv->{zone} - }else{ - if ( $argv->{zone} =~ /\D+/ ){ - $zone = Zone->search(name=>$argv->{zone})->first; - }else{ - $zone = Zone->retrieve($argv->{zone}); - } - } + if (defined $argv->{zone}) { + if (ref($argv->{zone})) { + # We're being passed an object + $zone = $argv->{zone}; + } + else { + if ($argv->{zone} =~ /\D+/){ + $zone = Zone->search(name=>$argv->{zone})->first; + } + else { + $zone = Zone->retrieve($argv->{zone}); + } + } } - if ( defined $argv->{name} ){ - # Convert to lowercase - my $name = lc($argv->{name}); - - # Remove whitespace - $name =~ s/\s+//g; - - # Remove trailing dots, if any - $name =~ s/\.$//; - - # Remove commas - $name =~ s/,//; - - # Valid characters - if ( $name =~ /[^A-Za-z0-9\.\-_@\*]/ ){ - $self->throw_user("Invalid name: $name. Contains invalid characters"); - } - - if ( $self->config->get('ALLOW_UNDERSCORES_IN_DEVICE_NAMES') eq '0' ){ - # Underscore only allowed at beginning of string or dotted section - if ( $name =~ /[^^.]_/ || $name =~ /_$/ ){ - $self->throw_user("Invalid name: $name. Invalid underscores"); - } - } - - # Name must not start or end with a dash - if ( $name =~ /^\-/ || $name =~ /\-$/ ){ - $self->throw_user("Invalid name: $name. Name must not start or end with a dash"); - } - - # Length restrictions (RFC 1035) - my $fqdn = $name.".".$zone->name; - if ( length($fqdn) > 255 ){ - $self->throw_user("Invalid FQDN: $fqdn. Length exceeds 255 characters"); - } - # labels (sections between dots) must not exceed 63 chars - foreach my $label ( split(/\./, $fqdn) ){ - unless ( length($label) >= 1 && length($label) < 64 ){ - $self->throw_user(sprintf("RR::validate_args(): '%s' has Invalid label: '%s'. ". - "Each label must be between 1 and 63 characters long", - $fqdn, $label)); - } - } - $argv->{name} = $name; + if (defined $argv->{name}) { + # Convert to lowercase + my $name = lc($argv->{name}); + + # Remove whitespace + $name =~ s/\s+//g; + + # Remove trailing dots, if any + $name =~ s/\.$//; + + # Remove commas + $name =~ s/,//; + + # Valid characters + if ($name =~ /[^A-Za-z0-9\.\-_@\*]/) { + $self->throw_user("Invalid name: $name. Contains invalid characters"); + } + + if ( + $self->config->get('ALLOW_UNDERSCORES_IN_DEVICE_NAMES') eq '1' + ) { + $logger->debug('Allow underscores in device name. No underscore validation check.'); + } + else { + # Underscore only allowed at beginning of string or dotted section + if ($name =~ /[^^.]_/ || $name =~ /_$/){ + $self->throw_user("Invalid name: $name. Invalid underscores"); + } + } + + # Name must not start or end with a dash + if ($name =~ /^\-/ || $name =~ /\-$/) { + $self->throw_user("Invalid name: $name. Name must not start or end with a dash"); + } + + # Length restrictions (RFC 1035) + my $fqdn = $name.".".$zone->name; + if (length($fqdn) > 255) { + $self->throw_user("Invalid FQDN: $fqdn. Length exceeds 255 characters"); + } + # labels (sections between dots) must not exceed 63 chars + for my $label (split(/\./, $fqdn)){ + unless (length($label) >= 1 && length($label) < 64) { + $self->throw_user( + sprintf( + "RR::validate_args(): '%s' has Invalid label: '%s'. ". + "Each label must be between 1 and 63 characters long", + $fqdn, + $label, + ) + ); + } + } + $argv->{name} = $name; } 1; } From 13cba7bbb719ef6a5c469b831894051682f46858 Mon Sep 17 00:00:00 2001 From: Matt Zagrabelny Date: Mon, 10 Feb 2020 14:10:49 -0600 Subject: [PATCH 2/6] New configuration parameter for allowing underscore validation overrides Setting this to true will give the web user an underscore "override" checkbox when creating a record within a domain. --- etc/Default.conf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/etc/Default.conf b/etc/Default.conf index c2159f273..5f7dd0f2d 100644 --- a/etc/Default.conf +++ b/etc/Default.conf @@ -578,6 +578,14 @@ IGNORE_IPV6_LINK_LOCAL => 0, # to 1 will allow underscores anywhere in a device name. ALLOW_UNDERSCORES_IN_DEVICE_NAMES => 0, +# Allow resource records (RR) to contain underscores by +# giving the web user a checkbox to override the underscore +# validation. This allows the default and common case of +# not allowing underscores to exist while still permitting the +# local user to override and allow a record with an underscore. +# This is useful for text (TXT) or service (SRV) records. +UNDERSCORES_IN_DEVICE_NAMES_OVERRIDE_ALLOWED => 0, + ##################################################################### # # IP Address Space Management From f588675e22744392874968adc7e320a909a63408 Mon Sep 17 00:00:00 2001 From: Matt Zagrabelny Date: Mon, 10 Feb 2020 14:16:46 -0600 Subject: [PATCH 3/6] Extend RR->_validat_args to check if underscore "override" is present Use extra_argv to pass UI checkbox value to this function to determine if underscore validation needs to occur. --- lib/Netdot/Model/RR.pm | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/Netdot/Model/RR.pm b/lib/Netdot/Model/RR.pm index 86c07e52d..1082ce350 100644 --- a/lib/Netdot/Model/RR.pm +++ b/lib/Netdot/Model/RR.pm @@ -719,14 +719,19 @@ sub add_alias { # _validate_args - Validate arguments to insert and update # # Args: -# hashref +# argv - hashref containing database field and values +# extra_argv - (optional) hashref containing extra parameters # Returns: # True, or throws exception if validation fails # Examples: # $class->_validate_args($argv); # sub _validate_args { - my ($self, $argv) = @_; + my ($self, $argv, $extra_argv) = @_; + + if (! defined $extra_argv) { + $extra_argv = {}; + } my $zone; if (ref($self)) { @@ -766,6 +771,12 @@ sub _validate_args { if ( $self->config->get('ALLOW_UNDERSCORES_IN_DEVICE_NAMES') eq '1' + || + ( + $self->config->get('UNDERSCORES_IN_DEVICE_NAMES_OVERRIDE_ALLOWED') eq '1' + && + $extra_argv->{allow_underscore_override} + ) ) { $logger->debug('Allow underscores in device name. No underscore validation check.'); } From 2b039b2895cfee0c2e76545fd90156ba176d99cc Mon Sep 17 00:00:00 2001 From: Matt Zagrabelny Date: Mon, 10 Feb 2020 14:19:15 -0600 Subject: [PATCH 4/6] Call _validate_args with extra_arguments Pass "allow_underscore_override" value into _validate_args. --- lib/Netdot/Model/RR.pm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/Netdot/Model/RR.pm b/lib/Netdot/Model/RR.pm index 1082ce350..d219cbecc 100644 --- a/lib/Netdot/Model/RR.pm +++ b/lib/Netdot/Model/RR.pm @@ -208,8 +208,11 @@ sub insert { expiration => $argv->{expiration}, info => $argv->{info}, ); + my $extra_arguments = { + allow_underscore_override => $argv->{allow_underscore_override}, + }; - $class->_validate_args(\%state); + $class->_validate_args(\%state, $extra_arguments); $rr = $class->SUPER::insert(\%state); From 15ccd61a12070c9c66b9c2558536a843bc7b84d1 Mon Sep 17 00:00:00 2001 From: Matt Zagrabelny Date: Mon, 10 Feb 2020 14:20:17 -0600 Subject: [PATCH 5/6] Add function to return underscore override UI elements If configuration values are set appropriately then return a string and checkbox for overriding underscore validation. --- lib/Netdot/UI.pm | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/lib/Netdot/UI.pm b/lib/Netdot/UI.pm index 27fa2f54e..089d750a8 100644 --- a/lib/Netdot/UI.pm +++ b/lib/Netdot/UI.pm @@ -416,6 +416,53 @@ sub form_field { } } + +############################################################################ + +=head2 underscore_override_form_field - Return if Underscore Override checkbox if enabled. + + This method will populate a hashref with a label and checkbox to allow the + user to override the underscore validation for names. + If ALLOW_UNDERSCORES_IN_DEVICE_NAMES is set to true, then there is no + need to return the checkbox since underscores are allowed at the global + level. + If UNDERSCORES_IN_DEVICE_NAMES_OVERRIDE_ALLOWED is set to true then + return the checkbox to allow the user to override the underscore check + at a per device name. + + Arguments: + hashref to populate with label and value + Returns: + Boolean true or false if the calling code should add label and value + to the UI. + + Examples: + + my $tmp = {}; + if ($ui->underscore_override_form_field($tmp)) { + # do something with $tmp + } + +=cut + +sub underscore_override_form_field { + my $self = shift; + my $hash = shift; + + if ( + ! $self->config->get('ALLOW_UNDERSCORES_IN_DEVICE_NAMES') + && + $self->config->get('UNDERSCORES_IN_DEVICE_NAMES_OVERRIDE_ALLOWED') + ) { + $hash->{label} = 'Allow underscores:'; + $hash->{value} = ''; + return 1; + } + + return 0; +} + + ############################################################################ =head2 table_descr_link - Generate link to display a table\'s description From d79151e0a350ef02a689cbdf59cf3dacba781954 Mon Sep 17 00:00:00 2001 From: Matt Zagrabelny Date: Mon, 10 Feb 2020 14:21:55 -0600 Subject: [PATCH 6/6] Call UI underscore override code Potentially alter form with underscore validation override checkbox. --- htdocs/management/host.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/management/host.html b/htdocs/management/host.html index 39a5bc7db..794f647a9 100644 --- a/htdocs/management/host.html +++ b/htdocs/management/host.html @@ -242,6 +242,12 @@ push( @field_headers, $tmp{label} ); push( @cell_data, $tmp{value} ); + my $tmp_underscore_override = {}; + if ($ui->underscore_override_form_field($tmp_underscore_override)) { + push(@field_headers, $tmp_underscore_override->{label}); + push(@cell_data, $tmp_underscore_override->{value}); + } + $m->comp('/generic/attribute_table.mhtml', %comphash); (@field_headers, @cell_data) = ((),());