Show the trust status of a user's identities

If a user's provider is untrusted, we show them it in the new
status column, so they can take steps to join a trusted site
and link that identity, then remove the untrusted one.  This
may be necessary to upgrade the user's effective groups to
their actual memberships.

Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
Shawn O. Pearce
2009-02-25 15:07:43 -08:00
parent a2299669f2
commit 92d7ab7556
10 changed files with 104 additions and 31 deletions

View File

@@ -51,8 +51,10 @@ public interface AccountConstants extends Constants {
String invalidSshKeyError();
String webIdLastUsed();
String webIdStatus();
String webIdEmail();
String webIdIdentity();
String untrustedProvider();
String buttonDeleteIdentity();
String buttonLinkIdentity();

View File

@@ -27,8 +27,10 @@ sshKeyLastUsed = Last Used
sshKeyStored = Stored
webIdLastUsed = Last Login
webIdStatus = Status
webIdEmail = Email Address
webIdIdentity = Identity
untrustedProvider = Untrusted
buttonDeleteIdentity = Delete
buttonLinkIdentity = Link Another Identity

View File

@@ -39,7 +39,7 @@ public interface AccountSecurity extends RemoteJsonService {
AsyncCallback<VoidResult> callback);
@SignInRequired
void myExternalIds(AsyncCallback<List<AccountExternalId>> callback);
void myExternalIds(AsyncCallback<ExternalIdDetail> callback);
@SignInRequired
void deleteExternalIds(Set<AccountExternalId.Key> keys,

View File

@@ -217,11 +217,12 @@ class ContactPanel extends Composite {
}
});
Util.ACCOUNT_SEC
.myExternalIds(new GerritCallback<List<AccountExternalId>>() {
public void onSuccess(final List<AccountExternalId> result) {
.myExternalIds(new GerritCallback<ExternalIdDetail>() {
public void onSuccess(final ExternalIdDetail detail) {
if (!isAttached()) {
return;
}
final List<AccountExternalId> result = detail.ids;
final Set<String> emails = new HashSet<String>();
for (final AccountExternalId i : result) {
if (i.getEmailAddress() != null

View File

@@ -0,0 +1,49 @@
// Copyright 2009 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.client.account;
import com.google.gerrit.client.reviewdb.AccountExternalId;
import com.google.gerrit.client.reviewdb.TrustedExternalId;
import com.google.gerrit.client.rpc.Common;
import java.util.List;
public class ExternalIdDetail {
protected List<AccountExternalId> ids;
protected List<TrustedExternalId> trusted;
protected ExternalIdDetail() {
}
public ExternalIdDetail(final List<AccountExternalId> myIds,
final List<TrustedExternalId> siteTrusts) {
ids = myIds;
trusted = siteTrusts;
}
public List<AccountExternalId> getIds() {
return ids;
}
public boolean isTrusted(final AccountExternalId id) {
switch (Common.getGerritConfig().getLoginType()) {
case HTTP:
return true;
case OPENID:
default:
return TrustedExternalId.isTrusted(id, trusted);
}
}
}

View File

@@ -31,7 +31,6 @@ import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
class ExternalIdPanel extends Composite {
@@ -86,20 +85,20 @@ class ExternalIdPanel extends Composite {
}
private void refresh() {
Util.ACCOUNT_SEC
.myExternalIds(new GerritCallback<List<AccountExternalId>>() {
public void onSuccess(final List<AccountExternalId> result) {
identites.display(result);
identites.finishDisplay(true);
}
});
Util.ACCOUNT_SEC.myExternalIds(new GerritCallback<ExternalIdDetail>() {
public void onSuccess(final ExternalIdDetail result) {
identites.display(result);
identites.finishDisplay(true);
}
});
}
private class IdTable extends FancyFlexTable<AccountExternalId> {
IdTable() {
table.setText(0, 2, Util.C.webIdLastUsed());
table.setText(0, 3, Util.C.webIdEmail());
table.setText(0, 4, Util.C.webIdIdentity());
table.setText(0, 3, Util.C.webIdStatus());
table.setText(0, 4, Util.C.webIdEmail());
table.setText(0, 5, Util.C.webIdIdentity());
table.addTableListener(new TableListener() {
public void onCellClicked(SourcesTableEvents sender, int row, int cell) {
if (cell != 1 && getRowItem(row) != null) {
@@ -113,6 +112,7 @@ class ExternalIdPanel extends Composite {
fmt.addStyleName(0, 2, S_DATA_HEADER);
fmt.addStyleName(0, 3, S_DATA_HEADER);
fmt.addStyleName(0, 4, S_DATA_HEADER);
fmt.addStyleName(0, 5, S_DATA_HEADER);
}
@Override
@@ -189,15 +189,16 @@ class ExternalIdPanel extends Composite {
}
}
void display(final List<AccountExternalId> result) {
void display(final ExternalIdDetail result) {
while (1 < table.getRowCount())
table.removeRow(table.getRowCount() - 1);
for (final AccountExternalId k : result) {
addOneId(k);
for (final AccountExternalId k : result.getIds()) {
addOneId(k, result);
}
final AccountExternalId mostRecent = AccountExternalId.mostRecent(result);
final AccountExternalId mostRecent =
AccountExternalId.mostRecent(result.getIds());
if (mostRecent != null) {
for (int row = 1; row < table.getRowCount(); row++) {
if (getRowItem(row) == mostRecent) {
@@ -212,7 +213,8 @@ class ExternalIdPanel extends Composite {
}
}
void addOneId(final AccountExternalId k) {
void addOneId(final AccountExternalId k, final ExternalIdDetail detail) {
final FlexCellFormatter fmt = table.getFlexCellFormatter();
final int row = table.getRowCount();
table.insertRow(row);
applyDataRowStyle(row);
@@ -227,15 +229,21 @@ class ExternalIdPanel extends Composite {
} else {
table.setHTML(row, 2, "&nbsp;");
}
table.setText(row, 3, k.getEmailAddress());
table.setText(row, 4, k.getExternalId());
if (detail.isTrusted(k)) {
table.setHTML(row, 3, "&nbsp;");
} else {
table.setText(row, 3, Util.C.untrustedProvider());
fmt.addStyleName(row, 3, "gerrit-Identity-UntrustedExternalId");
}
table.setText(row, 4, k.getEmailAddress());
table.setText(row, 5, k.getExternalId());
final FlexCellFormatter fmt = table.getFlexCellFormatter();
fmt.addStyleName(row, 1, S_ICON_CELL);
fmt.addStyleName(row, 2, S_DATA_CELL);
fmt.addStyleName(row, 2, "C_LAST_UPDATE");
fmt.addStyleName(row, 3, S_DATA_CELL);
fmt.addStyleName(row, 3, "C_LAST_UPDATE");
fmt.addStyleName(row, 4, S_DATA_CELL);
fmt.addStyleName(row, 5, S_DATA_CELL);
setRowItem(row, k);
}

View File

@@ -222,13 +222,13 @@ public class GroupCache {
default:
// Validate against the trusted provider list
//
return TrustedExternalId.isIdentityTrustable(getTrustedIds(db), db
.accountExternalIds().byAccount(accountId));
return TrustedExternalId.isIdentityTrustable(getTrustedExternalIds(db),
db.accountExternalIds().byAccount(accountId));
}
}
private synchronized List<TrustedExternalId> getTrustedIds(final ReviewDb db)
throws OrmException {
public synchronized List<TrustedExternalId> getTrustedExternalIds(
final ReviewDb db) throws OrmException {
if (trustedIds == null) {
trustedIds =
Collections.unmodifiableList(db.trustedExternalIds().all().toList());

View File

@@ -53,7 +53,7 @@ public final class TrustedExternalId {
return true;
}
private static boolean isTrusted(final AccountExternalId id,
public static boolean isTrusted(final AccountExternalId id,
final Collection<TrustedExternalId> trusted) {
if (id.getExternalId().startsWith("Google Account ")) {
// Assume this is a trusted token, its a legacy import from

View File

@@ -682,6 +682,11 @@
color: red;
font-weight: bold;
}
.gerrit-Identity-UntrustedExternalId {
white-space: nowrap;
color: red;
font-weight: bold;
}
.gerrit-AccountInfoBlock {
margin-bottom: 10px;

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server;
import com.google.gerrit.client.account.AccountSecurity;
import com.google.gerrit.client.account.ExternalIdDetail;
import com.google.gerrit.client.reviewdb.Account;
import com.google.gerrit.client.reviewdb.AccountAgreement;
import com.google.gerrit.client.reviewdb.AccountExternalId;
@@ -23,6 +24,7 @@ import com.google.gerrit.client.reviewdb.ContactInformation;
import com.google.gerrit.client.reviewdb.ContributorAgreement;
import com.google.gerrit.client.reviewdb.ReviewDb;
import com.google.gerrit.client.reviewdb.SystemConfig;
import com.google.gerrit.client.reviewdb.TrustedExternalId;
import com.google.gerrit.client.rpc.BaseServiceImplementation;
import com.google.gerrit.client.rpc.Common;
import com.google.gerrit.client.rpc.ContactInformationStoreException;
@@ -135,11 +137,15 @@ class AccountSecurityImpl extends BaseServiceImplementation implements
});
}
public void myExternalIds(AsyncCallback<List<AccountExternalId>> callback) {
run(callback, new Action<List<AccountExternalId>>() {
public List<AccountExternalId> run(ReviewDb db) throws OrmException {
public void myExternalIds(AsyncCallback<ExternalIdDetail> callback) {
run(callback, new Action<ExternalIdDetail>() {
public ExternalIdDetail run(ReviewDb db) throws OrmException {
final Account.Id me = Common.getAccountId();
return db.accountExternalIds().byAccount(me).toList();
final List<TrustedExternalId> trusted =
Common.getGroupCache().getTrustedExternalIds(db);
final List<AccountExternalId> myIds =
db.accountExternalIds().byAccount(me).toList();
return new ExternalIdDetail(myIds, trusted);
}
});
}