# ================================================================== # Gossamer Links - enhanced directory management system # # Website : http://gossamer-threads.com/ # Support : http://gossamer-threads.com/scripts/support/ # CVS Info : 087,071,086,086,085 # Revision : $Id: Login.pm,v 1.19 2005/05/08 09:56:44 brewt Exp $ # # Copyright (c) 2004 Gossamer Threads Inc. All Rights Reserved. # Redistribution in part or in whole strictly prohibited. Please # see LICENSE file for full details. # ================================================================== package Links::User::Login; # ================================================================== use strict; use Links qw/:objects/; use Links::Build; use Links::SiteHTML; sub handle { # ------------------------------------------------------------------- # Determine what to do. # my $input = $IN->get_hash; my $mtl = Links::Build::build('title', Links::language('LINKS_LOGIN'), "$CFG->{db_cgi_url}/user.cgi"); if ($input->{login}) { $PLG->dispatch('user_login', \&login_user); } elsif ($input->{signup_user}) { $PLG->dispatch('user_signup', \&signup_user); } elsif ($input->{validate_user}) { $PLG->dispatch('user_validate', \&validate_user); } elsif ($input->{send_validate}) { $PLG->dispatch('user_validate_email', \&send_validate); } elsif ($input->{send_pass} and $CFG->{user_allow_pass}) { $PLG->dispatch('user_pass_email', \&send_pass); } elsif ($input->{signup_form}) { print $IN->header(); print Links::SiteHTML::display('signup_form', { Username => $IN->param('Username') || '', Password => '', Email => $IN->param('Email') || '', main_title_loop => Links::Build::build('title', Links::language('LINKS_SIGNUP'), "$CFG->{db_cgi_url}/user.cgi?signup_form=1") }); } elsif ($input->{validate}) { print $IN->header(); print Links::SiteHTML::display('validate_form', { main_title_loop => Links::Build::build('title', Links::language('LINKS_VALIDATE'), "$CFG->{db_cgi_url}/user.cgi?validate=1") }); } elsif ($input->{logout}) { Links::Authenticate::auth('delete_session'); $USER = undef; print $IN->header(); print Links::SiteHTML::display('login', { Username => '', Password => '', Email => '', error => Links::language('USER_LOGOUT'), main_title_loop => $mtl }); } elsif ($input->{email_pass} and $CFG->{user_allow_pass}) { print $IN->header(); print Links::SiteHTML::display('login_email', { main_title_loop => Links::Build::build('title', Links::language('LINKS_EMAILPASS'), "$CFG->{db_cgi_url}/user.cgi?email_pass=1") }); } else { print $IN->header(); print Links::SiteHTML::display('login', { Username => $IN->param('Username') || '', main_title_loop => $mtl }); } } # ============================================================== sub login_user { # -------------------------------------------------------- # Logs a user in, and creates a session ID. # my $username = $IN->param('Username') || shift; my $password = $IN->param('Password') || shift; my $goto = shift || 'login_success'; my $mtl = Links::Build::build('title', Links::language('LINKS_LOGIN'), "$CFG->{db_cgi_url}/user.cgi"); # Make sure we have both a username and password. if (!$username or !$password) { print $IN->header(); print Links::SiteHTML::display('login', { error => Links::language('USER_BADLOGIN'), Username => $username, main_title_loop => $mtl }); return; } # Check that the user exists, and that the password is valid. my $user = Links::init_user($username, $password); if (!$user) { print $IN->header(); require Links::Authenticate; if (Links::Authenticate::auth_valid_user({ Username => $username, Password => $password })) { print Links::SiteHTML::display('login', { error => Links::language('USER_NOTVAL', $user->{Email}), Username => $user->{Username}, main_title_loop => $mtl }); } else { print Links::SiteHTML::display('login', { error => Links::language('USER_BADLOGIN'), main_title_loop => $mtl }); } return; } # Store the session in either a cookie or url based. my $results = Links::Authenticate::auth('create_session', { Username => $user->{Username} }); return if $results->{redirect}; # Get the $USER information. $USER = Links::Authenticate::auth('get_user', { Username => $username, Password => $password, auto_create => 1 }); print $IN->header(); # In case the session didn't print it. print Links::SiteHTML::display($goto, { %$user, main_title_loop => $mtl }); } sub signup_user { # -------------------------------------------------------- # Signs a new user up. # my $username = $IN->param('Username'); my $password = $IN->param('Password'); my $email = $IN->param('Email'); my $mtl = Links::Build::build('title', Links::language('LINKS_SIGNUP'), "$CFG->{db_cgi_url}/user.cgi?signup_form=1"); if (!$username or !$password or !$email) { print $IN->header(); print Links::SiteHTML::display('signup_form', { error => Links::language('USER_INVALIDSIGNUP'), main_title_loop => $mtl }); return; } unless ($email =~ /.\@.+\../) { print $IN->header(); print Links::SiteHTML::display('signup_form', { error => Links::language('USER_INVALIDEMAIL', $email), main_title_loop => $mtl }); return; } # Check that the username doesn't already exist. my $db = $DB->table('Users'); my $user = $db->get($username); if ($user) { print $IN->header(); print Links::SiteHTML::display( 'signup_form', { error => Links::language('USER_NAMETAKEN', $username), main_title_loop => $mtl }); return; } # Check that the email address doesn't already exist. my $hits = $db->count({ Email => $email }); if ($hits) { print $IN->header(); print Links::SiteHTML::display('signup_form', { error => Links::language('USER_EMAILTAKEN', $email), main_title_loop => $mtl }); return; } my ($code, $msg); # Add the user in, set defaults for fields not specified. $user = $IN->get_hash(); my $def = $db->default || {}; foreach (keys %$def) { $user->{$_} = $def->{$_} unless (exists $user->{$_}); } # Send validation email if needed. if ($CFG->{user_validation}) { my $code = time . $$ . int rand 1000; $user->{Status} = "Not Validated"; $user->{Validation} = $code; my $ret = $db->add($user); if (!$ret) { print $IN->header(); print Links::SiteHTML::display('signup_form', { error => $db->error, main_title_loop => $mtl }); return; } } else { $user->{Status} = "Registered"; $user->{Validation} = 0; my $ret = $db->add($user); if (!$ret) { print $IN->header(); print Links::SiteHTML::display('signup_form', { error => $db->error, main_title_loop => $mtl }); return; } } # Print the welcome screen. if ($CFG->{user_validation}) { print $IN->header(); print Links::SiteHTML::display('signup_success', { %$user, main_title_loop => $mtl }); Links::send_email('validate.eml', $user) or die "Unable to send message: $GT::Mail::error"; } else { my $results = Links::Authenticate::auth('create_session', { Username => $user->{Username} }); $USER = Links::Authenticate::auth('get_user', { Username => $user->{Username}, Password => $user->{Password}, auto_create => 1 }); print $IN->header(); print Links::SiteHTML::display('signup_success', { %$user, main_title_loop => $mtl }); } } sub validate_user { # -------------------------------------------------------- # Validates a user. # my $code = $IN->param('code'); $code =~ s/^\s*|\s*$//g; my $mtl = Links::Build::build('title', Links::language('LINKS_VALIDATE'), "$CFG->{db_cgi_url}/user.cgi?validate=1"); if (!$code) { print $IN->header; print Links::SiteHTML::display('validate_form', { error => Links::language('USER_INVALIDVAL'), main_title_loop => $mtl }); return; } my $db = $DB->table('Users'); my $sth = $db->select({ Validation => $code }); my $user = $sth->fetchrow_hashref; if (! $user) { print $IN->header; print Links::SiteHTML::display('validate_form', { error => Links::language('USER_INVALIDVAL'), main_title_loop => $mtl }); return; } $db->update({ Status => 'Registered' }, { Username => $user->{Username} }); login_user($user->{Username}, $user->{Password}, 'validate_success'); } sub send_pass { # ------------------------------------------------------------------- # Sends the user a password reminder email. # my $email = $IN->param('Email'); my $user_db = $DB->table('Users'); my $sth = $user_db->select( { Email => $email } ); print $IN->header(); my $user = $sth->fetchrow_hashref; if ($user and $email =~ /.+\@.+\..+/) { Links::send_email('password.eml', { %$user, %ENV }) or die "Unable to send message: $GT::Mail::error"; print Links::SiteHTML::display('login', { error => Links::language('USER_PASSSENT'), Username => '', Password => '', main_title_loop => Links::Build::build('title', Links::language('LINKS_LOGIN'), "$CFG->{db_cgi_url}/user.cgi") }); } else { print Links::SiteHTML::display('login_email', { error => Links::language('USER_NOEMAIL'), main_title_loop => Links::Build::build('title', Links::language('LINKS_EMAILPASS'), "$CFG->{db_cgi_url}/user.cgi?email_pass=1") }); } } sub send_validate { # ------------------------------------------------------------------- # Sends the validation email if the user needs another one. # my $email = $IN->param('Email'); my $user_db = $DB->table('Users'); my $sth = $user_db->select( { Email => $email } ); print $IN->header(); if ($sth->rows) { # Prepare the message. my $user = $sth->fetchrow_hashref; # Make sure there is a validation code. if (! $user->{Validation}) { $user->{Validation} = (time) . ($$) . (int rand(1000)); $user_db->modify($user); } Links::send_email('validate.eml', $user) or die "Unable to send message: $GT::Mail::error"; print Links::SiteHTML::display('login', { error => Links::language('USER_VALSENT'), Username => '', Password => '', main_title_loop => Links::Build::build('title', Links::language('LINKS_LOGIN'), "$CFG->{db_cgi_url}/user.cgi") }); } else { print Links::SiteHTML::display('login_email', { error => Links::language('USER_NOEMAIL'), main_title_loop => Links::Build::build('title', Links::language('LINKS_EMAILPASS'), "$CFG->{db_cgi_url}/user.cgi?email_pass=1") }); } } 1;