* @license PHP License * @package WB * @subpackage content */ /** * Load classes */ WBClass::load( 'WBUser' ); /** * User Auth * * The current user * * @version 0.4.3 * @package WB * @subpackage content */ class WBUser_Auth extends WBUser { /** * singleton * @var WBUser_Auth */ static private $current; /** * session object * @var patSession_Storage */ protected $sess; /** * logger * @var WBLog */ protected $log; /** * Private constructor * * Load authenticated user from session */ private function __construct() { WBClass::load('WBLog'); $this->log = WBLog::start(__CLASS__); $this->sess = WBClass::create('patSession'); $id = $this->sess->get('wb.user.auth.id'); $log = array( 'action' => 'continue', 'id' => $id ); if ($id) { $this->id = $id; $this->data = $this->sess->get('wb.user.auth.data'); $this->group = $this->sess->get('wb.user.auth.group'); $mandatorId = $this->sess->get('wb.user.auth.mandatorid'); $storage = $this->getStorageModule(); $storage->setMandatorId($mandatorId); $storage->populate($this->id, $this->data, $this->group); } $this->log->notice( $log ); } /** * get instance * * Implements global access method of singleton pattern * * @return WBUser_Auth */ static public function getCurrent() { if(self::$current) { return self::$current; } self::$current = new WBUser_Auth(); return self::$current; } /** * check whether user is logged in * * Use this to see if current user is well known * * @return bool true in case the user is logged in, false otherwise */ public function isAuthenticated() { if ($this->id === null) { return false; } return true; } /** * Set Mandators of User * * @see WBUser_Storage::setMandator() * @param string */ public function setMandatorId($id) { if (!$this->isAuthenticated()) { return false; } $this->sess->set('wb.user.auth.mandatorid', $id); parent::setMandatorId($id); } /** * Get Mandators of User * * @see WBUser_Storage::getMandator() * @return string */ public function getMandatorId() { return $this->sess->get('wb.user.auth.mandatorid'); } /** * login user * * Allows annonymous user to log in. Provide login data to log in. * Login data usually contains username (nickname) and a password. * Still, this method is just a wrapper for the actual authentication * module. Therefore it simply passes authentication data to the module. * * @see isAuthenticated() * @see logout() * @todo implement authentication module * @param array anything to log in with * @return string|null either the user id on success, or null * @see WBUser_Session::onLogin() */ public function login($data) { // already logged in if ($this->id !== null) { return $this->id; } // check credentials if (!isset($data['password'])) { return null; } $log = array( 'action' => 'login', 'status' => 'user_not_found', 'id' => '', 'nickname' => '', 'email' => '', 'approved' => 0, 'enabled' => 0 ); // login with e-mail address or nickname if (isset($data['nicknameoremail'])) { if (strstr($data['nicknameoremail'], '@')) { $data['email'] = $data['nicknameoremail']; $log['email'] = $data['email']; } else { $data['nickname'] = $data['nicknameoremail']; $log['nickname'] = $data['nickname']; } } // as concrete storage class for to authenticate user $storage = $this->getStorageModule(); $id = $storage->find($data); if (!$id) { $this->log->warn($log); return null; } $this->id = $id; $this->data = $storage->get(); $log['id'] = $this->id; $log['nickname'] = $this->data['nickname']; $log['email'] = $this->data['email']; $log['approved'] = $this->data['approved']; $log['enabled'] = $this->data['enabled']; $log['mandator'] = '-1'; // check approved flags if (!$log['enabled'] || ! $log['approved']) { $this->id = null; $this->data = array(); $log['status'] = 'user_not_allowed'; $this->log->warn($log); return null; } // verfiy password $hash = $storage->getPasswordHash($data['password']); if ($this->data['password'] != $hash) { $this->id = null; $this->data = array(); $log['status'] = 'wrong_password'; $this->log->warn($log); return null; } $save = array('lastlogin' => gmdate('Y-m-d H:i:s')); // automigrate password to new algorithm after login $migrate = intval(WBParam::get('wb/user/password/algomigrate', 0)); if (0 < $migrate) { $algo = WBParam::get('wb/user/password/algo', ''); if (!empty($algo) && $algo != $this->data['passwordalgo']) { $save['password'] = $data['password']; } } // fork session to separate between loged in and anonymous session $this->sess->fork(); $this->group = $storage->getGroup(); $mandatorId = 0; if ($this->isInGroup(WBUser::GROUP_ID_MANDATOR, true)) { $list = $this->storage->getMandators(); if (!empty($list)) { $mandatorId = $list[0]; } } $storage->setMandatorId($mandatorId); $this->group = $storage->getGroup(); $log['mandator'] = $mandatorId; $log['status'] = 'ok'; $this->log->notice($log); // store everything in session $this->sess->set('wb.user.auth.id', $this->id); $this->sess->set('wb.user.auth.data', $this->data); $this->sess->set('wb.user.auth.group', $this->group); $this->sess->set('wb.user.auth.mandatorid', $mandatorId); $storage->set($save); /** @var WBUser_Session */ $sess = WBClass::create('WBUser_Session'); $sess->onLogin(); return $this->id; } /** * logout current user * * Well in case current user is authenticated, she will be logged * out. * * @see login * @return bool - always true * @see WBUser_Session::onLogin() */ public function logout() { if( !$this->id ) { return true; } $log = array( 'action' => 'logout', 'id' => $this->id ); // log out $storage = $this->getStorageModule(); $storage->clear(); /** @var WBUser_Session */ $sess = WBClass::create('WBUser_Session'); $sess->onLogout(); $this->id = null; $this->data = null; $this->group = null; $this->sess->clear('wb.user.auth.id'); $this->sess->clear('wb.user.auth.data'); $this->sess->clear('wb.user.auth.group'); $this->sess->clear('wb.user.auth.mandatorid'); $this->log->notice( $log ); return true; } /** * load user and automatically log in * * This is like the "su" command * * @todo test and verify if this worls * @param string $id user's id * @return true on success, false otherwise */ public function load( $id ) { if( !parent::load( $id ) ) { return false; } $storage = $this->getStorageModule(); if (!$storage->load($id)) { return false; } // fork session to separate between loged in and anonymous session $this->id = $id; $this->sess->fork(); $this->group = $storage->getGroup(); $mandatorId = 0; if ($this->isInGroup(WBUser::GROUP_ID_MANDATOR, true)) { $list = $this->storage->getMandators(); if (!empty($list)) { $mandatorId = $list[0]; } } $storage->setMandatorId($mandatorId); $this->group = $storage->getGroup(); /** @var WBUser_Session */ $sess = WBClass::create('WBUser_Session'); $sess->onLogin(); return true; } /** * Save user information * * Save user data also in session * * @param array $data */ public function set($data) { if (!$this->id) { return; } parent::set($data); $data = $this->getEditableData($data); $this->data = array_merge($this->data, $data); $this->sess->set('wb.user.auth.data', $this->data); } /** * check group membership * * Checks if user is in specified group * * @param string $name group name to validate * @param bool $id whether $name is the group's id * @return bool true in case user is member of given group */ public function isInGroup($name, $id = false) { // user must be logged in if (!$this->isAuthenticated()) { return false; } return parent::isInGroup($name, $id); } /** * update user data * * store changed user data in session and table * @param array $data * @return bool true on success, false otherwise * @deprecated in favour of storage module */ public function setData( $data ) { if( !$this->id ) { return false; } // hash password if( isset( $data['password'] ) ) { $data['password'] = md5( $this->id . ':' . $data['password'] ); } // see what needs to be saved $saveable = array( 'forename', 'surname', 'password' ); $save = array(); foreach( $saveable as $s ) { if( !isset( $data[$s] ) || $data[$s] == $this->data[$s] ) { continue; } $save[$s] = $data[$s]; } // nothing to save if( empty( $save ) ) { return true; } // store in DB $table = WBClass::create( 'WBDatasource_Table' ); $table->save( 'user', $this->id, $save ); foreach( $save as $k => $v ) { $this->data[$k] = $v; } // store in session $this->sess->set( 'wb.user.auth.data', $this->data ); return true; } }