Use only the local-name of an email for the SSH usernames

This way users connect to "you@gerrit.com" rather than the much longer
(and uglier) "you@gmail.com@gerrit.com".  We still generate the user
from the email, preventing end-users from selecting their own SSH name.
We could in the future change this if there is sufficient demand.

Because we validate both the username and the SSH public key we can
only run into name duplication problems if multiple accounts have
the same local name in their preferred email address and use the same
SSH public key, which should only be possible if they are both using
"root@..." as their email and both keys were created on Debian with
the infamous broken ssh-keygen implementation.

Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
Shawn O. Pearce
2008-12-31 09:33:57 -08:00
parent c76e08c13e
commit 3dde99e429
7 changed files with 37 additions and 7 deletions

View File

@@ -21,6 +21,7 @@ public interface AccountConstants extends Constants {
String fullName();
String preferredEmail();
String sshUserName();
String registeredOn();
String defaultContext();

View File

@@ -2,6 +2,7 @@ accountSettingsHeading = Account Settings
fullName = Full Name
preferredEmail = Email Address
sshUserName = SSH Username
registeredOn = Registered
defaultContext = Default Context

View File

@@ -88,14 +88,15 @@ public class AccountSettings extends AccountScreen {
fieldIdx = 1;
}
info = new Grid(3, 2);
info = new Grid(4, 2);
info.setStyleName("gerrit-InfoBlock");
info.addStyleName("gerrit-AccountInfoBlock");
add(info);
infoRow(0, Util.C.fullName());
infoRow(1, Util.C.preferredEmail());
infoRow(2, Util.C.registeredOn());
infoRow(2, Util.C.sshUserName());
infoRow(3, Util.C.registeredOn());
final CellFormatter fmt = info.getCellFormatter();
fmt.addStyleName(0, 0, "topmost");
@@ -163,7 +164,8 @@ public class AccountSettings extends AccountScreen {
void display(final Account account) {
info.setText(0, fieldIdx, account.getFullName());
info.setText(1, fieldIdx, account.getPreferredEmail());
info.setText(2, fieldIdx, mediumFormat(account.getRegisteredOn()));
info.setText(2, fieldIdx, account.getSshUserName());
info.setText(3, fieldIdx, mediumFormat(account.getRegisteredOn()));
prefsPanel.display(account);
}
}

View File

@@ -106,6 +106,14 @@ public final class Account {
@Column(notNull = false)
protected String preferredEmail;
/**
* Username to authenticate as through SSH connections.
* <p>
* Note that this property tracks {@link #preferredEmail}.
*/
@Column(notNull = false)
protected String sshUserName;
/** Default number of lines of context when viewing a patch. */
@Column
protected short defaultContext;
@@ -150,9 +158,19 @@ public final class Account {
/** Set the email address the user prefers to be contacted through. */
public void setPreferredEmail(final String addr) {
if (addr != null && addr.contains("@")) {
sshUserName = addr.substring(0, addr.indexOf('@')).toLowerCase();
} else {
sshUserName = null;
}
preferredEmail = addr;
}
/** Get the name the user logins as through SSH. */
public String getSshUserName() {
return sshUserName;
}
/** Get the date and time the user first registered. */
public Timestamp getRegisteredOn() {
return registeredOn;

View File

@@ -29,6 +29,9 @@ public interface AccountAccess extends Access<Account, Account.Id> {
@Query("WHERE preferredEmail = ? LIMIT 2")
ResultSet<Account> byPreferredEmail(String email) throws OrmException;
@Query("WHERE sshUserName = ?")
ResultSet<Account> bySshUserName(String userName) throws OrmException;
@Query("WHERE fullName >= ? AND fullName <= ? ORDER BY fullName LIMIT ?")
ResultSet<Account> suggestByFullName(String nameA, String nameB, int limit)
throws OrmException;

View File

@@ -146,15 +146,15 @@ public class SshUtil {
/** Invalidate all cached keys for the given account. */
public static void invalidate(final Account acct) {
if (acct != null) {
invalidate(acct.getPreferredEmail());
invalidate(acct.getSshUserName());
}
}
/** Invalidate all cached keys for the given account. */
public static void invalidate(final String username){
public static void invalidate(final String username) {
synchronized (keys) {
keys.remove(username);
}
}
}
/** Locate keys for the requested account whose email matches the name given. */
@@ -172,7 +172,7 @@ public class SshUtil {
final ReviewDb db = rdf.open();
try {
final List<Account> matches =
db.accounts().byPreferredEmail(username).toList();
db.accounts().bySshUserName(username).toList();
if (matches.isEmpty()) {
return Collections.<AccountSshKey> emptyList();
}