Skip to content

Commit

Permalink
web: add option for making user name unique.
Browse files Browse the repository at this point in the history
We currently allow different accounts to have the same user name.
Hence in places where we need to identify users
(sending PMs, blocking users) we have to use numeric IDs,
which means that we have to display them in various places.
This is ugly; I'm not sure why I thought it was a good idea.

Anyway.  Add a project.inc option UNIQUE_USER_NAME.  If set:
- it won't let you create an account with a dup name,
    of change your name to a dup
- it doesn't show user IDs anywhere
- in places where you specify users, you use names

This is now the default for new projects.
Existing projects - which have lots of duplicate names -
can't use it unless they de-dup their names somehow
(and this might anger users).

Also some minor code cleanup.  sprintf() is our friend.
  • Loading branch information
davidpanderson committed May 8, 2024
1 parent cdc9cf2 commit 2f77d23
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 68 deletions.
2 changes: 1 addition & 1 deletion db/constraints.sql
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ alter table user
add unique(email_addr),
add unique(authenticator),
add index ind_tid (teamid),
add index user_name(name),
add unique(name),
add index user_tot (total_credit desc),
-- db_dump.C
add index user_avg (expavg_credit desc),
Expand Down
8 changes: 7 additions & 1 deletion html/inc/pm.inc
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,13 @@ function pm_form($replyto, $userid, $error = null) {
echo "<input type=\"hidden\" name=\"action\" value=\"send\">\n";
echo form_tokens($g_logged_in_user->authenticator);
start_table();
row2(tra("To")."<br /><small>".tra("User IDs or unique usernames, separated with commas")."</small>",
row2(
sprintf('%s <br><small>%s</small>',
tra("To"),
UNIQUE_USER_NAME
?tra('User names, separated with commas')
:tra("User IDs or unique usernames, separated with commas")
),
"<input type=\"text\" class=\"form-control\" name=\"to\" value=\"$writeto\">",
null, '20%'
);
Expand Down
8 changes: 6 additions & 2 deletions html/inc/user.inc
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,9 @@ function show_user_info_private($user) {
.$delete_account_str
);
}
row2(tra("User ID")."<br/><p class=\"small\">".tra("Used in community functions")."</p>", $user->id);
if (!UNIQUE_USER_NAME) {
row2(tra("User ID")."<br/><p class=\"small\">".tra("Used in community functions")."</p>", $user->id);
}
if (!NO_COMPUTING) {
row2(
tra("Account keys"),
Expand Down Expand Up @@ -459,7 +461,9 @@ function show_community_private($user) {
//
function show_user_summary_public($user) {
global $g_logged_in_user;
row2(tra("User ID"), $user->id);
if (!UNIQUE_USER_NAME) {
row2(tra("User ID"), $user->id);
}
row2(tra("%1 member since", PROJECT), date_str($user->create_time));
if (USER_COUNTRY) {
row2(tra("Country"), $user->country);
Expand Down
21 changes: 21 additions & 0 deletions html/inc/user_util.inc
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ function is_valid_user_name($name, &$reason) {
$reason = tra("user name may not contain HTML tags");
return false;
}
if (is_numeric($name)) {
$reason = tra("user name may not be a number");
return false;
}
return true;
}

Expand Down Expand Up @@ -228,6 +232,23 @@ function validate_post_make_user() {
if (!is_valid_user_name($new_name, $reason)) {
show_error($reason);
}
if (UNIQUE_USER_NAME) {
$u = BoincUser::lookup_name($new_name);
if ($u) {
page_head("That name is in use");
echo "<p>The following user names are taken;
please go back and use a different one.<p>
";
$users = BoincUser::enum(
sprintf("name like '%s%%'", $new_name)
);
foreach ($users as $u){
echo "<p>$u->name\n";
}
page_tail();
exit;
}
}

$new_email_addr = strtolower(post_str("new_email_addr"));
if (!is_valid_email_addr($new_email_addr)) {
Expand Down
3 changes: 3 additions & 0 deletions html/inc/util.inc
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ if (!defined('DARK_MODE')) {
if (!defined('VALIDATE_EMAIL_TO_POST')) {
define('VALIDATE_EMAIL_TO_POST', false);
}
if (!defined('UNIQUE_USER_NAME')) {
define('UNIQUE_USER_NAME', false);
}

// don't allow anything between .php and ? in URL
//
Expand Down
1 change: 1 addition & 0 deletions html/project.sample/project.inc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ display_errors();

//-------------- enable/disable web features

define('UNIQUE_USER_NAME', true);
define("FORUM_QA_MERGED_MODE", true);
// Set to true to merge Message boards and Q&A section
define ("DISABLE_PROFILES", true);
Expand Down
31 changes: 22 additions & 9 deletions html/user/edit_forum_preferences_action.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,22 +130,35 @@

} // DISABLE_FORUMS

$add_user_to_filter = (isset($_POST["add_user_to_filter"]) && $_POST["add_user_to_filter"]!="");
if ($add_user_to_filter){
$user_to_add = trim($_POST["forum_filter_user"]);
if ($user_to_add!="" and $user_to_add==strval(intval($user_to_add))){
$other_user = BoincUser::lookup_id($user_to_add);
if (!$other_user) {
echo tra("No such user:")." ".$user_to_add;
} else {
add_ignored_user($user, $other_user);
if (UNIQUE_USER_NAME) {
$name = post_str('forum_filter_user', true);
if ($name) {
$other_user = BoincUser::lookup(
sprintf("name='%s'", BoincDb::escape_string($name))
);
if (!$other_user) error_page('No such user');
add_ignored_user($user, $other_user);
}
} else {
// todo: clean up the following
$add_user_to_filter = (isset($_POST["add_user_to_filter"]) && $_POST["add_user_to_filter"]!="");
if ($add_user_to_filter){
$user_to_add = trim($_POST["forum_filter_user"]);
if ($user_to_add!="" and $user_to_add==strval(intval($user_to_add))){
$other_user = BoincUser::lookup_id($user_to_add);
if (!$other_user) {
echo tra("No such user:")." ".$user_to_add;
} else {
add_ignored_user($user, $other_user);
}
}
}
}

// Or remove some from the ignore list
//
$ignored_users = get_ignored_list($user);
// todo: use foreach
for ($i=0;$i<sizeof($ignored_users);$i++){
$remove = "remove".trim($ignored_users[$i]);
if (isset($_POST[$remove]) && $_POST[$remove]!=""){
Expand Down
41 changes: 33 additions & 8 deletions html/user/edit_forum_preferences_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,10 @@

// ------------ Message filtering -----------

row1(tra("Message filtering"));
row1(tra("Message blocking"));

// get list of blocked users
//
$filtered_userlist = get_ignored_list($user);
$forum_filtered_userlist = "";
for ($i=0; $i<sizeof($filtered_userlist); $i++){
Expand All @@ -146,16 +148,39 @@
echo "Missing user $id";
continue;
}
$forum_filtered_userlist .= "<input class=\"btn btn-default\" type=\"submit\" name=\"remove".$filtered_user->id."\" value=\"".tra("Remove")."\"> ".$filtered_user->id." - ".user_links($filtered_user)."<br>";
$forum_filtered_userlist .= sprintf(
'
%s %s
<input class="btn btn-default" type="submit" name="remove%d" value="%s">
<br>
',
UNIQUE_USER_NAME?'':"$filtered_user->id -",
user_links($filtered_user),
$filtered_user->id,
tra("Unblock")
);
}
}

row2(tra("Filtered users").
"<br><p class=\"text-muted\">".tra("Ignore message board posts and private messages from these users.")."</p>",
"$forum_filtered_userlist
<input type=\"text\" name=\"forum_filter_user\" size=12> ".tra("User ID (For instance: 123456789)")."
<p></p><input class=\"btn btn-default\" type=\"submit\" name=\"add_user_to_filter\" value=\"".tra("Add user to filter")."\">
"
row2(
sprintf(
'%s<br><p class="text-muted">%s</p>',
tra("Blocked users"),
tra('Ignore message board posts and private messages from these users.')
),
$forum_filtered_userlist
);
row2(
tra('Block user'),
sprintf(
'
%s
<input type="text" name="forum_filter_user" size=12>
<input class="btn btn-default" type="submit" name="add_user_to_filter" value="%s">
',
UNIQUE_USER_NAME?tra('User name'):tra('User ID (For instance: 123456789)'),
tra("Block")
)
);

row1(tra("Update"));
Expand Down
5 changes: 5 additions & 0 deletions html/user/edit_user_info_action.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@
}
$name = BoincDb::escape_string($name);

$u = BoincUser::lookup(sprintf("name='%s'", $name));
if ($u) {
error_page('That name is in use - go back and try another.');
}

$url = "";
$country = "";
$postal_code = "";
Expand Down
12 changes: 11 additions & 1 deletion html/user/pm.php
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,17 @@ function do_send($logged_in_user) {
}
BoincForumPrefs::lookup($user);
if (is_ignoring($user, $logged_in_user)) {
pm_form($replyto, $userid, tra("User %1 (ID: %2) is not accepting private messages from you.", $user->name, $user->id));
pm_form(
$replyto, $userid,
UNIQUE_USER_NAME
?tra("User %1 is not accepting private messages from you.",
$user->name
)
:tra("User %1 (ID: %2) is not accepting private messages from you.",
$user->name,
$user->id
)
);
}
if (!isset($userids[$user->id])) {
$userlist[] = $user;
Expand Down
114 changes: 68 additions & 46 deletions html/user/user_search.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,27 @@
require_once("../inc/user.inc");

function show_user($user) {
echo "
<tr>
<td>", user_links($user, BADGE_HEIGHT_MEDIUM), " (ID $user->id)</td>
";
if ($user->teamid) {
$team = BoincTeam::lookup_id($user->teamid);
echo sprintf('<tr><td>%s%s</td>',
user_links($user, BADGE_HEIGHT_MEDIUM),
UNIQUE_USER_NAME?'':" (ID $user->id)"
);
if (!DISABLE_TEAMS) {
if ($user->teamid) {
$team = BoincTeam::lookup_id($user->teamid);
echo "
<td> <a href=team_display.php?teamid=$team->id>$team->name</a> </td>
";
} else {
echo "<td><br></td>";
}
}
if (!NO_COMPUTING) {
echo "
<td> <a href=team_display.php?teamid=$team->id>$team->name</a> </td>
<td align=right>", format_credit($user->expavg_credit), "</td>
<td align=right>", format_credit_large($user->total_credit), "</td>
";
} else {
echo "<td><br></td>";
}
echo "
<td align=right>", format_credit($user->expavg_credit), "</td>
<td align=right>", format_credit_large($user->total_credit), "</td>
<td>", $user->country, "</td>
<td>", time_str($user->create_time),"</td>
</tr>
Expand All @@ -57,20 +63,26 @@ function user_search_form() {
echo "<select class=\"form-control\" name=\"country\"><option value=\"any\" selected>".tra("Any")."</option>";
echo country_select_options("asdf");
echo "</select></td></tr>";
row2(tra("With profile?"),
"<input type=radio name=profile value=either checked=1> ".tra("Either")."
&nbsp;<input type=radio name=profile value=no> ".tra("No")."
&nbsp;<input type=radio name=profile value=yes> ".tra("Yes")."
");
row2(tra("On a team?"),
"<input type=radio name=team value=either checked=1> ".tra("Either")."
&nbsp;<input type=radio name=team value=no> ".tra("No")."
&nbsp;<input type=radio name=team value=yes> ".tra("Yes")."
");
row1(tra("Ordering"), 2, "heading");
row2(tra("Decreasing sign-up time"), "<input type=radio name=search_type value=\"date\" checked>");
row2(tra("Decreasing average credit"), "<input type=radio name=search_type value=\"rac\">");
row2(tra("Decreasing total credit"), "<input type=radio name=search_type value=\"total\">");
if (!DISABLE_PROFILES) {
row2(tra("With profile?"),
"<input type=radio name=profile value=either checked=1> ".tra("Either")."
&nbsp;<input type=radio name=profile value=no> ".tra("No")."
&nbsp;<input type=radio name=profile value=yes> ".tra("Yes")."
");
}
if (!DISABLE_TEAMS) {
row2(tra("On a team?"),
"<input type=radio name=team value=either checked=1> ".tra("Either")."
&nbsp;<input type=radio name=team value=no> ".tra("No")."
&nbsp;<input type=radio name=team value=yes> ".tra("Yes")."
");
}
if (!NO_COMPUTING) {
row1(tra("Ordering"), 2, "heading");
row2(tra("Decreasing sign-up time"), "<input type=radio name=search_type value=\"date\" checked>");
row2(tra("Decreasing average credit"), "<input type=radio name=search_type value=\"rac\">");
row2(tra("Decreasing total credit"), "<input type=radio name=search_type value=\"total\">");
}
row2("", "<input class=\"btn btn-success\" type=submit name=action value=".tra("Search").">");
end_table();
echo "
Expand All @@ -96,17 +108,21 @@ function search_action() {
$s = BoincDb::escape_string($country);
$where .= " and country='$s'";
}
$t = get_str('team');
if ($t == 'yes') {
$where .= " and teamid<>0";
} else if ($t == 'no') {
$where .= " and teamid=0";
if (!DISABLE_TEAMS) {
$t = get_str('team');
if ($t == 'yes') {
$where .= " and teamid<>0";
} else if ($t == 'no') {
$where .= " and teamid=0";
}
}
$t = get_str('profile');
if ($t == 'yes') {
$where .= " and has_profile<>0";
} else if ($t == 'no') {
$where .= " and has_profile=0";
if (!DISABLE_PROFILES) {
$t = get_str('profile');
if ($t == 'yes') {
$where .= " and has_profile<>0";
} else if ($t == 'no') {
$where .= " and has_profile=0";
}
}

$search_type = get_str('search_type', true);
Expand All @@ -124,17 +140,23 @@ function search_action() {
foreach ($users as $user) {
if ($n==0) {
start_table('table-striped');
row_heading_array(
array(
tra("Name"),
tra("Team"),
tra("Average credit"),
tra("Total credit"),
tra("Country"),
tra("Joined")
),
array(null, null, ALIGN_RIGHT, ALIGN_RIGHT, null, null)
);
$x = ['Name'];
$y = [null];
if (!DISABLE_TEAMS) {
$x[] = 'Team';
$y[] = null;
}
if (!NO_COMPUTING) {
$x[] = 'Average credit';
$y[] = ALIGN_RIGHT;
$x[] = 'Total credit';
$y[] = ALIGN_RIGHT;
}
$x[] = 'Country';
$y[] = null;
$x[] = 'Joined';
$y[] = null;
row_heading_array($x, $y);
}
show_user($user);
$n++;
Expand Down

0 comments on commit 2f77d23

Please sign in to comment.