# Copyright (C) 2005 FishGrove Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# $Id: Incoming.pm,v 1.1 2006/03/07 14:39:10 slash5234 Exp $

package Affelio::App::Standalone::Public::Incoming;
{
    use strict;

    use lib("../../../../../extlib/");
    use lib("../../../../../lib/");
    use Affelio;
    use Affelio::misc::CGIError;
    use Affelio::misc::Debug qw(debug_print);
    use Affelio::misc::Encoding qw(db_encode db_decode);
    use Affelio::misc::Time;
    use Affelio::misc::WebInput;

    use Exporter;
    @Affelio::App::Standalone::Public::Incoming::ISA = "Exporter";
    @Affelio::App::Standalone::Public::Incoming::EXPORT = qw (run);

    #######################################################################
    #run
    #######################################################################
    sub run{
	use CGI qw(-unique_headers);
use CGI::Session; #qw(-ip_match);
use Error qw(:try);

use Affelio;
use Affelio::App::Standalone::Env;
use Affelio::misc::CGIError;
use Affelio::misc::Debug      qw(debug_print);
use Affelio::misc::Time qw(get_timestamp get_expire_stamp);
use Affelio::misc::MyCrypt qw(msg_decrypt url_decode);
use Affelio::misc::NetMisc;
use Affelio::misc::WebInput;

debug_print("StandAlone::incoming.cgi: start.");
my $q = new CGI;

############################################################################
#Load Affelio, CGI
############################################################################
my $cfg_dir = "./config/";
my $af;
try{
    $af = new Affelio(ConfigDir => $cfg_dir,
		      CGI => $q );
}catch Error with{
    my $e = shift;
    error($q, "Affelio load error.\n" . $e);
};
my $wi = new Affelio::misc::WebInput(); 

############################################################################
#Load session
############################################################################
my $session = $af->getSM()->get_session();

############################################################################
#Get args
############################################################################
my $forward_id = $q->url_param("forward_id");
my $referrer = $q->param("referrer");
$referrer =~ s|/$||; 
debug_print("StandAlone::incoming.cgi: forward_id      =$forward_id");

my $dest_URL = $wi->PTN_URL($q->url_param("dest_url"));
debug_print("StandAlone::incoming.cgi: dest_URL      =$dest_URL");

############################################################################
#Load Friend manager and get passAB
############################################################################
my $passAB;
try{
   $passAB = $af->getFM->get_attribute_by_afid($referrer, "password");
   
   $af->getFM->set_attribute_by_afid($referrer, 
				     "last_incoming",
				     Affelio::misc::Time::get_timestamp());
   $af->getFM->incr_attribute_by_afid($referrer, 
				      "count_incoming");

}catch Error with{
    my $e = shift;
    error($q, "Error from FriendManager.\n" . $e);
};
debug_print("StandAlone::incoming.cgi: passAB=$passAB\n");
if(!defined($passAB) || $passAB eq ""){
    error($q, "Affelio: Invalid forwarding. Shared key not found!");
}

$referrer,



############################################################################
#Decrypt the forward_id message;
############################################################################
my ($FID_timestamp, $FID_expire, $FID_remoteip, $FID_visitorAFID, $FID_visitor_nickname, $FID_visitor_type)
    =split('\*', msg_decrypt( url_decode($forward_id), $passAB ) ); 

$FID_visitorAFID = url_decode($FID_visitorAFID);
$FID_visitor_nickname = url_decode($FID_visitor_nickname);

debug_print("StandAlone::incoming.cgi: timestamp      =$FID_timestamp");
debug_print("StandAlone::incoming.cgi: expire         =$FID_expire");
debug_print("StandAlone::incoming.cgi: remote_ip      =$FID_remoteip");
debug_print("StandAlone::incoming.cgi: visitor_afid      =$FID_visitorAFID");
debug_print("StandAlone::incoming.cgi: visitor_nickname  =$FID_visitor_nickname");
debug_print("StandAlone::incoming.cgi: visitor_type(original)      =$FID_visitor_type");

if((my $i=index($FID_visitor_type, "self"))==0){
    $FID_visitor_type = "f1";
}elsif((my $i=index($FID_visitor_type, "f1"))==0){
    $FID_visitor_type = "f2";
}else{
    $FID_visitor_type = "pb";
}
debug_print("StandAlone::incoming.cgi: visitor_type(decreased)     =$FID_visitor_type");


############################################################################
#Error detection
############################################################################
my $errormsg="";
if(($FID_timestamp eq "") || ($FID_remoteip eq "") || 
   ($FID_visitorAFID eq "") || ($FID_expire eq "") ||
   ($FID_visitor_type eq "") ){
    $errormsg .= "Forward_Id data is invalid! \n";
}else{
    if($FID_remoteip ne $q->remote_addr){
	$errormsg .= "Your remote IP address does not match! \n";
    }
    if($FID_expire < get_timestamp() ){
	$errormsg .= "This forward_id is too late to start. \n";
    }
}
if($errormsg){
    #error $errormsg;
    debug_print("StandAlone::incoming.cgi: ERROR! : $errormsg");
    debug_print("StandAlone::incoming.cgi: Just go to my Affelio without any cookie."); 
    if($dest_URL ne ""){
	print $q->redirect( -url => $dest_URL);
    }else{
	print $q->redirect( -url => $af->{site__user_afid});
    }
}

############################################################################
#Check current session
############################################################################
#If a cookie is set already, check it and reuse it if we can.
my $ck_visitor_type="pb";
my $ck_visitor_nickname="anonymous";
my $ck_visitor_afid="";
if($session){
    debug_print("StandAlone::incoming.cgi: Found a pre-existing session!");
    $ck_visitor_type = $session->param("type");
    $ck_visitor_nickname = $session->param("user_nickname");
    $ck_visitor_afid = $session->param("user_afid");
}
debug_print("StandAlone::incoming.cgi: cookie visitor_type  = $ck_visitor_type");
debug_print("StandAlone::incoming.cgi: cookie visitor_nickname  = $ck_visitor_nickname");
debug_print("StandAlone::incoming.cgi: cookie visitor_afid  = $ck_visitor_afid");

if($session &&
   ( (($ck_visitor_type eq "self") && ( $FID_visitor_type ne "self") ) 

     || ( ($ck_visitor_type eq "f1") && (( $FID_visitor_type eq "f1") || ( $FID_visitor_type eq "f2") || ( $FID_visitor_type eq "pb") ) )

     || ( ($ck_visitor_type eq "f2") && (( $FID_visitor_type eq "f2") || ( $FID_visitor_type eq "pb")))
     )
   ){
    #########################
    # OK. 
    # This visitor is already authenticated as a closer visitor.
    # Use existing session.
    #########################
    debug_print("StandAlone::incoming.cgi: OK. You already have a cookie, and");
    debug_print("StandAlone::incoming.cgi: the existing session has the same or"); 
    debug_print("StandAlone::incoming.cgi: higher right!");
    debug_print("StandAlone::incoming.cgi: end. Forwarding to my homepage.");
    if($dest_URL ne ""){
	print $q->redirect( -url => $dest_URL);
    }else{
	print $q->redirect( -url => $af->{site__user_afid});
    }

}else{
    #########################
    # Startup a new session
    #########################
    debug_print("StandAlone::incoming.cgi: You don't have a cookie, or you have");
    debug_print("StandAlone::incoming.cgi: a cookie with lower rights.");
    debug_print("StandAlone::incoming.cgi: ");
    debug_print("StandAlone::incoming.cgi: Let's start up a session with a cooike.");

    #lookup our friend table with FID_visitorAFID
    my $tmp1;
    try{
	$tmp1 = $af->getFM->get_attribute_by_afid($FID_visitorAFID, "password");
    }catch Error with{
	my $e = shift;
	error($q, "Error from FriendManager.\n" . $e);
    };
    if($tmp1 ne ""){	$FID_visitor_type="f1";    }

    #Start up a sesion
    $af->getSM->startup_session(user_afid => $FID_visitorAFID,
				user_nickname => $FID_visitor_nickname,
				type => $FID_visitor_type);

    debug_print("StandAlone::incoming.cgi: startup_session finished.\n");    

    #Prepare a cookie with the session_id
    my $cookie = $af->getSM->issue_cookie();

    debug_print("StandAlone::incoming.cgi: end. Forwarding to my homepage.");
    if($dest_URL ne ""){
	print $q->redirect( -url => $dest_URL, 
			    -cookie => $cookie);
    }else{
	print $q->redirect( -url => $af->{site__user_afid},
			    -cookie => $cookie);
    }
}

exit(1);


    }	
}
1;
