#!%PERL% -w
# Copyright (c) vhffs project and its contributors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without 
# modification, are permitted provided that the following conditions 
# are met:
#
# 1. Redistributions of source code must retain the above copyright 
#   notice, this list of conditions and the following disclaimer.
#2. Redistributions in binary form must reproduce the above copyright
#   notice, this list of conditions and the following disclaimer in 
#   the documentation and/or other materials provided with the 
#   distribution.
#3. Neither the name of vhffs nor the names of its contributors 
#   may be used to endorse or promote products derived from this 
#   software without specific prior written permission.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
#"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
#LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
#FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
#COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
#INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
#BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
#CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
# POSSIBILITY OF SUCH DAMAGE.

use strict;
use utf8;
use POSIX qw(locale_h);
use HTML::Template;
use locale;
use Locale::gettext;
use CGI;
use CGI::Session;
use Encode;

use lib '%VHFFS_LIB_DIR%';
use Vhffs::User;
use Vhffs::Main;
use Vhffs::Panel::Main;
use Vhffs::Panel::User;
use Vhffs::Panel::Object;
use Vhffs::Panel::Template;
use Vhffs::Services::MailUser;
use Vhffs::Services::Newsletter;

my $panel = new Vhffs::Panel::Main();
exit 0 unless $panel;
my $session = $panel->get_session;
exit 0 unless $session;

my $cgi = $panel->{cgi};
my $vhffs = $panel->{vhffs};
my $maintemplate = $panel->{template};
my $user = $panel->{user};
my $templatedir = $panel->{templatedir};
my $template;
my $userp;

my $username = $cgi->param('name');
if( defined $username ) {
	$userp = Vhffs::User::get_by_username( $vhffs, $username );
} else {
	$userp = $user;
}

unless( defined $userp )  {
	$template = new HTML::Template( filename => $templatedir.'/panel/misc/simplemsg.tmpl' );
	$template->param( MESSAGE => gettext('Cannot get informations on this object') );
}
elsif( !$user->can_view( $userp ) )
{
	$template = new HTML::Template( filename => $templatedir.'/panel/misc/simplemsg.tmpl' );
	$template->param( MESSAGE => gettext( 'You\'re not allowed to do this, object is not in active state or you don\'t have enough ACL rights' ) );
}
else
{
	if( defined $cgi->param('prefs_submit') ) {
		unless( $user->can_modify( $userp ) ) {
			$panel->add_error( gettext( 'You\'re not allowed to do this, object is not in active state or you don\'t have enough ACL rights' ) );
		} else {
			my $mail = $cgi->param( 'MAIL' );
			my $firstname = Encode::decode_utf8( $cgi->param( 'FIRSTNAME' ) );
			my $lastname = Encode::decode_utf8( $cgi->param( 'LASTNAME' ) );
			my $city = Encode::decode_utf8( $cgi->param( 'CITY' ) );
			my $zipcode = Encode::decode_utf8( $cgi->param( 'ZIPCODE' ) );
			my $country = Encode::decode_utf8( $cgi->param( 'COUNTRY' ) );
			my $address = Encode::decode_utf8( $cgi->param( 'ADDRESS' ) );
			my $pass1 = $cgi->param( 'PASSWORD1' );
			my $pass2 = $cgi->param( 'PASSWORD2' );
			my $theme = $cgi->param( 'THEME' );
			my $lang = $cgi->param( 'LANG' );
			my $shell = $cgi->param( 'SHELL' );
			my $newslettercheckbox = $cgi->param('NEWSLETTER');
			$newslettercheckbox = ( defined $newslettercheckbox && $newslettercheckbox eq 'on' );

			my $pwd_change = 0;
			my $mail_change = 0;

			if( $userp->{'uid'} == $user->{'uid'} )  {
				# Checks data and perform requested modifications
				$panel->add_cookie( CGI->cookie( -name=>'theme', -value=>$theme, -expires=>'+10y' ) );
				Vhffs::Panel::User::set_theme( $userp, $theme );

				$panel->add_cookie( CGI->cookie( -name=>'language', -value=>$lang, -expires=>'+10y' ) );
				Vhffs::Panel::User::set_lang( $userp, $lang );
			}

			# Commit all the changes for the current user
			unless( defined $firstname && defined $lastname && defined $city && defined $mail && defined $zipcode && defined $country && defined $address && defined $shell )  {
				$panel->add_error( gettext( 'CGI Error !' ) );
			}
			else {
				# We don't really care about what user use as firstname, lastname, ... we just
				# want it not to break everything
				if( $firstname !~ /^[^<">]+$/ ) {
					$panel->add_error( gettext( 'Firstname is not correct !') );
				}
				if( $lastname !~ /^[^<">]+$/ ) {
					$panel->add_error( gettext( 'Lastname is not correct !') );
				}
				if( $city !~ /^[^<">]+$/ ) {
					$panel->add_error( gettext( 'City is not correct !') );
				}
				if( ! Vhffs::Functions::valid_mail($mail) ) {
					$panel->add_error( gettext( 'Email is not correct !') );
				}
				if( ! ( $zipcode =~ /^[\w\d\s\-]+$/ ) ) {
					$panel->add_error( gettext( "Zipcode is not correct !" ) );
				}
				if( $country !~ /^[^<">]+$/ ) {
					$panel->add_error( gettext( 'Country is not correct !') );
				}
				if( $address !~ /^[^<">]+$/ ) {
					$panel->add_error( gettext( 'Address is not correct !') );
				}
				if( $pass1 ne $pass2 ) {
					$panel->add_error( gettext( "Passwords don't match" ) );
				}
				if( $userp->have_activegroups > 0 ) {
					my $valid=0;
					foreach( Vhffs::Panel::User::list_shells( $vhffs ) ) {
						$valid = 1 if($shell eq $_);
					}
					unless( $valid ) {
						$panel->add_error( gettext( 'Wanted shell is not in the shell list' ) );
					}
				}
				else {
					$shell = Vhffs::Panel::User::default_shell( $ vhffs );
				}

				if(! $panel->has_errors) {
					$userp->set_firstname(  $firstname );
					$userp->set_lastname(  $lastname );
					$userp->set_city(  $city );
					$userp->set_zipcode( $zipcode );
					$userp->set_country( $country );
					$userp->set_address( $address );
					$userp->set_shell( $shell );

					if( ( length( $pass1 ) > 1 ) && ( $pass1 eq $pass2 ) ) { 
						$pwd_change = 1;
						$userp->set_password( $pass1 );
						$panel->add_info( gettext('Password changed') );

						my $mu = init Vhffs::Services::MailUser( $vhffs , $userp );
						if( defined $mu  &&  $mu->exists_box) {
							$mu->changepassword( $pass1 );
						}
					}

					my $prevmail = $userp->get_mail();
					if( $prevmail ne $mail ) {
						$mail_change = 1;

						my $newsletter = init Vhffs::Services::Newsletter( $vhffs , $userp );
						$newsletter->del if defined $newsletter;

						$userp->set_mail( $mail );
						my $subject = gettext("Mailbox modified");
						my $content = sprintf( gettext("Hello %s %s,\n\nYou changed your email, here are your new personal information :\n\nUser: %s\nMail: %s\n\nVHFFS administrators\n"), $userp->get_firstname, $userp->get_lastname, $userp->get_username, $userp->get_mail);
						$userp->send_mail_user( $subject, $content );
						$panel->add_info( gettext('Email address changed') );
					}

					if( $userp->commit < 0 ) {
						$panel->clear_infos();
						$panel->add_error( gettext('An error occured while updating the user account') );
					}

					# -- Mail User
					my $mu = init Vhffs::Services::MailUser( $vhffs , $userp );
					if( defined $mu )  {
					
						my $mail_activate = $cgi->param( "mail_activate" );
						my $nospam = $cgi->param( "mail_nospam" );
						my $novirus = $cgi->param( "mail_novirus" );
						$nospam = (( defined $nospam ) && ( $nospam eq "on" ));
						$novirus = ( ( defined $novirus ) && ( $novirus eq "on" ) );
    
						if( ( defined $mail_activate ) && ( $mail_activate eq "on" ) ) {
							my $usage = $cgi->param( "mail_usage" );
							if( ! defined $usage ) {
								$panel->add_error( gettext("You must choose a method for your mail") );
							}
							elsif( $usage == 1 ) {
								#Delete forward if necessary
								#In this case, we treat for popable accounts
								if( $mu->exists_box == 0 ) {
									# Box doesn't exists, need a password
									if( $pwd_change == 0 ) {
										$panel->add_error( gettext("Error ! You MUST provide a password in your account when you create your popable account") );
									} else  {
										# Del forward if needed
										$mu->delforward;
										if( $mu->addbox($pass1 ) < 0 ) {
											$panel->add_error( gettext("An error occured while adding the box") );
										} elsif( $nospam && ( $mu->change_spam_status < 0 ) ) {
											$panel->add_error( gettext("An error occured while adding the box (anti-spam adding)") );
										} elsif( $novirus && ( $mu->change_virus_status < 0 ) ) {
											$panel->add_error( gettext("An error occured while adding the box (anti-virus adding)") );
										} else {
											$panel->add_info( gettext("Mailbox successfully added") );
										}
									}
								} else {
									#Box already exists
									# The user changed his password, we must update password for mail
									if( $pwd_change ) {
										$mu->changepassword( $pass1);
									}

									# We change the spam status. if the spam status changed
									if( $vhffs->get_config->get_service('mail')->{'use_nospam'} eq 'yes' ) {
										if( $nospam != $mu->use_nospam ) {
											if( $mu->change_spam_status == 1 ) {
												$panel->add_info( gettext( "Change spam protection status for your account\n" ) );
											} else {
												$panel->add_error( gettext( "Error for spam protection\n" ) );
											}
										}
									}

									# As spam, the virus status changes only if the user changed values
									if( $vhffs->get_config->get_service('mail')->{'use_novirus'} eq 'yes' ) {
										if( $novirus != $mu->use_novirus ) {
											if( $mu->change_virus_status == 1 ) {
												$panel->add_info( gettext( "Changed anti-virus status for your account\n" ) );
											} else {
												$panel->add_error( gettext( "Error for virus protection\n" ) );
											}
										}
									}
								}
							}
							elsif( $usage == 2 ) {
								#Here, we create the forward
								my $ad = $userp->get_mail;
								if( $mu->exists_forward == 0 ) {
									if( ! defined $ad ) {
										$panel->add_error( gettext("There is a problem with the address you filled in your profile, unable to add forwarding") );
									} else {
										# Delete the box if necessary
										$mu->delbox;
										if( $mu->addforward( $userp->get_mail ) < 0) {
											$panel->add_error(  gettext("An error occured while adding the forwarding") );
										} else {
											$panel->add_info( gettext('Forward added') );
										}
									}
								}
								elsif( $mail_change == 1 ) {
									$mu->delforward;
									if( $mu->addforward( $mail ) < 0 ) {
										$panel->add_error( gettext("An error occured while the forwarding") );
									} else {
										$panel->add_info( gettext('Forward updated') );
									}
								}
							}	
						} elsif($mu->exists_box || $mu->exists_forward) {
							$panel->add_info( gettext('Mail deleted') );
							# User doesn't want mail anymore
							$mu->delbox;
							$mu->delforward;
						}
					}

					# -- Newsletter
					my $newsletter = init Vhffs::Services::Newsletter( $vhffs , $userp );
					if( defined $newsletter )  {
						if( $newslettercheckbox  &&  !$newsletter->exists ) {
							$newsletter->add;
						} elsif( !$newslettercheckbox  &&  $newsletter->exists  &&  $newsletter->get_collectmode != Vhffs::Services::Newsletter::PERMANENT ) {
							$newsletter->del;
						}
					}

				}
			}
		}
	}

	elsif( defined $cgi->param('update_ircnick_submit') ) {
		update_ircnick();
	}

	elsif( defined $cgi->param('update_permissions_submit') ) {
		update_permissions();
	}

	$panel->set_title( gettext("User Preferences") );

	$template = new Vhffs::Panel::Template( filename => $templatedir."/panel/user/prefs.tmpl" );

	$template->param( TEXT_USERNAME => gettext("Username") );
	$template->param( TEXT_MAIL => gettext("mail") );
	$template->param( TEXT_FIRSTNAME => gettext("Firstname") );
	$template->param( TEXT_LASTNAME => gettext("Lastname") );
	$template->param( TEXT_ZIPCODE => gettext("Zipcode") );
	$template->param( TEXT_CITY => gettext("City") );
	$template->param( TEXT_ADDRESS => gettext("Address") );
	$template->param( TEXT_COUNTRY => gettext("Country") );
	$template->param( TEXT_PASSWORD1 => gettext("Password") );
	$template->param( TEXT_PASSWORD2 => gettext("Confirm Password") );
	$template->param( TEXT_LANG => gettext("Language") );
	$template->param( TEXT_THEME => gettext("Theme") );
	$template->param( TEXT_SHELL => gettext("Shell") );
	$template->param( TEXT_SEND => gettext("Modify") );

	$template->param( VALUE_USERNAME => $userp->get_username ); 
	$template->param( VALUE_MAIL => $userp->get_mail ); 
	$template->param( VALUE_FIRSTNAME => $userp->get_firstname ); 
	$template->param( VALUE_LASTNAME => $userp->get_lastname ); 
	$template->param( VALUE_ZIPCODE => $userp->get_zipcode ); 
	$template->param( VALUE_CITY => $userp->get_city ); 
	$template->param( VALUE_ADDRESS => $userp->get_address ); 
	$template->param( VALUE_COUNTRY => $userp->get_country ); 

	$template->param( TEXT_DELETE_USER => gettext("Delete YOUR user") );
	$template->param( TEXT_BEFORE_DELETE => gettext("This action is non-reversible. Your user will be DESTROYED.") );
	$template->param( ASK_DELETE_USER => gettext("Are you SURE you want DELETE this user?") );
	$template->param( YES => gettext("Yes I'm sure of what I do") );
	$template->param( NO => gettext("No, I'm not sure, I prefer to keep it.") );
	$template->param( TEXT_DELETE => gettext("Delete") );

	if( $panel->use_users_avatars )  { 

		my $ta = new HTML::Template( filename => $templatedir."/panel/user/prefs_avatar.tmpl" );

		$ta->param( SEND_AVATAR => gettext("Send my avatar") );
		$ta->param( CURRENT_AVATAR => gettext("Current avatar") );
		$ta->param( TEXT_AVATAR => gettext("Send my avatar") );
		$ta->param( EXPLAIN_AVATAR => gettext("The avatar is a pictures that describes you. You can upload an PNG image and use it as avatar. This image will then appear in the public section.") );
		$ta->param( VALUE_OID => $userp->get_oid ); 

		$template->param( AVATAR => $ta->output );
	}

	# themes
	my @themes = Vhffs::Panel::Main::list_themes( $vhffs );
	my $curtheme = Vhffs::Panel::User::get_theme( $userp );
	my $themelist;
	foreach( @themes )
	{
		if($curtheme ne $_)
		{
			$themelist .= "<option value=\"".$_."\">".$_."</option>\n";
		}
		else
		{
			$themelist .= "<option value=\"".$_."\" selected=\"selected\">".$_."</option>\n";
		}
	}
	$template->param( THEME_LIST => $themelist );

	# languages
	my @langs = Vhffs::Panel::Main::list_languages( $vhffs );
	my $curlang = Vhffs::Panel::User::get_lang( $userp );
	my $langlist = '';
	foreach( @langs ) {
		if($curlang ne $_) {
			$langlist .= "<option value=\"".$_."\">".$_."</option>\n";
		} else {
			$langlist .= "<option value=\"".$_."\" selected=\"selected\">".$_."</option>\n";
		}
	}
	$template->param( LANG_LIST => $langlist );

	# shells
	if( $userp->have_activegroups > 0 )  {
		my @shells = Vhffs::Panel::User::list_shells( $vhffs );
		my $curshell = Vhffs::Panel::User::get_shell( $userp );
		my $shelllist = "";
		foreach( @shells )
		{
			if($curshell ne $_)
			{
				$shelllist .= "<option value=\"".$_."\">".$_."</option>\n";
			}
			else
			{
				$shelllist .= "<option value=\"".$_."\" selected=\"selected\">".$_."</option>\n";
			}
		}
		$template->param( SHELL_LIST => $shelllist );
	}
	else {
		my $defaultshell = Vhffs::Panel::User::default_shell( $vhffs );
		$template->param( SHELL_LIST => "<option value=\"".$defaultshell."\" selected=\"selected\">".$defaultshell."</option>\n" );
	}

	my $mu = init Vhffs::Services::MailUser( $vhffs , $userp );
	if( defined $mu )  {
    
		my $subtemplate = new HTML::Template( filename => $templatedir.'/panel/user/mailuser.tmpl' );
		my $config = $vhffs->get_config->get_service( 'mailuser' );

		#nothing, a forward, or a box but activated
		if( !$mu->exists || $mu->exists_forward || ( $mu->exists_box && $mu->get_box_status == Vhffs::Constants::ACTIVATED ) )  {
			my $tmp = '';

			$subtemplate->param( ACTIV_CHECKED => 1 ) if( $mu->exists == 1 );
			$subtemplate->param( POP_CHECKED => 1 ) if( $mu->exists_box == 1 && $mu->exists_forward == 0 );
			$subtemplate->param( FWD_CHECKED => 1 ) if( $mu->exists_forward == 1 );
			$subtemplate->param( TEXT_MAILACTIV => sprintf( gettext("Activate %s\@%s email"), $userp->get_username, $config->{domain}) );
			$subtemplate->param( TEXT_MAILINFO2 => gettext("There is two possible usages :") );
			$subtemplate->param( TEXT_MAILBOX => sprintf( gettext("Use VHFFS servers to manage this mail,<br/>you should use use the host pop.%s or imap.%s to fetch your mails") , $config->{domain} , $config->{domain} ) );
			$subtemplate->param( TEXT_MAILFORWARD => sprintf( gettext("Forward emails from %s\@%s to %s"), $userp->get_username, $config->{domain}, $userp->get_mail ) );

			if( defined ( my $url = $config->{'url_doc'} ) )  {
				$template->param( HELP_TEXT => gettext('Help') );
				$template->param( HELP_URL => $url );
			}

			if( $vhffs->get_config->get_service('mail')->{'use_nospam'} eq 'yes' )
			{
				my $subtemplate2 = new HTML::Template( filename => $templatedir.'/panel/user/mailuserspam.tmpl' );
				$subtemplate2->param( TEXT_NOSPAM => gettext("Use anti-spam protection") );
				$subtemplate2->param( ACTIV_CHECKED => "checked" ) if( $mu->use_nospam == 1         );
				$tmp .= $subtemplate2->output;
			}

			if( $vhffs->get_config->get_service('mail')->{'use_novirus'} eq 'yes' )
			{
				my $subtemplate2 = new HTML::Template( filename => $templatedir.'/panel/user/mailuservirus.tmpl' );
				$subtemplate2->param( TEXT_VIRUS => gettext("Use anti-virus protection") );
				$subtemplate2->param( ACTIV_CHECKED => "checked" ) if( $mu->use_novirus == 1         );
				$tmp .= $subtemplate2->output;
			}
   
			$subtemplate->param( MAILUSER_OPTIONS => $tmp );
		}
		else {
			$subtemplate->param( STATUSSTR => Vhffs::Functions::status_string_from_status_id( $mu->get_box_status ) );
		}

		$subtemplate->param( TEXT_LEGEND => sprintf( gettext("We offer you the possibility to have one email box on the domain %s") , $config->{domain}) );
		$template->param( MAILUSER => $subtemplate->output );
	}

	my $newsletter = init Vhffs::Services::Newsletter( $vhffs , $userp );
	if( defined $newsletter )  {
		if( $newsletter->get_collectmode != Vhffs::Services::Newsletter::PERMANENT ) {
			$template->param( NEWSLETTER_TEXT => gettext('Receive mails from the newsletter') );
			$template->param( NEWSLETTER_CHECKED => $newsletter->exists );
		}
	}

    if($user->is_admin) {
    	my $adminpart = Vhffs::Panel::Object::admin_part( $panel, $userp );
    	$template->param( ADMIN_PART => $adminpart->output ) if( defined $adminpart );
        $template->param( ADMIN => 1 );
        $template->param( PERMISSIONS => $userp->get_permissions );
        $template->param( USER_NORMAL => Vhffs::Constants::USER_NORMAL );
        $template->param( USER_MODERATOR => Vhffs::Constants::USER_MODERATOR );
        $template->param( USER_ADMIN => Vhffs::Constants::USER_ADMIN );
        $template->param( TEXT_IRCNICK => gettext('IRC nick') );
        $template->param( VALUE_USERNAME => $userp->get_username );
        $template->param( VALUE_IRCNICK => $userp->get_ircnick );
    }
}

$panel->build( $template );
$panel->display;

sub update_ircnick {
    unless( $user->is_admin ) {
        $panel->add_error( gettext('Only administrators can do this') );
        return;
    }

    my $ircnick = $cgi->param('ircnick');
    unless(defined $ircnick) {
        $panel->add_error( gettext('CGI Error !') );
        return;
    }

    if( $ircnick !~ /^[^<">\s]*$/ ) {
        $panel->add_error( gettext( 'IRC nick is not correct !') );
        return;
    }

    $userp->set_ircnick($ircnick);
    if($userp->commit < 0) {
        $panel->add_error( gettext('Unable to update user, please try again later') );
    } else {
        $panel->add_info( gettext('User successfully updated') );
    }
}

sub update_permissions {
    unless( $user->is_admin ) {
        $panel->add_error( gettext('Only administrators can do this') );
        return;
    }

    my $permissions = $cgi->param('permissions');
    unless(defined $permissions) {
        $panel->add_error( gettext('CGI Error !') );
        return;
    }

    $userp->set_admin($permissions);
    if($userp->commit < 0) {
        $panel->add_error( gettext('Unable to update user, please try again later') );
    } else {
        $panel->add_info( gettext('User successfully updated') );
    }
}
