acctfuncs.inc 23.1 KB
Newer Older
1
<?php
2

Dan McGee's avatar
Dan McGee committed
3
4
5
6
7
8
9
10
# Helper function- retrieve request param if available, "" otherwise
function in_request($name) {
	if (isset($_REQUEST[$name])) {
		return $_REQUEST[$name];
	}
	return "";
}

11
# Display the standard Account form, pass in default values if any
12

eric's avatar
eric committed
13
function display_account_form($UTYPE,$A,$U="",$T="",$S="",
14
			$E="",$P="",$C="",$R="",$L="",$I="",$UID=0) {
eric's avatar
eric committed
15
	# UTYPE: what user type the form is being displayed for
16
17
18
19
20
21
22
23
24
25
26
	# A: what "form" name to use
	# U: value to display for username
	# T: value to display for account type
	# S: value to display for account suspended
	# E: value to display for email address
	# P: password value
	# C: confirm password value
	# R: value to display for RealName
	# L: value to display for Language preference
	# I: value to display for IRC nick
	# N: new package notify value
eric's avatar
eric committed
27
	# UID: Users.ID value in case form is used for editing
28
29
30

	global $SUPPORTED_LANGS;

31
	print "<form action='account.php' method='post'>\n";
Lukas Fleischer's avatar
Lukas Fleischer committed
32
33
	print "<fieldset>";
	print "<input type='hidden' name='Action' value='".$A."' />\n";
eric's avatar
eric committed
34
	if ($UID) {
Lukas Fleischer's avatar
Lukas Fleischer committed
35
		print "<input type='hidden' name='ID' value='".$UID."' />\n";
eric's avatar
eric committed
36
	}
Lukas Fleischer's avatar
Lukas Fleischer committed
37
38
	print "</fieldset>";
	print "<table border='0' cellpadding='0' cellspacing='0' width='80%' style=\"margin:0 auto;\">\n";
39
40
41
42
43
	print "<tr><td colspan='2'>&nbsp;</td></tr>\n";

	print "<tr>";
	print "<td align='left'>".__("Username").":</td>";
	print "<td align='left'><input type='text' size='30' maxlength='64'";
Lukas Fleischer's avatar
Lukas Fleischer committed
44
	print " name='U' value='".htmlspecialchars($U,ENT_QUOTES)."' /> (".__("required").")</td>";
45
46
	print "</tr>\n";

47
	# Only TUs or Devs can promote/demote/suspend a user
eric's avatar
eric committed
48
	if ($UTYPE == "Trusted User" || $UTYPE == "Developer") {
49
50
51
		print "<tr>";
		print "<td align='left'>".__("Account Type").":</td>";
		print "<td align='left'><select name=T>\n";
eric's avatar
eric committed
52
53
		print "<option value='1'";
		$T == "User" ? print " selected>" : print ">";
54
		print __("Normal user")."\n";
eric's avatar
eric committed
55
56
57
		print "<option value='2'";
		$T == "Trusted User" ? print " selected>" : print ">";
		print __("Trusted user")."\n";
58
59

		# Only developers can make another account a developer
eric's avatar
eric committed
60
61
62
63
		if ($UTYPE == "Developer") {
			print "<option value='3'";
			$T == "Developer" ? print " selected>" : print ">";
			print __("Developer")."\n";
64
65
66
67
68
69
70
71
		}
		print "</select></td>";
		print "</tr>\n";

		print "<tr>";
		print "<td align='left'>".__("Account Suspended").":</td>";
		print "<td align='left'><input type='checkbox' name='S'";
		if ($S) {
Lukas Fleischer's avatar
Lukas Fleischer committed
72
			print " checked=\"checked\" />";
73
		} else {
Lukas Fleischer's avatar
Lukas Fleischer committed
74
			print " />";
75
76
77
78
79
80
81
		}
		print "</tr>\n";
	}

	print "<tr>";
	print "<td align='left'>".__("Email Address").":</td>";
	print "<td align='left'><input type='text' size='30' maxlength='64'";
Lukas Fleischer's avatar
Lukas Fleischer committed
82
	print " name='E' value='".htmlspecialchars($E,ENT_QUOTES)."' /> (".__("required").")</td>";
83
84
85
86
87
	print "</tr>\n";

	print "<tr>";
	print "<td align='left'>".__("Password").":</td>";
	print "<td align='left'><input type='password' size='30' maxlength='32'";
Lukas Fleischer's avatar
Lukas Fleischer committed
88
	print " name='P' value='".$P."' />";
89
	if ($A != "UpdateAccount") {
90
		print " (".__("required").")";
eric's avatar
eric committed
91
92
	}
	print "</td></tr>\n";
93
94
95
96

	print "<tr>";
	print "<td align='left'>".__("Re-type password").":</td>";
	print "<td align='left'><input type='password' size='30' maxlength='32'";
Lukas Fleischer's avatar
Lukas Fleischer committed
97
	print " name='C' value='".$C."' />";
98
	if ($A != "UpdateAccount") {
99
		print " (".__("required").")";
eric's avatar
eric committed
100
101
	}
	print "</td></tr>\n";
102
103
104
105

	print "<tr>";
	print "<td align='left'>".__("Real Name").":</td>";
	print "<td align='left'><input type='text' size='30' maxlength='32'";
Lukas Fleischer's avatar
Lukas Fleischer committed
106
	print " name='R' value='".htmlspecialchars($R,ENT_QUOTES)."' /></td>";
107
108
109
110
111
	print "</tr>\n";

	print "<tr>";
	print "<td align='left'>".__("IRC Nick").":</td>";
	print "<td align='left'><input type='text' size='30' maxlength='32'";
Lukas Fleischer's avatar
Lukas Fleischer committed
112
	print " name='I' value='".htmlspecialchars($I,ENT_QUOTES)."' /></td>";
113
114
115
116
117
	print "</tr>\n";

	print "<tr>";
	print "<td align='left'>".__("Language").":</td>";
	print "<td align='left'><select name=L>\n";
118
119

	reset($SUPPORTED_LANGS);
120
121
122
123
124
125
126
127
128
129
130
131
132
133
	while (list($code, $lang) = each($SUPPORTED_LANGS)) {
		if ($L == $code) {
			print "<option value=".$code." selected> ".$lang."\n";
		} else {
			print "<option value=".$code."> ".$lang."\n";
		}
	}
	print "</select></td>";
	print "</tr>\n";

	print "<tr><td colspan='2'>&nbsp;</td></tr>\n";
	print "<tr>";
	print "<td>&nbsp;</td>";
	print "<td align='left'>";
134

eric's avatar
eric committed
135
	if ($A == "UpdateAccount") {
eric's avatar
eric committed
136
		print "<input type='submit' class='button'";
Lukas Fleischer's avatar
Lukas Fleischer committed
137
		print " value='".__("Update")."' /> &nbsp; ";
138
	} else {
eric's avatar
eric committed
139
		print "<input type='submit' class='button'";
Lukas Fleischer's avatar
Lukas Fleischer committed
140
		print " value='".__("Create")."' /> &nbsp; ";
141
	}
Lukas Fleischer's avatar
Lukas Fleischer committed
142
	print "<input type='reset' class='button' value='".__("Reset")."' />";
143
144
145
146
147
148
149
150
151
152
153
	print "</td>";
	print "</tr>\n";

	print "</table>\n";
	print "</form>\n";
	return;
} # function display_account_form()


# process form input from a new/edit account form
#
eric's avatar
eric committed
154
function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="",
155
			$P="",$C="",$R="",$L="",$I="",$UID=0) {
eric's avatar
eric committed
156
	# UTYPE: The user's account type
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
	# TYPE: either "edit" or "new"
	# A: what parent "form" name to use
	# U: value to display for username
	# T: value to display for account type
	# S: value to display for account suspended
	# E: value to display for email address
	# P: password value
	# C: confirm password value
	# R: value to display for RealName
	# L: value to display for Language preference
	# I: value to display for IRC nick
	# N: new package notify value
	# UID: database Users.ID value

	# error check and process request for a new/modified account
	global $SUPPORTED_LANGS;

174
	if(isset($_COOKIE['AURSID'])) {
Loui Chang's avatar
Loui Chang committed
175
		$editor_user = uid_from_sid($_COOKIE['AURSID']);
176
177
	}
	else {
178
		$editor_user = null;
179
	}
180

181
182
	$dbh = db_connect();
	$error = "";
183
	if (empty($E) || empty($U)) {
184
185
		$error = __("Missing a required field.");
	}
186

187
188
189
	if ($TYPE == "new") {
		# they need password fields for this type of action
		#
190
		if (empty($P) || empty($C)) {
191
192
193
194
195
196
197
			$error = __("Missing a required field.");
		}
	} else {
		if (!$UID) {
			$error = __("Missing User ID");
		}
	}
198
199
200

  if (!$error && !valid_username($U) && !user_is_privileged($editor_user))
    $error = __("The username is invalid.") . "<ul>\n"
201
			."<li>" . __("It must be between %s and %s characters long",
202
203
			USERNAME_MIN_LEN,  USERNAME_MAX_LEN )
			. "</li>"
204
			. "<li>" . __("Start and end with a letter or number") . "</li>"
205
			. "<li>" . __("Can contain only one period, underscore or hyphen.")
206
207
			. "</li>\n</ul>";

208
209
210
	if (!$error && $P && $C && ($P != $C)) {
		$error = __("Password fields do not match.");
	}
211
	if (!$error && $P != '' && !good_passwd($P))
212
		$error = __("Your password must be at least %s characters.",PASSWD_MIN_LEN);
213

214
215
216
	if (!$error && !valid_email($E)) {
		$error = __("The email address is invalid.");
	}
eric's avatar
eric committed
217
218
219
	if ($UTYPE == "Trusted User" && $T == 3) {
		$error = __("A Trusted User cannot assign Developer status.");
	}
220
221
222
223
224
225
226
227
	if (!$error && !array_key_exists($L, $SUPPORTED_LANGS)) {
		$error = __("Language is not currently supported.");
	}
	if (!$error) {
		# check to see if this username is available
		# NOTE: a race condition exists here if we care...
		#
		$q = "SELECT COUNT(*) AS CNT FROM Users ";
228
		$q.= "WHERE Username = '".mysql_real_escape_string($U)."'";
eric's avatar
eric committed
229
230
231
		if ($TYPE == "edit") {
			$q.= " AND ID != ".intval($UID);
		}
232
233
234
235
236
		$result = db_query($q, $dbh);
		if ($result) {
			$row = mysql_fetch_array($result);
			if ($row[0]) {
				$error = __("The username, %h%s%h, is already in use.",
Viktor Leonhardt's avatar
Viktor Leonhardt committed
237
					"<b>", htmlspecialchars($U,ENT_QUOTES), "</b>");
238
239
240
241
242
243
244
245
			}
		}
	}
	if (!$error) {
		# check to see if this email address is available
		# NOTE: a race condition exists here if we care...
		#
		$q = "SELECT COUNT(*) AS CNT FROM Users ";
246
		$q.= "WHERE Email = '".mysql_real_escape_string($E)."'";
eric's avatar
eric committed
247
248
249
		if ($TYPE == "edit") {
			$q.= " AND ID != ".intval($UID);
		}
250
251
252
253
254
		$result = db_query($q, $dbh);
		if ($result) {
			$row = mysql_fetch_array($result);
			if ($row[0]) {
				$error = __("The address, %h%s%h, is already in use.",
Viktor Leonhardt's avatar
Viktor Leonhardt committed
255
						"<b>", htmlspecialchars($E,ENT_QUOTES), "</b>");
256
257
258
259
260
			}
		}
	}
	if ($error) {
		print "<span class='error'>".$error."</span><br/>\n";
eric's avatar
eric committed
261
		display_account_form($UTYPE, $A, $U, $T, $S, $E, "", "",
262
				$R, $L, $I, $UID);
263
264
265
	} else {
		if ($TYPE == "new") {
			# no errors, go ahead and create the unprivileged user
Denis's avatar
Denis committed
266
267
			$salt = generate_salt();
			$P = salted_hash($P, $salt);
268
			$escaped = array_map('mysql_real_escape_string',
Denis's avatar
Denis committed
269
270
271
				array($U, $E, $P, $salt, $R, $L, $I));
			$q = "INSERT INTO Users (" .
				"AccountTypeID, Suspended, Username, Email, Passwd, Salt" .
272
273
				", RealName, LangPreference, IRCNick) " .
				"VALUES (1, 0, '" . implode("', '", $escaped) . "')";
274
275
276
			$result = db_query($q, $dbh);
			if (!$result) {
				print __("Error trying to create account, %h%s%h: %s.",
Viktor Leonhardt's avatar
Viktor Leonhardt committed
277
						"<b>", htmlspecialchars($U,ENT_QUOTES), "</b>", mysql_error($dbh));
278
			} else {
279
280
281
				# account created/modified, tell them so.
				#
				print __("The account, %h%s%h, has been successfully created.",
Viktor Leonhardt's avatar
Viktor Leonhardt committed
282
						"<b>", htmlspecialchars($U,ENT_QUOTES), "</b>");
283
284
285
286
287
288
289
				print "<p>\n";
				print __("Click on the Home link above to login.");
				print "</p>\n";
			}

		} else {
			# no errors, go ahead and modify the user account
jchu's avatar
jchu committed
290

291
			$q = "UPDATE Users SET ";
292
			$q.= "Username = '".mysql_real_escape_string($U)."'";
eric's avatar
eric committed
293
294
295
296
297
298
299
300
			if ($T) {
				$q.= ", AccountTypeID = ".intval($T);
			}
			if ($S) {
				$q.= ", Suspended = 1";
			} else {
				$q.= ", Suspended = 0";
			}
301
			$q.= ", Email = '".mysql_real_escape_string($E)."'";
eric's avatar
eric committed
302
			if ($P) {
Denis's avatar
Denis committed
303
304
305
				$salt = generate_salt();
				$hash = salted_hash($P, $salt);
				$q .= ", Passwd = '$hash', Salt = '$salt'";
eric's avatar
eric committed
306
			}
307
308
309
			$q.= ", RealName = '".mysql_real_escape_string($R)."'";
			$q.= ", LangPreference = '".mysql_real_escape_string($L)."'";
			$q.= ", IRCNick = '".mysql_real_escape_string($I)."'";
310
			$q.= " WHERE ID = ".intval($UID);
311
312
313
			$result = db_query($q, $dbh);
			if (!$result) {
				print __("Error trying to modify account, %h%s%h: %s.",
Viktor Leonhardt's avatar
Viktor Leonhardt committed
314
						"<b>", htmlspecialchars($U,ENT_QUOTES), "</b>", mysql_error($dbh));
315
316
			} else {
				print __("The account, %h%s%h, has been successfully modified.",
Viktor Leonhardt's avatar
Viktor Leonhardt committed
317
						"<b>", htmlspecialchars($U,ENT_QUOTES), "</b>");
318
319
320
321
322
323
324
325
326
			}
		}
	}
	return;
}

# search existing accounts
#
function search_accounts_form() {
327
	include("search_accounts_form.php");
328
329
330
331
332
333
	return;
}


# search results page
#
eric's avatar
eric committed
334
function search_results_page($UTYPE,$O=0,$SB="",$U="",$T="",
335
		$S="",$E="",$R="",$I="") {
eric's avatar
eric committed
336
	# UTYPE: what account type the user belongs to
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
	# O: what row offset we're at
	# SB: how to sort the results
	# U: value to display for username
	# T: value to display for account type
	# S: value to display for account suspended
	# E: value to display for email address
	# R: value to display for RealName
	# I: value to display for IRC nick

	$HITS_PER_PAGE = 50;
	if ($O) {
		$OFFSET = intval($O);
	} else {
		$OFFSET = 0;
	}
	if ($OFFSET < 0) {
		$OFFSET = 0;
	}
	$search_vars = array();

	$q = "SELECT Users.*, AccountTypes.AccountType ";
	$q.= "FROM Users, AccountTypes ";
	$q.= "WHERE AccountTypes.ID = Users.AccountTypeID ";
	if ($T == "u") {
		$q.= "AND AccountTypes.ID = 1 ";
		$search_vars[] = "T";
	} elseif ($T == "t") {
		$q.= "AND AccountTypes.ID = 2 ";
		$search_vars[] = "T";
	} elseif ($T == "d") {
		$q.= "AND AccountTypes.ID = 3 ";
		$search_vars[] = "T";
	}
	if ($S) {
		$q.= "AND Users.Suspended = 1 ";
		$search_vars[] = "S";
	}
	if ($U) {
375
		$q.= "AND Username LIKE '%".mysql_real_escape_string($U)."%' ";
376
377
378
		$search_vars[] = "U";
	}
	if ($E) {
379
		$q.= "AND Email LIKE '%".mysql_real_escape_string($E)."%' ";
380
381
382
		$search_vars[] = "E";
	}
	if ($R) {
383
		$q.= "AND RealName LIKE '%".mysql_real_escape_string($R)."%' ";
384
385
386
		$search_vars[] = "R";
	}
	if ($I) {
387
		$q.= "AND IRCNick LIKE '%".mysql_real_escape_string($I)."%' ";
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
		$search_vars[] = "I";
	}
	switch ($SB) {
		case 't':
			$q.= "ORDER BY AccountTypeID, Username ";
			break;
		case 'r':
			$q.= "ORDER BY RealName, AccountTypeID ";
			break;
		case 'i':
			$q.= "ORDER BY IRCNick, AccountTypeID ";
			break;
		case 'v':
			$q.= "ORDER BY LastVoted, Username ";
			break;
		default:
			$q.= "ORDER BY Username, AccountTypeID ";
			break;
	}
	$search_vars[] = "SB";
408
	$q.= "LIMIT " . $HITS_PER_PAGE . " OFFSET " . $OFFSET;
409

410
411
	$dbh = db_connect();

412
413
414
415
416
417
418
	$result = db_query($q, $dbh);
	if (!$result) {
		print __("No results matched your search criteria.");
	} else {
		$num_rows = mysql_num_rows($result);
		if ($num_rows) {
			print "<table border='0' cellpadding='0'";
Lukas Fleischer's avatar
Lukas Fleischer committed
419
420
			print " cellspacing='0' width='90%'";
			print " style=\"margin:0 auto\">\n";
421
422
423
424
			print "<tr>";
			print "<td colspan='2'>";
			print "<table border='0' cellpadding='0'";
			print " cellspacing='0' width='100%'>\n";
Lukas Fleischer's avatar
Lukas Fleischer committed
425
			print "<tr>";
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
			print "<th class='header'>";
			print "<span class='f2'>".__("Username")."</span></th>";
			print "<th class='header'>";
			print "<span class='f2'>".__("Type")."</span></th>";
			print "<th class='header'>";
			print "<span class='f2'>".__("Status")."</span></th>";
			print "<th class='header'>";
			print "<span class='f2'>".__("Real Name")."</span></th>";
			print "<th class='header'>";
			print "<span class='f2'>".__("IRC Nick")."</span></th>";
			print "<th class='header'>";
			print "<span class='f2'>".__("Last Voted")."</span></th>";
			print "<th class='header'>";
			print "<span class='f2'>".__("Edit Account")."</span></th>";
			print "</tr>\n";
			$i = 0;
			while ($row = mysql_fetch_assoc($result)) {
				if ($i % 2) {
					$c = "data1";
				} else {
					$c = "data2";
				}
				print "<tr>";
				print "<td class='".$c."'>";
Lukas Fleischer's avatar
Lukas Fleischer committed
450
				print "<span class='f5'><a href='packages.php?SeB=m&amp;K=".$row["Username"]."'>".$row["Username"]."</a></span></td>";
451
452
453
454
455
456
457
458
459
460
461
				print "<td class='".$c."'>";
				print "<span class='f5'>".$row["AccountType"];
				print "</span></td>";
				print "<td class='".$c."'><span class='f5'>";
				if ($row["Suspended"]) {
					print __("Suspended");
				} else {
					print __("Active");
				}
				print "</span></td>";
				print "<td class='".$c."'><span class='f5'>";
Viktor Leonhardt's avatar
Viktor Leonhardt committed
462
				$row["RealName"] ? print htmlspecialchars($row["RealName"],ENT_QUOTES) : print "&nbsp;";
463
464
				print "</span></td>";
				print "<td class='".$c."'><span class='f5'>";
Viktor Leonhardt's avatar
Viktor Leonhardt committed
465
				$row["IRCNick"] ? print htmlspecialchars($row["IRCNick"],ENT_QUOTES) : print "&nbsp;";
466
467
468
469
470
471
472
				print "</span></td>";
				print "<td class='".$c."'><span class='f5'>";
				$row["LastVoted"]
						? print date("Ymd", $row["LastVoted"])
						: print __("Never");
				print "</span></td>";
				print "<td class='".$c."'><span class='f5'>";
eric's avatar
eric committed
473
474
475
476
477
				if ($UTYPE == "Trusted User" && $row["AccountType"] == "Developer") {
					# TUs can't edit devs
					#
					print "&nbsp;</span></td>";
				} else {
Lukas Fleischer's avatar
Lukas Fleischer committed
478
					$edit_url = "account.php?Action=DisplayAccount&amp;ID=".$row["ID"];
eric's avatar
eric committed
479
480
481
					print "<a href='".$edit_url . "'>";
					print "Edit</a></span></td>";
				}
482
483
484
485
486
487
488
489
				print "</tr>\n";
				$i++;
			}
			print "</table>\n";
			print "</td></tr>\n";

			print "<tr>";
			print "<td align='left'>";
490
			print "<form action='account.php' method='post'>\n";
Lukas Fleischer's avatar
Lukas Fleischer committed
491
492
			print "<fieldset>";
			print "<input type='hidden' name='Action' value='SearchAccounts' />\n";
493
			print "<input type='hidden' name='O'";
Lukas Fleischer's avatar
Lukas Fleischer committed
494
			print " value='".($OFFSET-$HITS_PER_PAGE)."' />\n";
495
496
497
			reset($search_vars);
			while (list($k, $ind) = each($search_vars)) {
				print "<input type='hidden' name='".$ind."'";
Lukas Fleischer's avatar
Lukas Fleischer committed
498
				print " value='".${$ind}."' />\n";
499
			}
eric's avatar
eric committed
500
			print "<input type='submit' class='button'";
Lukas Fleischer's avatar
Lukas Fleischer committed
501
502
			print " value='&lt;-- ".__("Less")."' />";
			print "</fieldset>";
503
504
505
			print "</form>\n";
			print "</td>";
			print "<td align='right'>";
506
			print "<form action='account.php' method='post'>\n";
Lukas Fleischer's avatar
Lukas Fleischer committed
507
508
			print "<fieldset>";
			print "<input type='hidden' name='Action' value='SearchAccounts' />\n";
509
			print "<input type='hidden' name='O'";
Lukas Fleischer's avatar
Lukas Fleischer committed
510
			print " value='".($OFFSET+$HITS_PER_PAGE)."' />\n";
511
512
513
			reset($search_vars);
			while (list($k, $ind) = each($search_vars)) {
				print "<input type='hidden' name='".$ind."'";
Lukas Fleischer's avatar
Lukas Fleischer committed
514
				print " value='".${$ind}."' />\n";
515
			}
eric's avatar
eric committed
516
			print "<input type='submit' class='button'";
Lukas Fleischer's avatar
Lukas Fleischer committed
517
518
			print " value='".__("More")." --&gt;' />";
			print "</fieldset>";
519
520
521
522
523
			print "</form>\n";
			print "</td>";
			print "</tr>\n";
			print "</table>\n";
		} else {
Lukas Fleischer's avatar
Lukas Fleischer committed
524
			print "<p style=\"text-align:center;\">\n";
525
			print __("No more results to display.");
Lukas Fleischer's avatar
Lukas Fleischer committed
526
			print "</p>\n";
527
528
529
530
531
		}
	}
	return;
}

532
533
# Display non-editable account info
#
534
function display_account_info($U="", $T="", $E="", $R="", $I="") {
535
536
537
538
539
540
541
542
	# U: value to display for username
	# T: value to display for account type
	# E: value to display for email address
	# R: value to display for RealName
	# I: value to display for IRC nick

	global $SUPPORTED_LANGS;

Lukas Fleischer's avatar
Lukas Fleischer committed
543
	print "<table border='0' cellpadding='0' cellspacing='0' width='33%' style=\"margin:0 auto;\">\n";
544
545
546
547
548
549
550
551
	print "  <tr>\n";
	print "    <td colspan='2'>&nbsp;</td>\n";
	print "  </tr>\n";

	print "  <tr>\n";
	print "    <td align='left'>".__("Username").":</td>\n";
	print "    <td align='left'>".$U."</td>\n";
	print "  </tr>\n";
552

553
554
555
556
557
558
559
	print "  <tr>\n";
	print "    <td align='left'>".__("Account Type").":</td>\n";
	print "    <td align='left'>";
	if ($T == "User") {
		print __("User");
	} elseif ($T == "Trusted User") {
		print __("Trusted User");
560
	} elseif ($T == "Developer") {
561
562
		print __("Developer");
	}
Lukas Fleischer's avatar
Lukas Fleischer committed
563
564
	print "    </td>\n";
	print "  </tr>\n";
565

566
567
	print "  <tr>\n";
	print "    <td align='left'>".__("Email Address").":</td>\n";
Viktor Leonhardt's avatar
Viktor Leonhardt committed
568
	print "    <td align='left'><a href='mailto:".htmlspecialchars($E,ENT_QUOTES)."'>".htmlspecialchars($E,ENT_QUOTES)."</a></td>\n";
569
570
571
572
	print "  </tr>\n";

	print "  <tr>\n";
	print "    <td align='left'>".__("Real Name").":</td>\n";
Viktor Leonhardt's avatar
Viktor Leonhardt committed
573
	print "    <td align='left'>".htmlspecialchars($R,ENT_QUOTES)."</td>\n";
574
575
576
577
	print "  </tr>\n";

	print "  <tr>\n";
	print "    <td align='left'>".__("IRC Nick").":</td>\n";
Viktor Leonhardt's avatar
Viktor Leonhardt committed
578
	print "    <td align='left'>".htmlspecialchars($I,ENT_QUOTES)."</td>\n";
579
580
	print "  </tr>\n";

581
	print "  <tr>\n";
Lukas Fleischer's avatar
Lukas Fleischer committed
582
	print "    <td colspan='2'><a href='packages.php?K=".$U."&amp;SeB=m'>".__("View this user's packages")."</a></td>\n";
583
584
	print "  </tr>\n";

585
586
587
588
	print "</table>\n";
	return;
}

589
590
591
592
593
/*
 * Returns SID (Session ID) and error (error message) in an array
 * SID of 0 means login failed.
 */
function try_login() {
594
	global $MAX_SESSIONS_PER_USER, $PERSISTENT_COOKIE_TIMEOUT;
595

Loui Chang's avatar
Loui Chang committed
596
	$login_error = "";
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
	$new_sid = "";
	$userID = null;

	if ( isset($_REQUEST['user']) || isset($_REQUEST['passwd']) ) {

		$userID = valid_user($_REQUEST['user']);

		if ( user_suspended( $userID ) ) {
			$login_error = "Account Suspended.";
		}
		elseif ( $userID && isset($_REQUEST['passwd'])
		  && valid_passwd($userID, $_REQUEST['passwd']) ) {

			$logged_in = 0;
			$num_tries = 0;

			# Account looks good.  Generate a SID and store it.

			$dbh = db_connect();
			while (!$logged_in && $num_tries < 5) {
617
618
619
620
621
				if ($MAX_SESSIONS_PER_USER) {
					# Delete all user sessions except the
					# last ($MAX_SESSIONS_PER_USER - 1).
					$q = "DELETE s.* FROM Sessions s ";
					$q.= "LEFT JOIN (SELECT SessionID FROM Sessions ";
622
					$q.= "WHERE UsersId = " . $userID . " ";
623
624
625
					$q.= "ORDER BY LastUpdateTS DESC ";
					$q.= "LIMIT " . ($MAX_SESSIONS_PER_USER - 1) . ") q ";
					$q.= "ON s.SessionID = q.SessionID ";
626
					$q.= "WHERE s.UsersId = " . $userID . " ";
627
628
629
630
					$q.= "AND q.SessionID IS NULL;";
					db_query($q, $dbh);
				}

631
632
				$new_sid = new_sid();
				$q = "INSERT INTO Sessions (UsersID, SessionID, LastUpdateTS)"
633
				  ." VALUES (" . $userID . ", '" . $new_sid . "', UNIX_TIMESTAMP())";
634
				$result = db_query($q, $dbh);
635

636
637
638
639
640
				# Query will fail if $new_sid is not unique
				if ($result) {
					$logged_in = 1;
					break;
				}
641

642
				$num_tries++;
643
			}
644

645
646
647
			if ($logged_in) {
				# set our SID cookie

Dan McGee's avatar
Dan McGee committed
648
649
				if (isset($_POST['remember_me']) &&
					$_POST['remember_me'] == "on") {
650
					# Set cookies for 30 days.
651
					$cookie_time = time() + $PERSISTENT_COOKIE_TIMEOUT;
652
653
654
655
656
657

					# Set session for 30 days.
					$q = "UPDATE Sessions SET LastUpdateTS = $cookie_time ";
					$q.= "WHERE SessionID = '$new_sid'";
					db_query($q, $dbh);
				}
658
659
				else
					$cookie_time = 0;
660

661
				setcookie("AURSID", $new_sid, $cookie_time, "/");
662
				header("Location: " . $_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING']);
663
664
665
666
667
668
669
670
				$login_error = "";

			}
			else {
				$login_error = "Error trying to generate session id.";
			}
		}
		else {
671
			$login_error = __("Bad username or password.");
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
		}
	}
	return array('SID' => $new_sid, 'error' => $login_error);
}

/*
 * Only checks if the name itself is valid
 * Longer or equal to USERNAME_MIN_LEN
 * Shorter or equal to USERNAME_MAX_LEN
 * Starts and ends with a letter or number
 * Contains at most ONE dot, hyphen, or underscore
 * Returns the username if it is valid
 * Returns nothing if it isn't valid
 */
function valid_username( $user )
{
	if (!empty($user)) {
689

690
691
692
		#Is username at not too short or too long?
		if ( strlen($user) >= USERNAME_MIN_LEN &&
		  strlen($user) <= USERNAME_MAX_LEN ) {
693

694
			$user = strtolower($user);
695
			# Does username:
696
697
698
699
700
701
702
703
704
			# start and end with a letter or number
			# contain only letters and numbers,
			#  and at most has one dash, period, or underscore
			if ( preg_match("/^[a-z0-9]+[.\-_]?[a-z0-9]+$/", $user) ) {
				#All is good return the username
				return $user;
			}
		}
	}
705

706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
	return;
}

/*
 * Checks if the username is valid and if it exists in the database
 * Returns the username ID or nothing
 */
function valid_user( $user )
{
	/*	if ( $user = valid_username($user) ) { */
	if ( $user ) {
		$dbh = db_connect();
		$q = "SELECT ID FROM Users WHERE Username = '"
			. mysql_real_escape_string($user). "'";

		$result = mysql_fetch_row(db_query($q, $dbh));
722
723

		# Is the username in the database?
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
		if ($result[0]) {
			return $result[0];
		}
	}
	return;
}

function good_passwd( $passwd )
{
	if ( strlen($passwd) >= PASSWD_MIN_LEN ) {
		return true;
	}
	return false;
}

/* Verifies that the password is correct for the userID specified.
 * Returns true or false
 */
function valid_passwd( $userID, $passwd )
{
744
	if ( strlen($passwd) > 0 ) {
745
746
		$dbh = db_connect();

Denis's avatar
Denis committed
747
748
749
750
751
		# get salt for this user
		$salt = get_salt($userID);
		if ($salt) {
			# use salt
			$passwd_q = "SELECT ID FROM Users" .
752
				" WHERE ID = " . $userID  . " AND Passwd = '" .
Denis's avatar
Denis committed
753
754
755
756
757
758
759
760
				salted_hash($passwd, $salt) . "'";
			$passwd_result = mysql_fetch_row(db_query($passwd_q, $dbh));
			if ($passwd_result[0]) {
				return true;
			}
		} else {
			# check without salt
			$nosalt_q = "SELECT ID FROM Users".
761
				" WHERE ID = " . $userID .
Denis's avatar
Denis committed
762
763
764
765
766
767
				" AND Passwd = '" . md5($passwd) . "'";
			$nosalt_result = mysql_fetch_row(db_query($nosalt_q, $dbh));
			if ($nosalt_result[0]) {
				# password correct, but salt it first
				if (!save_salt($userID, $passwd)) {
					trigger_error("Unable to salt user's password;" .
768
						" ID " . $userID, E_USER_WARNING);
Denis's avatar
Denis committed
769
770
771
772
773
					return false;
				}

				return true;
			}
774
775
776
777
778
779
780
781
782
783
784
		}
	}
	return false;
}

/*
 * Is the user account suspended?
 */
function user_suspended( $id )
{
	$dbh = db_connect();
785
	$q = "SELECT Suspended FROM Users WHERE ID = " . $id;
786
787
788
789
790
791
792
793
794
795
796
797
798
	$result = mysql_fetch_row(db_query($q, $dbh));
	if ($result[0] == 1 ) {
		return true;
	}
	return false;
}

/*
 * This should be expanded to return something
 */
function user_delete( $id )
{
	$dbh = db_connect();
799
	$q = "DELETE FROM Users WHERE ID = " . $id;
800
801
802
803
804
805
806
807
808
809
810
	$result = mysql_fetch_row(db_query($q, $dbh));
	return;
}

/*
 * A different way of determining a user's privileges
 * rather than account_from_sid()
 */
function user_is_privileged( $id )
{
	$dbh = db_connect();
811
	$q = "SELECT AccountTypeID FROM Users WHERE ID = " . $id;
812
	$result = mysql_fetch_row(db_query($q, $dbh));
813
	if( $result[0] > 1) {
814
		return $result[0];
815
	}
816
817
818
819
	return 0;

}

820
# Clear out old expired sessions.
821
function clear_expired_sessions($dbh = null) {
822
823
	global $LOGIN_TIMEOUT;

824
	if (empty($dbh)) {
825
		$dbh = db_connect();
826
	}
827

828
	$q = "DELETE FROM Sessions WHERE LastUpdateTS < (UNIX_TIMESTAMP() - $LOGIN_TIMEOUT)";
829
830
831
832
	db_query($q, $dbh);

	return;
}
833