From ed1523094d9bf3ae757dce4f2c0e5aae4a415fd2 Mon Sep 17 00:00:00 2001 From: Dave Borowitz Date: Tue, 15 Sep 2015 11:06:47 -0400 Subject: [PATCH] Add push cert status to change screen Add a status icon next to the uploader with a check/warning/X depending on the push cert status. Include messages in the title on hover. If the uploader is the same as the change owner, place the status icon next to the owner. PushCertificateInfo and GpgKeyInfo are moved to gerrit-gwtui-common so they can be referenced from ChangeInfo. The new question mark icon is the help-browser icon from the public-domain Tango collection: http://tango.freedesktop.org/Tango_Icon_Library Change-Id: Iec666c668342b00fd92609dd28feb082d5a560a8 --- .../com/google/gerrit/client/Resources.java | 3 + .../google/gerrit/client/info/ChangeInfo.java | 3 + .../gerrit/client/info}/GpgKeyInfo.java | 19 +++- .../client/info/PushCertificateInfo.java | 25 +++++ .../com/google/gerrit/client/question.png | Bin 0 -> 932 bytes .../gerrit/client/account/AccountApi.java | 1 + .../client/account/MyGpgKeysScreen.java | 1 + .../gerrit/client/change/ChangeScreen.java | 94 +++++++++++++++--- .../gerrit/client/change/ChangeScreen.ui.xml | 4 + .../client/changes/ChangeConstants.java | 5 + .../client/changes/ChangeConstants.properties | 5 + 11 files changed, 143 insertions(+), 17 deletions(-) rename {gerrit-gwtui/src/main/java/com/google/gerrit/client/account => gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info}/GpgKeyInfo.java (69%) create mode 100644 gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/PushCertificateInfo.java create mode 100644 gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/question.png diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/Resources.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/Resources.java index 0db7ea4725..a5a02cdfe8 100644 --- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/Resources.java +++ b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/Resources.java @@ -104,4 +104,7 @@ public interface Resources extends ClientBundle { @Source("warning.png") public ImageResource warning(); + + @Source("question.png") + public ImageResource question(); } diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/ChangeInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/ChangeInfo.java index ed3d4ec5de..dd88b04fd8 100644 --- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/ChangeInfo.java +++ b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/ChangeInfo.java @@ -311,6 +311,9 @@ public class ChangeInfo extends JavaScriptObject { public final native boolean hasFetch() /*-{ return this.hasOwnProperty('fetch') }-*/; public final native NativeMap fetch() /*-{ return this.fetch; }-*/; + public final native boolean hasPushCertificate() /*-{ return this.hasOwnProperty('push_certificate'); }-*/; + public final native PushCertificateInfo pushCertificate() /*-{ return this.push_certificate; }-*/; + public static void sortRevisionInfoByNumber(JsArray list) { final int editParent = findEditParent(list); Collections.sort(Natives.asList(list), new Comparator() { diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/GpgKeyInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GpgKeyInfo.java similarity index 69% rename from gerrit-gwtui/src/main/java/com/google/gerrit/client/account/GpgKeyInfo.java rename to gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GpgKeyInfo.java index d1bb42689c..f7477a1d73 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/GpgKeyInfo.java +++ b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GpgKeyInfo.java @@ -12,17 +12,34 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.gerrit.client.account; +package com.google.gerrit.client.info; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArrayString; public class GpgKeyInfo extends JavaScriptObject { + public enum Status { + BAD, OK, TRUSTED; + } + public final native String id() /*-{ return this.id; }-*/; public final native String fingerprint() /*-{ return this.fingerprint; }-*/; public final native JsArrayString userIds() /*-{ return this.user_ids; }-*/; public final native String key() /*-{ return this.key; }-*/; + private final native String statusRaw() /*-{ return this.status; }-*/; + public final Status status() { + String s = statusRaw(); + if (s == null) { + return null; + } + return Status.valueOf(s); + } + + public final native boolean hasProblems() + /*-{ return this.hasOwnProperty('problems'); }-*/; + public final native JsArrayString problems() /*-{ return this.problems; }-*/; + protected GpgKeyInfo() { } } diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/PushCertificateInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/PushCertificateInfo.java new file mode 100644 index 0000000000..ebfec1a36a --- /dev/null +++ b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/PushCertificateInfo.java @@ -0,0 +1,25 @@ +// Copyright (C) 2015 The Android Open Source Project +// +// 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.info; + +import com.google.gwt.core.client.JavaScriptObject; + +public class PushCertificateInfo extends JavaScriptObject { + public final native String certificate() /*-{ return this.certificate; }-*/; + public final native GpgKeyInfo key() /*-{ return this.key; }-*/; + + protected PushCertificateInfo() { + } +} diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/question.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/question.png new file mode 100644 index 0000000000000000000000000000000000000000..f25fc3fbf106af60de59581bf2e6fba58d489bf8 GIT binary patch literal 932 zcmV;V16%xwP)n<^0M7t*KyZHC1w??>xEt=fabLR*P`s^00F8@s%vX0ly3W2Q;1iYQ`2d{1 zn56SU!aH>A*UV&krU`gE?uNYufcfLL`>KjUEiXOnoQe)`qCG}W|1bb+O7eK1#?QvJ zs|dgU_0&(D106tZ+zosBJd?&v>qnWFmUKydqeslSKE)YIWlRZ)Gjda>n*%4R*)(?6s}$J0tF zrB0rXshXW1sfM?{P>GRo72Li*T~yy3kh%V?FTe2QhE1d6Y3FzU6LKF3;uj?|T^;O;NgH2_-9*%2UxlCj?MeRpHZ4w8sFjOr1-Y$4FjHVOs`O z6+Qs2{*%TqbaEVv&fkX!tu7E!h&mkz2FsQcy_m!>B&KO#Sq7GA5DFBqd&fqUQXD+m zfn!?;p^>;U$?D=fJf(uyMMMYXO4>Md`aVN{(Y9gut;(G&D3o z09{?N%Y*_27>1l9_a8%EHtR(M(E9O_Gnox*SF!%CmFQBU zOF`};huu%zOT%N;EOv}x2@;w%)hg>aX0MU5~e$Dv-j=Valc(v;nT_sm!fGJ@x&;<^^bV( zeDYmpd~&)e>v=ba>Hp#^rKnR%1p%a#U9+> cb) { RestApi call = ChangeApi.detail(changeId.get()); - ChangeList.addOptions(call, EnumSet.of( - ListChangesOption.CHANGE_ACTIONS, - ListChangesOption.ALL_REVISIONS)); + EnumSet opts = EnumSet.of( + ListChangesOption.ALL_REVISIONS, + ListChangesOption.CHANGE_ACTIONS); + if (enableSignedPush()) { + opts.add(ListChangesOption.PUSH_CERTIFICATES); + } + ChangeList.addOptions(call, opts); if (!fg) { call.background(); } @@ -1146,13 +1160,14 @@ public class ChangeScreen extends Screen { } private void renderChangeInfo(ChangeInfo info) { + RevisionInfo revisionInfo = info.revision(revision); changeInfo = info; lastDisplayedUpdate = info.updated(); labels.set(info); renderOwner(info); - renderUploader(info, revision); + renderUploader(info, revisionInfo); renderActionTextDate(info); renderDiffBaseListBox(info); initReplyButton(info, revision); @@ -1189,7 +1204,7 @@ public class ChangeScreen extends Screen { // render it faster. if (!info.status().isOpen() || !revision.equals(info.currentRevision()) - || info.revision(revision).isEdit()) { + || revisionInfo.isEdit()) { setVisible(strategy, false); } @@ -1200,7 +1215,6 @@ public class ChangeScreen extends Screen { quickApprove.setVisible(false); actions.reloadRevisionActions(emptyMap); - RevisionInfo revisionInfo = info.revision(revision); boolean current = revision.equals(info.currentRevision()) && !revisionInfo.isEdit(); @@ -1252,10 +1266,12 @@ public class ChangeScreen extends Screen { : String.valueOf(info.owner()._accountId()), Change.Status.NEW)); } - private void renderUploader(ChangeInfo info, String revision) { - AccountInfo uploader = info.revision(revision).uploader(); - if (uploader == null - || uploader._accountId() == info.owner()._accountId()) { + private void renderUploader(ChangeInfo changeInfo, RevisionInfo revInfo) { + AccountInfo uploader = revInfo.uploader(); + boolean isOwner = uploader == null + || uploader._accountId() == changeInfo.owner()._accountId(); + renderPushCertificate(revInfo, isOwner ? ownerPanel : uploaderPanel); + if (isOwner) { uploaderRow.getStyle().setDisplay(Display.NONE); return; } @@ -1269,6 +1285,37 @@ public class ChangeScreen extends Screen { uploaderName.setTitle(email(uploader, name)); } + private void renderPushCertificate(RevisionInfo revInfo, FlowPanel panel) { + if (!enableSignedPush()) { + return; + } + Image status = new Image(); + panel.add(status); + status.setStyleName(style.pushCertStatus()); + if (!revInfo.hasPushCertificate() + || revInfo.pushCertificate().key() == null) { + status.setResource(Gerrit.RESOURCES.question()); + status.setTitle(Util.C.pushCertMissing()); + return; + } + PushCertificateInfo certInfo = revInfo.pushCertificate(); + GpgKeyInfo.Status s = certInfo.key().status(); + switch (s) { + case BAD: + status.setResource(Gerrit.RESOURCES.redNot()); + status.setTitle(problems(Util.C.pushCertBad(), certInfo)); + break; + case OK: + status.setResource(Gerrit.RESOURCES.warning()); + status.setTitle(problems(Util.C.pushCertOk(), certInfo)); + break; + case TRUSTED: + status.setResource(Gerrit.RESOURCES.greenCheck()); + status.setTitle(Util.C.pushCertTrusted()); + break; + } + } + private static String name(AccountInfo info) { return info.name() != null ? info.name() @@ -1279,6 +1326,21 @@ public class ChangeScreen extends Screen { return info.email() != null ? info.email() : name; } + private static String problems(String msg, PushCertificateInfo info) { + if (info.key() == null + || !info.key().hasProblems() + || info.key().problems().length() == 0) { + return msg; + } + + StringBuilder sb = new StringBuilder(); + sb.append(msg).append(':'); + for (String problem : Natives.asList(info.key().problems())) { + sb.append('\n').append(problem); + } + return sb.toString(); + } + private void renderSubmitType(String action) { try { SubmitType type = SubmitType.valueOf(action); diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.ui.xml index e40b431aed..c643072b06 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.ui.xml +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.ui.xml @@ -334,6 +334,10 @@ limitations under the License. .changeExtension { padding-top: 5px; } + + .pushCertStatus { + padding-left: 5px; + } diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeConstants.java index ca4c633e12..1fb997f500 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeConstants.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeConstants.java @@ -202,4 +202,9 @@ public interface ChangeConstants extends Constants { String diffAllUnified(); String votable(); + + String pushCertMissing(); + String pushCertBad(); + String pushCertOk(); + String pushCertTrusted(); } diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeConstants.properties index e3481615a2..a5fa7b4844 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeConstants.properties +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeConstants.properties @@ -184,3 +184,8 @@ diffAllSideBySide = All Side-by-Side diffAllUnified = All Unified votable = Votable: + +pushCertMissing = This patch set was created without a push certificate +pushCertBad = Push certificate is invalid +pushCertOk = Push certificate is valid, but key is not trusted +pushCertTrusted = Push certificate is valid and key is trusted