Changeset 746 for trunk/Modules/User/User.php
- Timestamp:
- Sep 10, 2015, 10:10:34 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Modules/User/User.php
r738 r746 1 1 <?php 2 2 3 include_once(dirname(__FILE__).'/UserModel.php'); 3 4 include_once(dirname(__FILE__).'/UserList.php'); 4 5 include_once(dirname(__FILE__).'/UserPage.php'); 5 6 define('LOGIN_USED', 'Přihlašovací jméno již použito.');7 define('NAME_USED', 'Jméno uživatele již použito');8 define('EMAIL_USED', 'Email je již použitý. Použijte jiný email nebo si můžete nechat zaslat nové heslo na email.');9 define('USER_REGISTRATED', 'Uživatel registrován. Na zadanou emailovou adresu byl poslán mail s odkazem pro aktivování účtu.');10 define('USER_REGISTRATION_CONFIRMED', 'Vaše registrace byla potvrzena.');11 define('DATA_MISSING', 'Chybí emailová adresa, přezdívka, nebo některé z hesel.');12 define('PASSWORDS_UNMATCHED', 'Hesla si neodpovídají.');13 define('ACCOUNT_LOCKED', 'Účet je uzamčen. Po registraci je nutné provést aktivaci účtu pomocí odkazu zaslaného v aktivačním emailu.');14 define('USER_NOT_LOGGED', 'Nejste přihlášen.');15 define('USER_LOGGED', 'Uživatel přihlášen.');16 define('USER_NOT_REGISTRED', 'Uživatel neregistrován.');17 define('USER_ALREADY_LOGGED', 'Uživatel již přihlášen.');18 define('USER_LOGGED_IN', 'Byl jste přihlášen.');19 define('USER_LOGGED_OUT', 'Byl jste odhlášen.');20 define('BAD_PASSWORD', 'Špatné heslo.');21 define('USER_NOT_FOUND', 'Uživatel nenalezen.');22 define('USER_PASSWORD_RECOVERY_SUCCESS', 'Přihlašovací údaje byly odeslány na zadanou emailovou adresu.');23 define('USER_PASSWORD_RECOVERY_FAIL', 'Podle zadaných údajů nebyl nalezen žádný uživatel.');24 define('USER_PASSWORD_RECOVERY_CONFIRMED', 'Nové heslo bylo aktivováno.');25 26 define('USER_EVENT_REGISTER', 1);27 define('USER_EVENT_LOGIN', 2);28 define('USER_EVENT_LOGOUT', 3);29 define('USER_EVENT_OPTIONS_CHANGED', 4);30 31 class PasswordHash32 {33 function Hash($Password, $Salt)34 {35 return(sha1(sha1($Password).$Salt));36 }37 38 function Verify($Password, $Salt, $StoredHash)39 {40 return($this->Hash($Password, $Salt) == $StoredHash);41 }42 43 function GetSalt()44 {45 mt_srand(microtime(true) * 100000 + memory_get_usage(true));46 return sha1(uniqid(mt_rand(), true));47 }48 }49 50 // TODO: Make User class more general without dependencies to System, Mail, Log51 52 class User extends Model53 {54 var $Roles = array();55 var $User = array();56 var $OnlineStateTimeout;57 var $PermissionCache = array();58 var $PermissionGroupCache = array();59 var $PermissionGroupCacheOp = array();60 /** @var Password */61 var $PasswordHash;62 63 function __construct($System)64 {65 parent::__construct($System);66 $this->OnlineStateTimeout = 600; // in seconds67 $this->PasswordHash = new PasswordHash();68 $this->User = array('Id' => null, 'Member' => null);69 }70 71 function Check()72 {73 $SID = session_id();74 // Lookup user record75 $Query = $this->Database->select('UserOnline', '*', 'SessionId="'.$SID.'"');76 if($Query->num_rows > 0)77 {78 // Refresh time of last access79 $this->Database->update('UserOnline', 'SessionId="'.$SID.'"', array('ActivityTime' => 'NOW()'));80 } else $this->Database->insert('UserOnline', array('SessionId' => $SID,81 'User' => null, 'LoginTime' => 'NOW()', 'ActivityTime' => 'NOW()',82 'IpAddress' => GetRemoteAddress(), 'HostName' => gethostbyaddr(GetRemoteAddress()),83 'ScriptName' => $_SERVER['PHP_SELF']));84 85 // Logged permanently?86 if(array_key_exists('LoginHash', $_COOKIE))87 {88 $DbResult = $this->Database->query('SELECT * FROM `UserOnline` WHERE `User`='.$_COOKIE['LoginUserId'].89 ' AND `StayLogged`=1 AND SessionId!="'.$SID.'"');90 if($DbResult->num_rows > 0)91 {92 $DbRow = $DbResult->fetch_assoc();93 if(sha1($_COOKIE['LoginUserId'].$DbRow['StayLoggedHash']) == $_COOKIE['LoginHash'])94 {95 $this->Database->query('DELETE FROM `UserOnline` WHERE `SessionId`="'.$SID.'"');96 $this->Database->query('UPDATE `UserOnline` SET `SessionId`="'.$SID.'" WHERE `Id`='.$DbRow['Id']);97 }98 }99 }100 101 // Check login102 $Query = $this->Database->select('UserOnline', '*', '`SessionId`="'.$SID.'"');103 $Row = $Query->fetch_assoc();104 if($Row['User'] != '')105 {106 $Query = $this->Database->query('SELECT `User`.*, `UserCustomerRel`.`Customer` AS `Member` FROM `User` '.107 ' LEFT JOIN `UserCustomerRel` ON `UserCustomerRel`.`User`=`User`.`Id` WHERE `User`.`Id`='.$Row['User']);108 $this->User = $Query->fetch_assoc();109 $Result = USER_LOGGED;110 } else111 {112 $Query = $this->Database->select('User', '*', 'Id IS NULL');113 $this->User = array('Id' => null, 'Member' => null);114 $Result = USER_NOT_LOGGED;115 }116 117 // Remove nonactive users118 $DbResult = $this->Database->select('UserOnline', '`Id`, `User`', '(`ActivityTime` < DATE_SUB(NOW(), INTERVAL '.$this->OnlineStateTimeout.' SECOND)) AND (`StayLogged` = 0)');119 while($DbRow = $DbResult->fetch_array())120 {121 $this->Database->delete('UserOnline', 'Id='.$DbRow['Id']);122 if($DbRow['User'] != null) $this->System->ModuleManager->Modules['Log']->NewRecord('User', 'Logout');123 }124 //$this->LoadPermission($this->User['Role']);125 126 // Role and permission127 //$this->LoadRoles();128 }129 130 function Register($Login, $Password, $Password2, $Email, $Name)131 {132 if(($Email == '') || ($Login == '') || ($Password == '') || ($Password2 == '') || ($Name == '')) $Result = DATA_MISSING;133 else if($Password != $Password2) $Result = PASSWORDS_UNMATCHED;134 else135 {136 // Is user registred yet?137 $Query = $this->Database->select('User', '*', 'Login = "'.$Login.'"');138 if($Query->num_rows > 0) $Result = LOGIN_USED;139 else140 {141 $Query = $this->Database->select('User', '*', 'Name = "'.$Name.'"');142 if($Query->num_rows > 0) $Result = NAME_USED;143 else144 {145 $Query = $this->Database->select('User', '*', 'Email = "'.$Email.'"');146 if($Query->num_rows > 0) $Result = EMAIL_USED;147 else148 {149 $PasswordHash = new PasswordHash();150 $Salt = $PasswordHash->GetSalt();151 $this->Database->insert('User', array('Name' => $Name, 'Login' => $Login,152 'Password' => $PasswordHash->Hash($Password, $Salt), 'Salt' => $Salt,153 'Email' => $Email, 'RegistrationTime' => 'NOW()',154 'Locked' => 1));155 $UserId = $this->Database->insert_id;156 $this->Database->insert('PermissionUserAssignment', array('User' => $UserId,157 'AssignedGroup' => 2));158 159 $NewPassword = substr(sha1(strtoupper($Login)), 0, 7);160 161 // Send activation mail to user email162 $ServerURL = 'http://'.$this->System->Config['Web']['Host'].$this->System->Config['Web']['RootFolder'];163 $Mail = new Mail();164 $Mail->Subject = 'Registrace nového účtu';165 $Mail->AddBody('Provedli jste registraci nového účtu na serveru <a href="'.$ServerURL.'">'.$ServerURL.'"</a>.'.166 '<br/>\nPokud jste tak neučinili, měli by jste tento email ignorovat.<br/><br/>\n\n'.167 'Váš účet je: '.$Login."\n<br/>Pro dokončení registrace klikněte na tento odkaz: ".'<a href="'.168 $ServerURL.'/user/?Action=UserRegisterConfirm&User='.169 $UserId.'&H='.$NewPassword.'">'.$ServerURL.'/?Action=UserRegisterConfirm&User='.170 $UserId.'&H='.$NewPassword.'</a>.'."\n<br> \n\n'.171 '<br/><br/>Na tento email neodpovídejte.", 'text/html');172 $Mail->AddTo($Email, $Name);173 $Mail->From = $this->System->Config['Web']['Title'].' <noreplay@zdechov.net>';174 $Mail->Send();175 176 $Result = USER_REGISTRATED;177 $this->System->ModuleManager->Modules['Log']->NewRecord('User', 'NewRegistration', $Login);178 }179 }180 }181 }182 return($Result);183 }184 185 function RegisterConfirm($Id, $Hash)186 {187 $DbResult = $this->Database->select('User', 'Id, Login, Password', 'Id = '.$Id);188 if($DbResult->num_rows > 0)189 {190 $Row = $DbResult->fetch_array();191 $NewPassword = substr(sha1(strtoupper($Row['Login'])), 0, 7);192 if($Hash == $NewPassword)193 {194 $this->Database->update('User', 'Id='.$Row['Id'], array('Locked' => 0));195 $Output = USER_REGISTRATION_CONFIRMED;196 $this->System->ModuleManager->Modules['Log']->NewRecord('User', 'RegisterConfirm', 'Login='.197 $Row['Login'].', Id='.$Row['Id']);198 } else $Output = PASSWORDS_UNMATCHED;199 } else $Output = USER_NOT_FOUND;200 return($Output);201 }202 203 function Login($Login, $Password, $StayLogged = false)204 {205 $SID = session_id();206 $Query = $this->Database->select('User', '*', 'Login="'.$Login.'"');207 if($Query->num_rows > 0)208 {209 $Row = $Query->fetch_assoc();210 $PasswordHash = new PasswordHash();211 if(!$PasswordHash->Verify($Password, $Row['Salt'], $Row['Password'])) $Result = BAD_PASSWORD;212 else if($Row['Locked'] == 1) $Result = ACCOUNT_LOCKED;213 else214 {215 $this->Database->update('User', 'Id='.$Row['Id'], array('LastLoginTime' => 'NOW()',216 'LastIpAddress' => GetRemoteAddress()));217 $Hash = new PasswordHash();218 $StayLoggedSalt = $Hash->GetSalt();219 $this->Database->update('UserOnline', 'SessionId="'.$SID.'"', array(220 'User' => $Row['Id'], 'StayLogged' => $StayLogged, 'StayLoggedHash' => $StayLoggedSalt));221 if($StayLogged)222 {223 setcookie('LoginUserId', $Row['Id'], time()+365*24*60*60, $this->System->Link('/'));224 setcookie('LoginHash', sha1($Row['Id'].$StayLoggedSalt), time()+365*24*60*60, $this->System->Link('/'));225 } else {226 setcookie('LoginUserId', '', time() - 3600, $this->System->Link('/'));227 setcookie('LoginHash', '', time() - 3600, $this->System->Link('/'));228 }229 230 $Result = USER_LOGGED_IN;231 $this->Check();232 $this->System->ModuleManager->Modules['Log']->NewRecord('User', 'Login', 'Login='.$Login.',Host='.gethostbyaddr(GetRemoteAddress()));233 }234 } else $Result = USER_NOT_REGISTRED;235 return($Result);236 }237 238 function Logout()239 {240 $SID = session_id();241 $this->Database->update('UserOnline', 'SessionId="'.$SID.'"', array('User' => null));242 $this->System->ModuleManager->Modules['Log']->NewRecord('User', 'Logout', $this->User['Login']);243 $this->Check();244 return(USER_LOGGED_OUT);245 }246 247 function LoadRoles()248 {249 $this->Roles = array();250 $DbResult = $this->Database->select('UserRole', '*');251 while($DbRow = $DbResult->fetch_array())252 $this->Roles[] = $DbRow;253 }254 255 function LoadPermission($Role)256 {257 $this->User['Permission'] = array();258 $DbResult = $this->Database->query('SELECT `UserRolePermission`.*, `PermissionOperation`.`Description` FROM `UserRolePermission` JOIN `PermissionOperation` ON `PermissionOperation`.`Id` = `UserRolePermission`.`Operation` WHERE `UserRolePermission`.`Role` = '.$Role);259 if($DbResult->num_rows > 0)260 while($DbRow = $DbResult->fetch_array())261 $this->User['Permission'][$DbRow['Operation']] = $DbRow;262 }263 264 function PermissionMatrix()265 {266 $Result = array();267 $DbResult = $this->Database->query('SELECT `UserRolePermission`.*, `PermissionOperation`.`Description`, `UserRole`.`Title` FROM `UserRolePermission` LEFT JOIN `PermissionOperation` ON `PermissionOperation`.`Id` = `UserRolePermission`.`Operation` LEFT JOIN `UserRole` ON `UserRole`.`Id` = `UserRolePermission`.`Role`');268 while($DbRow = $DbResult->fetch_array())269 {270 $Value = '';271 if($DbRow['Read']) $Value .= 'R';272 if($DbRow['Write']) $Value .= 'W';273 $Result[$DbRow['Description']][$DbRow['Title']] = $Value;274 }275 return($Result);276 }277 278 function CheckGroupPermission($GroupId, $OperationId)279 {280 $PermissionExists = false;281 // First try to check cache group-group relation282 if(array_key_exists($GroupId, $this->PermissionGroupCache))283 {284 $PermissionExists = true;285 } else286 {287 // If no permission combination exists in cache, do new check of database items288 $DbResult = $this->Database->select('PermissionGroupAssignment', '*', '(`Group`="'.$GroupId.289 '") AND (`AssignedGroup` IS NOT NULL)');290 $DbRow = array();291 while($DbRow[] = $DbResult->fetch_array());292 $this->PermissionGroupCache[$GroupId] = $DbRow;293 $PermissionExists = true;294 }295 if($PermissionExists)296 {297 foreach($this->PermissionGroupCache[$GroupId] as $DbRow)298 {299 if($DbRow['AssignedGroup'] != '')300 if($this->CheckGroupPermission($DbRow['AssignedGroup'], $OperationId) == true) return(true);301 }302 }303 304 // Check group-operation relation305 if(array_key_exists($GroupId.','.$OperationId, $this->PermissionGroupCacheOp))306 {307 $PermissionExists = true;308 } else309 {310 // If no permission combination exists in cache, do new check of database items311 $DbResult = $this->Database->select('PermissionGroupAssignment', '*', '`Group`="'.$GroupId.'" AND `AssignedOperation`="'.$OperationId.'"');312 if($DbResult->num_rows > 0) $this->PermissionGroupCacheOp[$GroupId.','.$OperationId] = true;313 else $this->PermissionGroupCacheOp[$GroupId.','.$OperationId] = false;314 $PermissionExists = true;315 }316 if($PermissionExists)317 {318 return($this->PermissionGroupCacheOp[$GroupId.','.$OperationId]);319 }320 return(false);321 }322 323 function CheckPermission($Module, $Operation, $ItemType = '', $ItemIndex = 0)324 {325 // Get module id326 $DbResult = $this->Database->select('Module', 'Id', '`Name`="'.$Module.'"');327 if($DbResult->num_rows > 0)328 {329 $DbRow = $DbResult->fetch_assoc();330 $ModuleId = $DbRow['Id'];331 } else return(false);332 333 // First try to check cache334 if(in_array(array($Module, $Operation, $ItemType, $ItemType), $this->PermissionCache))335 {336 $OperationId = array_search(array($Module, $Operation, $ItemType, $ItemIndex), $this->PermissionCache);337 $PermissionExists = is_numeric($OperationId);338 } else339 {340 // If no permission combination exists in cache, do new check of database items341 $DbResult = $this->Database->select('PermissionOperation', 'Id', '(`Module`="'.$ModuleId.342 '") AND (`Item`="'.$ItemType.'") AND (`ItemId`='.$ItemIndex.') AND (`Operation`="'.$Operation.'")');343 if($DbResult->num_rows > 0)344 {345 $DbRow = $DbResult->fetch_array();346 $OperationId = $DbRow['Id'];347 $this->PermissionCache[$DbRow['Id']] = array($Module, $Operation, $ItemType, $ItemIndex);348 $PermissionExists = true;349 } else350 {351 $this->PermissionCache[count($this->PermissionCache).'_'] = array($Module, $Operation, $ItemType, $ItemIndex);352 $PermissionExists = false;353 }354 }355 356 if($PermissionExists)357 {358 if($this->User['Id'] == null) $UserCondition = '(`User` IS NULL)';359 else $UserCondition = '(`User`="'.$this->User['Id'].'")';360 // Check user-operation relation361 $DbResult = $this->Database->select('PermissionUserAssignment', '*', $UserCondition.' AND (`AssignedOperation`="'.$OperationId.'")');362 if($DbResult->num_rows > 0) return(true);363 364 // Check user-group relation365 $DbResult = $this->Database->select('PermissionUserAssignment', 'AssignedGroup', $UserCondition);366 while($DbRow = $DbResult->fetch_array())367 {368 if($this->CheckGroupPermission($DbRow['AssignedGroup'], $OperationId) == true) return(true);369 }370 return(false);371 } else return(false);372 }373 374 function PasswordRecoveryRequest($Login, $Email)375 {376 $DbResult = $this->Database->select('User', 'Login, Name, Id, Email, Password', '`Login`="'.$Login.'" AND `Email`="'.$Email.'"');377 if($DbResult->num_rows > 0)378 {379 $Row = $DbResult->fetch_array();380 $NewPassword = substr(sha1(strtoupper($Row['Login'])), 0, 7);381 382 $ServerURL = 'http://'.$this->System->Config['Web']['Host'].$this->System->Config['Web']['RootFolder'];383 $Mail = new Mail();384 $Mail->Subject = 'Obnova hesla';385 $Mail->From = $this->System->Config['Web']['Title'].' <noreplay@zdechov.net>';386 $Mail->AddTo($Row['Email'], $Row['Name']);387 $Mail->AddBody('Požádali jste o zaslání nového hesla na serveru <a href="'.$ServerURL.'">'.$ServerURL.'"</a>.<br />\n'.388 "Pokud jste tak neučinili, měli by jste tento email ignorovat.<br /><br />\n\nVaše nové heslo k účtu ".389 $Row['Login'].' je: '.$NewPassword."\n<br/>".390 'Pro aktivaci tohoto hesla klikněte na <a href="'.$ServerURL.'/user/?Action=PasswordRecoveryConfirm&User='.391 $Row['Id'].'&H='.$Row['Password'].'&P='.$NewPassword.'">tento odkaz</a>.'."\n<br />".392 "Po přihlášení si prosím změňte heslo na nové.\n\n<br><br>Na tento email neodpovídejte.", 'text/html');393 $Mail->Send();394 395 $Output = USER_PASSWORD_RECOVERY_SUCCESS;396 $this->System->ModuleManager->Modules['Log']->NewRecord('User', 'PasswordRecoveryRequest', 'Login='.$Login.',Email='.$Email);397 } else $Output = USER_PASSWORD_RECOVERY_FAIL;398 return($Output);399 }400 401 function PasswordRecoveryConfirm($Id, $Hash, $NewPassword)402 {403 $DbResult = $this->Database->select('User', 'Id, Login, Password', 'Id = '.$Id);404 if($DbResult->num_rows > 0)405 {406 $Row = $DbResult->fetch_array();407 $NewPassword2 = substr(sha1(strtoupper($Row['Login'])), 0, 7);408 if(($NewPassword == $NewPassword2) and ($Hash == $Row['Password']))409 {410 $PasswordHash = new PasswordHash();411 $Salt = $PasswordHash->GetSalt();412 $this->Database->update('User', 'Id='.$Row['Id'], array('Password' => $PasswordHash->Hash($NewPassword, $Salt),413 'Salt' => $Salt, 'Locked' => 0));414 $Output = USER_PASSWORD_RECOVERY_CONFIRMED;415 $this->System->ModuleManager->Modules['Log']->NewRecord('User', 'PasswordRecoveryConfirm', 'Login='.$Row['Login']);416 } else $Output = PASSWORDS_UNMATCHED;417 } else $Output = USER_NOT_FOUND;418 return($Output);419 }420 421 function CheckToken($Module, $Operation, $Token)422 {423 $DbResult = $this->Database->select('APIToken', 'User', '`Token`="'.$Token.'"');424 if($DbResult->num_rows > 0)425 {426 $DbRow = $DbResult->fetch_assoc();427 $User = new User($this->System);428 $User->User = array('Id' => $DbRow['User']);429 return($User->CheckPermission($Module, $Operation));430 } else return(false);431 }432 }433 6 434 7 class ModuleUser extends AppModule … … 543 116 } 544 117 118 function DoUpgrade() 119 { 120 /* 121 122 if($this->InstalledVersion == '1.0') { 123 $this->System->Database->Query('SELECT * FROM User WHERE Id=1'); 124 $this->InstalledVersion = '1.1'; 125 } 126 */ 127 } 128 545 129 function DoStart() 546 130 {
Note:
See TracChangeset
for help on using the changeset viewer.