Updated init script.
[dtbartle/bnbt.git] / tracker_users.cpp
1 /***\r
2 *\r
3 * BNBT Beta 8.0 - A C++ BitTorrent Tracker\r
4 * Copyright (C) 2003-2004 Trevor Hogan\r
5 *\r
6 * CBTT variations (C) 2003-2005 Harold Feit\r
7 *\r
8 * This library is free software; you can redistribute it and/or\r
9 * modify it under the terms of the GNU Lesser General Public\r
10 * License as published by the Free Software Foundation; either\r
11 * version 2.1 of the License, or (at your option) any later version.\r
12 *\r
13 * This library is distributed in the hope that it will be useful,\r
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
16 * Lesser General Public License for more details.\r
17 *\r
18 * You should have received a copy of the GNU Lesser General Public\r
19 * License along with this library; if not, write to the Free Software\r
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
21 *\r
22 ***/\r
23 \r
24 #include "bnbt.h"\r
25 #include "atom.h"\r
26 #include "md5.h"\r
27 #include "sort.h"\r
28 #include "tracker.h"\r
29 #include "util.h"\r
30 \r
31 void CTracker :: serverResponseUsers( struct request_t *pRequest, struct response_t *pResponse, user_t user )\r
32 {\r
33         pResponse->strCode = "200 OK";\r
34 \r
35         pResponse->mapHeaders.insert( pair<string, string>( "Content-Type", string( "text/html; charset=" ) + gstrCharSet ) );\r
36 \r
37         pResponse->strContent += "<html>\n";\r
38         pResponse->strContent += "<head>\n";\r
39         if ( !gstrTrackerTitle.empty( ) )\r
40                 pResponse->strContent += "<title>" + gstrTrackerTitle + " - Users Info</title>\n";\r
41         else\r
42                 pResponse->strContent += "<title>BNBT Users Info</title>\n";\r
43 \r
44         if( !gstrStyle.empty( ) )\r
45                 pResponse->strContent += "<link rel=stylesheet type=\"text/css\" href=\"" + gstrStyle + "\">\n";\r
46 \r
47         pResponse->strContent += "</head>\n";\r
48         pResponse->strContent += "<body>\n";\r
49 \r
50         if( !m_bDisableLogon )\r
51         {\r
52                 if( user.strLogin.empty( ) )\r
53                         pResponse->strContent += "<p class=\"login1_index\">You are not logged in. Click <a href=\"/login.html\">here</a> to login.</p>\n";\r
54                 else\r
55                         pResponse->strContent += "<p class=\"login2_index\">You are logged in as <span class=\"username\">" + UTIL_RemoveHTML( user.strLogin ) + "</span>. Click <a href=\"/login.html?logout=1\">here</a> to logout.</p>\n";\r
56         }\r
57 \r
58         if ( !gstrTrackerTitle.empty( ) )\r
59                 pResponse->strContent += "<h3>" + gstrTrackerTitle + " - Users Info</h3>\n";\r
60         else\r
61                 pResponse->strContent += "<h3>BNBT Users Info</h3>\n";\r
62 \r
63         // The Trinity Edition - Addition Begins\r
64         // The following adds an RTT link to the USERS page\r
65 \r
66         pResponse->strContent += "<p><a href=\"/index.html\">Return to Tracker</a></p>\n";\r
67 \r
68         // ------------------------------------------------- End of Addition\r
69 \r
70         if( user.iAccess & ACCESS_ADMIN )\r
71         {\r
72                 //\r
73                 // create user\r
74                 //\r
75 \r
76                 if( pRequest->mapParams.find( "us_login" ) != pRequest->mapParams.end( ) &&\r
77                         pRequest->mapParams.find( "us_password" ) != pRequest->mapParams.end( ) &&\r
78                         pRequest->mapParams.find( "us_password_verify" ) != pRequest->mapParams.end( ) &&\r
79                         pRequest->mapParams.find( "us_email" ) != pRequest->mapParams.end( ) )\r
80                 {\r
81                         string strLogin = pRequest->mapParams["us_login"];\r
82                         string strPass = pRequest->mapParams["us_password"];\r
83                         string strPass2 = pRequest->mapParams["us_password_verify"];\r
84                         string strMail = pRequest->mapParams["us_email"];\r
85                         string strAccView = pRequest->mapParams["us_access_view"];\r
86                         string strAccDL = pRequest->mapParams["us_access_dl"];\r
87                         string strAccComments = pRequest->mapParams["us_access_comments"];\r
88                         string strAccUpload = pRequest->mapParams["us_access_upload"];\r
89                         string strAccEdit = pRequest->mapParams["us_access_edit"];\r
90                         string strAccAdmin = pRequest->mapParams["us_access_admin"];\r
91                         string strAccSignup = pRequest->mapParams["us_access_signup"];\r
92 \r
93                         if( strLogin.empty( ) || strPass.empty( ) || strPass2.empty( ) || strMail.empty( ) )\r
94                         {\r
95                                 // The Trinity Edition - Modification Begins\r
96                                 // Created Links to either "Make Corrections" or "Start Over"\r
97                                 // when creating a NEW USER FAILS because ALL FIELDS WERE NOT FILLED IN\r
98 \r
99                                 pResponse->strContent += "<p>Unable to create user. You must fill in all the fields.</p>\n";\r
100                                 pResponse->strContent += "<p>What would you like to do?</p>\n";\r
101                                 pResponse->strContent += "<p><a href=\"javascript:history.back()\">Make Corrections</a> | <a href=\"/users.html\">Start Over</a></p>\n";                                \r
102 \r
103                                 /* Original Source Code:\r
104                                 pResponse->strContent += "<p>Unable to create user. You must fill in all the fields. Click <a href=\"/users.html\">here</a> to return to the users page.</p>\n";\r
105                                 */\r
106 \r
107                                 // ------------------------------------------------- End of Modification\r
108 \r
109                                 pResponse->strContent += "</body>\n";\r
110                                 pResponse->strContent += "</html>\n";\r
111 \r
112                                 return;\r
113                         }\r
114                         else\r
115                         {\r
116                                 if( strPass == strPass2 )\r
117                                 {\r
118                                         if( m_pUsers->getItem( strLogin ) )\r
119                                         {\r
120                                                 pResponse->strContent += "<p>Unable to create user. The user \"" + UTIL_RemoveHTML( strLogin ) + "\" already exists. Click <a href=\"/users.html\">here</a> to return to the users page.</p>\n";\r
121                                                 pResponse->strContent += "</body>\n";\r
122                                                 pResponse->strContent += "</html>\n";\r
123 \r
124                                                 return;\r
125                                         }\r
126                                         else\r
127                                         {\r
128                                                 int iAccess = 0;\r
129 \r
130                                                 if( strAccView == "on" )\r
131                                                         iAccess += ACCESS_VIEW;\r
132                                                 if( strAccDL == "on" )\r
133                                                         iAccess += ACCESS_DL;\r
134                                                 if( strAccComments == "on" )\r
135                                                         iAccess += ACCESS_COMMENTS;\r
136                                                 if( strAccUpload == "on" )\r
137                                                         iAccess += ACCESS_UPLOAD;\r
138                                                 if( strAccEdit == "on" )\r
139                                                         iAccess += ACCESS_EDIT;\r
140                                                 if( strAccAdmin == "on" )\r
141                                                         iAccess += ACCESS_ADMIN;\r
142                                                 if( strAccSignup == "on" )\r
143                                                         iAccess += ACCESS_SIGNUP;\r
144 \r
145                                                 addUser( strLogin, strPass, iAccess, strMail );\r
146 \r
147                                                 pResponse->strContent += "<p>Created user \"" + UTIL_RemoveHTML( strLogin ) + "\". Click <a href=\"/users.html\">here</a> to return to the users page.</p>\n";\r
148                                                 pResponse->strContent += "</body>\n";\r
149                                                 pResponse->strContent += "</html>\n";\r
150 \r
151                                                 return;\r
152                                         }\r
153                                 }\r
154                                 else\r
155                                 {\r
156                                         pResponse->strContent += "<p>Unable to create user. The passwords did not match. Click <a href=\"/users.html\">here</a> to return to the users page.</p>\n";\r
157                                         pResponse->strContent += "</body>\n";\r
158                                         pResponse->strContent += "</html>\n";\r
159 \r
160                                         return;\r
161                                 }\r
162                         }\r
163                 }\r
164 \r
165                 //\r
166                 // edit user\r
167                 //\r
168 \r
169                 string strPass = pRequest->mapParams["us_password"];\r
170                 string strPass2 = pRequest->mapParams["us_password_verify"];\r
171                 string strMail = pRequest->mapParams["us_email"];\r
172                 string strAccView = pRequest->mapParams["us_access_view"];\r
173                 string strAccDL = pRequest->mapParams["us_access_dl"];\r
174                 string strAccComments = pRequest->mapParams["us_access_comments"];\r
175                 string strAccUpload = pRequest->mapParams["us_access_upload"];\r
176                 string strAccEdit = pRequest->mapParams["us_access_edit"];\r
177                 string strAccAdmin = pRequest->mapParams["us_access_admin"];\r
178                 string strAccSignup = pRequest->mapParams["us_access_signup"];\r
179 \r
180                 string strUser = pRequest->mapParams["user"];\r
181                 string strAction = pRequest->mapParams["action"];\r
182                 string strOK = pRequest->mapParams["ok"];\r
183 \r
184                 if( strAction == "edit" )\r
185                 {\r
186                         CAtom *pUserToEdit = m_pUsers->getItem( strUser );\r
187 \r
188                         if( pUserToEdit && pUserToEdit->isDicti( ) )\r
189                         {\r
190                                 if( strOK == "1" )\r
191                                 {\r
192                                         // edit password\r
193 \r
194                                         if( !strPass.empty( ) && !strPass2.empty( ) )\r
195                                         {\r
196                                                 if( strPass == strPass2 )\r
197                                                 {\r
198                                                         string strA1 = strUser + ":" + gstrRealm + ":" + strPass;\r
199 \r
200                                                         unsigned char szMD5[16];\r
201 \r
202                                                         MD5_CTX md5;\r
203 \r
204                                                         MD5Init( &md5 );\r
205                                                         MD5Update( &md5, (unsigned char *)strA1.c_str( ), strA1.size( ) );\r
206                                                         MD5Final( szMD5, &md5 );\r
207 \r
208                                                         ( (CAtomDicti *)pUserToEdit )->setItem( "md5", new CAtomString( string( (char *)szMD5, 16 ) ) );\r
209                                                 }\r
210                                                 else\r
211                                                 {\r
212                                                         pResponse->strContent += "<p>Unable to edit user. The passwords did not match. Click <a href=\"/users.html\">here</a> to return to the users page.</p>\n";\r
213                                                         pResponse->strContent += "</body>\n";\r
214                                                         pResponse->strContent += "</html>\n";\r
215 \r
216                                                         return;\r
217                                                 }\r
218                                         }\r
219 \r
220                                         // edit mail\r
221 \r
222                                         ( (CAtomDicti *)pUserToEdit )->setItem( "email", new CAtomString( strMail ) );\r
223 \r
224                                         // edit access\r
225 \r
226                                         int iAccess = 0;\r
227 \r
228                                         if( strAccView == "on" )\r
229                                                 iAccess += ACCESS_VIEW;\r
230                                         if( strAccDL == "on" )\r
231                                                 iAccess += ACCESS_DL;\r
232                                         if( strAccComments == "on" )\r
233                                                 iAccess += ACCESS_COMMENTS;\r
234                                         if( strAccUpload == "on" )\r
235                                                 iAccess += ACCESS_UPLOAD;\r
236                                         if( strAccEdit == "on" )\r
237                                                 iAccess += ACCESS_EDIT;\r
238                                         if( strAccAdmin == "on" )\r
239                                                 iAccess += ACCESS_ADMIN;\r
240                                         if( strAccSignup == "on" )\r
241                                                 iAccess += ACCESS_SIGNUP;\r
242 \r
243                                         ( (CAtomDicti *)pUserToEdit )->setItem( "access", new CAtomLong( iAccess ) );\r
244 \r
245                                         saveUsers( );\r
246 \r
247                                         pResponse->strContent += "<p>Edited user \"" + UTIL_RemoveHTML( strUser ) + "\". Click <a href=\"/users.html\">here</a> to return to the users page.</p>\n";\r
248                                         pResponse->strContent += "</body>\n";\r
249                                         pResponse->strContent += "</html>\n";\r
250 \r
251                                         return;\r
252                                 }\r
253                                 else\r
254                                 {\r
255                                         int iAccess = 0;\r
256 \r
257                                         CAtom *pAccessToEdit = ( (CAtomDicti *)pUserToEdit )->getItem( "access" );\r
258 \r
259                                         if( pAccessToEdit && pAccessToEdit->isLong( ) )\r
260                                                 iAccess = (int)( (CAtomLong *)pAccessToEdit )->getValue( );\r
261 \r
262                                         pResponse->strContent += "<form method=\"get\" action=\"/users.html\">\n";\r
263                                         pResponse->strContent += "<p><strong>Edit User \"" + UTIL_RemoveHTML( strUser ) + "\"</strong></p>\n";\r
264                                         pResponse->strContent += "<input name=\"user\" type=hidden value=\"" + UTIL_StringToEscaped( strUser ) + "\">\n";\r
265                                         pResponse->strContent += "<input name=\"action\" type=hidden value=\"edit\">\n";\r
266                                         pResponse->strContent += "<input name=\"ok\" type=hidden value=1>\n";\r
267                                         pResponse->strContent += "<input name=\"us_password\" type=password size=20> Password (optional)<br>\n";\r
268                                         pResponse->strContent += "<input name=\"us_password_verify\" type=password size=20> Verify Password (optional)<br><br>\n";\r
269                                         pResponse->strContent += "<input name=\"us_email\" type=text size=40";\r
270 \r
271                                         CAtom *pMailToEdit = ( (CAtomDicti *)pUserToEdit )->getItem( "email" );\r
272 \r
273                                         if( pMailToEdit )\r
274                                                 pResponse->strContent += " value=\"" + pMailToEdit->toString( ) + "\"";\r
275 \r
276                                         pResponse->strContent += "> E-Mail<br><br>\n";\r
277                                         pResponse->strContent += "<input name=\"us_access_view\" type=checkbox";\r
278 \r
279                                         if( iAccess & ACCESS_VIEW )\r
280                                                 pResponse->strContent += " checked";\r
281 \r
282                                         pResponse->strContent += "> View Access (Basic)<br>\n";\r
283                                         pResponse->strContent += "<input name=\"us_access_dl\" type=checkbox";\r
284 \r
285                                         if( iAccess & ACCESS_DL )\r
286                                                 pResponse->strContent += " checked";\r
287 \r
288                                         pResponse->strContent += "> DL Access (Downloader)<br>\n";\r
289                                         pResponse->strContent += "<input name=\"us_access_comments\" type=checkbox";\r
290 \r
291                                         if( iAccess & ACCESS_COMMENTS )\r
292                                                 pResponse->strContent += " checked";\r
293 \r
294                                         pResponse->strContent += "> Comments Access (Poster)<br>\n";\r
295                                         pResponse->strContent += "<input name=\"us_access_upload\" type=checkbox";\r
296 \r
297                                         if( iAccess & ACCESS_UPLOAD )\r
298                                                 pResponse->strContent += " checked";\r
299 \r
300                                         pResponse->strContent += "> Upload Access (Uploader)<br>\n";\r
301                                         pResponse->strContent += "<input name=\"us_access_edit\" type=checkbox";\r
302 \r
303                                         if( iAccess & ACCESS_EDIT )\r
304                                                 pResponse->strContent += " checked";\r
305 \r
306                                         pResponse->strContent += "> Edit Access (Moderator)<br>\n";\r
307                                         pResponse->strContent += "<input name=\"us_access_admin\" type=checkbox";\r
308 \r
309                                         if( iAccess & ACCESS_ADMIN )\r
310                                                 pResponse->strContent += " checked";\r
311 \r
312                                         pResponse->strContent += "> Admin Access (Admin)<br>\n";\r
313                                         pResponse->strContent += "<input name=\"us_access_signup\" type=checkbox";\r
314 \r
315                                         if( iAccess & ACCESS_SIGNUP )\r
316                                                 pResponse->strContent += " checked";\r
317 \r
318                                         pResponse->strContent += "> Signup Access<br><br>\n";\r
319                                         pResponse->strContent += "<input type=submit value=\"Edit User\">\n";\r
320                                         pResponse->strContent += "</form>\n";\r
321                                         pResponse->strContent += "</body>\n";\r
322                                         pResponse->strContent += "</html>\n";\r
323 \r
324                                         return;\r
325                                 }\r
326                         }\r
327                         else\r
328                         {\r
329                                 pResponse->strContent += "<p>Unable to edit user. The user \"" + UTIL_RemoveHTML( strUser ) + "\" does not exist. Click <a href=\"/users.html\">here</a> to return to the users page.</p>\n";\r
330                                 pResponse->strContent += "</body>\n";\r
331                                 pResponse->strContent += "</html>\n";\r
332 \r
333                                 return;\r
334                         }\r
335                 }\r
336 \r
337                 //\r
338                 // delete user\r
339                 //\r
340 \r
341                 else if( strAction == "delete" )\r
342                 {\r
343                         if( strOK == "1" )\r
344                         {\r
345                                 deleteUser( strUser );\r
346 \r
347                                 pResponse->strContent += "<p>Deleted user \"" + UTIL_RemoveHTML( strUser ) + "\". Click <a href=\"/users.html\">here</a> to return to the users page.</p>\n";\r
348                                 pResponse->strContent += "</body>\n";\r
349                                 pResponse->strContent += "</html>\n";\r
350 \r
351                                 return;\r
352                         }\r
353                         else\r
354                         {\r
355                                 pResponse->strContent += "<p>Are you sure you want to delete the user \"" + UTIL_RemoveHTML( strUser ) + "\"? WARNING! If there are no admin users, you won't be able to administrate your tracker!</p>\n";\r
356                                 pResponse->strContent += "<p><a href=\"/users.html?user=" + UTIL_StringToEscaped( strUser ) + "&action=delete&ok=1\">OK</a></p>\n";\r
357                                 pResponse->strContent += "</body>\n";\r
358                                 pResponse->strContent += "</html>\n";\r
359 \r
360                                 return;\r
361                         }\r
362                 }\r
363 \r
364                 //\r
365                 // create user\r
366                 //\r
367 \r
368                 pResponse->strContent += "<form method=\"get\" action=\"/users.html\">\n";\r
369                 pResponse->strContent += "<p><strong>Create User</strong></p>\n";\r
370                 pResponse->strContent += "<input name=\"us_login\" type=text size=24> Login<br><br>\n";\r
371                 pResponse->strContent += "<input name=\"us_password\" type=password size=20> Password<br>\n";\r
372                 pResponse->strContent += "<input name=\"us_password_verify\" type=password size=20> Verify Password<br><br>\n";\r
373                 pResponse->strContent += "<input name=\"us_email\" type=text size=40> E-Mail<br><br>\n";\r
374                 pResponse->strContent += "<input name=\"us_access_view\" type=checkbox> View Access (Basic)<br>\n";\r
375                 pResponse->strContent += "<input name=\"us_access_dl\" type=checkbox> DL Access (Downloader)<br>\n";\r
376                 pResponse->strContent += "<input name=\"us_access_comments\" type=checkbox> Comments Access (Poster)<br>\n";\r
377                 pResponse->strContent += "<input name=\"us_access_upload\" type=checkbox> Upload Access (Uploader)<br>\n";\r
378                 pResponse->strContent += "<input name=\"us_access_edit\" type=checkbox> Edit Access (Moderator)<br>\n";\r
379                 pResponse->strContent += "<input name=\"us_access_admin\" type=checkbox> Admin Access (Admin)<br>\n";\r
380                 pResponse->strContent += "<input name=\"us_access_signup\" type=checkbox> Signup Access<br><br>\n";\r
381                 pResponse->strContent += "<input type=submit value=\"Create User\">\n";\r
382                 pResponse->strContent += "</form>\n";\r
383 \r
384                 //\r
385                 // user table\r
386                 //\r
387 \r
388                 if( m_pUsers )\r
389                 {\r
390                         if( m_pUsers->isEmpty( ) )\r
391                         {\r
392                                 pResponse->strContent += "<p><strong>WARNING! Your tracker does not have any users. Guests will have full access until someone creates the first user.</strong></p>\n";\r
393                                 pResponse->strContent += "</body>\n";\r
394                                 pResponse->strContent += "</html>\n";\r
395 \r
396                                 return;\r
397                         }\r
398 \r
399                         map<string, CAtom *> *pmapDicti = m_pUsers->getValuePtr( );\r
400 \r
401                         unsigned long iKeySize = pmapDicti->size( );\r
402 \r
403                         // add the users into this structure one by one and sort it afterwards\r
404 \r
405                         struct user_t *pUsersT = new struct user_t[iKeySize];\r
406 \r
407                         unsigned long i = 0;\r
408 \r
409                         for( map<string, CAtom *> :: iterator it = pmapDicti->begin( ); it != pmapDicti->end( ); it++ )\r
410                         {\r
411                                 pUsersT[i].strLogin = (*it).first;\r
412                                 pUsersT[i].strLowerLogin = UTIL_ToLower( pUsersT[i].strLogin );\r
413                                 pUsersT[i].iAccess = m_iGuestAccess;\r
414 \r
415                                 if( (*it).second->isDicti( ) )\r
416                                 {\r
417                                         CAtom *pMD5 = ( (CAtomDicti *)(*it).second )->getItem( "md5" );\r
418                                         CAtom *pAccess = ( (CAtomDicti *)(*it).second )->getItem( "access" );\r
419                                         CAtom *pMail = ( (CAtomDicti *)(*it).second )->getItem( "email" );\r
420                                         CAtom *pCreated = ( (CAtomDicti *)(*it).second )->getItem( "created" );\r
421 \r
422                                         if( pMD5 )\r
423                                                 pUsersT[i].strMD5 = pMD5->toString( );\r
424 \r
425                                         if( pMail )\r
426                                         {\r
427                                                 pUsersT[i].strMail = pMail->toString( );\r
428                                                 pUsersT[i].strLowerMail = UTIL_ToLower( pUsersT[i].strMail );\r
429                                         }\r
430 \r
431                                         if( pAccess && pAccess->isLong( ) )\r
432                                                 pUsersT[i].iAccess = (int)( (CAtomLong *)pAccess )->getValue( );\r
433 \r
434                                         if( pCreated )\r
435                                                 pUsersT[i].strCreated = pCreated->toString( );\r
436                                 }\r
437 \r
438                                 i++;\r
439                         }\r
440 \r
441                         string strSort = pRequest->mapParams["sort"];\r
442 \r
443                         if( !strSort.empty( ) )\r
444                         {\r
445                                 int iSort = atoi( strSort.c_str( ) );\r
446 \r
447                                 if( iSort == SORTU_ALOGIN )\r
448                                         qsort( pUsersT, iKeySize, sizeof( struct user_t ), asortuByLogin );\r
449                                 else if( iSort == SORTU_AACCESS )\r
450                                         qsort( pUsersT, iKeySize, sizeof( struct user_t ), asortuByAccess );\r
451                                 else if( iSort == SORTU_AEMAIL )\r
452                                         qsort( pUsersT, iKeySize, sizeof( struct user_t ), asortuByMail );\r
453                                 else if( iSort == SORTU_ACREATED )\r
454                                         qsort( pUsersT, iKeySize, sizeof( struct user_t ), asortuByCreated );\r
455                                 else if( iSort == SORTU_DLOGIN )\r
456                                         qsort( pUsersT, iKeySize, sizeof( struct user_t ), dsortuByLogin );\r
457                                 else if( iSort == SORTU_DACCESS )\r
458                                         qsort( pUsersT, iKeySize, sizeof( struct user_t ), dsortuByAccess );\r
459                                 else if( iSort == SORTU_DEMAIL )\r
460                                         qsort( pUsersT, iKeySize, sizeof( struct user_t ), dsortuByMail );\r
461                                 else if( iSort == SORTU_DCREATED )\r
462                                         qsort( pUsersT, iKeySize, sizeof( struct user_t ), dsortuByCreated );\r
463                                 else\r
464                                 {\r
465                                         // default action is to sort by created\r
466 \r
467                                         qsort( pUsersT, iKeySize, sizeof( struct user_t ), dsortuByCreated );\r
468                                 }\r
469                         }\r
470                         else\r
471                         {\r
472                                 // default action is to sort by created\r
473 \r
474                                 qsort( pUsersT, iKeySize, sizeof( struct user_t ), dsortuByCreated );\r
475                         }\r
476 \r
477                         // some preliminary search crap\r
478 \r
479                         string strSearch = pRequest->mapParams["search"];\r
480                         string strLowerSearch = UTIL_ToLower( strSearch );\r
481                         string strSearchResp = UTIL_StringToEscaped( strSearch );\r
482 \r
483                         if( !strSearch.empty( ) )\r
484                                 pResponse->strContent += "<p class=\"search_results\">Search results for \"" + UTIL_RemoveHTML( strSearch ) + "\".</p>\n";\r
485 \r
486                         // which page are we viewing\r
487 \r
488                         unsigned int iStart = 0;\r
489 \r
490                         if( m_iUsersPerPage > 0 )\r
491                         {\r
492                                 string strPage = pRequest->mapParams["page"];\r
493 \r
494                                 if( !strPage.empty( ) )\r
495                                         iStart = atoi( strPage.c_str( ) ) * m_iUsersPerPage;\r
496 \r
497                                 pResponse->strContent += "<p class=\"pagenum_top\">Page " + CAtomInt( ( iStart / m_iUsersPerPage ) + 1 ).toString( ) + "</p>\n";\r
498                         }\r
499 \r
500                         bool bFound = false;\r
501 \r
502                         int iAdded = 0;\r
503                         int iSkipped = 0;\r
504 \r
505                         // for correct page numbers after searching\r
506 \r
507                         int iFound = 0;\r
508 \r
509                         for( unsigned long i = 0; i < iKeySize; i++ )\r
510                         {\r
511                                 if( !strSearch.empty( ) )\r
512                                 {\r
513                                         // only display entries that match the search\r
514 \r
515                                         if( pUsersT[i].strLowerLogin.find( strLowerSearch ) == string :: npos )\r
516                                                 continue;\r
517                                 }\r
518 \r
519                                 iFound++;\r
520 \r
521                                 if( m_iUsersPerPage == 0 || iAdded < m_iUsersPerPage )\r
522                                 {\r
523                                         if( !bFound )\r
524                                         {\r
525                                                 // output table headers\r
526 \r
527                                                 pResponse->strContent += "<p>Users</p>\n";\r
528                                                 pResponse->strContent += "<table summary=\"users\">\n";\r
529                                                 pResponse->strContent += "<tr><th class=\"name\">Login";\r
530                                                 pResponse->strContent += "<br><a class=\"sort\" href=\"/users.html?sort=" + SORTUSTR_ALOGIN;\r
531 \r
532                                                 if( !strSearch.empty( ) )\r
533                                                         pResponse->strContent += "&search=" + strSearchResp;\r
534 \r
535                                                 pResponse->strContent += "\">A</a> <a class=\"sort\" href=\"/users.html?sort=" + SORTUSTR_DLOGIN;\r
536 \r
537                                                 if( !strSearch.empty( ) )\r
538                                                         pResponse->strContent += "&search=" + strSearchResp;\r
539 \r
540                                                 pResponse->strContent += "\">Z</a>";\r
541                                                 pResponse->strContent += "</th><th>Access";\r
542                                                 pResponse->strContent += "<br><a class=\"sort\" href=\"/users.html?sort=" + SORTUSTR_AACCESS;\r
543 \r
544                                                 if( !strSearch.empty( ) )\r
545                                                         pResponse->strContent += "&search=" + strSearchResp;\r
546 \r
547                                                 pResponse->strContent += "\">A</a> <a class=\"sort\" href=\"/users.html?sort=" + SORTUSTR_DACCESS;\r
548 \r
549                                                 if( !strSearch.empty( ) )\r
550                                                         pResponse->strContent += "&search=" + strSearchResp;\r
551 \r
552                                                 pResponse->strContent += "\">Z</a>";\r
553                                                 pResponse->strContent += "</th><th>E-Mail";\r
554                                                 pResponse->strContent += "<br><a class=\"sort\" href=\"/users.html?sort=" + SORTUSTR_AEMAIL;\r
555 \r
556                                                 if( !strSearch.empty( ) )\r
557                                                         pResponse->strContent += "&search=" + strSearchResp;\r
558 \r
559                                                 pResponse->strContent += "\">A</a> <a class=\"sort\" href=\"/users.html?sort=" + SORTUSTR_DEMAIL;\r
560 \r
561                                                 if( !strSearch.empty( ) )\r
562                                                         pResponse->strContent += "&search=" + strSearchResp;\r
563 \r
564                                                 pResponse->strContent += "\">Z</a>";\r
565                                                 pResponse->strContent += "</th><th>Created";\r
566                                                 pResponse->strContent += "<br><a class=\"sort\" href=\"/users.html?sort=" + SORTUSTR_ACREATED;\r
567 \r
568                                                 if( !strSearch.empty( ) )\r
569                                                         pResponse->strContent += "&search=" + strSearchResp;\r
570 \r
571                                                 pResponse->strContent += "\">A</a> <a class=\"sort\" href=\"/users.html?sort=" + SORTUSTR_DCREATED;\r
572 \r
573                                                 if( !strSearch.empty( ) )\r
574                                                         pResponse->strContent += "&search=" + strSearchResp;\r
575 \r
576                                                 pResponse->strContent += "\">Z</a>";\r
577                                                 pResponse->strContent += "</th><th>Admin</th></tr>\n";\r
578 \r
579                                                 bFound = true;\r
580                                         }\r
581 \r
582                                         if( iSkipped == (int)iStart )\r
583                                         {\r
584                                                 // output table rows\r
585 \r
586                                                 if( iAdded % 2 )\r
587                                                         pResponse->strContent += "<tr class=\"even\">";\r
588                                                 else\r
589                                                         pResponse->strContent += "<tr class=\"odd\">";\r
590 \r
591                                                 pResponse->strContent += "<td class=\"name\">";\r
592                                                 pResponse->strContent += UTIL_RemoveHTML( pUsersT[i].strLogin );\r
593                                                 pResponse->strContent += "</td><td>";\r
594                                                 pResponse->strContent += UTIL_AccessToString( pUsersT[i].iAccess );\r
595                                                 pResponse->strContent += "</td><td>";\r
596                                                 pResponse->strContent += UTIL_RemoveHTML( pUsersT[i].strMail );\r
597                                                 pResponse->strContent += "</td><td>";\r
598 \r
599                                                 if( !pUsersT[i].strCreated.empty( ) )\r
600                                                 {\r
601                                                         // strip year and seconds from time\r
602 \r
603                                                         pResponse->strContent += pUsersT[i].strCreated.substr( 5, pUsersT[i].strCreated.size( ) - 8 );\r
604                                                 }\r
605 \r
606                                                 pResponse->strContent += "</td><td>[<a href=\"/users.html?user=" + UTIL_StringToEscaped( pUsersT[i].strLogin ) + "&action=edit\">Edit</a>] [<a href=\"/users.html?user=" + UTIL_StringToEscaped( pUsersT[i].strLogin ) + "&action=delete\">Delete</a>]</td></tr>\n";\r
607 \r
608                                                 iAdded++;\r
609                                         }\r
610                                         else\r
611                                                 iSkipped++;\r
612                                 }\r
613                         }\r
614 \r
615                         delete [] pUsersT;\r
616 \r
617                         // some finishing touches\r
618 \r
619                         if( bFound )\r
620                                 pResponse->strContent += "</table>\n";\r
621 \r
622                         pResponse->strContent += "<span class=\"search_users\"><form method=\"get\" action=\"/users.html\">\n";\r
623 \r
624                         if( !strSort.empty( ) )\r
625                                 pResponse->strContent += "<input name=\"sort\" type=hidden value=\"" + strSort + "\">\n";\r
626 \r
627                         pResponse->strContent += "Search <input name=\"search\" type=text size=40> <a href=\"/users.html\">Clear Search</a>\n";\r
628                         pResponse->strContent += "</form></span>\n";\r
629 \r
630                         // page numbers\r
631 \r
632                         if( m_iUsersPerPage > 0 )\r
633                         {\r
634                                 pResponse->strContent += "<p class=\"pagenum_bottom\">";\r
635 \r
636                                 for( unsigned long i = 0; i < (unsigned int)iFound; i += m_iUsersPerPage )\r
637                                 {\r
638                                         pResponse->strContent += " ";\r
639 \r
640                                         // don't link to current page\r
641 \r
642                                         if( i != iStart )\r
643                                         {\r
644                                                 pResponse->strContent += "<a href=\"/users.html?page=" + CAtomInt( i / m_iUsersPerPage ).toString( );\r
645 \r
646                                                 if( !strSort.empty( ) )\r
647                                                         pResponse->strContent += "&sort=" + strSort;\r
648 \r
649                                                 if( !strSearch.empty( ) )\r
650                                                         pResponse->strContent += "&search=" + strSearchResp;\r
651 \r
652                                                 pResponse->strContent += "\">";\r
653                                         }\r
654 \r
655                                         pResponse->strContent += CAtomInt( ( i / m_iUsersPerPage ) + 1 ).toString( );\r
656 \r
657                                         if( i != iStart )\r
658                                                 pResponse->strContent += "</a>";\r
659 \r
660                                         pResponse->strContent += " ";\r
661 \r
662                                         // don't display a bar after the last page\r
663 \r
664                                         if( i + (unsigned int)m_iUsersPerPage < (unsigned int)iFound )\r
665                                                 pResponse->strContent += "|";\r
666                                 }\r
667 \r
668                                 pResponse->strContent += "</p>\n";\r
669                         }\r
670                 }\r
671         }\r
672         else\r
673                 pResponse->strContent += "<p class=\"denied\">You are not authorized to view this page.</p>\n";\r
674 \r
675         pResponse->strContent += "</body>\n";\r
676         pResponse->strContent += "</html>\n";\r
677 }\r