acctfuncs.inc.php 23.4 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";
36
		print "<input type='hidden' name='token' value='".htmlspecialchars($_COOKIE['AURSID'])."' />\n";
eric's avatar
eric committed
37
	}
Lukas Fleischer's avatar
Lukas Fleischer committed
38
39
	print "</fieldset>";
	print "<table border='0' cellpadding='0' cellspacing='0' width='80%' style=\"margin:0 auto;\">\n";
40
41
42
43
44
	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
45
	print " name='U' value='".htmlspecialchars($U,ENT_QUOTES)."' /> (".__("required").")</td>";
46
47
	print "</tr>\n";

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

		# Only developers can make another account a developer
eric's avatar
eric committed
61
62
63
64
		if ($UTYPE == "Developer") {
			print "<option value='3'";
			$T == "Developer" ? print " selected>" : print ">";
			print __("Developer")."\n";
65
66
67
68
69
70
71
72
		}
		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
73
			print " checked=\"checked\" />";
74
		} else {
Lukas Fleischer's avatar
Lukas Fleischer committed
75
			print " />";
76
77
78
79
80
81
82
		}
		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
83
	print " name='E' value='".htmlspecialchars($E,ENT_QUOTES)."' /> (".__("required").")</td>";
84
85
86
87
88
	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
89
	print " name='P' value='".$P."' />";
90
	if ($A != "UpdateAccount") {
91
		print " (".__("required").")";
eric's avatar
eric committed
92
93
	}
	print "</td></tr>\n";
94
95
96
97

	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
98
	print " name='C' value='".$C."' />";
99
	if ($A != "UpdateAccount") {
100
		print " (".__("required").")";
eric's avatar
eric committed
101
102
	}
	print "</td></tr>\n";
103
104
105
106

	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
107
	print " name='R' value='".htmlspecialchars($R,ENT_QUOTES)."' /></td>";
108
109
110
111
112
	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
113
	print " name='I' value='".htmlspecialchars($I,ENT_QUOTES)."' /></td>";
114
115
116
117
118
	print "</tr>\n";

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

	reset($SUPPORTED_LANGS);
121
122
123
124
125
126
127
128
129
130
131
132
133
134
	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'>";
135

eric's avatar
eric committed
136
	if ($A == "UpdateAccount") {
eric's avatar
eric committed
137
		print "<input type='submit' class='button'";
Lukas Fleischer's avatar
Lukas Fleischer committed
138
		print " value='".__("Update")."' /> &nbsp; ";
139
	} else {
eric's avatar
eric committed
140
		print "<input type='submit' class='button'";
Lukas Fleischer's avatar
Lukas Fleischer committed
141
		print " value='".__("Create")."' /> &nbsp; ";
142
	}
Lukas Fleischer's avatar
Lukas Fleischer committed
143
	print "<input type='reset' class='button' value='".__("Reset")."' />";
144
145
146
147
148
149
150
151
152
153
154
	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
155
function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="",
156
			$P="",$C="",$R="",$L="",$I="",$UID=0) {
eric's avatar
eric committed
157
	# UTYPE: The user's account type
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
	# 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;

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

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

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

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

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

215
216
217
	if (!$error && !valid_email($E)) {
		$error = __("The email address is invalid.");
	}
eric's avatar
eric committed
218
219
220
	if ($UTYPE == "Trusted User" && $T == 3) {
		$error = __("A Trusted User cannot assign Developer status.");
	}
221
222
223
224
225
226
227
228
	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 ";
229
		$q.= "WHERE Username = '".db_escape_string($U)."'";
eric's avatar
eric committed
230
231
232
		if ($TYPE == "edit") {
			$q.= " AND ID != ".intval($UID);
		}
233
234
235
236
237
		$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
238
					"<b>", htmlspecialchars($U,ENT_QUOTES), "</b>");
239
240
241
242
243
244
245
246
			}
		}
	}
	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 ";
247
		$q.= "WHERE Email = '".db_escape_string($E)."'";
eric's avatar
eric committed
248
249
250
		if ($TYPE == "edit") {
			$q.= " AND ID != ".intval($UID);
		}
251
252
253
254
255
		$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
256
						"<b>", htmlspecialchars($E,ENT_QUOTES), "</b>");
257
258
259
260
261
			}
		}
	}
	if ($error) {
		print "<span class='error'>".$error."</span><br/>\n";
eric's avatar
eric committed
262
		display_account_form($UTYPE, $A, $U, $T, $S, $E, "", "",
263
				$R, $L, $I, $UID);
264
265
266
	} else {
		if ($TYPE == "new") {
			# no errors, go ahead and create the unprivileged user
Denis's avatar
Denis committed
267
268
			$salt = generate_salt();
			$P = salted_hash($P, $salt);
269
			$escaped = array_map('db_escape_string',
Denis's avatar
Denis committed
270
271
272
				array($U, $E, $P, $salt, $R, $L, $I));
			$q = "INSERT INTO Users (" .
				"AccountTypeID, Suspended, Username, Email, Passwd, Salt" .
273
274
				", RealName, LangPreference, IRCNick) " .
				"VALUES (1, 0, '" . implode("', '", $escaped) . "')";
275
276
277
			$result = db_query($q, $dbh);
			if (!$result) {
				print __("Error trying to create account, %h%s%h: %s.",
Viktor Leonhardt's avatar
Viktor Leonhardt committed
278
						"<b>", htmlspecialchars($U,ENT_QUOTES), "</b>", mysql_error($dbh));
279
			} else {
280
281
282
				# account created/modified, tell them so.
				#
				print __("The account, %h%s%h, has been successfully created.",
Viktor Leonhardt's avatar
Viktor Leonhardt committed
283
						"<b>", htmlspecialchars($U,ENT_QUOTES), "</b>");
284
285
286
287
288
289
290
				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
291

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

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


# search results page
#
eric's avatar
eric committed
335
function search_results_page($UTYPE,$O=0,$SB="",$U="",$T="",
336
		$S="",$E="",$R="",$I="") {
eric's avatar
eric committed
337
	# UTYPE: what account type the user belongs to
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
375
	# 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) {
376
		$q.= "AND Username LIKE '%".db_escape_like($U)."%' ";
377
378
379
		$search_vars[] = "U";
	}
	if ($E) {
380
		$q.= "AND Email LIKE '%".db_escape_like($E)."%' ";
381
382
383
		$search_vars[] = "E";
	}
	if ($R) {
384
		$q.= "AND RealName LIKE '%".db_escape_like($R)."%' ";
385
386
387
		$search_vars[] = "R";
	}
	if ($I) {
388
		$q.= "AND IRCNick LIKE '%".db_escape_like($I)."%' ";
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
		$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";
409
	$q.= "LIMIT " . $HITS_PER_PAGE . " OFFSET " . $OFFSET;
410

411
412
	$dbh = db_connect();

413
414
415
416
417
418
419
	$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
420
421
			print " cellspacing='0' width='90%'";
			print " style=\"margin:0 auto\">\n";
422
423
424
425
			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
426
			print "<tr>";
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
			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
451
				print "<span class='f5'><a href='packages.php?SeB=m&amp;K=".$row["Username"]."'>".$row["Username"]."</a></span></td>";
452
453
454
455
456
457
458
459
460
461
462
				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
463
				$row["RealName"] ? print htmlspecialchars($row["RealName"],ENT_QUOTES) : print "&nbsp;";
464
465
				print "</span></td>";
				print "<td class='".$c."'><span class='f5'>";
Viktor Leonhardt's avatar
Viktor Leonhardt committed
466
				$row["IRCNick"] ? print htmlspecialchars($row["IRCNick"],ENT_QUOTES) : print "&nbsp;";
467
468
469
470
471
472
473
				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
474
475
476
477
478
				if ($UTYPE == "Trusted User" && $row["AccountType"] == "Developer") {
					# TUs can't edit devs
					#
					print "&nbsp;</span></td>";
				} else {
Lukas Fleischer's avatar
Lukas Fleischer committed
479
					$edit_url = "account.php?Action=DisplayAccount&amp;ID=".$row["ID"];
eric's avatar
eric committed
480
481
482
					print "<a href='".$edit_url . "'>";
					print "Edit</a></span></td>";
				}
483
484
485
486
487
488
489
490
				print "</tr>\n";
				$i++;
			}
			print "</table>\n";
			print "</td></tr>\n";

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

533
534
# Display non-editable account info
#
535
function display_account_info($U="", $T="", $E="", $R="", $I="") {
536
537
538
539
540
541
542
543
	# 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
544
	print "<table border='0' cellpadding='0' cellspacing='0' width='33%' style=\"margin:0 auto;\">\n";
545
546
547
548
549
550
551
552
	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";
553

554
555
556
557
558
559
560
	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");
561
	} elseif ($T == "Developer") {
562
563
		print __("Developer");
	}
Lukas Fleischer's avatar
Lukas Fleischer committed
564
565
	print "    </td>\n";
	print "  </tr>\n";
566

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

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

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

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

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

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

Loui Chang's avatar
Loui Chang committed
597
	$login_error = "";
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
	$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) {
618
619
620
621
622
				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 ";
623
					$q.= "WHERE UsersId = " . $userID . " ";
624
625
626
					$q.= "ORDER BY LastUpdateTS DESC ";
					$q.= "LIMIT " . ($MAX_SESSIONS_PER_USER - 1) . ") q ";
					$q.= "ON s.SessionID = q.SessionID ";
627
					$q.= "WHERE s.UsersId = " . $userID . " ";
628
629
630
631
					$q.= "AND q.SessionID IS NULL;";
					db_query($q, $dbh);
				}

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

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

643
				$num_tries++;
644
			}
645

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

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

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

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

			}
			else {
				$login_error = "Error trying to generate session id.";
			}
		}
		else {
672
			$login_error = __("Bad username or password.");
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
		}
	}
	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)) {
690

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

695
			$user = strtolower($user);
696
			# Does username:
697
698
699
700
701
702
703
704
705
			# 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;
			}
		}
	}
706

707
708
709
710
711
712
713
714
715
716
717
718
719
	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 = '"
720
			. db_escape_string($user). "'";
721

722
		$result = db_query($q, $dbh);
723
		# Is the username in the database?
724
725
726
		if ($result) {
			$row = mysql_fetch_row($result);
			return $row[0];
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
		}
	}
	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 )
{
745
	if ( strlen($passwd) > 0 ) {
746
747
		$dbh = db_connect();

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

/*
 * Is the user account suspended?
 */
function user_suspended( $id )
{
elij's avatar
elij committed
790
791
792
	if (!$id) {
		return false;
	}
793
	$dbh = db_connect();
794
	$q = "SELECT Suspended FROM Users WHERE ID = " . $id;
795
796
797
798
799
800
	$result = db_query($q, $dbh);
	if ($result) {
		$row = mysql_fetch_row($result);
		if ($result[0] == 1 ) {
			return true;
		}
801
802
803
804
805
806
807
808
809
810
	}
	return false;
}

/*
 * This should be expanded to return something
 */
function user_delete( $id )
{
	$dbh = db_connect();
811
	$q = "DELETE FROM Users WHERE ID = " . $id;
812
	db_query($q, $dbh);
813
814
815
816
817
818
819
820
821
822
	return;
}

/*
 * A different way of determining a user's privileges
 * rather than account_from_sid()
 */
function user_is_privileged( $id )
{
	$dbh = db_connect();
823
	$q = "SELECT AccountTypeID FROM Users WHERE ID = " . $id;
824
825
826
827
828
829
	$result = db_query($q, $dbh);
	if ($result) {
		$row = mysql_fetch_row($result);
		if( $result[0] > 1) {
			return $result[0];
		}
830
	}
831
832
833
834
	return 0;

}

835
# Clear out old expired sessions.
836
function clear_expired_sessions($dbh = null) {
837
838
	global $LOGIN_TIMEOUT;

839
	if (empty($dbh)) {
840
		$dbh = db_connect();
841
	}
842

843
	$q = "DELETE FROM Sessions WHERE LastUpdateTS < (UNIX_TIMESTAMP() - $LOGIN_TIMEOUT)";
844
845
846
847
	db_query($q, $dbh);

	return;
}
848