#!/usr/bin/perl
# gRSShopper 0.3 Login 0.5 -- gRSShopper administration module
# 29 January 2012 - Stephen Downes
# Copyright (C) <2012> ";
print POUT "\n$ENV{'REMOTE_ADDR'}\t$vars->{action}\n$sq"
|| print "Error printing to log: $! ";
close POUT;
for ($vars->{action}) {
/Login/ && do { &user_login($dbh,$query); last; };
/Logout/ && do { &user_logout($dbh,$query); last; };
/openidloginform/ && do { &openid_login_form($dbh,$query); last; };
/OpenID/ && do { &openidq($dbh,$query); exit; };
/Register/ && do { ®istration_form_text($dbh,$query); last; };
/New/ && do { &new_user($dbh,$query); last; };
/Remove/ && do { &remove_user($dbh,$query); last; };
/Email/ && do { &email_password($dbh,$query); last; };
/Send/ && do { &send_password($dbh,$query); last; };
/reset/ && do { &reset_password($dbh,$query); last; };
/changepwdscr/ && do { &change_password_screen($dbh,$query); last; };
/changepwdinp/ && do { &change_password_input($dbh,$query); last; };
/Subscribe/ && do { &subscribe($dbh,$query); last; };
/Unsub/ && do { &unsubscribe($dbh,$query); last; };
/Options/ && do { &options($dbh,$query); last; };
/form_socialnet/ && do { &form_socialnet($dbh,$query); last; };
/update_socialnet/ && do { &update_socialnet($dbh,$query); last; };
/EditInfo/ && do { &edit_info($dbh,$query); last; };
/edit_info_in/ && do { &edit_info_in($dbh,$query);
&edit_info($dbh,$query); last; };
/add/ && do { &add_subscription($dbh,$query);
&subscribe($dbh,$query); last; };
&login_form_text($dbh,$vars); last;
}
if ($dbh) { $dbh->disconnect; } # Close Database and Exit
exit;
#-------------------------------------------------------------------------------
#
# Functions
#
#-------------------------------------------------------------------------------
# ------- Header ------------------------------------------------------------
sub header {
my ($dbh,$query,$table,$format,$title) = @_;
my $template = "page_header";
return &template($dbh,$query,$template,$title);
}
# ------- Footer -----------------------------------------------------------
sub footer {
my ($dbh,$query,$table,$format,$title) = @_;
my $template = "page_footer";
return &template($dbh,$query,$template,$title);
}
# ------- Make Admin Links -------------------------------------------------------
#
sub make_admin_links {
my ($input) = @_;
}
# -------- Login Form Text ----------------------------------------------------
sub login_form_text {
my ($dbh,$vars) = @_;
$Site->{header} =~ s/\Q[*page_title*]\E/Login/g;
print "Content-type: text/html; charset=utf-8\n\n";
print $Site->{header};
if ($vars->{openid_enabled}) { print qq| $vars->{msg}
Login using OpenID
(About OpenID on $Site->{st_name})
By logging in you agree to allow this site to set three cookies on your browser:
the login name you enter below, an ID number corresponding to that name, and a
session variable, used to prevent fake logins, that changes each time you login. Not a registered user?
Click Here Forget your password?
Click Here About OpenID on $Site->{st_name} OpenID is not enabled on this website.
Ask the site administrator to load
Net::OpenID::Consumer if you would like to use it. $vars->{msg} This site does not support OpenID. Ask the site administrator to load
Net::OpenID::Consumer if you would like to use it. Identity verified. You are $Person->{person_openid}Login
Login Using OpenID
Login Using OpenID
Registration and Newsletter Subscription
";
print $Site->{footer};
return;
}
#
# -------- Login --------------------------------------------------------------
sub user_login {
my ($dbh,$query) = @_;
my $vars = $query->Vars;
# Check Input Variables
unless (($vars->{person_title}) && ($vars->{person_password})) { # Unless fields filled
&error($dbh,$query,"","Login info not provided"); } # User Login Error
# Get Person Data
my $stmt = qq|SELECT * FROM person WHERE person_title = ? ORDER BY person_id LIMIT 1|;
my $sth = $dbh -> prepare($stmt);
$sth -> execute($vars->{person_title});
my $ref = $sth -> fetchrow_hashref();
unless ($ref) {
&anonymous($Person);
&error($dbh,$query,"","Login Error
User name not found.
Click here to recover your login inormation.");
}
# Password Check
exit unless (&password_check($vars->{person_password},$ref->{person_password}));
while (my($x,$y) = each %$ref) { $Person->{$x} = $y; }
$sth->finish( );
unless ($Person->{person_id}) {
&error("","","","Unknown error (seriously, this shouldn't happen");
exit;# No Person Data - Send Error
}
&user_are_go($dbh,$query);
}
# -------- Logout -------------------------------------------------------------
sub user_logout {
my ($dbh,$options) = @_;
print "Content-type: text/html; charset=utf-8\n"; # Print HTTP header
# Define Cookie Names
my $site_base = &get_cookie_base();
my $id_cookie_name = $site_base."_person_id";
my $title_cookie_name = $site_base."_person_title";
my $session_cookie_name = $site_base."_session";
my $salt = "logout";
my $sessionid = crypt("anymouse",$salt);
my $cookie1 = $query->cookie(-name=>$id_cookie_name,
-value=>'2',
-expires=>'-1y',
-path=>'/',
-domain=>$Site->{co_host},
-secure=>0);
my $cookie2 = $query->cookie(-name=>$title_cookie_name,
-value=>'Anymouse',
-expires=>'-1y',
-path=>'/',
-domain=>$Site->{co_host},
-secure=>0);
my $cookie3 = $query->cookie(-name=>$session_cookie_name,
-value=>$sessionid,
-expires=>'-1y',
-path=>'/',
-domain=>$Site->{co_host},
-secure=>0);
print $query->header(-cookie=>[$cookie1,$cookie2,$cookie3]);
#print "Content-type: text/html; charset=utf-8\n"; # Print HTTP header
print "\n\n";
&anonymous($Person); # Make anonymous
# Print Jumpoff Page
$Site->{header} =~ s/\Q[*page_title*]\E/Logout/g;
print $Site->{header};
print "Logout successful
";
&print_nav_options($dbh,$options);
print $Site->{footer};
if ($dbh) { $dbh->disconnect; } # Close Database and Exit
exit;
}
# -------- Open ID ----------------------------------------------------------
sub openidq {
my ($dbh,$query) = @_;
my $vars;
unless ($vars->{openid_enabled}) {
print qq|OpenIDLogin
";
exit;
}
# Assertion - get verified identity object
my $vident = eval { $csr->verified_identity; };
if (! $vident) {
if ($@) { $csr->_fail("runtime_error", $@); }
&error($dbh,$query,"","OpenID runtime error");
}
$Person->{person_openid} = $vident->url;
# Not Already Logged In with regular ID?
if (($Person->{person_id} eq 2) ||
($Person->{person_id} eq "")) {
# Try to find an account for this OpenID
my $stmt = qq|SELECT * FROM person WHERE person_openid = ? LIMIT 1|;
my $sth = $dbh -> prepare($stmt);
$sth -> execute($Person->{person_openid});
my $ref = $sth -> fetchrow_hashref();
if ($ref) {
# Write Login Account Cookies
$Person->{person_id} = $vars->{person_id} = $ref->{person_id};
$Person->{person_title} = $vars->{person_title} = $ref->{person_title};
&user_are_go($dbh,$query);
exit;
} else {
# Brand New User, Yippee
$Person->{person_title} = $vars->{person_title} = $Person->{person_openid};
$vars->{person_openid} = $Person->{person_openid};
# Require Unique Name
# Prevents stacking OpenID accounts
if (&db_locate($dbh,"person",{person_title => $vars->{person_title}}) ) {
&error($dbh,$query,"","Someone else named '$vars->{person_title}' has already registered.");
};
# Create the User Record
my $idval = 'new';
$vars->{person_crdate} = time;
$vars->{key} = &db_insert($dbh,$query,"person",$vars,$idval);
unless ($vars->{key}) {
&error($dbh,$query,"","Error, no new account was created.");
}
$Person->{person_id} = $vars->{person_id} = $vars->{key};
# Send Email to Admin
my $subj = "New OpenID User Registration";
my $pagetext = qq|
New OpenID User Registration:
Userid: $vars->{person_title}
Email: $vars->{person_email}
Remove this user?
$Site->{script}?action=Remove&person_id=$vars->{key}
|;
&send_email($Site->{em_copy},$Site->{em_from},$subj,$pagetext);
# Create Login Message
$vars->{msg} .= qq|
OpenID login successful.
To personalize your account, click on [Options]
To associate your OpenID account with a previously existing
$Site->{st_name} account, login to that account using
your userid and password, then login using OpenID again.|;
# Write Login Account Cookies
&user_are_go($dbh,$query);
exit;
}
# Already Logged In
} else {
# Remove old stand-alone OpenID
my $stmt = "DELETE FROM person WHERE person_openid=?";
my $sth = $dbh->prepare($stmt);
$sth->execute($Person->{person_openid});
$sth->finish( );
# Associate ID with OpenID
&db_update($dbh,"person",{person_openid => $Person->{person_openid}}, $Person->{person_id});
# Print Jumpoff Page
print "Content-type: text/html; charset=utf-8\n\n";
$Site->{header} =~ s/\Q[*page_title*]\E/OpenID Login Successful/g;
print $Site->{header};
print "Login Successful
";
print qq|
This is your private page. If you want to see how the public sees you, Click here.
|; print qq|
| UserID: | $pdata->{person_title} |
| Name: | $pdata->{person_name} |
| Home Page: | $pdata->{person_url} |
| Email: | $pdata->{person_email} |
| Organization: | $pdata->{person_organization} |
| Location: | $pdata->{person_city}|; if ($pdata->{person_city}) { print ", "; } print qq| $pdata->{person_country} |
| Change Email Address and personal Info | |
| $netname: | $netid | $netok |
| Edit Social Network Info | ||
| $ref->{feed_title}: | \n$ref->{feed_html} | Look |
Pending Approval
Approved
RetiredAdd a New Feed | ||
| $p->{page_title}: | Read |
| Edit Newsletter Subscriptions | |
| OpenID: | $Person->{person_openid} |
| Associate OpenID account with your $Site->{st_name} account | |
[Logout]|; if ($vars->{refer}) { my $rf = $vars->{refer}; $rf =~ s/AND/&/g; $rf =~ s/COMM/#/g; print qq| [ Go back to where you were]|; } print qq|
|; print $Site->{footer}; } # ------- Anon Options ------------------------------------------------------------ sub anon_options { my ($dbh,$query) = @_; my $vars = $query->Vars; print qq|Welcome to $Site->{st_name}. You are using this site anonymously and will be identified as 'Anymouse' if you choose to post comments.
If you wish to sign your name to comments or to receive a newsletter by email, you will need to login or register.
".$Site->{footer}; return; } # -------- User Are Go -------------------------------------------------------- # Writes login cookies after succcessful login or registration # As in: Thunderbirds Are Go # # Used by: user_login() sub user_are_go { my ($dbh,$query) = @_; my $vars = $query->Vars; # Define Cookie Names my $site_base = &get_cookie_base(); my $id_cookie_name = $site_base."_person_id"; my $title_cookie_name = $site_base."_person_title"; my $session_cookie_name = $site_base."_session"; # $Site->{co_host} = "www.downes.ca"; # print "Content-type: text/html; charset=utf-8\n\n"; # Print HTTP header # print "User are go
"; my $exp; if ($vars->{remember}) { $exp = '+1y'; } else { $exp = '+1h'; } # Prepare Session ID my $salt = $site_base . time; my $sessionid = crypt("anymouse",$salt); # Store session ID in DB &db_update($dbh,"person",{person_mode => $sessionid}, $Person->{person_id}); my $cookie1 = $query->cookie(-name=>$id_cookie_name, -value=>$Person->{person_id}, -expires=>$exp, -domain=>$Site->{co_host}, -secure=>0); my $cookie2 = $query->cookie(-name=>$title_cookie_name, -value=>$Person->{person_title}, -expires=>$exp, -domain=>$Site->{co_host}, -secure=>0); my $cookie3 = $query->cookie(-name=>$session_cookie_name, -value=>$sessionid, -expires=>$exp, -domain=>$Site->{co_host}, -secure=>0); print $query->header(-cookie=>[$cookie1,$cookie2,$cookie3]); print "\n\n"; # Print Jumpoff Page $Site->{header} =~ s/\Q[*page_title*]\E/Login Successful/g; print $Site->{header}; #if ($options->{new} eq "yes") { &show_subscriptions($dbh,$vars,$person); } print "
User number $pid has been deleted.
"; print $Site->{footer}; } # ------------------------------------------------------------------------------------- # # find_person # # This function allows a person to identify themselves to edit their data, # or an administrator to find a person given name, email, etc. # Returns a single value, $pid person->person_id # # ------------------------------------------------------------------------------------- sub find_person { my ($dbh,$query) = @_; my $vars = $query->Vars; # Admin Only return $Person->{person_id} unless ($Person->{person_status} eq "admin"); return $Person->{person_id} unless ( # On request only $vars->{pid} || $vars->{ptitle} || $vars->{pname} || $vars->{pemail} ); if ($vars->{pid} and &db_locate($dbh,"person",{ # Check ID person_id => $vars->{pid}})) { return $vars->{pid}; } my $pid; # Check Title if ($vars->{ptitle} and $pid = &db_locate($dbh,"person",{ person_title => $vars->{ptitle}})) { return $pid; } # Check Name if ($vars->{pname} and $pid = &db_locate($dbh,"person",{ person_name => $vars->{pname}})) { return $pid; } # Check Email if ($vars->{pemail} and $pid = &db_locate($dbh,"person",{ person_email => $vars->{pemail}})) { return $pid; } &error($dbh,$query,"","User not found"); # Not found exit; } # ------- Edit Info Form --------------------------------------------- sub edit_info { my ($dbh,$query) = @_; my $vars = $query->Vars; print "Content-type: text/html; charset=utf-8\n\n"; # Print Header my $script = $Site->{script}; $Site->{header} =~ s/\Q[*page_title*]\E/Change Email and Personal Info/g; print $Site->{header}; # Determine Person my $pid = &find_person($dbh,$query); &error($dbh,$query,"","Cannot edit anonymous account") if ($pid eq "2"); # Get Person Info my $record = &db_get_record($dbh,'person',{person_id => $pid}); # while (my ($px,$py) = each %$record) { print "$px = $pyYour personal data has been updated.
|; } # ------- Manage Subscriptions --------------------------------------------- sub subscribe { my ($dbh,$query) = @_; $Site->{header} =~ s/\Q[*page_title*]\E/Manage Subscriptions/g; # print form print qq|Content-type: text/html; charset=utf-8\n\n|. $Site->{header}. qq||; &print_nav_options($dbh,$query); print $Site->{footer}; } # ------- Subscription Form Text -------------------------------------------- # Dynamic generation of subscription options # Used by: subscribe() # registration_form_text() # Get Array of Subscriptions sub subscription_form_text { my ($dbh,$query,$man) = @_; my $vars = $query->Vars; # Get Person Data my $pid = &find_person($dbh,$query); my $pdata = &db_get_record($dbh,"person",{person_id =>$pid}); my $pname = $pdata->{person_name} || $pdata->{person_email} || $pdata->{person_id}; # Get Person's Existing Subscriptions my $sub_ary_ref; unless ($vars->{action} eq "Register") { if ($man eq "manage" && ($pid eq "0" || $pid eq "2" || $pid eq "")) { return "No subscriptions for anonymous users." } my $stmt = "SELECT subscription_box FROM subscription WHERE subscription_person = '$pid'"; $sub_ary_ref = $dbh->selectcol_arrayref($stmt); } # Initialize Form Text my $form_text = ""; if ($pname) { $form_text .= qq|
Displaying subscriptions for $pname
|; } $form_text .= qq|Select newsletter subscriptions (you may choose more than one; leave blank for none)
|; # Get List of Subscribable Pages my $pages = {}; my $sql = qq|SELECT page_id,page_title,page_autosub FROM page WHERE page_sub = 'yes' ORDER BY page_title|; my $sth = $dbh->prepare($sql); $sth->execute(); # For Each Subscribable Page... $form_text .= qq|\n|;
while (my $p = $sth -> fetchrow_hashref()) {
# Does the user already subscribe?
my $selected = "";
if (&index_of($p->{page_id},$sub_ary_ref) > -1) {
$selected = " checked";
}
# Is it a default subscribe?
if ($p->{page_autosub} eq "yes") {
$selected = " checked";
}
# Create the form text for that page
$form_text .= qq|
$p->{page_title}
|;
}
$form_text .= qq|
No longer subscribed to anything.
|; return; } # Insert Subscriptions my @nls = split /\0/,$vars->{newsletter}; foreach my $newsl (@nls) { my $nl={}; $nl->{subscription_box} = $newsl; $nl->{subscription_person} = $pid; $nl->{subscription_crdate} = time; my $sub = &db_insert($dbh,$query,"subscription",$nl); unless ($sub) { &error($dbh,$query,"","For some unknown reason your subscription failed. Please try again later."); } } # Notify $vars->{msg} .= qq|Subscriptions have been updated.
|; #¬ify_subscribe($person_id,"Subscribe",$sb); return; } # ------- Unsubscribe ------------------------------------------------------ sub unsubscribe { my ($dbh,$query) = @_; my $vars = $query->Vars; $vars->{sid} =~ s/\s//g; # Clean email address unless (&db_locate($dbh,"person",{ # If person exists... person_id => $vars->{pid}, person_email => $vars->{sid}})) { &error($dbh,$query,"","Looking for $vars->{pid} $vars->{sid}Your email subscription has been cancelled.
Email: $vars->{sid}
If you wish to restart it any time in the future,
return to your options page
to resubscribe.
Please Note: We have made some changes to the login system recently. If your password is continually being rejected, it's probably our fault, not yours. Please follow the link to recover your login information and you'll be back online in no time. Our apologies for any inconvenience.
|; return 1 if ($dbpwd eq crypt($inputpwn, $dbpwd)); # Salted crypt match &anonymous($Person); &error($dbh,$query,"","$msg
Incorrect password.
Click here to recover your login inormation.
"; # End form &print_nav_options($dbh,$query); print $Site->{footer}; } # ------------------------------------------------------------------------------------- # # send_password # # Sends password to the user's email address # # ------------------------------------------------------------------------------------- sub send_password { my ($dbh,$query) = @_; my $vars = $query->Vars; #return unless ($Person->{person_status} eq "Admin"); unless ($vars->{person_email}) { &error($dbh,$query,"","Please enter something!."); } my $person = &db_get_record($dbh,'person',{person_email => $vars->{person_email}}); unless ($person) { $person = &db_get_record($dbh,'person',{person_title => $vars->{person_email}}); } unless ($person) { $person = &db_get_record($dbh,'person',{person_name => $vars->{person_email}}); } # We generate a random string, store it in $person->{person_midm}, then send it as a key # to reset the password my $reset_key = &generate_random_string(64); &db_update($dbh,"person",{person_midm=>$reset_key},$person->{person_id}); if ($person) { # If there's a person # With an email if ($person->{person_email}) { # Send the password $Site->{st_name} =~ s/'/'/g; &send_email($person->{person_email},$person->{person_email}, "To reset your password from ".$Site->{st_name}, "\nTo reset your password from $Site->{st_name} go to the following URL\n\n" . "$Site->{st_cgi}login.cgi?action=reset&key=$person->{person_id},$reset_key\n\n"); print "Content-type: text/html; charset=utf-8\n\n"; $Site->{header} =~ s/\Q[*page_title*]\E/Password Retrieval/g; print $Site->{header} . qq|
We have sent you a reset URL. To reset your password, please check your email inbox.
|; &print_nav_options($dbh,$query); print $Site->{footer}; } else { &error($dbh,$query,"","Could not find your email address."); } } else { &error($dbh,$query,"","Could not find $vars->{person_email} in my database."); } } # ------------------------------------------------------------------------------------- # # reset_password # # Resets password and sends to the user's email address # Requires key cerated by send_password # # ------------------------------------------------------------------------------------- sub reset_password { my ($dbh,$query) = @_; my $vars = $query->Vars; my ($id,$key) = split ",",$vars->{key}; my $person = &db_get_record($dbh,'person',{person_id => $id}); &error($dbh,"","","Blank midm") unless ($person->{person_midm}); &error($dbh,"","","Reset key expired") if ($person->{person_midm} eq "expired"); &error($dbh,"","","Key mismatch") unless ($person->{person_midm} eq $key); my $new_password = generate_random_string(10); my $encryptedPsw = &encryptingPsw($new_password, 4); &db_update($dbh,"person",{person_password=>$encryptedPsw},$id); my $expired = "expired"; &db_update($dbh,"person",{person_midm=>$expired},$id); if ($person->{person_email}) { # Send the password $Site->{st_name} =~ s/'/'/g; &send_email($person->{person_email},$person->{person_email}, "Password reset for ".$Site->{st_name}, "\nYour password has been reset:\n\n" . "Userid: $person->{person_title} \n Password: $new_password\n\n"); print "Content-type: text/html; charset=utf-8\n\n"; $Site->{header} =~ s/\Q[*page_title*]\E/Password Retrieval/g; print $Site->{header} . qq|
Your password has been reset. Please check your email inbox.
Click here to login with your new password.
";
&error($dbh,"","","Attempting to change password: incorrect old password")
unless &password_check($vars->{op},$Person->{person_password},"Password Change Error");
&error($dbh,"","","Password Change Error
New password is blank.")
unless ($vars->{npa});
&error($dbh,"","","Password Change Error
New passwords do not match.")
unless ($vars->{npa} eq $vars->{npb});
my $encryptedPsw = &encryptingPsw($vars->{npa}, 4);
&db_update($dbh,"person",{person_password=>$encryptedPsw},$Person->{person_id});
print $Site->{header} . qq|
Your password has been changed.
Click here to login with your new password.
Use this form to edit your social network information. We will be able to use
this information to help you post from the $Site->{st_name} site to your social
network, and to associate posts we havest from these social networks with your
$Site->{st_name} identity.
Please note that providing this information is
optional. Also, your social network identity will not be displayed to
the public unless you have checked the 'public' box for that social network name.