* Created Validate->is_alphanumeric, ->is_domain_name and ->is_positive_integer.

* In 'home', finished 'config_step1' sanity checks and framed up the base for step 2.

Signed-off-by: Digimer <digimer@alteeve.ca>
This commit is contained in:
Digimer 2017-09-05 14:55:48 +02:00
parent 3ac52e1724
commit c4a857e8d8
7 changed files with 382 additions and 39 deletions

View File

@ -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";

View File

@ -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")
{

View File

@ -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 >>'.

View File

@ -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 }});

View File

@ -40,6 +40,8 @@ This is the AN::Tools master 'words' file.
<key name="striker_0011">Internet-Facing Network Count</key>
<key name="striker_0012"><![CDATA[How many internal networks will this dashboard have access to? In most cases, this is just '1'.<br /><b>NOTE</b>: 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.]]></key>
<key name="striker_0013">Next</key>
<key name="striker_0014">Step 1</key>
<key name="striker_0015">IFN Count</key>
<!-- These are works and strings used by javascript/jqery -->
<key name="js_0001">Up</key>

View File

@ -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 {

View File

@ -72,6 +72,105 @@
</table>
<!-- end config_step1 -->
<!-- start config_step2 -->
<table>
<div id="config_step1_div">
<form name="config_step1" action="">
<tr>
<td colspan="2">
<span name="#!variable!step1_welcome_title_id!#" id="#!variable!step1_welcome_title_id!#" class="config_header1">#!string!striker_0001!#</span><br />
<span name="#!variable!step1_welcome_message_id!#" id="#!variable!step1_welcome_message_id!#" class="config_header2">#!string!striker_0002!#</span>
</td>
</tr>
<tr>
<td colspan="2">
<hr>
&nbsp;
</td>
</tr>
<tr>
<td width="75%">
1.
</td>
<td width="25%">
<table class="data_table">
<tr>
<td class="column_header" colspan="2">
#!string!striker_0014!#
</td>
</tr>
<tr class="data_row">
<!-- Organization name -->
<td class="column_row_name">
#!string!striker_0003!#:
</td>
<td class="column_row_value">
#!variable!organization!#
<input type="hidden" name="organization" id="organization" value="#!variable!organization!#">
</td>
</tr>
<tr class="data_row">
<!-- Prefix -->
<td class="column_row_name">
#!string!striker_0005!#:
</td>
<td class="column_row_value_fixed">
#!variable!prefix!#
<input type="hidden" name="prefix" id="prefix" value="#!variable!prefix!#">
</td>
</tr>
<tr class="data_row">
<!-- Domain name -->
<td class="column_row_name">
#!string!striker_0007!#:
</td>
<td class="column_row_value_fixed">
#!variable!domain!#
<input type="hidden" name="domain" id="domain" value="#!variable!domain!#">
</td>
</tr>
<tr class="data_row">
<!-- Sequence number -->
<td class="column_row_name">
#!string!striker_0009!#:
</td>
<td class="column_row_value_fixed">
#!variable!sequence!#
<input type="hidden" name="sequence" id="sequence" value="#!variable!sequence!#">
</td>
</tr>
<tr class="data_row">
<!-- IFN count -->
<td class="column_row_name">
#!string!striker_0015!#:
</td>
<td class="column_row_value_fixed">
#!variable!ifn_count!#
<input type="hidden" name="ifn_count" id="ifn_count" value="#!variable!ifn_count!#">
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
2.
</td>
</tr>
<tr>
<td colspan="2">
<br />
<hr>
<input type="submit" name="next" id="next" value="#!string!striker_0013!#">
</td>
</tr>
<input type="hidden" name="step" id="step" value="step2">
<input type="hidden" name="cgi_list" id="cgi_list" value="organization,prefix,domain,sequence,next,step,#!variable!cgi_list!#">
</form>
</div>
</table>
<!-- end config_step2 -->
<!-- start select_form -->
#!variable!description!#<br />
<input type="select" name="#!variable!name!#" id="#!variable!id!#" #!variable!extra!#>#!variable!options!#</select>
@ -79,12 +178,12 @@
<!-- start input_text_form -->
<span id="description_id">#!variable!description!#</span><br />
<input type="text" name="#!variable!name!#" id="#!variable!id!#" value="#!variable!value!#" placeholder="#!variable!field!#" #!variable!extra!#>
<input type="text" name="#!variable!name!#" id="#!variable!id!#" value="#!variable!value!#" placeholder="#!variable!field!#" class="#!variable!class!#" #!variable!extra!#>
<!-- end input_text_form -->
<!-- start input_number_form -->
<span id="description_id">#!variable!description!#</span><br />
<input type="number" name="#!variable!name!#" id="#!variable!id!#" value="#!variable!value!#" placeholder="#!variable!field!#" #!variable!extra!#>
<input type="number" name="#!variable!name!#" id="#!variable!id!#" value="#!variable!value!#" placeholder="#!variable!field!#" class="#!variable!class!#" #!variable!extra!#>
<!-- end input_number_form -->
<!-- start footer -->