openrat-cms

# OpenRat Content Management System
git clone http://git.code.weiherhei.de/openrat-cms.git
Log | Files | Refs

StartAction.class.php (32903B)


      1 <?php
      2 
      3 namespace cms\action;
      4 
      5 use cms\model\User;
      6 use cms\model\Project;
      7 use cms\model\Value;
      8 use cms\model\Element;
      9 use cms\model\Page;
     10 use cms\model\BaseObject;
     11 use cms\model\Language;
     12 use cms\model\Model;
     13 
     14 
     15 use database\Database;
     16 use Http;
     17 use Logger;
     18 use \security\Password;
     19 use Session;
     20 use \Html;
     21 use \Mail;
     22 
     23 // OpenRat Content Management System
     24 // Copyright (C) 2002-2007 Jan Dankert, jandankert@jandankert.de
     25 //
     26 // This program is free software; you can redistribute it and/or
     27 // modify it under the terms of the GNU General Public License
     28 // as published by the Free Software Foundation; version 2.
     29 //
     30 // This program is distributed in the hope that it will be useful,
     31 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     32 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     33 // GNU General Public License for more details.
     34 //
     35 // You should have received a copy of the GNU General Public License
     36 // along with this program; if not, write to the Free Software
     37 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     38 
     39 
     40 if	( !defined('PROJECTID_ADMIN') )
     41 	define('PROJECTID_ADMIN',-1);
     42 
     43 /**
     44  * Action-Klasse fuer die Start-Action
     45  * @author $Author$
     46  * @version $Revision$
     47  * @package openrat.actions
     48  * @deprecated
     49  */
     50 
     51 class StartAction extends BaseAction
     52 {
     53 	public $security = Action::SECURITY_USER;
     54 	
     55 	var $mustChangePassword = false;
     56 	
     57 	function setDb( $dbid )
     58 	{
     59 		global $conf;
     60 
     61 		if	( !isset($conf['database'][$dbid] ))
     62 			throw new \LogicException( 'unknown DB-Id: '.$dbid );
     63 			
     64 		$db = db_connection();
     65 		if	( is_object($db) )
     66 		{
     67 			$db->rollback();
     68 		}
     69 
     70 		$db = new Database( $conf['database'][$dbid] );
     71 		$db->id = $dbid;
     72 		$db->start();
     73 		Session::setDatabase( $db );
     74 	}
     75 
     76 
     77 
     78 	function checkForDb()
     79 	{
     80 		global $conf;
     81 		$dbid = $this->getRequestVar('dbid'); 
     82 
     83 		if	( $dbid != '' )
     84 			$this->setDb( $dbid );
     85 	}
     86 
     87 
     88 
     89 	function setDefaultDb()
     90 	{
     91 		if	( $this->hasRequestVar(REQ_PARAM_DATABASE_ID) )
     92 		{
     93 			$dbid = $this->getRequestVar(REQ_PARAM_DATABASE_ID);
     94 		}
     95 		else
     96 		{
     97 			global $conf;
     98 	
     99 			if	( !isset($conf['database']['default']) )
    100 				throw new \LogicException('default-database not set');
    101 	
    102 			$dbid = $conf['database']['default'];
    103 		}
    104 		
    105 		$this->setDb( $dbid );
    106 	}
    107 
    108 
    109 
    110 	function checkLogin( $name,$pw,$pw1,$pw2 )
    111 	{
    112 		Logger::debug( "login user $name" );
    113 	
    114 		global $conf;
    115 		global $SESS;
    116 	
    117 		unset( $SESS['user'] );	
    118 	
    119 		
    120 		$db = db_connection();
    121 		
    122 		if	( !$db->available )
    123 		{
    124 			$this->addNotice('database',$db->conf['description'],'DATABASE_CONNECTION_ERROR',OR_NOTICE_ERROR,array(),array('Database Error: '.$db->error));
    125 			$this->callSubAction('showlogin');
    126 			return false;
    127 		}
    128 		
    129 		$ip = getenv("REMOTE_ADDR");
    130 	
    131 		$user = new User();
    132 		$user->name = $name;
    133 		
    134 		$ok = $user->checkPassword( $pw );
    135 		
    136 		$this->mustChangePassword = $user->mustChangePassword;
    137 		
    138 		if	( $this->mustChangePassword )
    139 		{
    140 			// Der Benutzer hat zwar ein richtiges Kennwort eingegeben, aber dieses ist abgelaufen.
    141 			// Wir versuchen hier, das neue zu setzen (sofern eingegeben).
    142 			if	( empty($pw1) )
    143 			{
    144 			}
    145 			elseif	( $pw1 != $pw2 )
    146 			{
    147 				$this->addValidationError('password1','PASSWORDS_DO_NOT_MATCH');
    148 				$this->addValidationError('password2','');
    149 			}
    150 			elseif	( strlen($pw2) < $conf['security']['password']['min_length'] )
    151 			{
    152 				$this->addValidationError('password1','PASSWORD_MINLENGTH',array('minlength'=>$conf['security']['password']['min_length']));
    153 				$this->addValidationError('password2','');
    154 			}
    155 			else
    156 			{
    157 				// Kennw�rter identisch und lang genug.
    158 				$user->setPassword( $pw1,true );
    159 				
    160 				// Das neue Kennwort ist gesetzt, die Anmeldung ist also doch noch gelungen. 
    161 				$ok = true;
    162 				$this->mustChangePassword = false;
    163 				$user->mustChangePassword = false;
    164 			}
    165 		}
    166 		
    167 		// Falls Login erfolgreich
    168 		if  ( $ok )
    169 		{
    170 			// Login war erfolgreich!
    171 			$user->load();
    172 			$user->setCurrent();
    173 			Logger::info( 'login successful' );
    174 
    175 			return true;
    176 		}
    177 		else
    178 		{
    179 			Logger::info( "login for user $name failed" );
    180 
    181 			return false;
    182 		}
    183 	}
    184 
    185 
    186 
    187 	/**
    188 	 * Anzeigen der Loginmaske.
    189 	 *
    190 	 * Es wird nur die Loginmaske angezeigt.
    191 	 * Hier nie "304 not modified" setzen, da sonst keine
    192 	 * Login-Fehlermeldung erscheinen kann
    193 	 */
    194 	function loginView()
    195 	{
    196 		global $conf;
    197 		$sso = $conf['security']['sso'];
    198 		$ssl = $conf['security']['ssl'];
    199 		
    200 		$ssl_trust    = false;
    201 		$ssl_user_var = '';
    202 		extract( $ssl, EXTR_PREFIX_ALL, 'ssl' );
    203 		
    204 		if	( $sso['enable'] )
    205 		{
    206 			$authid = $this->getRequestVar( $sso['auth_param_name']);
    207 			
    208 			if	( empty( $authid) )
    209 				throw new \SecurityException( 'no authorization data (no auth-id)');
    210 				
    211 			if	( $sso['auth_param_serialized'] )
    212 				$authid = unserialize( $authid );
    213 			
    214 			$purl = parse_url($sso['url']);
    215 			// Verbindung zu URL herstellen.
    216 			$errno=0; $errstr='';
    217 			$fp = fsockopen ($purl['host'],80, $errno, $errstr, 30);
    218 			if	( !$fp )
    219 			{
    220 				echo "Connection failed: $errstr ($errno)";
    221 			}
    222 			else
    223 			{
    224 				$http_get = $purl['path'];
    225 				if	( !empty($purl['query']) ) 
    226 					$http_get .= '?'.$purl['query'];
    227 
    228 				$header = array();
    229 					
    230 				$header[] = "GET $http_get HTTP/1.0";
    231 				$header[]  ="Host: ".$purl['host'];
    232 				$header[] = "User-Agent: Mozilla/5.0 (OpenRat CMS Single Sign-on Check)";
    233 				$header[] = "Connection: Close";
    234 				
    235 				if	( $sso['cookie'] )
    236 				{
    237 					$cookie = 'Cookie: ';
    238 					if	( is_array($authid))
    239 						foreach( $authid as $cookiename=>$cookievalue)
    240 							$cookie .= $cookiename.'='.$cookievalue."; ";
    241 					else
    242 						$cookie .= $sso['cookie_name'].'='.$authid;
    243 						
    244 					$header[] = $cookie;
    245 				}
    246 				
    247 //				Html::debug($header);
    248 				fputs ($fp, implode("\r\n",$header)."\r\n\r\n");
    249 				
    250 				$inhalt=array();
    251 				while (!feof($fp)) {
    252 					$inhalt[] = fgets($fp,128);
    253 				}
    254 				fclose($fp);
    255 				
    256 				$html = implode('',$inhalt);
    257 //				Html::debug($html);
    258 				if	( !preg_match($sso['expect_regexp'],$html) )
    259 					throw new \SecurityException('auth failed');
    260 				$treffer=0;
    261 				if	( !preg_match($sso['username_regexp'],$html,$treffer) )
    262 					throw new \SecurityException('auth failed');
    263 				if	( !isset($treffer[1]) )
    264 					throw new \SecurityException('authorization failed');
    265 					
    266 				$username = $treffer[1];
    267 				
    268 //				Html::debug( $treffer );
    269 				$this->setDefaultDb();
    270 
    271 				$user = User::loadWithName( $username );
    272 				
    273 				if	( ! $user->isValid( ))
    274 					throw new \SecurityException('authorization failed: user not found: '.$username);
    275 					
    276 				$user->setCurrent();
    277 
    278 				$this->callSubAction('show');
    279 			}
    280 		}
    281 
    282 		elseif	( $ssl_trust )
    283 		{
    284 			if	( empty($ssl_user_var) )
    285 				throw new \LogicException( 'please set environment variable name in ssl-configuration.' );
    286 
    287 			$username = getenv( $ssl_user_var );
    288 
    289 			if	( empty($username) )
    290 				throw new \SecurityException( 'no username in client certificate ('.$ssl_user_var.') (or there is no client certificate...?)' );
    291 			
    292 			$this->setDefaultDb();
    293 
    294 			$user = User::loadWithName( $username );
    295 
    296 			if	( !$user->isValid() )
    297 				throw new \LogicException( 'unknown username: '.$username );
    298 
    299 			$user->setCurrent();
    300 
    301 			$this->callSubAction('show');
    302 		}
    303 		
    304 		foreach( $conf['database'] as $dbname=>$dbconf )
    305 		{
    306 			if	( is_array($dbconf) && $dbconf['enabled'] )
    307 				$dbids[$dbname] = array('key'  =>$dbname,
    308 				                        'value'=>Text::maxLength($dbconf['description']),
    309 				                        'title'=>$dbconf['description'].' ('.$dbconf['host'].')' );
    310 		}
    311 		
    312 		$openid_provider = array();
    313 		foreach( explode(',',$conf['security']['openid']['provider']) as $provider )
    314 			$openid_provider[$provider] = config('security','openid','provider.'.$provider.'.name');
    315 		$this->setTemplateVar('openid_providers',$openid_provider);
    316 		$this->setTemplateVar('openid_user_identity',config('security','openid','user_identity'));
    317 		//$this->setTemplateVar('openid_provider','identity');
    318 
    319 		
    320 		if	( empty($dbids) )
    321 			$this->addNotice('','','no_database_configuration',OR_NOTICE_WARN);
    322 		
    323 		if	( !isset($this->templateVars['login_name']) && isset($_COOKIE['or_username']) )
    324 			$this->setTemplateVar('login_name',$_COOKIE['or_username']);
    325 		
    326 		if	( !isset($this->templateVars['login_name']) )
    327 			$this->setTemplateVar('login_name',@$conf['security']['default']['username']);
    328 
    329 		if	( $this->templateVars['login_name']== @$conf['security']['default']['username'])
    330 			$this->setTemplateVar('login_password',@$conf['security']['default']['password']);
    331 
    332 		$this->setTemplateVar( 'dbids',$dbids );
    333 		
    334 		$db = Session::getDatabase();
    335 		if	( is_object($db) )
    336 			$this->setTemplateVar('actdbid',$db->id);
    337 		elseif( isset($this->templateVars['actid']) )
    338 			;
    339 		else
    340 			$this->setTemplateVar('actdbid',$conf['database']['default']);
    341 
    342 
    343 		// Den Benutzernamen aus dem Client-Zertifikat lesen und in die Loginmaske eintragen. 
    344 		$ssl_user_var = $conf['security']['ssl']['user_var'];
    345 		if	( !empty($ssl_user_var) )
    346 		{
    347 			$username = getenv( $ssl_user_var );
    348 
    349 			if	( empty($username) )
    350 			{
    351 				echo lang('ERROR_LOGIN_BROKEN_SSL_CERT');
    352 				Logger::warn( 'no username in SSL client certificate (var='.$ssl_user_var.').' );
    353 				exit;
    354 			}
    355 			
    356 			// Benutzername ist in Eingabemaske unveränderlich
    357 			$this->setTemplateVar('force_username',$username);
    358 		}
    359 
    360 		$this->setTemplateVar('objectid'  ,$this->getRequestVar('objectid'  ,OR_FILTER_NUMBER) );
    361 		$this->setTemplateVar('projectid' ,$this->getRequestVar('projectid' ,OR_FILTER_NUMBER) );
    362 		$this->setTemplateVar('modelid'   ,$this->getRequestVar('modelid'   ,OR_FILTER_NUMBER) );
    363 		$this->setTemplateVar('languageid',$this->getRequestVar('languageid',OR_FILTER_NUMBER) );
    364 				
    365 		$this->setTemplateVar('register'     ,$conf['login'   ]['register' ]);
    366 		$this->setTemplateVar('send_password',$conf['login'   ]['send_password']);
    367 	}
    368 
    369 
    370 
    371 	/**
    372 	 * Setzt die neue Projekt-Id und lädt die Workbench neu.
    373 	 * 
    374 	 */
    375 	public function projectmenuPost()
    376 	{
    377 		
    378 		$this->evaluateRequestVars( array('projectid'=>$this->getRequestId()) );
    379 	}
    380 	
    381 	
    382 	/**
    383 	 * Erzeugt ein Projekt-Auswahlmenue.
    384 	 */
    385 	public function projectmenuView()
    386 	{
    387 		$user = Session::getUser();
    388 		
    389 		if	( $user->mustChangePassword ) 
    390 		{
    391 			$this->addNotice( 'user',$user->name,'PASSWORD_TIMEOUT','warn' );
    392 			$this->callSubAction( 'changepassword' ); // Zwang, das Kennwort zu �ndern.
    393 		}
    394 		
    395 
    396 		// Diese Seite gilt pro Sitzung. 
    397 		//$this->lastModified( $user->loginDate );
    398 
    399 		// Projekte ermitteln
    400 		$projects = $user->getReadableProjects(); 
    401 		
    402 		$list     = array();
    403 		
    404 		foreach( $projects as $id=>$name )
    405 		{
    406 			$p = array();
    407 			$p['url' ] = Html::url('start','project',$id);
    408 			$p['name'] = $name;
    409 			$p['id'  ] = $id;
    410 
    411 			$tmpProject = new Project( $id );
    412 			$p['defaultmodelid'   ] = $tmpProject->getDefaultModelId();
    413 			$p['defaultlanguageid'] = $tmpProject->getDefaultLanguageId();
    414 			$p['models'           ] = $tmpProject->getModels();
    415 			$p['languages'        ] = $tmpProject->getLanguages();
    416 			
    417 			$list[] = $p;
    418 		}
    419 
    420 		$this->setTemplateVar('projects',$list);
    421 		
    422 		if	( empty($list) )
    423 		{
    424 			// Kein Projekt vorhanden. Eine Hinweismeldung ausgeben.
    425 			if	( $this->userIsAdmin() )
    426 				// Administratoren bekommen bescheid, dass sie ein Projekt anlegen sollen
    427 				$this->addNotice('','','ADMIN_NO_PROJECTS_AVAILABLE',OR_NOTICE_WARN);
    428 			else
    429 				// Normale Benutzer erhalten eine Meldung, dass kein Projekt zur Verf�gung steht
    430 				$this->addNotice('','','NO_PROJECTS_AVAILABLE',OR_NOTICE_WARN);
    431 		}
    432 		
    433 		//$this->metaValues();
    434 	}
    435 
    436 
    437 
    438 	/**
    439 	 * Erzeugt eine Anwendungsliste.
    440 	 */
    441 	public function applicationsView()
    442 	{
    443 		global $conf;
    444 		
    445 		// Diese Seite gilt pro Sitzung. 
    446 		$user       = Session::getUser();
    447 		$userGroups = $user->getGroups();
    448 		$this->lastModified( $user->loginDate );
    449 
    450 		// Applikationen ermitteln
    451 		$list = array();
    452 		foreach( $conf['applications'] as $id=>$app )
    453 		{
    454 			if	( !is_array($app) )
    455 				continue;
    456 				
    457 			if	( isset($app['group']) )
    458 				if	( !in_array($app['group'],$userGroups) )
    459 					continue; // Keine Berechtigung, da Benutzer nicht in Gruppe vorhanden.
    460 					
    461 			$p = array();
    462 			$p['url']         = $app['url'];
    463 			$p['description'] = @$app['description'];
    464 			if	( isset($app['param']) )
    465 			{
    466 				$p['url'] .= strpos($p['url'],'?')!==false?'&':'?';
    467 				$p['url'] .= $app['param'].'='.session_id();
    468 			}
    469 			$p['name'] = $app['name'];
    470 			
    471 			$list[] = $p;
    472 		}
    473 
    474 
    475 		$this->setTemplateVar('applications',$list);
    476 	}
    477 
    478 	
    479 
    480 	/**
    481 	 * Open-Id Login, �berpr�fen der Anmeldung.<br>
    482 	 * Spezifikation: http://openid.net/specs/openid-authentication-1_1.html<br>
    483 	 * Kapitel "4.4. check_authentication"<br>
    484 	 * <br>
    485 	 * Im 2. Schritt (Mode "id_res") erfolgte ein Redirect vom Open-Id Provider an OpenRat zur�ck.<br>
    486 	 * Wir befinden uns nun im darauf folgenden Request des Browsers.<br>
    487 	 * <br>
    488 	 * Es muss noch beim OpenId-Provider die Best�tigung eingeholt werden, danach ist der
    489 	 * Benutzer angemeldet.<br>
    490 	 */
    491 	function openid()
    492 	{
    493 		global $conf;
    494 		$openId = Session::get('openid');
    495 
    496 		if	( !$openId->checkAuthentication() )
    497 		{
    498 			$this->addNotice('user',$openId->user,'LOGIN_OPENID_FAILED',OR_NOTICE_ERROR,array('name'=>$openId->user),array($openId->error) );
    499 			$this->addValidationError('openid_url','');
    500 			$this->callSubAction('showlogin');
    501 			return;
    502 		}
    503 		
    504 		//Html::debug($openId);
    505 		
    506 		// Anmeldung wurde mit "is_valid:true" best�tigt.
    507 		// Der Benutzer ist jetzt eingeloggt.
    508 		$username = $openId->getUserFromIdentiy();
    509 		
    510 		if	( empty($username) )
    511 		{
    512 			// Es konnte kein Benutzername ermittelt werden.
    513 			$this->addNotice('user',$username,'LOGIN_OPENID_FAILED','error',array('name'=>$username) );
    514 			$this->addValidationError('openid_url','');
    515 			$this->callSubAction('showlogin');
    516 			return;
    517 		}
    518 		
    519 		$user = User::loadWithName( $username );
    520 		
    521 		if	( $user->userid <=0)
    522 		{
    523 			// Benutzer ist (noch) nicht vorhanden.
    524 			if	( $conf['security']['openid']['add'])  // Anlegen?
    525 			{
    526 				$user->name     = $username;
    527 				$user->add();
    528 
    529 				$user->mail     = $openId->info['email'];
    530 				$user->fullname = $openId->info['fullname'];
    531 				$user->save();  // Um E-Mail zu speichern (wird bei add() nicht gemacht)
    532 			}
    533 			else
    534 			{
    535 				// Benutzer ist nicht in Benutzertabelle vorhanden (und angelegt werden soll er auch nicht).
    536 				$this->addNotice('user',$username,'LOGIN_OPENID_FAILED','error',array('name'=>$username) );
    537 				$this->addValidationError('openid_url','');
    538 				$this->callSubAction('showlogin');
    539 				return;
    540 			}
    541 		}
    542 		else
    543 		{
    544 			// Benutzer ist bereits vorhanden.
    545 			if	( @$conf['security']['openid']['update_user'])
    546 			{
    547 				$user->fullname = $openId->info['fullname'];
    548 				$user->mail     = $openId->info['email'];
    549 				$user->save();
    550 			}
    551 		}
    552 
    553 		$user->setCurrent();  // Benutzer ist jetzt in der Sitzung.
    554 	}
    555 	
    556 
    557 	/**
    558 	 * Login.
    559 	 */
    560 	function loginPost()
    561 	{
    562 		global $conf;
    563 
    564 		$this->checkForDb();
    565 		Session::setUser('');
    566 		
    567 		if	( $conf['login']['nologin'] )
    568 			throw new \SecurityException('login disabled');
    569 
    570 		$openid_user   = $this->getRequestVar('openid_url'    );
    571 		$loginName     = $this->getRequestVar('login_name'    ,OR_FILTER_ALPHANUM);
    572 		$loginPassword = $this->getRequestVar('login_password',OR_FILTER_ALPHANUM);
    573 		$newPassword1  = $this->getRequestVar('password1'     ,OR_FILTER_ALPHANUM);
    574 		$newPassword2  = $this->getRequestVar('password2'     ,OR_FILTER_ALPHANUM);
    575 		
    576 		// Cookie setzen
    577         $this->setCookie('or_username',$loginName );
    578 		
    579 		// Login mit Open-Id.
    580 		if	( $this->hasRequestVar('openid_provider') && ($this->getRequestVar('openid_provider') != 'identity' || !empty($openid_user)) )
    581 		{
    582 			$openId = new OpenId($this->getRequestVar('openid_provider'),$openid_user);
    583 			
    584 			if	( ! $openId->login() )
    585 			{
    586 				$this->addNotice('user',$openid_user,'LOGIN_OPENID_FAILED','error',array('name'=>$openid_user),array($openId->error) );
    587 				$this->addValidationError('openid_url','');
    588 				$this->callSubAction('showlogin');
    589 				return;
    590 			}
    591 			
    592 			Session::set('openid',$openId);
    593 			$openId->redirect();
    594 		}
    595 		
    596 
    597 		// Ermitteln, ob der Baum angezeigt werden soll
    598 		// Ist die Breite zu klein, dann wird der Baum nicht angezeigt
    599 		Session::set('showtree',intval($this->getRequestVar('screenwidth')) > $conf['interface']['min_width'] );
    600 
    601 		$loginOk = $this->checkLogin( $loginName,
    602 		                              $loginPassword,
    603 		                              $newPassword1,
    604 		                              $newPassword2 );
    605 
    606 		usleep(hexdec(Password::randomHexString(1))); // delay: 0-255 ms
    607 		
    608 		if	( !$loginOk )
    609 		{
    610 			
    611 			if	( $this->mustChangePassword )
    612 			{
    613 				// Anmeldung gescheitert, Benutzer muss Kennwort �ndern.
    614 				$this->addNotice('user',$loginName,'LOGIN_FAILED_MUSTCHANGEPASSWORD','error' );
    615 				$this->addValidationError('password1','');
    616 				$this->addValidationError('password2','');
    617 			}
    618 			else
    619 			{
    620 				// Anmeldung gescheitert.
    621 				$this->addNotice('user',$loginName,'LOGIN_FAILED','error',array('name'=>$loginName) );
    622 				$this->addValidationError('login_name'    ,'');
    623 				$this->addValidationError('login_password','');
    624 			}
    625 
    626 			Logger::debug("Login failed for user '$loginName'");
    627 			
    628 			$this->callSubAction('login');
    629 			return;
    630 		}
    631 		else
    632 		{
    633 			Logger::debug("Login successful for user '$loginName'");
    634 			
    635 			// Anmeldung erfolgreich.
    636 			if	( config('security','renew_session_login') )
    637 				$this->recreateSession();
    638 			
    639 			$user = Session::getUser();
    640 			$this->addNotice('user',$user->name,'LOGIN_OK',OR_NOTICE_OK,array('name'=>$user->fullname));
    641 		}
    642 		
    643 		// Benutzer ist angemeldet
    644 	}
    645 
    646 
    647 	/**
    648 	 * Benutzer meldet sich ab.
    649 	 */
    650 	function logoutPost()
    651 	{
    652 		global $conf;
    653 		
    654 		$user = Session::getUser();
    655 		if	( is_object($user) )
    656 			$this->setTemplateVar('login_username',$user->name);
    657 		
    658 		if	( config('security','renew_session_logout') )
    659 			$this->recreateSession();
    660 
    661 		session_unset();
    662 		
    663 		if	( @$conf['theme']['compiler']['compile_at_logout'] )
    664 		{
    665 			foreach( $conf['action'] as $actionName => $actionConfig )
    666 			{
    667 				foreach( $actionConfig as $subActionName=>$subaction )
    668 				{
    669 					if	( is_array($subaction) &&
    670 						  !isset($subaction['goto'  ]) && 
    671 						  !isset($subaction['direct']) &&
    672 						  !isset($subaction['action']) &&
    673 						  !isset($subaction['alias' ]) &&
    674 						  $subActionName != 'menu'            )
    675 					{
    676 						$engine = new template_engine\TemplateEngine();
    677 						$engine->compile( strtolower(str_replace('Action','',$actionName)).'/'.$subActionName);
    678 					}
    679 				}
    680 			}
    681 		}
    682 		
    683 		// Umleiten auf eine definierte URL.s
    684 		$redirect_url = @$conf['security']['logout']['redirect_url'];
    685 
    686 		if	( !empty($redirect_url) )
    687 		{
    688 			header('Location: '.$redirect_url);
    689 			exit;
    690 		}
    691 	}
    692 
    693 	
    694 	
    695 	/**
    696 	 * Benutzer meldet sich ab.
    697 	 */
    698 	function logoutView()
    699 	{
    700 	}
    701 	
    702 
    703 	/**
    704 	 * Ausw�hlen der Administration.
    705 	 */
    706 	function administrationPost()
    707 	{
    708 	}
    709 	
    710 	
    711 	
    712 	/**
    713 	 * Auswaehlen des Benutzer-Profiles.
    714 	 */
    715 	function profilePost()
    716 	{
    717 	}
    718 	
    719 	
    720 	
    721 	/**
    722 	 * Auswaehlen der Startseite.
    723 	 */
    724 	function startPost()
    725 	{
    726 	}
    727 	
    728 	
    729 	
    730 	/**
    731 	 * Ausgeben von maschinenlesbaren Benutzerinformationen.
    732 	 * 
    733 	 * Diese Funktion dient dem Single-Signon f�r fremde Anwendungen, welche
    734 	 * die Benutzerinformationen des angemeldeten Benutzers aus dieser
    735 	 * Anwendung auslesen k�nnen.
    736 	 */
    737 	function userinfo()
    738 	{
    739 		$user = Session::getUser();
    740 		$info = array('username'   => $user->name,
    741 		              'fullname'   => $user->fullname,
    742 		              'mail'       => $user->mail,
    743 		              'telephone'  => $user->tel,
    744 		              'style'      => $user->style,
    745 		              'admin'      => $user->isAdmin?'true':'false',
    746 		              'ldap'       => $user->ldap_dn,
    747 		              'groups'     => implode(',',$user->getGroups()),
    748 		              'description'=> $user->desc
    749 		             );
    750 		        
    751 		// Wenn der HTTP-Parameter "xml" vorhanden ist, dann geben wir die
    752 		// Informationen per XML aus.     
    753 		if	( $this->hasRequestVar('xml') )
    754 		{
    755 			header('Content-Type: text/xml');
    756 			echo '<userinfo>';
    757 			foreach( $info as $n=>$i )
    758 				echo '<'.$n.'>'.$i.'</'.$n.'>'."\n";
    759 			echo '</userinfo>';
    760 			
    761 		}
    762 		
    763 		// Sonst normale Textausgabe im INI-Datei-Format.
    764 		else
    765 		{
    766 			header('Content-Type: text/plain');
    767 			foreach( $info as $n=>$i )
    768 				echo $n.'="'.$i."\"\n";
    769 		}
    770 		
    771 		exit; // Fertig.
    772 	}
    773 	
    774 	
    775 	function project()
    776 	{
    777 		$user = Session::getUser();
    778 		if   ( ! is_object($user) )
    779 		{
    780 			$this->callSubAction('show');
    781 			return;
    782 		}
    783 
    784 		$this->evaluateRequestVars( array('projectid'=>$this->getRequestId()) );
    785 		
    786 		Session::setUser( $user );
    787 	}
    788 
    789 
    790 	function object()
    791 	{
    792 		$user = Session::getUser();
    793 		if   ( ! is_object($user) )
    794 		{
    795 			$this->callSubAction('show');
    796 			return;
    797 		}
    798 		
    799 		$this->evaluateRequestVars( array('objectid'=>$this->getRequestId()) );
    800 
    801 		Session::setUser( $user );
    802 	}
    803 
    804 
    805 	function languagePost()
    806 	{
    807 		$user = Session::getUser();
    808 		if   ( ! is_object($user) )
    809 		{
    810 			throw new \LogicException('No user in session');
    811 			return;
    812 		}
    813 		
    814 		$this->evaluateRequestVars( array(REQ_PARAM_LANGUAGE_ID=>$this->getRequestId()) );
    815 	}
    816 
    817 
    818 	function modelPost()
    819 	{
    820 		$user = Session::getUser();
    821 		if   ( ! is_object($user) )
    822 		{
    823 			$this->callSubAction('show');
    824 			return;
    825 		}
    826 		
    827 		$this->evaluateRequestVars( array(REQ_PARAM_MODEL_ID=>$this->getRequestId()) );
    828 	}
    829 	
    830 
    831 	/**
    832 	 * Auswerten der Request-Variablen.
    833 	 */
    834 	private function evaluateRequestVars( $add = array() )
    835 	{
    836 	}
    837 
    838 
    839 	function switchuser()
    840 	{
    841 		$user = Session::getUser();
    842 		
    843 		if	( ! $user->isAdmin )
    844 			throw new \SecurityException("");
    845 		
    846 		$this->recreateSession();
    847 		
    848 		$newUser = new User( $this->getRequestId() );
    849 		$newUser->load();
    850 		
    851 		$newUser->setCurrent();
    852 	}
    853 	
    854 	
    855 	function showView()
    856 	{
    857 		global $conf;
    858 		global $PHP_AUTH_USER;
    859 		global $PHP_AUTH_PW;
    860 
    861 		$user = Session::getUser();
    862 		// Gast-Login
    863 		if   ( ! is_object($user) )
    864 		{
    865 			if	( $conf['security']['guest']['enable'] )
    866 			{
    867 				$this->setDefaultDb();
    868 				$username = $conf['security']['guest']['user'];
    869 				$user = User::loadWithName($username);
    870 				if	( $user->userid > 0 )
    871 					$user->setCurrent();
    872 				else
    873 				{
    874 					Logger::warn('Guest login failed, user not found: '.$username);
    875 					$this->addNotice('user',$username,'LOGIN_FAILED',OR_NOTICE_WARN,array('name'=>$username) );
    876 					$user = null;
    877 				}
    878 			}
    879 		}
    880 		
    881 		if   ( ! is_object($user) )
    882 		{
    883 			switch( $conf['security']['login']['type'] )
    884 			{
    885 					
    886 				// Authorization ueber HTTP
    887 				//
    888 				case 'http':
    889 					$ok = false;
    890 		
    891 				    if	( isset($_SERVER['PHP_AUTH_USER']) )
    892 				    {
    893 				    	$this->setDefaultDb();
    894 						$ok = $this->checkLogin( $_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW'] );
    895 				    }
    896 				    
    897 					if	( ! $ok )
    898 					{
    899 						header( 'WWW-Authenticate: Basic realm="'.OR_TITLE.' - '.lang('HTTP_REALM').'"' );
    900 						header( 'HTTP/1.0 401 Unauthorized' );
    901 						echo 'Authorization Required!';
    902 						exit;
    903 					}
    904 					break;
    905 					
    906 				case 'form':
    907 					// Benutzer ist nicht angemeldet
    908 					$this->callSubAction( 'showlogin' ); // Anzeigen der Login-Maske
    909 					return;
    910 					break;
    911 					
    912 				default:
    913 					throw new \LogicException('Unknown auth-type: '.$conf['security']['login']['type'].'. Please check the configuration setting /security/login/type' );
    914 			}
    915 		}
    916 		
    917 		if	( $user->mustChangePassword ) 
    918 		{
    919 			$this->addNotice( 'user',$user->name,'PASSWORD_TIMEOUT','warn' );
    920 			$this->callSubAction( 'changepassword' ); // Zwang, das Kennwort zu �ndern.
    921 		}
    922 
    923 		// Seite �ndert sich nur 1x pro Session
    924 		$this->lastModified( $user->loginDate );
    925 
    926 		$this->metaValues();
    927 	}
    928 
    929 
    930 
    931 	function checkMenu( $name )
    932 	{
    933 		global $conf;
    934 		
    935 		switch( $name )
    936 		{
    937 			case 'applications':
    938 				// Men�punkt "Anwendungen" wird nur angezeigt, wenn weitere Anwendungen
    939 				// konfiguriert sind.
    940 				return count(@$conf['applications']) > 0;
    941 
    942 			case 'register': // Registrierung
    943 				// Nur, wenn aktiviert und gegen eigene Datenbank authentisiert wird.
    944 				return @$conf['login']['register'] && @$conf['security']['auth']['type'] == 'database';
    945 
    946 			case 'password': // Kennwort vergessen
    947 				// Nur, wenn aktiviert und gegen eigene Datenbank authentisiert wird.
    948 				// Deaktiviert, falls LDAP-Lookup aktiviert ist.
    949 				return @$conf['login']['send_password'] && @$conf['security']['auth']['type'] == 'database'
    950 				                                        && !@$conf['security']['auth']['userdn'];
    951 				
    952 			case 'administration':
    953 				// "Administration" nat�rlich nur f�r Administratoren.
    954 				return $this->userIsAdmin();
    955 
    956 			case 'login':
    957 				return !@$conf['login']['nologin'];
    958 				
    959 			case 'logout':
    960 				return true;
    961 				
    962 			case 'projectmenu':
    963 				return true;
    964 				
    965 			default:
    966 				return false;
    967 		}	
    968 	}
    969 	
    970 	
    971 	/**
    972 	 * Maske anzeigen, um Benutzer zu registrieren.
    973 	 */
    974 	function register()
    975 	{
    976 		
    977 	}
    978 
    979 	
    980 	/**
    981 	 * Registriercode erzeugen und per E-Mail dem Benutzer mitteilen.
    982 	 * Maske anzeigen, damit Benuter Registriercode anzeigen kann.
    983 	 */
    984 	public function registercode()
    985 	{
    986 		$email_address = $this->getRequestVar('mail','mail');
    987 		
    988 		if	( ! Mail::checkAddress($email_address) )
    989 		{
    990 			$this->addValidationError('mail');
    991 			$this->setTemplateVar('mail',$email_address);
    992 			$this->callSubAction('register');
    993 			return;
    994 		}
    995 		
    996 		
    997 		srand ((double)microtime()*1000003);
    998 		$registerCode = rand();
    999 		
   1000 		Session::set('registerCode',$registerCode                );
   1001 					
   1002 		// E-Mail and die eingegebene Adresse verschicken
   1003 		$mail = new Mail($email_address,
   1004 		                 'register_commit_code','register_commit_code');
   1005 		$mail->setVar('code',$registerCode); // Registrierungscode als Text-Variable
   1006 		
   1007 		if	( $mail->send() )
   1008 		{
   1009 			$this->addNotice('','','mail_sent',OR_NOTICE_OK);
   1010 		}
   1011 		else
   1012 		{
   1013 			$this->addNotice('','','mail_not_sent',OR_NOTICE_ERROR,array(),$mail->error);
   1014 			$this->callSubAction('register');
   1015 			return;
   1016 		}
   1017 	}
   1018 
   1019 	
   1020 	
   1021 	public function registeruserdata()
   1022 	{
   1023 		global $conf;
   1024 
   1025 		Session::set('registerMail',$this->getRequestVar('mail') );
   1026 		// TODO: Attribut "Password" abfragen
   1027 		foreach( $conf['database'] as $dbname=>$dbconf )
   1028 		{
   1029 			if	( is_array($dbconf) && $dbconf['enabled'] )
   1030 				$dbids[$dbname] = $dbconf['description'];
   1031 		}
   1032 
   1033 		$this->setTemplateVar( 'dbids',$dbids );
   1034 		
   1035 		$db = Session::getDatabase();
   1036 		if	( is_object($db) )
   1037 			$this->setTemplateVar('actdbid',$db->id);
   1038 		else
   1039 			$this->setTemplateVar('actdbid',$conf['database']['default']);
   1040 	}
   1041 
   1042 	
   1043 	/**
   1044 	 * Benutzerregistierung.
   1045 	 * Benutzer hat Best�tigungscode erhalten und eingegeben.
   1046 	 */
   1047 	public function registercommit()
   1048 	{
   1049 		global $conf;
   1050 		$this->checkForDb();
   1051 
   1052 		$origRegisterCode  = Session::get('registerCode');
   1053 		$inputRegisterCode = $this->getRequestVar('code');
   1054 		
   1055 		if	( $origRegisterCode != $inputRegisterCode )
   1056 		{
   1057 			// Best�tigungscode stimmt nicht.
   1058 			$this->addValidationError('code','code_not_match');
   1059 			$this->callSubAction('registeruserdata');
   1060 			return;
   1061 		}
   1062 
   1063 		// Best�tigungscode stimmt �berein.
   1064 		// Neuen Benutzer anlegen.
   1065 			
   1066 		if	( !$this->hasRequestVar('username') )
   1067 		{
   1068 			$this->addValidationError('username');
   1069 			$this->callSubAction('registeruserdata');
   1070 			return;
   1071 		}
   1072 		
   1073 		$user = User::loadWithName( $this->getRequestVar('username') );
   1074 		if	( $user->isValid() )
   1075 		{
   1076 			$this->addValidationError('username','USER_ALREADY_IN_DATABASE');
   1077 			$this->callSubAction('registeruserdata');
   1078 			return;
   1079 		}
   1080 		
   1081 		if	( strlen($this->getRequestVar('password')) < $conf['security']['password']['min_length'] )
   1082 		{
   1083 			$this->addValidationError('password','password_minlength',array('minlength'=>$conf['security']['password']['min_length']));
   1084 			$this->callSubAction('registeruserdata');
   1085 			return;
   1086 		}
   1087 		
   1088 		$newUser = new User();
   1089 		$newUser->name = $this->getRequestVar('username');
   1090 		$newUser->add();
   1091 			
   1092 		$newUser->mail     = Session::get('registerMail');
   1093 		$newUser->save();
   1094 			
   1095 		$newUser->setPassword( $this->getRequestVar('password'),true );
   1096 			
   1097 		$this->addNotice('user',$newUser->name,'user_added','ok');
   1098 	}
   1099 
   1100 
   1101 
   1102 	/**
   1103 	 * Vergessenes Kennwort zusenden lassen.
   1104 	 */
   1105 	public function password()
   1106 	{
   1107 		global $conf;
   1108 		
   1109 		// TODO: Attribut "Password" abfragen
   1110 		foreach( $conf['database'] as $dbname=>$dbconf )
   1111 		{
   1112 			if	( is_array($dbconf) && $dbconf['enabled'] )
   1113 				$dbids[$dbname] = $dbconf['description'];
   1114 		}
   1115 
   1116 		$this->setTemplateVar( 'dbids',$dbids );
   1117 		
   1118 		
   1119 		$db = Session::getDatabase();
   1120 		
   1121 		if	( is_object($db) )
   1122 			$this->setTemplateVar('actdbid',$db->id);
   1123 		else
   1124 			$this->setTemplateVar('actdbid',$conf['database']['default']);
   1125 		
   1126 	}	
   1127 	
   1128 	
   1129 	/*
   1130 	function changepassword()
   1131 	{
   1132 	}
   1133 	*/
   1134 	
   1135 	
   1136 	/*
   1137 	function setnewpassword()
   1138 	{
   1139 		$oldPw  = $this->getRequestVar('password_old'  );
   1140 		$newPw1 = $this->getRequestVar('password_new_1');
   1141 		$newPw2 = $this->getRequestVar('password_new_2');
   1142 		
   1143 		if	( $newPw1 == $newPw2 )
   1144 		{
   1145 			// Aktuellen Benutzer aus der Sitzung ermitteln
   1146 			$user = $this->getUserFromSession();
   1147 			
   1148 			// Altes Kennwort pr�fen.
   1149 			$ok = $user->checkPassword( $oldPw );
   1150 			
   1151 			if	( $ok )  // Altes Kennwort ist ok.
   1152 			{
   1153 				$user->setPassword( $newPw1 ); // Setze neues Kennwort
   1154 				$user->mustChangePassword = false;
   1155 				Session::setUser($user);
   1156 				$this->addNotice('user',$user->name,'password_set','ok');
   1157 			}
   1158 			else
   1159 			{
   1160 				// Altes Kennwort falsch.
   1161 				$this->addNotice('user',$user->name,'password_error','error');
   1162 			}
   1163 		}
   1164 		else
   1165 		{
   1166 			// Beide neuen Kennw�rter stimmen nicht �berein
   1167 			$this->addNotice('user',$user->name,'passwords_not_match','error');
   1168 		}
   1169 	}
   1170 	*/
   1171 	
   1172 	
   1173 	/**
   1174 	 * Einen Kennwort-Anforderungscode an den Benutzer senden.
   1175 	 */
   1176 	public function passwordcode()
   1177 	{
   1178 		if	( !$this->hasRequestVar('username') )
   1179 		{
   1180 			$this->addValidationError('username');
   1181 			$this->callSubAction('password');
   1182 			return;
   1183 		}
   1184 		
   1185 		$this->checkForDb();
   1186 
   1187 		$user = User::loadWithName( $this->getRequestVar("username") );
   1188 
   1189 		Password::delay();
   1190 		
   1191 		//		Html::debug($user);
   1192 		if	( $user->isValid() )
   1193 		{
   1194 			srand ((double)microtime()*1000003);
   1195 			$code = rand();
   1196 			$this->setSessionVar("password_commit_code",$code);
   1197 			
   1198 			$eMail = new Mail( $user->mail,'password_commit_code' );
   1199 			$eMail->setVar('name',$user->getName());
   1200 			$eMail->setVar('code',$code);
   1201 			if	( $eMail->send() )
   1202 				$this->addNotice('user',$user->getName(),'mail_sent',OR_NOTICE_OK);
   1203 			else
   1204 				$this->addNotice('user',$user->getName(),'mail_not_sent',OR_NOTICE_ERROR,array(),$eMail->error);
   1205 			
   1206 		}
   1207 		else
   1208 		{
   1209 			//$this->addNotice('','user','username_not_found');
   1210 			// Trotzdem vort�uschen, eine E-Mail zu senden, damit die G�ltigkeit
   1211 			// eines Benutzernamens nicht von au�en gepr�ft werden kann.
   1212 			// 
   1213 			$this->addNotice('user',$this->getRequestVar("username"),'mail_sent');
   1214 		}
   1215 		
   1216 		$this->setSessionVar("password_commit_name",$user->name);
   1217 	}
   1218 
   1219 	
   1220 	
   1221 	/**
   1222 	 * Anzeige Formular zum Eingeben des Kennwort-Codes.
   1223 	 *
   1224 	 */
   1225 	public function passwordinputcode()
   1226 	{
   1227 		
   1228 	}
   1229 	
   1230 	
   1231 	/**
   1232 	 * Neues Kennwort erzeugen und dem Benutzer zusenden.
   1233 	 */
   1234 	public function passwordcommit()
   1235 	{
   1236 		$username = $this->getSessionVar("password_commit_name");
   1237 
   1238 		if	( $this->getRequestVar("code")=='' ||
   1239 			  $this->getSessionVar("password_commit_code") != $this->getRequestVar("code") )
   1240 		{
   1241 			$this->addValidationError('code','PASSWORDCODE_NOT_MATCH');
   1242 			$this->callSubAction('passwordinputcode');
   1243 		  	return;
   1244 		}
   1245 		
   1246 		$user  = User::loadWithName( $username );
   1247 			
   1248 		if	( !$user->isValid() )
   1249 		{
   1250 			// Benutzer konnte nicht geladen werden.
   1251 			$this->addNotice('user',$username,'error',OR_NOTICE_ERROR);
   1252 			return;
   1253 		}
   1254 		
   1255 		$newPw = User::createPassword(); // Neues Kennwort erzeugen.
   1256 		
   1257 		$eMail = new Mail( $user->mail,'password_new' );
   1258 		$eMail->setVar('name'    ,$user->getName());
   1259 		$eMail->setVar('password',$newPw          );
   1260 
   1261 		if	( $eMail->send() )
   1262 		{
   1263 			$user->setPassword( $newPw, false ); // Kennwort muss beim n�. Login ge�ndert werden.
   1264 			$this->addNotice('user',$username,'mail_sent',OR_NOTICE_OK);
   1265 		}
   1266 		else
   1267 		{
   1268 			// Sollte eigentlich nicht vorkommen, da der Benutzer ja auch schon den
   1269 			// Code per E-Mail erhalten hat.
   1270 			$this->addNotice('user',$username,'error',OR_NOTICE_ERROR,array(),$eMail->error);
   1271 		}
   1272 	}
   1273 	
   1274 
   1275 	/**
   1276 	 * Erzeugt eine neue Sitzung.
   1277 	 */
   1278 	private function recreateSession()
   1279 	{
   1280 		
   1281 		// PHP < 4.3.2 kennt die Funktion session_regenerate_id() nicht.
   1282 		if	( version_compare(phpversion(),"4.3.2","<") )
   1283 		{
   1284 			$randlen = 32;
   1285 			$randval = "0123456789abcdefghijklmnopqrstuvwxyz";
   1286 			$newid   = "";
   1287 			for ($i = 1; $i <= $randlen; $i++)
   1288 			{
   1289 				$newid .= substr($randval, rand(0,(strlen($randval) - 1)), 1);
   1290 			}
   1291 			session_id( $newid );
   1292 		}
   1293 		elseif( version_compare(phpversion(),"4.3.2","==") )
   1294 		{
   1295 			session_regenerate_id();
   1296 			
   1297 			// Bug in PHP 4.3.2: Session-Cookie wird nicht neu gesetzt.
   1298 			if ( ini_get("session.use_cookies") )
   1299                 $this->setCookie( session_name(),session_id() );
   1300 		}
   1301 		elseif	( version_compare(phpversion(),"5.1.0",">") )
   1302 		{
   1303 			session_regenerate_id(true);
   1304 		}
   1305 		else
   1306 		{
   1307 			// 5.1.0 > PHP >= 4.3.3
   1308 		}
   1309 	}
   1310 
   1311 	
   1312 
   1313 
   1314 	
   1315 	
   1316 	/**
   1317 	 * Ermittelt die letzten Änderungen, die durch den aktuellen Benutzer im aktuellen Projekt gemacht worden sind.
   1318 	 */
   1319 	public function userprojecttimelineView()
   1320 	{
   1321 		//$project = Session::getProject();
   1322 		//$result = $project->getMyLastChanges();
   1323 		$result = array();
   1324 		
   1325 		$this->setTemplateVar('timeline', $result);
   1326 	}
   1327 
   1328 
   1329 }
   1330 
   1331 
   1332 ?>