diff --git a/AN/Tools/Database.pm b/AN/Tools/Database.pm index 88481144..c7763b90 100755 --- a/AN/Tools/Database.pm +++ b/AN/Tools/Database.pm @@ -2894,8 +2894,6 @@ sub write reenter => $reenter, }}); - print $THIS_FILE." ".__LINE__."; ID: [$id], query: [$query]\n"; - # Make logging code a little cleaner my $say_server = $id eq "" ? "#!string!log_0129!#" : $an->data->{database}{$id}{host}.":".$an->data->{database}{$id}{port}." -> ".$an->data->{database}{$id}{name}; #print "id: [$id], say_server: [$say_server]\n"; diff --git a/AN/Tools/Get.pm b/AN/Tools/Get.pm index 332f7c01..41953d68 100755 --- a/AN/Tools/Get.pm +++ b/AN/Tools/Get.pm @@ -139,6 +139,7 @@ sub cgi $an->data->{cgi}{$variable}{value} = ""; $an->data->{cgi}{$variable}{mimetype} = "string"; $an->data->{cgi}{$variable}{filehandle} = ""; + $an->data->{cgi}{$variable}{alert} = 0; # This is set if a sanity check fails if ($variable eq "file") { diff --git a/AN/Tools/Validate.pm b/AN/Tools/Validate.pm index e6c931b8..7a94156c 100755 --- a/AN/Tools/Validate.pm +++ b/AN/Tools/Validate.pm @@ -12,7 +12,10 @@ our $VERSION = "3.0.0"; my $THIS_FILE = "Validate.pm"; ### Methods; +# is_alphanumeric +# is_domain_name # is_ipv4 +# is_positive_integer # is_uuid =pod @@ -78,6 +81,96 @@ sub parent # Public methods # ############################################################################################################# +=head2 is_alphanumeric + +This verifies that the passed-in string contains only alpha-numeric characters. This is strict and will return invalid if spaces, hyphens or other characters are found. + +NOTE: An empty string is considered invalid. + + $string = "4words"; + if ($an->Validate->is_alphanumeric({string => $string})) + { + print "The string: [$string] is valid!\n"; + } + +=head2 Parameters; + +=head3 string (required) + +This is the string name to validate. + +=cut +sub is_alphanumeric +{ + my $self = shift; + my $parameter = shift; + my $an = $self->parent; + + my $valid = 1; + my $debug = 3; + my $string = defined $parameter->{string} ? $parameter->{string} : ""; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { string => $string }}); + + if (not $string) + { + $valid = 0; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }}); + } + + if ($string !~ /^[a-zA-Z0-9]+$/) + { + $valid = 0; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }}); + } + + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }}); + return($valid); +} + +=head2 is_domain_name + +Checks if the passed-in string is a valid domain name. Returns 'C<< 1 >>' if OK, 'C<< 0 >>' if not. + + $name = "alteeve.com"; + if ($an->Validate->is_domain_name({name => $name})) + { + print "The domain name: [$name] is valid!\n"; + } + +=head2 Parameters; + +=head3 name (required) + +This is the domain name to validate. + +=cut +sub is_domain_name +{ + my $self = shift; + my $parameter = shift; + my $an = $self->parent; + + my $valid = 1; + my $debug = 3; + my $name = $parameter->{name} ? $parameter->{name} : ""; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { name => $name }}); + + if (not $name) + { + $valid = 0; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }}); + } + elsif (($name !~ /^((([a-z]|[0-9]|\-)+)\.)+([a-z])+$/i) && (($name !~ /^\w+$/) && ($name !~ /-/))) + { + # Doesn't appear to be valid. + $valid = 0; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }}); + } + + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }}); + return($valid); +} + =head2 is_ipv4 Checks if the passed-in string is an IPv4 address. Returns 'C<< 1 >>' if OK, 'C<< 0 >>' if not. @@ -141,6 +234,64 @@ sub is_ipv4 return($valid); } +=head2 is_positive_integer + +This method verifies that the passed in value is a positive integer. + +NOTE: This method is strict and will only validate numbers without decimal places and that have no sign or a positive sign only (ie: C<< +3 >>, or C<< 3 >> are valid, but C<< -3 >> or C<< 3.0 >> are not). + + my $number = 3; + if ($an->Validate->is_positive_integer({number => $number})) + { + print "The number: [$number] is valid!\n"; + } + +=head2 Parameters; + +=head3 number (required) + +This is the number to verify. + +=head3 zero (optional) + +If set, the number C<< 0 >> will be considered valid. By default, c<< 0 >> is not considered "positive". + +=cut +sub is_positive_integer +{ + my $self = shift; + my $parameter = shift; + my $an = $self->parent; + + my $debug = 3; + my $valid = 1; + my $number = defined $parameter->{number} ? $parameter->{number} : ""; + my $zero = defined $parameter->{zero} ? $parameter->{zero} : 0; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + number => $number, + zero => $zero, + }}); + + # We'll strip a positive leading character as that is allowed. + $number =~ s/^\+//; + + # Now anything + if ($number !~ /^\d+$/) + { + $valid = 0; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }}); + } + + if ((not $zero) && (not $number)) + { + $valid = 0; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }}); + } + + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }}); + return($valid); +} + =head2 is_uuid This method takes a UUID string and returns 'C<< 1 >>' if it is a valid UUID string. Otherwise it returns 'C<< 0 >>'. diff --git a/cgi-bin/home b/cgi-bin/home index c6d42b6a..3d192219 100755 --- a/cgi-bin/home +++ b/cgi-bin/home @@ -41,23 +41,24 @@ elsif ($an->data->{cgi}{step}{value} eq "step1") { # Sanity check step1. my $sane = sanity_check_step1($an); + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { sane => $sane }}); if ($sane) - { - # No good - $body = config_step1($an); - } - else { # Step 1 was sanem show step 2. $body = config_step2($an); } + else + { + # No good + $body = config_step1($an); + } } else { $body = get_network_details($an); } -my $buttons = $an->Template->get({file => "main.html", name => "button_bar"}); -my $footer = $an->Template->get({file => "main.html", name => "footer"}); +my $buttons = $an->Template->get({file => "main.html", name => "button_bar"}); +my $footer = $an->Template->get({file => "main.html", name => "footer"}); # Display the page. my $template = $an->Template->get({file => "main.html", name => "master", variables => { @@ -86,9 +87,20 @@ sub config_step2 { my ($an) = @_; - # TODO... + my $step2_body = $an->Template->get({file => "main.html", name => "config_step2", variables => { + step1_welcome_title_id => "", + step1_welcome_message_id => "", + organization => $an->data->{cgi}{organization}{value}, + prefix => $an->data->{cgi}{prefix}{value}, + domain => $an->data->{cgi}{domain}{value}, + sequence => $an->data->{cgi}{sequence}{value}, + ifn_count => $an->data->{cgi}{ifn_count}{value}, + hostname_form => "", + cgi_list => "hostname", + }}); + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { step2_body => $step2_body }}); - return(0); + return($step2_body); } # This sanity-checks step 1 and returns '1' if there was a problem. @@ -96,9 +108,48 @@ sub sanity_check_step1 { my ($an) = @_; + # This will flip if we run into a problem. my $sane = 1; - # TODO... + # Organization just needs *something* + if ((not defined $an->data->{cgi}{organization}{value}) or (not $an->data->{cgi}{organization}{value})) + { + $an->data->{cgi}{organization}{alert} = 1; + $sane = 0; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::organization::alert" => $an->data->{cgi}{organization}{alert} }}); + } + + # The prefix needs to be alphanumeric and be between 1 ~ 5 chatacters. + if ((not $an->Validate->is_alphanumeric({string => $an->data->{cgi}{prefix}{value}})) or (length($an->data->{cgi}{prefix}{value}) > 5)) + { + $an->data->{cgi}{prefix}{alert} = 1; + $sane = 0; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::prefix::alert" => $an->data->{cgi}{prefix}{alert} }}); + } + + # We can use Validate to check the domain. + if (not $an->Validate->is_domain_name({name => $an->data->{cgi}{domain}{value}})) + { + $an->data->{cgi}{domain}{alert} = 1; + $sane = 0; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::domain::alert" => $an->data->{cgi}{domain}{alert} }}); + } + + # The sequence and IFN count need to be integers. + if (not $an->Validate->is_positive_integer({number => $an->data->{cgi}{sequence}{value}})) + { + $an->data->{cgi}{sequence}{alert} = 1; + $sane = 0; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::sequence::alert" => $an->data->{cgi}{sequence}{alert} }}); + } + if (not $an->Validate->is_positive_integer({number => $an->data->{cgi}{ifn_count}{value}})) + { + $an->data->{cgi}{ifn_count}{alert} = 1; + $sane = 0; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { sane => $sane, "cgi::ifn_count::alert" => $an->data->{cgi}{ifn_count}{alert} }}); + } + + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { sane => $sane }}); return($sane); } @@ -112,51 +163,62 @@ sub config_step1 my $reload_old_config = ""; if (1) { + ### TODO: ... # Old config exists. Load the detail and present the option to reload. } - my $say_organization = $an->Template->get({file => "main.html", name => "input_text_form", variables => { + my $organization_class = $an->data->{cgi}{organization}{alert} ? "input_alert" : "input_clear"; + my $say_organization = $an->Template->get({file => "main.html", name => "input_text_form", variables => { name => "organization", id => "organization", field => "#!string!striker_0003!#", description => "#!string!striker_0004!#", value => defined $an->data->{cgi}{organization}{value} ? $an->data->{cgi}{organization}{value} : "", + class => $organization_class, extra => "", }}); $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_organization => $say_organization }}); - my $say_prefix = $an->Template->get({file => "main.html", name => "input_text_form", variables => { + my $prefix_class = $an->data->{cgi}{prefix}{alert} ? "input_alert" : "input_clear"; + my $say_prefix = $an->Template->get({file => "main.html", name => "input_text_form", variables => { name => "prefix", id => "prefix", field => "#!string!striker_0005!#", description => "#!string!striker_0006!#", value => defined $an->data->{cgi}{prefix}{value} ? $an->data->{cgi}{prefix}{value} : "", + class => $prefix_class, extra => "maxlength=\"5\"", }}); $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_prefix => $say_prefix }}); - my $say_domain = $an->Template->get({file => "main.html", name => "input_text_form", variables => { + my $domain_class = $an->data->{cgi}{domain}{alert} ? "input_alert" : "input_clear"; + my $say_domain = $an->Template->get({file => "main.html", name => "input_text_form", variables => { name => "domain", id => "domain", field => "#!string!striker_0007!#", description => "#!string!striker_0008!#", value => defined $an->data->{cgi}{domain}{value} ? $an->data->{cgi}{domain}{value} : "", + class => $domain_class, extra => "maxlength=\"255\"", }}); $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_domain => $say_domain }}); - my $say_sequence = $an->Template->get({file => "main.html", name => "input_number_form", variables => { + my $sequence_class = $an->data->{cgi}{sequence}{alert} ? "input_alert" : "input_clear"; + my $say_sequence = $an->Template->get({file => "main.html", name => "input_number_form", variables => { name => "sequence", id => "sequence", field => "#!string!striker_0009!#", description => "#!string!striker_0010!#", value => defined $an->data->{cgi}{sequence}{value} ? $an->data->{cgi}{sequence}{value} : "", + class => $sequence_class, extra => "maxlength=\"2\"", }}); $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_domain => $say_domain }}); - my $say_ifn_count = $an->Template->get({file => "main.html", name => "input_number_form", variables => { + my $ifn_count_class = $an->data->{cgi}{ifn_count}{alert} ? "input_alert" : "input_clear"; + my $say_ifn_count = $an->Template->get({file => "main.html", name => "input_number_form", variables => { name => "ifn_count", id => "ifn_count", field => "#!string!striker_0011!#", description => "#!string!striker_0012!#", value => defined $an->data->{cgi}{ifn_count}{value} ? $an->data->{cgi}{ifn_count}{value} : "", + class => $ifn_count_class, extra => "maxlength=\"2\"", }}); $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_ifn_count => $say_ifn_count }}); diff --git a/cgi-bin/words.xml b/cgi-bin/words.xml index 7fa1b2b1..4b7c8507 100644 --- a/cgi-bin/words.xml +++ b/cgi-bin/words.xml @@ -40,6 +40,8 @@ This is the AN::Tools master 'words' file. Internet-Facing Network Count NOTE: You must have a network interface for the back-channel network, plus one for each internal network. If you have two interfaces for each network, we will setup bonds for redundancy automatically.]]> Next + Step 1 + IFN Count Up diff --git a/html/skins/alteeve/main.css b/html/skins/alteeve/main.css index 756ab0ae..3d71e5be 100644 --- a/html/skins/alteeve/main.css +++ b/html/skins/alteeve/main.css @@ -10,19 +10,15 @@ Colours; - Footer text: #515151 */ -input[type=text] { - width: 100%; - padding: 6px 10px; - margin: 2px 0; - display: inline-block; +input[type=text].input_clear, input[type=number].input_clear { border: 1px solid #9ba0a5; - border-radius: 2px; - box-sizing: border-box; - background-color: #343434; - color: #f7f7f7; } -input[type=number] { +input[type=text].input_alert, input[type=number].input_alert { + border: 2px solid red; +} + +input[type=text], input[type=number] { width: 100%; padding: 6px 10px; margin: 2px 0; @@ -41,19 +37,52 @@ body { color: #f2f2f2; } +table.data_table { + border: 1px solid #8f8f8f; + border-radius: 4px; +} +tr.data_row { + border-top: 1px solid #5f5f5f; +} + +td.column_header { + text-align: left; + color: #9ba0a5; + padding: 0.15em; +} + +td.column_row_name { + text-align: left; + color: #f7f7f7; + padding: 0.2em; +} + +td.column_row_value { + text-align: left; + color: #f7f7f7; + padding: 0.2em; +} + +td.column_row_value_fixed { + text-align: left; + color: #f7f7f7; + font-family: 'Dejavu Sans Mono', Courier; + padding: 0.2em; +} + .body_table { - width: 90%; -/* border: 0.1em solid blue; */ - margin: auto; - top: 0; + width: 90%; +/* border: 0.1em solid blue; */ + margin: auto; + top: 0; position: absolute; - left: 5% + left: 5%; } .config_header1 { - color: #f7f7f7; + color: #f7f7f7; text-align: center; - font-size: 2em; + font-size: 2em; } .config_header2 { @@ -63,12 +92,13 @@ body { } table { - border-spacing: 0; + border-spacing: 0; border-collapse: collapse; + vertical-align: top; } td { /* border: 1px solid green; */ - padding: 0; + padding: 0; border-collapse: collapse; } @@ -76,7 +106,7 @@ td { border-top: 0.3em solid transparent; border-left: 0.3em solid transparent; border-right: 0.3em solid transparent; - height: 2.5em; + height: 2.5em; } .top_icon { diff --git a/html/skins/alteeve/main.html b/html/skins/alteeve/main.html index b64c9697..5200003c 100644 --- a/html/skins/alteeve/main.html +++ b/html/skins/alteeve/main.html @@ -72,6 +72,105 @@ + + +
+
+
+ + + + + + + + + + + + + + + + + + + +
+ #!string!striker_0001!#
+ #!string!striker_0002!# +
+
+   +
+ 1. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ #!string!striker_0014!# +
+ #!string!striker_0003!#: + + #!variable!organization!# + +
+ #!string!striker_0005!#: + + #!variable!prefix!# + +
+ #!string!striker_0007!#: + + #!variable!domain!# + +
+ #!string!striker_0009!#: + + #!variable!sequence!# + +
+ #!string!striker_0015!#: + + #!variable!ifn_count!# + +
+
+ 2. +
+
+
+ +
+ + #!variable!description!#
#!variable!options!# @@ -79,12 +178,12 @@ #!variable!description!#
- + #!variable!description!#
- +