* Finished working on the log in and log out functions of Striker. Still super basic, but it works!

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 7 years ago
parent 3fce021498
commit 1079c65687
  1. 115
      Anvil/Tools/Account.pm
  2. 15
      Anvil/Tools/Get.pm
  3. 54
      cgi-bin/home
  4. 38
      html/skins/alteeve/main.html
  5. 2
      share/words.xml

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

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

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

@ -2,13 +2,13 @@
<table id="button_bar">
<tr>
<td>
<img src="#!data!skin::url!#/images/striker_icon_on.png" class="top_icon">
#!variable!striker_button!#
</td>
<td>
<img src="#!data!skin::url!#/images/anvil_icon_on.png" class="top_icon">
#!variable!anvil_button!#
</td>
<td>
<img src="#!data!skin::url!#/images/users_icon_on.png" class="top_icon">
#!variable!user_button!#
</td>
<td>
<a href="https://alteeve.com/w/Support" target="_new"><img src="#!data!skin::url!#/images/help_icon_on.png" id="help_icon" class="top_icon"></a>
@ -17,10 +17,34 @@
</table>
<!-- end button_bar -->
<!-- start anvil_button_off -->
<img src="#!data!skin::url!#/images/anvil_icon_off.png" class="top_icon">
<!-- end anvil_button_off -->
<!-- start anvil_button_on -->
<a href="?anvil=true"><img src="#!data!skin::url!#/images/anvil_icon_on.png" class="top_icon">
<!-- end anvil_button_on -->
<!-- start striker_button_off -->
<img src="#!data!skin::url!#/images/striker_icon_off.png" class="top_icon">
<!-- end striker_button_off -->
<!-- start striker_button_on -->
<a href="?striker=true"><img src="#!data!skin::url!#/images/striker_icon_on.png" class="top_icon">
<!-- end striker_button_on -->
<!-- start user_button_off -->
<img src="#!data!skin::url!#/images/users_icon_off.png" class="top_icon">
<!-- end user_button_off -->
<!-- start user_button_on -->
<a href="?logout=true"><img src="#!data!skin::url!#/images/users_icon_on.png" alt="#!string!message_0033!#" class="top_icon">
<!-- end user_button_on -->
<!-- start config_step1 -->
<table>
<div id="config_step1_div">
<form name="config_step1" action="">
<form name="config_step1" action="" method="post">
<tr>
<td>
<span name="#!variable!step1_welcome_title_id!#" id="#!variable!step1_welcome_title_id!#" class="config_header1">#!string!striker_0001!#</span><br />
@ -77,7 +101,7 @@
<!-- start config_step2 -->
<table>
<div id="config_step1_div">
<form name="config_step1" action="">
<form name="config_step1" action="" method="post">
<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 />
@ -210,7 +234,7 @@
<!-- start config_step3 -->
<table>
<div id="config_step3_div">
<form name="config_step3" action="">
<form name="config_step3" action="" method="post">
<tr>
<td>
<span name="#!variable!step1_welcome_title_id!#" id="#!variable!step1_welcome_title_id!#" class="config_header1">#!string!striker_0001!#</span><br />
@ -332,7 +356,7 @@
<!-- start striker-login -->
<table class="login"">
<form name="striker_login" action="">
<form name="striker_login" action="" method="post">
<div id="striker_login">
<tr>
<td>

@ -58,6 +58,7 @@ NOTE: You must update the password of any other system using this host's
<key name="message_0030">Failed to write the new password to the temporary file: [#!variable!file!#]. Please check the logs for details.</key>
<key name="message_0031">Beginning configuration of local system.</key>
<key name="message_0032"><![CDATA[Forgot your password?<br />Use '<span class="code">anvil-change-password</span>' from the console to reset it.]]></key>
<key name="message_0033">Log out</key>
<!-- Log entries -->
<key name="log_0001">Starting: [#!variable!program!#].</key>
@ -400,6 +401,7 @@ Here we will inject 't_0006', which injects 't_0001' which has a variable: [#!st
<key name="error_0025">The user ID passed in to Account->read_details: [#!variable!uuid!#] is not a valid UUID.</key>
<key name="error_0026">The user ID passed in to Account->read_details: [#!variable!uuid!#] was not found in the database.</key>
<key name="error_0027">Login failed, please try again.</key>
<key name="error_0028"><![CDATA[There appears to be a problem with Striker. The login failed, please check: [<span class="code">#!data!sys::log_file!#</span>] for details.]]></key>
<!-- These are works and strings used by javascript/jqery -->
<key name="js_0001">Up</key>

Loading…
Cancel
Save