diff --git a/Anvil/Tools/Account.pm b/Anvil/Tools/Account.pm index 64c9269e..6a8a61ba 100755 --- a/Anvil/Tools/Account.pm +++ b/Anvil/Tools/Account.pm @@ -317,13 +317,25 @@ AND if ($test_password_hash eq $user_password_hash) { # User passed a valid username/password. Create a session hash. - my ($session_hash, $session_salt) = $anvil->Account->_build_cookie_hash({uuid => $anvil->data->{cookie}{anvil_user_uuid}, offset => 0}); + my ($session_hash, $session_salt) = $anvil->Account->_build_cookie_hash({ + debug => $debug, + uuid => $user_uuid, + offset => 0, + }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { session_hash => $session_hash, session_salt => $session_salt, }}); - my $query = " + if (not $session_hash) + { + # Something went wrong generating the session cookie, login failed. + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $anvil->Words->string({key => "error_0028"}) }}); + return(1); + } + else + { + my $query = " UPDATE users SET @@ -332,15 +344,16 @@ SET WHERE user_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($user_uuid)." ;"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); - $anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__}); - - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0183", variables => { user => $anvil->data->{cgi}{username}{value} }}); - $anvil->Account->_write_cookies({ - debug => $debug, - hash => $session_hash, - uuid => $user_uuid, - }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); + $anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__}); + + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0183", variables => { user => $anvil->data->{cgi}{username}{value} }}); + $anvil->Account->_write_cookies({ + debug => $debug, + hash => $session_hash, + uuid => $user_uuid, + }); + } } else { @@ -377,6 +390,26 @@ sub logout # Delete the user's cookie data. Sending nothing to '_write_cookies' does this. $anvil->Account->_write_cookies({debug => $debug}); + + # Delete the user's session salt. + if ($anvil->data->{cookie}{anvil_user_uuid}) + { + my $query = " +UPDATE + users +SET + user_session_salt = '', + modified_date = ".$anvil->data->{sys}{use_db_fh}->quote($anvil->data->{sys}{db_timestamp})." +WHERE + user_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($anvil->data->{cookie}{anvil_user_uuid})." +;"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); + $anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__}); + + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0183", variables => { user => $anvil->data->{cgi}{username}{value} }}); + } + + # Log that they're out $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0179"}); return(0); @@ -466,8 +499,6 @@ sub read_cookies if ($count < 1) { - - die; # The user in the cookie isn't in the database. The user was deleted? $anvil->Account->logout(); @@ -485,8 +516,18 @@ sub read_cookies $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "users::user_session_salt" => $anvil->data->{users}{user_session_salt} }}); # Generate a hash using today and yesterday's date. - my ($today_hash) = $anvil->Account->_build_cookie_hash({uuid => $anvil->data->{cookie}{anvil_user_uuid}, offset => 0}); - my ($yesterday_hash) = $anvil->Account->_build_cookie_hash({uuid => $anvil->data->{cookie}{anvil_user_uuid}, offset => -86400}); + my ($today_hash) = $anvil->Account->_build_cookie_hash({ + debug => $debug, + uuid => $anvil->data->{cookie}{anvil_user_uuid}, + salt => $anvil->data->{users}{user_session_salt}, + offset => 0, + }); + my ($yesterday_hash) = $anvil->Account->_build_cookie_hash({ + debug => $debug, + uuid => $anvil->data->{cookie}{anvil_user_uuid}, + salt => $anvil->data->{users}{user_session_salt}, + offset => -86400, + }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { today_hash => $today_hash, yesterday_hash => $yesterday_hash, @@ -514,6 +555,9 @@ sub read_cookies } else { + ### TODO: left off here. First check fails and the user is logged out. + #die; + # The user's cookie is invalid, log the user out. $anvil->Account->logout(); @@ -796,7 +840,9 @@ WHERE =head2 _build_cookie_hash -This takes a (user) UUID and offset (stated as seconds) and builds a hash approporiate for use in cookies (or a test hash to validate a read cookie hash). +This takes a (user) UUID and offset (stated as seconds) and builds a hash approporiate for use in cookies (or a test hash to validate a read cookie hash). The resulting hash and the salt used to generate the hash are returned. + +If there is a problem, C<< 0 >> will be returned for both the hash and salt. Parameters; @@ -822,6 +868,7 @@ sub _build_cookie_hash my $offset = defined $parameter->{offset} ? $parameter->{offset} : 0; my $user_agent = defined $parameter->{user_agent} ? $parameter->{user_agent} : $ENV{HTTP_USER_AGENT}; + my $salt = defined $parameter->{salt} ? $parameter->{salt} : ""; my $uuid = defined $parameter->{uuid} ? $parameter->{uuid} : $anvil->data->{cookie}{anvil_user_uuid}; # I know I could do chained conditionals, but it gets hard to read. $user_agent = "" if not defined $user_agent; @@ -829,25 +876,47 @@ sub _build_cookie_hash $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { offset => $offset, user_agent => $user_agent, + salt => $salt, uuid => $uuid, }}); + if (not $anvil->Validate->is_uuid({uuid => $uuid})) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Account->_build_cookie_hash()", parameter => "uuid" }}); + return(0, 0); + } + if (not $user_agent) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Account->_build_cookie_hash()", parameter => "user_agent" }}); + return(0, 0); + } + my $date = $anvil->Get->date_and_time({date_only => 1, offset => $offset}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { date => $date }}); - my $session_string = $uuid.$date.$user_agent; + my $session_string = $uuid.":".$date.":".$user_agent; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { session_string => $session_string }}); + if (not $salt) + { + $salt = $anvil->Get->_salt; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { salt => $salt }}); + } + # Generate a hash, but unike normal passwords, we won't re-encrypt it. - my $answer = $anvil->Account->encrypt_password({password => $session_string, hash_count => 0}); - my $hash = $answer->{user_password_hash}; - my $salt = $answer->{user_salt}; + my $answer = $anvil->Account->encrypt_password({ + debug => $debug, + hash_count => 0, + password => $session_string, + salt => $salt, + }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - hash => $hash, - salt => $salt, + hash => $answer->{user_password_hash}, + salt => $answer->{user_salt}, }}); - return($hash, $salt); + return($answer->{user_password_hash}, $answer->{user_salt}); } =head2 _write_cookies diff --git a/Anvil/Tools/Get.pm b/Anvil/Tools/Get.pm index eace8ce9..dc691e8d 100755 --- a/Anvil/Tools/Get.pm +++ b/Anvil/Tools/Get.pm @@ -209,10 +209,19 @@ sub cgi $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { variable => $variable }}); push @{$cgis}, $variable; } - - $cgi_count = @{$cgis}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { cgi_count => $cgi_count }}); } + elsif (exists $cgi->{param}) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { 'cgi->{param}' => $cgi->{param} }}); + foreach my $variable (sort {$a cmp $b} keys %{$cgi->{param}}) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { variable => $variable }}); + push @{$cgis}, $variable; + } + } + + $cgi_count = @{$cgis}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { cgi_count => $cgi_count }}); # If we don't have at least one variable, we're done. if ($cgi_count < 1) diff --git a/cgi-bin/home b/cgi-bin/home index 04763582..a961c65a 100755 --- a/cgi-bin/home +++ b/cgi-bin/home @@ -70,7 +70,7 @@ my $body = ""; # If any jobs are pending/running, show the "unavailable" option. my $available = check_availability($anvil); -$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { available => $available }}); +$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { available => $available }}); if (not $available) { # Set the body to 'say::maintenance'. @@ -79,7 +79,7 @@ if (not $available) # If there is no user account yet, then the system is new and needs to be reconfigured. my $configured = check_if_configured($anvil); -$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { configured => $configured }}); +$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { configured => $configured }}); if (not $configured) { $body = configure_striker($anvil); @@ -90,7 +90,11 @@ else $body = process_task($anvil); } -my $buttons = $anvil->Template->get({file => "main.html", name => "button_bar"}); +my $buttons = $anvil->Template->get({file => "main.html", name => "button_bar", variables => { + anvil_button => 0 ? $anvil->Template->get({file => "main.html", name => "anvil_button_on"}) : $anvil->Template->get({file => "main.html", name => "anvil_button_off"}), + striker_button => 0 ? $anvil->Template->get({file => "main.html", name => "striker_button_on"}) : $anvil->Template->get({file => "main.html", name => "striker_button_off"}), + user_button => $anvil->data->{sys}{users}{user_name} ? $anvil->Template->get({file => "main.html", name => "user_button_on"}) : $anvil->Template->get({file => "main.html", name => "user_button_off"}), +}}); my $footer = $anvil->Template->get({file => "main.html", name => "footer"}); # Display the page. @@ -130,7 +134,7 @@ sub process_task $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::login::value" => $anvil->data->{cgi}{login}{value} }}); # Woot! - my $failed = $anvil->Account->login({debug => 2}); + my $failed = $anvil->Account->login({debug => 3}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { failed => $failed }}); if (not $failed) { @@ -138,21 +142,26 @@ sub process_task $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { logged_in => $logged_in }}); } } + elsif ((defined $anvil->data->{cgi}{logout}) && ($anvil->data->{cgi}{logout}{value})) + { + # Bye now! + $anvil->Account->logout({debug => 3}); + } else { # Is the user logged in? # 0 - The cookies were read, the account was validated and the user's details were loaded. # 1 - No cookie was found or read. The user needs to log in # 2 - There was a problem reading the user's UUID (it wasn't found in the database), so the - # cookies were deleted (via C<< Account->_logout() >>. The user needs to log back in. + # cookies were deleted (via C<< Account->logout() >>. The user needs to log back in. # 3 - There user's hash is invalid, it is probably expired. The user has been logged out and # needs to log back in. - my $cookie_problem = $anvil->Account->read_cookies({debug => 2}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { cookie_problem => $cookie_problem }}); + my $cookie_problem = $anvil->Account->read_cookies({debug => 3}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { cookie_problem => $cookie_problem }}); if (not $cookie_problem) { $logged_in = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { logged_in => $logged_in }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { logged_in => $logged_in }}); } } @@ -252,13 +261,13 @@ sub check_if_configured variable_source_uuid => $anvil->Get->host_uuid, variable_source_table => "hosts", }); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { configured => $configured, variable_uuid => $variable_uuid, modified_date => $modified_date, }}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { configured => $configured }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { configured => $configured }}); return($configured); } @@ -269,12 +278,25 @@ sub check_availability my ($anvil) = @_; my $available = 1; - my $query = "SELECT job_progress, modified_date, extract(epoch from modified_date) FROM jobs WHERE job_name = 'configure::network' AND job_progress != 100 AND job_host_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($anvil->Get->host_uuid).";"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); + my $query = " +SELECT + job_progress, + modified_date, + extract(epoch from modified_date) +FROM + jobs +WHERE + job_name = 'configure::network' +AND + job_progress != 100 +AND + job_host_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($anvil->Get->host_uuid)." +;"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { query => $query }}); my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); my $count = @{$results}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { results => $results, count => $count, }}); @@ -286,7 +308,7 @@ sub check_availability my $unixtime = $results->[0]->[2]; my $seconds_ago = $anvil->Convert->add_commas({number => (time - $unixtime)}); $available = 0; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { available => $available, percent => $percent, seconds_ago => $seconds_ago, @@ -300,10 +322,10 @@ sub check_availability title => "#!string!striker_0046!#", description => $anvil->Words->string({key => "striker_0047", variables => { percent => $percent, timestamp => $timestamp, seconds_ago => $seconds_ago }}), }}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'say::maintenance' => $anvil->data->{say}{maintenance} }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'say::maintenance' => $anvil->data->{say}{maintenance} }}); } - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { available => $available }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { available => $available }}); return($available); } diff --git a/html/skins/alteeve/main.html b/html/skins/alteeve/main.html index b47416d5..c3912422 100644 --- a/html/skins/alteeve/main.html +++ b/html/skins/alteeve/main.html @@ -2,13 +2,13 @@
- + #!variable!striker_button!# - + #!variable!anvil_button!# - + #!variable!user_button!# @@ -17,10 +17,34 @@
+ + + + + + + + + + + + + + + + + + + + + +#!string!message_0033!# + +
-
+
#!string!striker_0001!#
@@ -77,7 +101,7 @@
- +
#!string!striker_0001!#
@@ -210,7 +234,7 @@
- +
#!string!striker_0001!#
@@ -332,7 +356,7 @@ - +