<?php
#################################################
#
#	 This file is part of VFront.
#
#    VFront 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
#    any later version.
#
#    VFront 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, see <http://www.gnu.org/licenses/>.
#




/**
 * Classe generica per l'autenticazione a VFront. 
 * L'accesso pu� essere in 1 o 2 passi
 * In 1 passo se si usa l'autenticazione mediante il database di VFront
 * In 2 mediante strumenti esterni (LDAP, altro DB, ecc) per l'autenticazione
 * e il DB di VFRont per l'accreditamento dei diritti
 * @package VFront
 * @subpackage Authentication
 * @author Mario Marcello Verona <marcelloverona@gmail.com>
 * @copyright 2007-2010 M.Marcello Verona
 * @version 0.96 $Id: auth.php 880 2010-12-14 12:43:47Z marciuz $
 * @license http://www.gnu.org/licenses/gpl.html GNU Public License 
 */
class auth{
	
	/**
	* @desc Utente oggetto dell'autenticazione
	* @var string
	*/
	var $user;
	
	/**
	* @desc Password oggetto dell'autenticazione
	* @var string
	*/
	var $passw;
	
	/**
	* Array restituito dalla classe 
	* 'response' => true | false 
	* 0 => (array) info_account | null 
	* @var array
	*/
	var $auth_obj = array('response'=>false);
	
	/**
	* Presenza dell'utente nel frontend
	* @var array
	*/
	var $utente_in_frontend = array('response'=>false);
	
	/**
	* Autenticazione esterna, impostata nel file CONF
	* @var string soap | ldap | db | db_ext | null=dbvfront
	*/
	var $tipo_external_auth = '';  // soap | ldap | db | db_ext | null=dbvfront
	
	
	/**
	*	Tipo di autenticazione. 
	* 	La modalit� di accesso pu� essere in 2 step o 1 step. 
	*	Nella modalit� 1 step l'autorizzazione e l'accreditamento sono congiunti,
	*	nel 2 step sono separati
	* 	Variabile obsoleta, mantenuta per compatibilit�
	* @var string 1step | 2step
	*/
	var $modalita_auth = ''; // 1step | 2step
	
	
	/**
	 * Autenticazione ed accreditamento dei diritti
	 *
	 * @param string $user Email dell'utente
	 * @param string $passw Password
	 * @return auth
	 */
	function  __construct($user,$passw){
		
		global  $vmsql, $vmreg, $db1,$conf_auth;
		
		
		$this->tipo_external_auth = $conf_auth['tipo_external_auth'];
		
		$this->user = trim($user);
		$this->passw = trim($passw);
		
		
		switch($this->tipo_external_auth){
			
			case 'soap': require_once(FRONT_REALPATH.'/inc/auth.soap.php');
						$this->auth_obj = auth_soap($this->user , $this->passw);
						$this->modalita_auth='2step';
			break;
			
			case 'db': require_once(FRONT_REALPATH.'/inc/auth.db.php');
						$this->auth_obj = auth_db($this->user , $this->passw);
						$this->modalita_auth='2step';
			break;
				
			case 'db_ext': require_once(FRONT_REALPATH.'/inc/auth.db_ext.php');
						$this->auth_obj = auth_db_ext($this->user , $this->passw);
						$this->modalita_auth='2step';
			break;
			
			case 'ldap': require_once(FRONT_REALPATH.'/inc/auth.ldap.php');
						$this->auth_obj = auth_ldap($this->user , $this->passw);
						$this->modalita_auth='2step';
			break;
			
			case null: $this->modalita_auth='1step';
					   $this->__step_1();
		}
		
		
		// l'uente non esiste, mandalo via
		if($this->auth_obj['response']===false){
			
			
			$this->__respingi_utente(0);
		}
		
		// L'utente esiste in autorizzazione, ora esiste anche in DB? (2 passi)
		else{
			
			if($this->tipo_external_auth!==null){
			
				$this->__step_2();
			}
		
		
		}
		
	} //-- Fine funzione AUTH
	
	
	
	
	
	
	/**
	 * @desc Funzione di autenticazione basata sul DB di VFront, tabella utenti
	 *
	 */
	function __step_1(){
		
		global  $vmsql, $vmreg, $db1,$conf_auth;
		
					// Verifico che esista nel db Frontend
					$this->utente_in_frontend = $this->__frontend_user($this->user , $this->passw);
					
					// L'utente esiste anche nel DB!
					// prende i dati, li mette in sessione, lo fa andare avanti
					if($this->utente_in_frontend['response']){
						
						$this->__metti_in_sessione();
						header("Location: ".FRONT_DOCROOT."/index.php");
						exit;
					}
					else{
						
						// recover password procedure
						if($conf_auth['tipo_external_auth']==''){
							
							$this->utente_in_frontend = $this->__frontend_user_recover_passw($this->user , $this->passw);
							
							if($this->utente_in_frontend['response']){
								
								$this->__metti_in_sessione();
								header("Location: ".FRONT_DOCROOT."/index.php");
								exit;
							}
						}
						
						$this->__respingi_utente(0);
						
					}
	}
	
	
	
	
	/**
	 * @desc Funzione di accreditamento e inserimento se non esistono i diritti
	 *
	 */
	function __step_2(){
		
		global  $vmsql, $vmreg, $db1,$conf_auth;
		
		
			// Verifico che esista nel db Frontend, senza password, l'utente e' gia' autenticato
				$this->utente_in_frontend = $this->__frontend_user($this->user , $this->passw, false);
				
					// L'utente esiste anche nel DB!
					// prende i dati, li mette in sessione, lo fa andare avanti
					if($this->utente_in_frontend['response']){
						
						$this->__metti_in_sessione();
						header("Location: ".FRONT_DOCROOT."/index.php");
						exit;
					}
					
					// L'utente e' autorizzato ma non c'e' nel DB.
					// Prendo i dati a disposizioni e creo un record nel DB con livello di accesso default
					else{
						
							// test primo utente:
							// se non ci sono utenti il primo utente e' amministratore
							$q_test1=$vmreg->query("SELECT count(*) FROM {$db1['frontend']}{$db1['sep']}utente");
							list($n_users)=$vmreg->fetch_row($q_test1);
							
							$livello_insert=($n_users==0) ? 3 : 1;
							
							$sql_ins = sprintf("INSERT INTO {$db1['frontend']}{$db1['sep']}utente 
												(nick, nome, cognome, email, passwd, gid, livello, data_ins)
										        VALUES ('%s','%s','%s','%s','%s',%d,%d,'%s')", //,%d)",
												$this->auth_obj[0][$conf_auth['campo_nick']],
												$this->auth_obj[0][$conf_auth['campo_nome']],
												$this->auth_obj[0][$conf_auth['campo_cognome']],
												$this->auth_obj[0][$conf_auth['campo_email']],  // email in questo caso = nick
												$this->auth_obj[0][$conf_auth['campo_password']], 
												0, // Imposta nel gruppo default 0
												$livello_insert, // Imposta il livello di amministrazione a 1 (nessuna amministrazione)
												date("Y-m-d")
												);
							
							// INSERISCE NEL DB
							$q_ins = $vmreg->query($sql_ins);
							if($vmreg->affected_rows($q_ins)!=1){
								
								openErrorGenerico(_('Authorization management error'),true);
								exit;
							}
							
							
							
							
							
							else{
								
								$this->utente_in_frontend = $this->__frontend_user($this->user , $this->passw, false);
								
								$this->__metti_in_sessione();
								
								header("Location: ".FRONT_DOCROOT."/index.php");
								exit;
							}
							
							
						
					} 
		
	}
	
	
	
	
	
	
	/**
	 * Funzione di logout
	 *
	 * @param int $tipo_err 0=errore nell'utente password, 1=livello troppo basso per vedere la pagina
	 */
	function __respingi_utente($tipo_err=0){
		
		switch($tipo_err){
			
			case 0: // errore nell'utente password
				unset($_SESSION['user']);
				unset($_SESSION['gid']);				
				header("Location: ".FRONT_DOCROOT."/index.php?nolog"); exit;
			break;
			
			
			case 1: // livello troppo basso per vedere la pagina
				header("Location: ".FRONT_DOCROOT."/index.php?accesso_vietato=1"); exit;
			break;
		}
	}
	
	
	
	
	
	
	/**
	 * @desc Cerca l'utente nel DB di VFront
	 * @param string $user Nome utente
	 * @param string $passw Password
	 * @param bool $use_passw Utilizza la password per l'autenticazione (default=true)
	 * @return array Array con le informazioni sull'utente
	 */
	function __frontend_user($user,$passw='',$use_passw=true){
		
		global  $vmsql, $vmreg, $db1;
		
		// cerca l'utente in database
		$sql = "SELECT * FROM {$db1['frontend']}{$db1['sep']}utente 
				WHERE nick='".$vmreg->escape($user)."' ";
		
		if($use_passw)	$sql.=" AND passwd='".md5($passw)."'";
		
		$sql.=" LIMIT 1";
		
		$q= $vmreg->query($sql);
		
		// L'utente esiste anche nel DB!
		// prende i dati, li mette in sessione, lo fa andare avanti
		if($vmreg->num_rows($q)==1){

			$RS= $vmreg->fetch_assoc($q);

			return array('response'=>true,$RS);
		}
		
		// L'utente � autorizzato ma non c'� nel DB.
		else{
			
			return array('response'=>false);
		}
		
	}
	
	
	
	
	/**
	 * @desc Recover password procedure
	 * @param string $user Nome utente
	 * @param string $recover_passw Password
	 * @return array Array con le informazioni sull'utente
	 */
	function __frontend_user_recover_passw($user,$recover_passw){
		
		global  $vmsql, $vmreg, $db1;
		
		// cerca l'utente in database
		$sql = "SELECT * FROM {$db1['frontend']}{$db1['sep']}utente 
				WHERE nick='".$vmreg->escape($user)."' ";
		
		$sql.=" AND recover_passwd='".md5($recover_passw)."'";
		
		$sql.=" LIMIT 1";
		
		$q= $vmreg->query($sql);
		
		
		// L'utente esiste anche nel DB!
		// prende i dati, li mette in sessione, lo fa andare avanti
		if($vmreg->num_rows($q)==1){
			
			$RS= $vmreg->fetch_assoc($q);
			
			$sql_up="UPDATE {$db1['frontend']}{$db1['sep']}utente 
								SET passwd=recover_passwd ,
								recover_passwd='' 
								WHERE id_utente=".intval($RS['id_utente']);
			
			// UPDATE USER DATA:
			$q_up= $vmreg->query($sql_up);
			
			
			
			return array('response'=>true,$RS);
		}
		
		// L'utente � autorizzato ma non c'� nel DB.
		else{
			
			return array('response'=>false);
		}
		
	}
	
	
	
	/**
	 * @desc Inserisce in sessione le variabili relative all'utente quando autenticato e accreditato
	 *
	 */
	function __metti_in_sessione(){
		
		$_SESSION['user']=array(
						'uid'	=> $this->utente_in_frontend[0]['id_utente'],
						'nick'	=> $this->utente_in_frontend[0]['nick'],
						'email'	=> $this->utente_in_frontend[0]['email'],
						'nome'	=> $this->utente_in_frontend[0]['nome'],
						'cognome'=>$this->utente_in_frontend[0]['cognome'],
						'data_ins'=>$this->utente_in_frontend[0]['data_ins'],
						'gid'     =>$this->utente_in_frontend[0]['gid'],
						'livello' =>$this->utente_in_frontend[0]['livello']
						);
						
		$_SESSION['gid']=$this->utente_in_frontend[0]['gid'];
	}
}




?>