openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit c6d5fc0d2056e85645cfa2a331e7b094276e10d8
parent a99215609f725a0b957fbdd6a311b7317d4ea282
Author: dankert <openrat@jandankert.de>
Date:   Fri, 15 Apr 2022 14:51:22 +0200

Refactoring: User,Config and Database info is now stored in the Request, because so there is no session required for clients which are using Basic Authorization.

Diffstat:
Mmodules/cms/Dispatcher.class.php | 49+++++++++++++++++++++++++------------------------
Mmodules/cms/action/Action.class.php | 22+++++-----------------
Mmodules/cms/action/LoginAction.class.php | 2+-
Mmodules/cms/action/ProfileAction.class.php | 7++++---
Mmodules/cms/action/RequestParams.class.php | 37++++++++++++++++++++++++++-----------
Mmodules/cms/action/SearchAction.class.php | 2+-
Mmodules/cms/action/configuration/ConfigurationEditAction.class.php | 5+++--
Mmodules/cms/action/configuration/ConfigurationSrcAction.class.php | 3++-
Mmodules/cms/action/login/LoginLicenseAction.class.php | 2+-
Mmodules/cms/action/login/LoginLoginAction.class.php | 11++++++-----
Mmodules/cms/action/login/LoginLogoutAction.class.php | 3++-
Mmodules/cms/action/login/LoginOidcAction.class.php | 3++-
Mmodules/cms/action/login/LoginUserinfoAction.class.php | 2+-
Mmodules/cms/action/profile/ProfileEditAction.class.php | 3++-
Mmodules/cms/action/profile/ProfilePwAction.class.php | 2+-
Mmodules/cms/action/profile/ProfileUserinfoAction.class.php | 2+-
Mmodules/cms/action/user/UserSwitchAction.class.php | 3++-
Mmodules/cms/auth/InternalAuth.class.php | 4++++
Mmodules/cms/auth/RememberAuth.class.php | 5+++--
Mmodules/cms/base/Configuration.class.php | 3++-
Mmodules/cms/base/DB.class.php | 3++-
Mmodules/cms/base/Startup.class.php | 3++-
Mmodules/cms/generator/Publisher.class.php | 3++-
Mmodules/cms/generator/ValueGenerator.class.php | 11++++++-----
Mmodules/cms/model/BaseObject.class.php | 13+++++++------
Mmodules/cms/model/Project.class.php | 3++-
Mmodules/cms/model/User.class.php | 22++++++++++++----------
Mmodules/cms/model/Value.class.php | 3++-
Mmodules/cms/output/UIOutput.class.php | 4++--
Mmodules/cms/ui/action/index/IndexManifestAction.class.php | 2+-
Mmodules/cms/ui/action/index/IndexShowAction.class.php | 4++--
Mmodules/cms/ui/action/title/TitleShowAction.class.php | 2+-
Amodules/util/Request.class.php | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmodules/util/Session.class.php | 80+++++++++++++++++++------------------------------------------------------------
Mmodules/util/Tree.class.php | 2+-
35 files changed, 222 insertions(+), 170 deletions(-)

diff --git a/modules/cms/Dispatcher.class.php b/modules/cms/Dispatcher.class.php @@ -37,6 +37,7 @@ use LogicException; use util\exception\UIException; use util\exception\SecurityException; use util\json\JSON; +use util\Request; use util\Session; use util\Text; use util\text\TextMessage; @@ -65,9 +66,10 @@ class Dispatcher */ public function doAction() { - // Start the session. - session_name(getenv('CMS_SESSION_NAME') ?: 'or_sid'); - session_start(); + if ( $this->request->withAuthorization ) + ; // No session required (otherwise every API request would create a new session) + else + Session::start(); $this->checkConfiguration(); @@ -166,7 +168,7 @@ class Dispatcher /** - * Make a authentication, if there is a HTTP authorization. + * Make an authentication, if there is a HTTP authorization. */ private function checkLogin() { @@ -177,7 +179,7 @@ class Dispatcher throw new SecurityException('user cannot be authenticated'); $user = User::loadWithName( $this->request->authUser,User::AUTH_TYPE_INTERNAL ); - Session::setUser( $user ); + Request::setUser( $user ); } } @@ -245,7 +247,7 @@ class Dispatcher return Session::get('action'); case 'user': - $user = Session::getUser(); + $user = Request::getUser(); if (is_object($user)) return $user->name; else @@ -260,7 +262,7 @@ class Dispatcher private function checkConfiguration() { - $conf = Session::getConfig(); + $conf = Request::getConfig(); $configFile = getenv( 'CMS_CONFIG_FILE' ) ?: Startup::DEFAULT_CONFIG_FILE; @@ -284,7 +286,7 @@ class Dispatcher // Sprache lesen $languages = []; - if ( $user = Session::getUser() ) + if ( $user = Request::getUser() ) $languages[] = $user->language; // user language has precedence. else { $i18nConfig = (new Config($conf))->subset('i18n'); @@ -319,7 +321,7 @@ class Dispatcher // Schreibt die Konfiguration in die Sitzung. Diese wird anschliessend nicht // mehr veraendert. - Session::setConfig($conf); + Request::setConfig($conf); } } @@ -431,8 +433,8 @@ class Dispatcher if ( $databaseId = $this->request->getDatabaseId() ) $possibleDbIds[] = $databaseId; - if ( Session::getDatabaseId() ) - $possibleDbIds[] = Session::getDatabaseId(); + if ( $dbId = Request::getDatabaseId() ) + $possibleDbIds[] = $dbId; if ( Cookie::has(Action::COOKIE_DB_ID) ) $possibleDbIds[] = Cookie::get(Action::COOKIE_DB_ID); @@ -441,32 +443,31 @@ class Dispatcher $possibleDbIds[] = $enabledDbids[0]; - foreach( $possibleDbIds as $dbid ) { - if ( in_array($dbid,$enabledDbids) ) { + foreach( $possibleDbIds as $dbId ) { + if ( in_array($dbId,$enabledDbids) ) { - $dbConfig = $allDbConfig->subset( $dbid ); + $dbConfig = $allDbConfig->subset( $dbId ); try { $key = $this->request->isAction && !Startup::readonly() ?'write':'read'; $db = new Database( $dbConfig->merge( $dbConfig->subset($key))->getConfig() ); - $db->id = $dbid; + $db->id = $dbId; } catch(\Exception $e) { - throw new UIException(Messages::DATABASE_CONNECTION_ERROR, "Could not connect to DB " . $dbid, [], $e); + throw new UIException(Messages::DATABASE_CONNECTION_ERROR, "Could not connect to DB " . $dbId, [], $e); } // Is this the first time we are connected to this database in this session? - $firstDbContact = Session::getDatabaseId() != $dbid; + $firstDbContact = Request::getDatabaseId() != $dbId; - Session::setDatabaseId( $dbid ); - Session::setDatabase ( $db ); + Request::setDatabase ( $db ); if ( $firstDbContact ) // Test, if we must install/update the database scheme. - $this->updateDatabase( $dbid ); + $this->updateDatabase( $dbId ); return; } @@ -509,7 +510,7 @@ class Dispatcher { // Verbindung zur Datenbank // - $db = Session::getDatabase(); + $db = Request::getDatabase(); if (is_object($db)) { // Transactions are only needed for POST-Request @@ -529,7 +530,7 @@ class Dispatcher private function commitDatabaseTransaction() { - $db = Session::getDatabase(); + $db = Request::getDatabase(); if (is_object($db)) // Transactions were only started for POST-Request @@ -541,7 +542,7 @@ class Dispatcher private function rollbackDatabaseTransaction() { - $db = Session::getDatabase(); + $db = Request::getDatabase(); if (is_object($db)) // Transactions were only started for POST-Request @@ -579,7 +580,7 @@ class Dispatcher $date = explode(" ",$micro_date); $filename = $dir.'/'.$auditConfig->get('prefix','audit' ).'-'.date('c',$date[1]).'-'.$date[0].'.json'; - $user = Session::getUser(); + $user = Request::getUser(); $data = array( 'database' => array( diff --git a/modules/cms/action/Action.class.php b/modules/cms/action/Action.class.php @@ -11,6 +11,7 @@ use logger\Logger; use util\Cookie; use util\ClassUtils; use util\exception\SecurityException; +use util\Request; use util\Session; use util\text\TextMessage; @@ -73,7 +74,7 @@ abstract class Action public function __construct() { - $this->currentUser = Session::getUser(); + $this->currentUser = Request::getUser(); $this->response = new Response(); } @@ -219,19 +220,7 @@ abstract class Action */ protected function userIsAdmin() { - $user = $this->getUserFromSession(); - - return is_object($user) && $user->isAdmin; - } - - - /** - * Ermitteln des Benutzerobjektes aus der Session - * @return User - */ - protected function getUserFromSession() - { - return Session::getUser(); + return $this->currentUser && $this->currentUser->isAdmin; } @@ -241,9 +230,8 @@ abstract class Action */ protected function getCurrentUserId() { - $user = $this->getUserFromSession(); - if ( $user ) - return $user->userid; + if ( $this->currentUser ) + return $this->currentUser->userid; else return null; } diff --git a/modules/cms/action/LoginAction.class.php b/modules/cms/action/LoginAction.class.php @@ -89,7 +89,7 @@ class LoginAction extends BaseAction $conf = Configuration::rawConfig(); // Diese Seite gilt pro Sitzung. - $user = Session::getUser(); + $user = $this->currentUser; $userGroups = $user->getGroups(); $this->lastModified( $user->loginDate ); diff --git a/modules/cms/action/ProfileAction.class.php b/modules/cms/action/ProfileAction.class.php @@ -30,6 +30,7 @@ use security\Base2n; use util\exception\SecurityException; use util\exception\ValidationException; use util\mail\Mail; +use util\Request; use util\Session; use util\UIUtils; @@ -56,7 +57,7 @@ class ProfileAction extends BaseAction { parent::__construct(); - $this->user = Session::getUser(); + $this->user = $this->currentUser; } @@ -68,11 +69,11 @@ class ProfileAction extends BaseAction protected function setLanguage($languageISOcode ) { // Overwrite configuration - $conf = Session::getConfig(); + $conf = Request::getConfig(); $language = new Language(); $conf['language'] = $language->getLanguage($languageISOcode); $conf['language']['language_code'] = $languageISOcode; - Session::setConfig($conf); + Request::setConfig($conf); } diff --git a/modules/cms/action/RequestParams.class.php b/modules/cms/action/RequestParams.class.php @@ -2,14 +2,10 @@ namespace cms\action; -use cms\auth\Auth; -use cms\auth\InternalAuth; -use util\exception\SecurityException; use util\exception\ValidationException; use util\json\JSON; use util\mail\Mail; use util\Text; -use util\XML; use util\YAML; @@ -31,6 +27,11 @@ class RequestParams public $isAction; + /** + * Request headers. + * @var array + */ + public $headers; public $authUser; public $authPassword; @@ -57,13 +58,7 @@ class RequestParams $this->isAction = @$_SERVER['REQUEST_METHOD'] == 'POST'; $this->headers = array_change_key_case(getallheaders(), CASE_LOWER); - if ( @$this->headers['authorization'] ) { - $this->withAuthorization = true; - // Only supporting Basic Auth - // Maybe in the future we will support JWT Bearer tokens... - if ( substr( $this->headers['authorization'],0,6 ) == 'Basic ' ) - list($this->authUser,$this->authPassword) = explode(':',base64_decode( substr( $this->headers['authorization'],6) ) ); - } + $this->tryBasicAuthorization(); $this->setParameterStore(); @@ -372,4 +367,24 @@ class RequestParams $this->action = $action; $this->method = $method; } + + + /** + * Basic Authorization. + * + * Try login with basic authorization. This is useful for API clients, they to not need to track a session with cookies. + */ + private function tryBasicAuthorization() + { + if ( $auth = @$this->headers['authorization'] ) { + + $this->withAuthorization = true; + if ( substr( $auth,0,6 ) == 'Basic ' ) + list($this->authUser,$this->authPassword) = explode(':',base64_decode( substr( $this->headers['authorization'],6) ) ); + else + // Only supporting Basic Auth + // Maybe in the future we will support JWT Bearer tokens... + error_log('Only supporting basic authorization. Authorization header will be ignored.'); + } + } } \ No newline at end of file diff --git a/modules/cms/action/SearchAction.class.php b/modules/cms/action/SearchAction.class.php @@ -61,7 +61,7 @@ class SearchAction extends BaseAction public function editView() { - $user = Session::getUser(); + $user = $this->currentUser; $this->setTemplateVar( 'users' ,User::listAll() ); $this->setTemplateVar( 'act_userid',$user->userid ); } diff --git a/modules/cms/action/configuration/ConfigurationEditAction.class.php b/modules/cms/action/configuration/ConfigurationEditAction.class.php @@ -4,6 +4,7 @@ use cms\action\ConfigurationAction; use cms\action\Method; use cms\base\DefaultConfig; use util\ArrayUtils; +use util\Request; use util\Session; class ConfigurationEditAction extends ConfigurationAction { @@ -12,7 +13,7 @@ class ConfigurationEditAction extends ConfigurationAction { public function view() { $defaultConfig = DefaultConfig::get();; - $currentConfig = Session::getConfig(); + $currentConfig = Request::getConfig(); $currentConfig['system'] = $this->getSystemConfiguration(); @@ -22,7 +23,7 @@ class ConfigurationEditAction extends ConfigurationAction { $pad = str_repeat("\xC2\xA0",10); // Hard spaces $flatDefaultConfig = ArrayUtils::dryFlattenArray( $defaultConfig , $pad ); - $flatCMSConfig = ArrayUtils::dryFlattenArray( Session::getConfig(), $pad ); + $flatCMSConfig = ArrayUtils::dryFlattenArray( Request::getConfig(), $pad ); $flatConfig = ArrayUtils::dryFlattenArray( $currentConfig , $pad ); $config = array_map( function($key,$value) use ($flatConfig,$flatCMSConfig,$flatDefaultConfig) { diff --git a/modules/cms/action/configuration/ConfigurationSrcAction.class.php b/modules/cms/action/configuration/ConfigurationSrcAction.class.php @@ -2,12 +2,13 @@ namespace cms\action\configuration; use cms\action\ConfigurationAction; use cms\action\Method; +use util\Request; use util\Session; class ConfigurationSrcAction extends ConfigurationAction implements Method { public function view() { - $conf = Session::getConfig(); + $conf = Request::getConfig(); unset( $conf['language']); // Mask passwords. diff --git a/modules/cms/action/login/LoginLicenseAction.class.php b/modules/cms/action/login/LoginLicenseAction.class.php @@ -40,7 +40,7 @@ class LoginLicenseAction extends LoginAction { $this->setTemplateVar('cms_version' , Configuration::Conf()->subset('application')->get('version' ) ); $this->setTemplateVar('cms_operator', Configuration::Conf()->subset('application')->get('operator') ); - $user = Session::getUser() ?: new User(); // empty user object as default. + $user = $this->currentUser ?: new User(); // empty user object as default. $this->setTemplateVar('user_login' , $user->loginDate ); $this->setTemplateVar('user_name' , $user->name ); diff --git a/modules/cms/action/login/LoginLoginAction.class.php b/modules/cms/action/login/LoginLoginAction.class.php @@ -19,6 +19,7 @@ use util\exception\ObjectNotFoundException; use util\exception\SecurityException; use util\exception\ValidationException; use util\mail\Mail; +use util\Request; use util\Session; use util\text\TextMessage; @@ -54,8 +55,8 @@ class LoginLoginAction extends LoginAction implements Method { $this->setTemplateVar( 'dbids',$dbids ); // Database was already connected in the Dispatcher. So we MUST have a db connection here. - $db = Session::getDatabase(); - $this->setTemplateVar('dbid',$db->id); + $dbId = Request::getDatabaseId(); + $this->setTemplateVar('dbid',$dbId); $this->setTemplateVar('register' ,$loginConfig->get('register' )); $this->setTemplateVar('send_password',$loginConfig->get('send_password')); @@ -73,7 +74,7 @@ class LoginLoginAction extends LoginAction implements Method { public function post() { - Session::setUser(null); // Altes Login entfernen. + Request::setUser(null); // Altes Login entfernen. if ( Configuration::subset('login')->is('nologin',false ) ) throw new SecurityException('login disabled'); @@ -207,12 +208,12 @@ class LoginLoginAction extends LoginAction implements Method { $this->addNoticeFor( $user,Messages::LOGIN_OK, array('name' => $user->getName() )); // Setting the user-defined language - $config = Session::getConfig(); + $config = Request::getConfig(); $language = new Language(); $config['language'] = $language->getLanguage($user->language); $config['language']['language_code'] = $user->language; - Session::setConfig( $config ); + Request::setConfig( $config ); return; // everything ok, user logged in. } diff --git a/modules/cms/action/login/LoginLogoutAction.class.php b/modules/cms/action/login/LoginLogoutAction.class.php @@ -6,6 +6,7 @@ use cms\action\Method; use cms\base\Configuration; use language\Messages; use util\Cookie; +use util\Request; use util\Session; @@ -27,7 +28,7 @@ class LoginLogoutAction extends LoginAction implements Method { // Cookie mit Logintoken löschen. $this->setCookie(Action::COOKIE_TOKEN ); - Session::setUser(null); + Request::setUser(null); $this->addNoticeFor( $this->currentUser, Messages::LOGOUT_OK ); } diff --git a/modules/cms/action/login/LoginOidcAction.class.php b/modules/cms/action/login/LoginOidcAction.class.php @@ -8,6 +8,7 @@ use cms\base\Startup; use cms\model\User; use Exception; use openid_connect\OpenIDConnectClient; +use util\Request; use util\Session; /** @@ -58,7 +59,7 @@ class LoginOidcAction extends LoginAction implements Method { } - Session::setUser( $user ); + Request::setUser( $user ); } catch( Exception $e) { throw new \RuntimeException('OpenId-Connect authentication failed',0,$e); diff --git a/modules/cms/action/login/LoginUserinfoAction.class.php b/modules/cms/action/login/LoginUserinfoAction.class.php @@ -8,7 +8,7 @@ use util\Session; class LoginUserinfoAction extends LoginAction implements Method { public function view() { - $user = Session::getUser(); + $user = $this->currentUser; $info = array('username' => $user->name, 'fullname' => $user->fullname, diff --git a/modules/cms/action/profile/ProfileEditAction.class.php b/modules/cms/action/profile/ProfileEditAction.class.php @@ -7,6 +7,7 @@ use cms\base\Startup; use language\Language; use language\Messages; use security\Base2n; +use util\Request; use util\Session; class ProfileEditAction extends ProfileAction implements Method { @@ -86,7 +87,7 @@ class ProfileEditAction extends ProfileAction implements Method { }); // Overwrite user in session with new settings. - Session::setUser( $this->user ); + Request::setUser( $this->user ); $this->user->persist(); $this->addNoticeFor( $this->user,Messages::SAVED); diff --git a/modules/cms/action/profile/ProfilePwAction.class.php b/modules/cms/action/profile/ProfilePwAction.class.php @@ -14,7 +14,7 @@ class ProfilePwAction extends ProfileAction implements Method { // // Hier wird festgestellt, ob der Benutzer sich über die interne Datenbank angemeldet hat. // Nur dann kann man auch sein Kennwort ändern. - $user = $this->getUserFromSession(); + $user = $this->currentUser; $pwchangePossible = $user->type == User::AUTH_TYPE_INTERNAL; $this->setTemplateVar('pwchange_enabled', $pwchangePossible); } diff --git a/modules/cms/action/profile/ProfileUserinfoAction.class.php b/modules/cms/action/profile/ProfileUserinfoAction.class.php @@ -18,7 +18,7 @@ class ProfileUserinfoAction extends ProfileAction implements Method { */ public function view() { - $user = Session::getUser(); + $user = $this->currentUser; $currentStyle = $this->getUserStyle($user); $this->setTemplateVar('style',$currentStyle); diff --git a/modules/cms/action/user/UserSwitchAction.class.php b/modules/cms/action/user/UserSwitchAction.class.php @@ -3,6 +3,7 @@ namespace cms\action\user; use cms\action\Method; use cms\action\UserAction; use language\Messages; +use util\Request; use util\Session; @@ -14,6 +15,6 @@ class UserSwitchAction extends UserAction implements Method { $this->addNoticeFor( $this->user,Messages::USER_LOGIN ); // Und in der Sitzung speichern. - Session::setUser( $this->user ); + Request::setUser( $this->user ); } } diff --git a/modules/cms/auth/InternalAuth.class.php b/modules/cms/auth/InternalAuth.class.php @@ -42,11 +42,15 @@ SQL // Benutzer ist nicht vorhanden. // Trotzdem das Kennwort hashen, um Timingattacken zu verhindern. $unusedHash = Password::hash(User::pepperPassword($password), Password::bestAlgoAvailable()); + if ( DEVELOPMENT ) + Logger::debug('user not found'); return Auth::STATUS_FAILED ; } $lockedUntil = $row_user['password_locked_until']; if ( $lockedUntil && $lockedUntil > Startup::getStartTime() ) { + if ( DEVELOPMENT ) + Logger::debug('user account ist locked until '.date('r',$lockedUntil)); return Auth::STATUS_FAILED + Auth::STATUS_ACCOUNT_LOCKED; // Password is locked } diff --git a/modules/cms/auth/RememberAuth.class.php b/modules/cms/auth/RememberAuth.class.php @@ -12,6 +12,7 @@ use logger\Logger; use util\Cookie; use security\Password; use \util\exception\ObjectNotFoundException; +use util\Request; use util\Session; use util\text\TextMessage; @@ -117,7 +118,7 @@ SQL protected function makeDBWritable( $dbid ) { - $oldDB = Session::getDatabase(); + $oldDB = Request::getDatabase(); if ( $oldDB ) { $oldDB->rollback(); $oldDB->disconnect(); @@ -130,6 +131,6 @@ SQL $writableDB->id = $dbid; $writableDB->start(); - Session::setDatabase( $writableDB ); + Request::setDatabase( $writableDB ); } } \ No newline at end of file diff --git a/modules/cms/base/Configuration.class.php b/modules/cms/base/Configuration.class.php @@ -3,6 +3,7 @@ namespace cms\base; use configuration\Config; +use util\Request; use util\Session; class Configuration { @@ -29,7 +30,7 @@ class Configuration { private static function getConfig() { - return Session::getConfig(); + return Request::getConfig(); } diff --git a/modules/cms/base/DB.class.php b/modules/cms/base/DB.class.php @@ -3,6 +3,7 @@ namespace cms\base; use RuntimeException; +use util\Request; use util\Session; class DB { @@ -23,7 +24,7 @@ class DB { */ public static function get() { - $db = Session::getDatabase(); + $db = Request::getDatabase(); if (!is_object($db)) throw new RuntimeException('no database available'); diff --git a/modules/cms/base/Startup.class.php b/modules/cms/base/Startup.class.php @@ -20,6 +20,7 @@ namespace cms\base; use ErrorException; use logger\Logger; use util\exception\ValidationException; +use util\Request; use util\Session; class Startup { @@ -211,7 +212,7 @@ class Startup { // Aktuelle Datenbankverbindung ist readonly. //$db = DB::get(); - $db = Session::getDatabase(); + $db = Request::getDatabase(); if ($db && isset($db->conf['readonly']) && $db->conf['readonly']) return true; diff --git a/modules/cms/generator/Publisher.class.php b/modules/cms/generator/Publisher.class.php @@ -13,6 +13,7 @@ use cms\model\Project; use logger\Logger; use cms\generator\target\TargetFactory; use util\exception\PublisherException; +use util\Request; use util\Session; use util\text\TextMessage; use util\text\variables\VariableResolver; @@ -140,7 +141,7 @@ class Publisher Logger::debug( TextMessage::create('Executing system command: ${0}',[$systemCommand]) ); /** @var ModelBase $baseObjectToEnv */ - foreach (['user' => Session::getUser(), + foreach (['user' => Request::getUser(), 'project' => $this->project] as $key => $baseObjectToEnv) { diff --git a/modules/cms/generator/ValueGenerator.class.php b/modules/cms/generator/ValueGenerator.class.php @@ -29,6 +29,7 @@ use util\exception\ObjectNotFoundException; use util\exception\PublisherException; use util\Html; use util\Http; +use util\Request; use util\Text; use util\Transformer; @@ -971,27 +972,27 @@ class ValueGenerator extends BaseGenerator break; case 'act_user_username': - $user = \util\Session::getUser(); + $user = Request::getUser(); if ( $user ) $inhalt = $user->name; break; case 'act_user_fullname': - $user = \util\Session::getUser(); + $user = Request::getUser(); if ( $user ) $inhalt = $user->fullname; break; case 'act_user_mail': - $user = \util\Session::getUser(); + $user = Request::getUser(); if ( $user ) $inhalt = $user->mail; break; case 'act_user_desc': - $user = \util\Session::getUser(); + $user = Request::getUser(); if ( $user ) $inhalt = $user->desc; break; case 'act_user_tel': - $user = \util\Session::getUser(); + $user = Request::getUser(); if ( $user ) $inhalt = $user->tel; break; diff --git a/modules/cms/model/BaseObject.class.php b/modules/cms/model/BaseObject.class.php @@ -9,6 +9,7 @@ use cms\base\Startup; use cms\generator\Publisher; use util\ArrayUtils; use phpseclib\Math\BigInteger; +use util\Request; use util\text\variables\VariableResolver; use util\YAML; @@ -241,7 +242,7 @@ class BaseObject extends ModelBase { if ( is_null($this->aclMask) ) { - $user = \util\Session::getUser(); + $user = Request::getUser(); $this->aclMask = 0; @@ -773,7 +774,7 @@ SQL $stmt->setInt ('parentid',$this->parentid ); - $user = \util\Session::getUser(); + $user = Request::getUser(); $this->lastchangeUser = $user; $this->lastchangeDate = Startup::now(); $stmt->setString('filename' , $this->filename ); @@ -802,7 +803,7 @@ SQL ' lastchange_userid = {userid} '. ' WHERE id={objectid}'); - $user = \util\Session::getUser(); + $user = Request::getUser(); $this->lastchangeUser = $user; $this->lastchangeDate = Startup::now(); $userid = $this->lastchangeUser ? $this->lastchangeUser->userid : null; @@ -840,7 +841,7 @@ SQL ' published_userid = {userid} '. ' WHERE id={objectid}'); - $user = \util\Session::getUser(); + $user = Request::getUser(); $this->publishedUser = $user; $this->publishedDate = Startup::now(); @@ -946,7 +947,7 @@ SQL SQL ); - $user = \util\Session::getUser(); + $user = Request::getUser(); $currentUserId = $user ? $user->userid : 0; if ( !$this->parentid ) @@ -980,7 +981,7 @@ SQL */ private function grantToActualUser() { - $user = \util\Session::getUser(); + $user = Request::getUser(); if ( $user ) { // User logged in? diff --git a/modules/cms/model/Project.class.php b/modules/cms/model/Project.class.php @@ -6,6 +6,7 @@ use cms\base\DB; use database\Database; use logger\Logger; use util\FileUtils; +use util\Request; use util\Session; @@ -846,7 +847,7 @@ SQL $sql->setInt( 'languageid', 0 ); - $user = Session::getUser(); + $user = Request::getUser(); $sql->setInt( 'userid', $user->userid ); return $sql->getAll(); diff --git a/modules/cms/model/User.class.php b/modules/cms/model/User.class.php @@ -25,6 +25,7 @@ use cms\base\Language; use language\Messages; use security\Password; use util\exception\ObjectNotFoundException; +use util\Request; /** @@ -153,7 +154,7 @@ SQL { $this->loginDate = time(); - \util\Session::setUser( $this ); + Request::setUser( $this ); } @@ -728,16 +729,21 @@ SQL /** - * Setzt ein neues Kennwort fuer diesen Benutzer. + * Sets a new password for the user. + * + * if the user account was locked it will be unlocked. * * @param $password string new password * @param $forever int true, wenn Kennwort dauerhaft. */ public function setPassword($password, $forever = true ) { - $sql = DB::sql( 'UPDATE {{user}} SET password_hash={password},password_algo={algo},password_expires={expires} '. - 'WHERE id={userid}' ); - + $sql = DB::sql( <<<SQL + UPDATE {{user}} + SET password_hash={password}, password_algo={algo}, password_expires={expires}, password_fail_count=0, password_locked_until=NULL + WHERE id={userid} +SQL + ); if ( $forever ) { $algo = Password::bestAlgoAvailable(); $expire = null; @@ -749,11 +755,7 @@ SQL } // Hashsumme für Kennwort erzeugen - if ( $expire == null ) - $sql->setNull('expires'); - else - $sql->setInt('expires',$expire); - + $sql->setIntOrNull('expires',$expire); $sql->setInt ('algo' ,$algo ); $sql->setString('password',Password::hash(User::pepperPassword($password),$algo) ); $sql->setInt ('userid' ,$this->userid ); diff --git a/modules/cms/model/Value.class.php b/modules/cms/model/Value.class.php @@ -9,6 +9,7 @@ use cms\macros\MacroRunner; use \util\exception\ObjectNotFoundException; use logger\Logger; use util\exception\GeneratorException; +use util\Request; use util\Text; use util\Html; use util\Http; @@ -294,7 +295,7 @@ SQL $stmt->setBoolean( 'publish' ,$this->publish ); $stmt->setInt ( 'lastchange_date' ,Startup::now() ); - $user = \util\Session::getUser(); + $user = Request::getUser(); $stmt->setIntOrNull( 'lastchange_userid',$user?$user->userid:null ); // user may be null, if a guest is saving. $stmt->execute(); diff --git a/modules/cms/output/UIOutput.class.php b/modules/cms/output/UIOutput.class.php @@ -16,7 +16,7 @@ use \util\exception\ObjectNotFoundException; use util\exception\UIException; use util\exception\SecurityException; use template_engine\engine\TemplateEngine; -use util\Session;use util\text\TextMessage; +use util\Request;use util\Session;use util\text\TextMessage; /** @@ -80,7 +80,7 @@ class UIOutput extends BaseOutput */ protected static function getCustomTimezone() { - $user = Session::getUser(); // the user timezone has precedence. + $user = Request::getUser(); // the user timezone has precedence. if ( $user && $user->timezone && in_array( $user->timezone,timezone_identifiers_list() ) ) // user is set and a timezone is set and timezone is valid return( $user->timezone ); // Timezone from user setting elseif ( $configuredTimezone = Configuration::subset('ui')->get('timezone') ) diff --git a/modules/cms/ui/action/index/IndexManifestAction.class.php b/modules/cms/ui/action/index/IndexManifestAction.class.php @@ -33,7 +33,7 @@ use \util\exception\ObjectNotFoundException; class IndexManifestAction extends IndexAction implements Method { public function view() { - $user = Session::getUser(); + $user = $this->currentUser; if ( $user ) $this->lastModified( C::subset('config')->get('last_modification_time',time() ) ); diff --git a/modules/cms/ui/action/index/IndexShowAction.class.php b/modules/cms/ui/action/index/IndexShowAction.class.php @@ -29,7 +29,7 @@ class IndexShowAction extends IndexAction implements Method { $this->addContentSecurityPolicy(); - $user = Session::getUser(); + $user = $this->currentUser; // Is a user logged in? if ( !is_object($user) ) @@ -37,7 +37,7 @@ class IndexShowAction extends IndexAction implements Method { // Lets try an auto login. $this->tryAutoLogin(); - $user = Session::getUser(); + $user = $this->currentUser; } $configLastModificationTime = C::subset('config')->get('last_modification_time', 0); diff --git a/modules/cms/ui/action/title/TitleShowAction.class.php b/modules/cms/ui/action/title/TitleShowAction.class.php @@ -14,7 +14,7 @@ class TitleShowAction extends TitleAction implements Method { $this->setTemplateVar('buildinfo',Startup::TITLE.' '.Startup::VERSION.' - build date '.Startup::DATE ); - $user = Session::getUser(); + $user = $this->currentUser; if ( !is_object($user) ) { diff --git a/modules/util/Request.class.php b/modules/util/Request.class.php @@ -0,0 +1,67 @@ +<?php + +namespace util; + +use cms\model\User; +use database\Database; +use security\Password; + + +/** + * Request + * + */ +class Request +{ + private static $user; + private static $config; + private static $databaseId; + + /** + * Database object. + * Request scope. + * @var + */ + private static $database; + + public static function setConfig($config ) { + self::$config = $config; + Session::set( Session::KEY_CONFIG,$config ); + } + public static function getConfig() { + return self::$config ?: Session::get( Session::KEY_CONFIG ); + } + + public static function setUser( $user ) { + self::$user = $user; + Session::set( Session::KEY_USER, $user ); + } + public static function getUser() { + return self::$user ?: Session::get( Session::KEY_USER ); + } + + public static function getDatabaseId() { + return self::$databaseId ?: Session::get( Session::KEY_DBID ); + } + + /** + * @return Database + */ + public static function getDatabase() + { + return self::$database; + } + + /** + * @param $db Database + * @return void + */ + public static function setDatabase($db ) + { + self::$databaseId = $db->id; + Session::set( Session::KEY_DBID,self::$databaseId ); + + self::$database = $db; + } +} + diff --git a/modules/util/Session.class.php b/modules/util/Session.class.php @@ -4,6 +4,7 @@ namespace util; use cms\model\User; +use security\Password; /** @@ -31,9 +32,12 @@ class Session const KEY_REGISTER_MAIL = 'register_mail'; const KEY_MAIL_CHANGE_CODE = 'mail_change_code'; const KEY_MAIL_CHANGE_MAIL = 'mail_change_mail'; + const KEY_TOKEN = 'token'; const PRAEFIX = 'ors_'; + private static $sessionStarted; + public static function get($var) { $SESS = &$_SESSION; @@ -52,66 +56,6 @@ class Session /** - * @return array - */ - public static function getConfig() - { - return Session::get(self::KEY_CONFIG); - } - - public static function setConfig($var) - { - Session::set(self::KEY_CONFIG, $var); - } - - - /** - * Current user. - * - * Gets the current user from session or <code>null</code>, if no user is present. - * - * @return User|null - */ - public static function getUser() - { - return Session::get(self::KEY_USER); - } - - public static function setUser($var) - { - Session::set(self::KEY_USER, $var); - } - - - /** - * @return \database\Database - */ - public static function getDatabase() - { - return Session::get(self::KEY_DB); - } - - public static function setDatabase($var) - { - Session::set(self::KEY_DB, $var); - } - - - /** - * @return String DB-Id - */ - public static function getDatabaseId() - { - return Session::get(self::KEY_DBID); - } - - public static function setDatabaseId($var) - { - Session::set(self::KEY_DBID, $var); - } - - - /** * Schliesst die aktuelle Session * * Diese Funktion sollte so schnell wie moeglich aufgerufen werden, da vorher @@ -122,11 +66,25 @@ class Session public static function close() { session_write_close(); + self::$sessionStarted = false; } public static function token() { - return substr(session_id(), -10); + return self::get( self::KEY_TOKEN ); + } + + + public static function start() + { + // Start the session. + session_name(getenv('CMS_SESSION_NAME') ?: 'or_sid'); + session_start(); + + if ( ! self::token() ) + self::set( self::KEY_TOKEN,Password::randomHexString(15 ) ); + + self::$sessionStarted = true; } } diff --git a/modules/util/Tree.class.php b/modules/util/Tree.class.php @@ -38,7 +38,7 @@ class Tree public function __construct() { // Feststellen, ob der angemeldete Benutzer ein Administrator ist - $user = Session::getUser(); + $user = Request::getUser(); $this->userIsAdmin = is_object($user) && $user->isAdmin; }