source: trunk/Modules/User/User.php

Last change on this file was 896, checked in by chronos, 15 months ago
  • Fixed: Load correctly user properties which can be null.
File size: 8.5 KB
Line 
1<?php
2
3include_once(dirname(__FILE__).'/ModuleUser.php');
4include_once(dirname(__FILE__).'/UserList.php');
5include_once(dirname(__FILE__).'/Options.php');
6include_once(dirname(__FILE__).'/Registration.php');
7include_once(dirname(__FILE__).'/Profile.php');
8
9class PageUserLogin extends Page
10{
11 function Show(): string
12 {
13 $Output = '<form action="'.$this->System->Link('/?action=login').'" method="post" class="Form">'.
14 '<fieldset><legend>'.T('Login').'</legend>
15 <table>
16 <tr>
17 <th class="Left">'.T('Name').':</th><td><input type="text" name="LoginUser" size="13" /></td>
18 </tr>
19 <tr>
20 <th class="Left">'.T('Password').':</th><td><input type="password" name="LoginPass" size="13" /></td>
21 </tr>
22 <tr>
23 <th class="Left">'.T('Stay logged').':</th><td><input type="checkbox" name="StayLogged" /></td>
24 </tr>
25 <tr>
26 <th class="Center"colspan="2"><input type="submit" value="'.T('Do login').'" /></th>
27 </tr>
28 </table>
29 </fieldset></form>';
30 return $Output;
31 }
32}
33
34// User licence levels
35define('LICENCE_ANONYMOUS', -1);
36define('LICENCE_USER', 0);
37define('LICENCE_MODERATOR', 1);
38define('LICENCE_ADMIN', 2);
39
40class User
41{
42 var $Id;
43 public string $Name;
44 var $Team;
45 var $Role;
46 var $Redirecting;
47 var $Language;
48 var $System;
49 var $Database;
50 var $OnlineStateTimeout;
51 var $PreferredVersion = 0;
52 public string $PreferredVersionGame;
53 public string $Email;
54 public string $Info;
55
56 function __construct(System $System)
57 {
58 $this->System = &$System;
59 $this->Database = &$System->Database;
60 $this->OnlineStateTimeout = 600; // in seconds
61 if (isset($_SESSION)) $this->Check();
62 }
63
64 function __destroy()
65 {
66 }
67
68 function Login($Name, $Password, $StayLogged = false)
69 {
70 $SID = session_id();
71 $DbResult = $this->Database->query('SELECT `ID` FROM `User` WHERE '.
72 'LOWER(`Name`) = LOWER("'.$Name.'") AND `Pass` = '.$this->CryptPasswordSQL('"'.$Password.'"', '`Salt`'));
73 if ($DbResult->num_rows > 0)
74 {
75 $User = $DbResult->fetch_assoc();
76 $this->Id = $User['ID'];
77
78 // Prepare cookies for permanent login
79 $StayLoggedSalt = $this->GetPasswordSalt();
80 if ($StayLogged == true) $StayLoggedValue = 1; else $StayLoggedValue = 0;
81 $this->Database->update('UserOnline', '`SessionId`="'.$SID.'"', array(
82 'User' => $User['ID'], 'StayLogged' => $StayLoggedValue, 'StayLoggedHash' => $StayLoggedSalt));
83 if ($StayLogged)
84 {
85 setcookie('LoginUserId', $User['ID'], time() + 365 * 24 * 60 * 60);
86 setcookie('LoginHash', sha1($User['ID'].$StayLoggedSalt), time() + 365 * 24 * 60 * 60);
87 } else {
88 setcookie('LoginUserId', '', time() - 3600);
89 setcookie('LoginHash', '', time() - 3600);
90 }
91
92 $this->Database->query('UPDATE `UserTrace` SET '.
93 '`LastLogin` = NOW(), '.
94 '`LastIP` = "'.GetRemoteAddress().'", '.
95 '`UserAgent` = "'.$this->System->Database->real_escape_string($_SERVER['HTTP_USER_AGENT']).'" '.
96 ' WHERE `User` = '.$this->Id);
97 $this->System->ModuleManager->Modules['Log']->WriteLog('Login', LOG_TYPE_USER);
98 $this->Check();
99 };
100 }
101
102 function Logout()
103 {
104 $SID = session_id();
105 if ($this->Role != LICENCE_ANONYMOUS)
106 {
107 $this->Database->update('UserOnline', '`SessionId`="'.$SID.'"', array('User' => null));
108 $this->Database->query('UPDATE `UserTrace` SET '.
109 '`LastLogout` = NOW() WHERE `User` = '.$this->Id);
110 $this->System->ModuleManager->Modules['Log']->WriteLog('Logout: '.$this->Name, LOG_TYPE_USER);
111 $this->Check();
112 }
113 }
114
115 function Load()
116 {
117 $DbResult = $this->Database->query('SELECT `User`.`PreferredVersion`,`User`.`ID`,`User`.`Team`,`User`.`Redirecting`,`User`.`Email`,`User`.`Info`,'.
118 '`User`.`Language`,`User`.`Name`,`User`.`GM`,`ClientVersion`.`Version` AS `PreferredVersionGame` FROM `User` '.
119 'LEFT JOIN `ClientVersion` ON `ClientVersion`.`Id` = `User`.`PreferredVersion` '.
120 'WHERE `User`.`ID` = '.$this->Id);
121 if ($DbResult->num_rows > 0)
122 {
123 $User = $DbResult->fetch_assoc();
124 // Security: Password and Salt hash should not be loaded to variables
125 $this->Id = $User['ID'];
126 $this->Team = $User['Team'];
127 $this->Redirecting = $User['Redirecting'];
128 $this->Language = $User['Language'];
129 $this->Name = $User['Name'];
130 $this->Role = $User['GM'];
131 $this->Email = $User['Email'];
132 if ($User['Info'] != null) $this->Info = $User['Info'];
133 else $this->Info = '';
134 if ($User['PreferredVersionGame'] != null) $this->PreferredVersionGame = $User['PreferredVersionGame'];
135 else $this->PreferredVersionGame = '';
136 } else $this->SetAnonymous();
137 }
138
139 function SetAnonymous()
140 {
141 $this->Id = NULL;
142 $this->Name = 'anonymous';
143 $this->Role = LICENCE_ANONYMOUS;
144 $this->Language = NULL;
145 $this->Redirecting = 1;
146 $this->Team = '';
147 $this->Email = '';
148 }
149
150 function Licence($Licence)
151 {
152 if (GetRemoteAddress() == '') return true; // Execution from command line
153 else return $this->Role >= $Licence;
154 }
155
156 function CheckToken($Licence, $Token)
157 {
158 $DbResult = $this->Database->select('APIToken', 'User', '`Token`="'.$Token.'"');
159 if ($DbResult->num_rows > 0)
160 {
161 $DbRow = $DbResult->fetch_assoc();
162 $DbResult2 = $this->Database->select('User', 'GM', '`ID`="'.$DbRow['User'].'"');
163 $DbRow2 = $DbResult2->fetch_assoc();
164 return $DbRow2['GM'] >= $Licence;
165 } else return false;
166 }
167
168 function GetPasswordSalt()
169 {
170 return substr(sha1(mt_rand()), 0, 8);
171 }
172
173 function CryptPasswordSQL($Password, $Salt)
174 {
175 return 'SHA1(CONCAT(SHA1('.$Password.'), '.$Salt.'))';
176 }
177
178 function Check()
179 {
180 $SID = session_id();
181 // Lookup user record
182 $Query = $this->Database->select('UserOnline', '*', 'SessionId="'.$SID.'"');
183 if ($Query->num_rows > 0)
184 {
185 // Refresh time of last access
186 $this->Database->update('UserOnline', 'SessionId="'.$SID.'"', array('ActivityTime' => 'NOW()'));
187 } else
188 {
189 if (GetRemoteAddress() != '') $HostName = gethostbyaddr(GetRemoteAddress());
190 else $HostName = '';
191 $this->Database->insert('UserOnline', array('SessionId' => $SID,
192 'User' => null, 'LoginTime' => 'NOW()', 'ActivityTime' => 'NOW()',
193 'IpAddress' => GetRemoteAddress(), 'HostName' => $HostName,
194 'ScriptName' => GetRequestURI(), 'StayLogged' => 0, 'StayLoggedHash' => ''));
195 }
196
197 // Logged permanently?
198 if (array_key_exists('LoginHash', $_COOKIE))
199 {
200 $DbResult = $this->Database->query('SELECT * FROM `UserOnline` WHERE `User`='.$_COOKIE['LoginUserId'].
201 ' AND `StayLogged`=1 AND SessionId!="'.$SID.'"');
202 if ($DbResult->num_rows > 0)
203 {
204 $DbRow = $DbResult->fetch_assoc();
205 if (sha1($_COOKIE['LoginUserId'].$DbRow['StayLoggedHash']) == $_COOKIE['LoginHash'])
206 {
207 $this->Database->query('DELETE FROM `UserOnline` WHERE `SessionId`="'.$SID.'"');
208 $this->Database->query('UPDATE `UserOnline` SET `SessionId`="'.$SID.'" WHERE `Id`='.$DbRow['Id']);
209 }
210 }
211 }
212
213 // Check login
214 $Query = $this->Database->select('UserOnline', '*', '`SessionId`="'.$SID.'"');
215 $Row = $Query->fetch_assoc();
216 if ($Row['User'] != '')
217 {
218 $this->Id = $Row['User'];
219 $this->Load();
220 } else
221 {
222 $this->SetAnonymous();
223 }
224
225 // Remove nonactive users
226 $DbResult = $this->Database->select('UserOnline', '`Id`, `User`', '(`ActivityTime` < DATE_SUB(NOW(), INTERVAL '.$this->OnlineStateTimeout.' SECOND)) AND (`StayLogged` = 0)');
227 while ($DbRow = $DbResult->fetch_array())
228 {
229 $this->Database->delete('UserOnline', 'Id='.$DbRow['Id']);
230 }
231 }
232
233 function Register($UserName, $Password, $Email, $Language, $Team, $PreferredVersion)
234 {
235 $Salt = $this->GetPasswordSalt();
236 if ($Team == null) $Team = 'NULL';
237 if ($PreferredVersion == null) $PreferredVersion = 'NULL';
238 $this->Database->query('INSERT INTO `User` '.
239 '(`Name` , `Pass` , `Salt`, `Email` , `Language` , `Team` , `NeedUpdate`, `RegistrationTime`, `PreferredVersion` ) '.
240 'VALUES ("'.$UserName.'", '.$this->CryptPasswordSQL('"'.$Password.'"', '"'.$Salt.'"').
241 ', "'.$Salt.'", "'.$Email.'", '.$Language.', '.$Team.', 1, NOW(), '.$PreferredVersion.')');
242 $UserId = $this->Database->insert_id;
243 $this->Database->query('INSERT INTO `UserTrace` (`User`, `LastIP`, `UserAgent`) '.
244 'VALUES ('.$UserId.', "'.GetRemoteAddress().'", '.
245 '"'.$this->Database->real_escape_string($_SERVER['HTTP_USER_AGENT']).'")');
246 }
247}
Note: See TracBrowser for help on using the repository browser.