#!/usr/bin/perl -w

###
##
# login
#
# The CGI that does the deed.
#
#  * Present a form
#  * Check it when filled in
#  * Notify the connecting IP of the outcome
#  * Inform and optionally redirect the user
#
# RJF & SDE, 7.4.01 
#
# License: GPL.
##
###

use lib '/usr/local/nocat'; # or wherever.
use NoCat;
use strict;

my $authserv	= NoCat->auth_service( ConfigFile => $ENV{NOCAT} );
my $cgi		= $authserv->cgi;
my %p		= $cgi->Vars;

# Debug configuration setup.
$authserv->check_config(qw( 
    LoginForm FatalForm RenewForm SuccessForm
    LoginGreeting LoginMissing LoginBadUser LoginBadPass 
));

$authserv->log( 7, sprintf( "User %s from %s requests %s", 
    $p{user} || "", $cgi->remote_host, lc( $p{mode} ) || "form" ) );

# Have we filled in the form yet?  No?  If not, present one.
$authserv->display( LoginForm => "LoginGreeting" ) unless $p{mode};

# Verify prerequisites.
$authserv->display( FatalForm => "Your MAC address is undefined.  Problem with the gateway?" )
    unless $p{mac};
$authserv->display( FatalForm => "Your gateway token is undefined.  Problem with the gateway?" )
    unless $p{token};

# If the user skipped authentication, set public-class service.
if ( $p{mode} =~ /^skip/io or ( $p{class} and $p{class} =~ /^public/io ) ) {
    $p{user}	= "UNKNOWN";
    $p{class}	= "Public";

# Otherwise, attempt to authenticate the user.
} else {
    # Are we just missing required fields?
    $authserv->display( LoginForm => "LoginMissing"   ) unless $p{user} and $p{pass};

    # Does the login info match what we have on file?
    my $user = $authserv->user->fetch( $authserv->{UserIDField} => $p{user} );

    $authserv->display( LoginForm => "LoginBadUser"   ) unless $user->id;
    $authserv->display( LoginForm => "LoginBadPass"   ) unless $user->authenticate( $p{pass} );
    # $authserv->display( LoginForm => "LoginBadStatus" ) unless $user->authorize;

    # Set the service class based on the user's authorization.
    $p{class} = $user->authorize ? "Member" : "Public";
}

# Set the class variable for $authserv->renewal.
$cgi->param( class => $p{class} );

# Finally, notify the gateway (and the user) as to the outcome.
my ( $form, $refresh, $gw );

# Either we're requesting the renewal popup box...
if ( $p{mode} =~ /^popup/io ) {
    $form = "RenewForm";
    $refresh = $authserv->renew_url;

# Or we're either logging in, or renewing, in which case, notify the gateway.
} elsif ($gw = $authserv->notify( Permit => \%p )) {
    if ( $p{mode} =~ /^renew/io ) {
	$form = "RenewForm";
	$refresh = $authserv->renew_url( $gw );
    } else {
	$form = "SuccessForm";
	$refresh = "5; URL=" . ($p{redirect} || $authserv->{HomePage});
	$p{popup} = $authserv->renew_url( $gw ); 
	    # set the javascript *link* to the popup box.
    }

# Or something's really wrong.
} else {
  $authserv->display( FatalForm => "Authentication error: $!" );
}

$p{logout} = $authserv->logout_url; # Make a logout link.

# Execute on the plan and tell a compelling story to the user.
print $cgi->header( -Refresh => $refresh ), $authserv->template( $form => \%p );

# Fin
