source: trunk/Modules/User/User.php@ 789

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