From eb47db12feab2fa806e8ccd51a75d7d11525968f Mon Sep 17 00:00:00 2001 From: David Ostrovsky Date: Sat, 31 Aug 2013 22:23:05 +0200 Subject: [PATCH] Check required capabilities during UiAction gathering Currently UiAction imlementation has to provide isVisible() method. If UiAction specifies RequiresCapability annotation, then that check can be done during UiAction gathering. The following prerequisities must be met, to satisfy the check: 1. user has to be authenticated 2.1 user is a member of the Administrators group or 2.2 user is a member of a group, which has the required capability Change-Id: I0bfb8dd5048bd2a52583f83aa38105bc176f1cca --- .../changedetail/PatchSetDetailFactory.java | 4 +++- .../gerrit/server/change/ChangeJson.java | 19 ++++++++++++------- .../server/extensions/webui/UiActions.java | 19 ++++++++++++++++--- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/PatchSetDetailFactory.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/PatchSetDetailFactory.java index 461a26341d..35af351472 100644 --- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/PatchSetDetailFactory.java +++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/PatchSetDetailFactory.java @@ -48,6 +48,7 @@ import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; +import com.google.inject.util.Providers; import org.eclipse.jgit.lib.ObjectId; import org.slf4j.Logger; @@ -179,7 +180,8 @@ class PatchSetDetailFactory extends Handler { detail.setCommands(Lists.newArrayList(Iterables.transform( UiActions.sorted(UiActions.plugins(UiActions.from( revisions, - new RevisionResource(new ChangeResource(control), patchSet)))), + new RevisionResource(new ChangeResource(control), patchSet), + Providers.of(user)))), new Function() { @Override public UiCommandDetail apply(UiAction.Description in) { diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java index 684840fbd2..994af88186 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java @@ -123,7 +123,7 @@ public class ChangeJson { private final Provider db; private final LabelNormalizer labelNormalizer; - private final CurrentUser user; + private final Provider user; private final AnonymousUser anonymous; private final IdentifiedUser.GenericFactory userFactory; private final ChangeControl.GenericFactory changeControlGenericFactory; @@ -144,7 +144,7 @@ public class ChangeJson { ChangeJson( Provider db, LabelNormalizer ln, - CurrentUser u, + Provider userProvider, AnonymousUser au, IdentifiedUser.GenericFactory uf, ChangeControl.GenericFactory ccf, @@ -157,7 +157,7 @@ public class ChangeJson { Revisions revisions) { this.db = db; this.labelNormalizer = ln; - this.user = u; + this.user = userProvider; this.anonymous = au; this.userFactory = uf; this.changeControlGenericFactory = ccf; @@ -256,7 +256,9 @@ public class ChangeJson { out.updated = in.getLastUpdatedOn(); out._number = in.getId().get(); out._sortkey = in.getSortKey(); - out.starred = user.getStarredChanges().contains(in.getId()) ? true : null; + out.starred = user.get().getStarredChanges().contains(in.getId()) + ? true + : null; out.reviewed = in.getStatus().isOpen() && isChangeReviewed(cd) ? true : null; out.labels = labelsFor(cd, has(LABELS), has(DETAILED_LABELS)); @@ -290,7 +292,8 @@ public class ChangeJson { out.actions = Maps.newTreeMap(); for (UiAction.Description d : UiActions.from( changes, - new ChangeResource(control(cd)))) { + new ChangeResource(control(cd)), + user)) { out.actions.put(d.getId(), new ActionInfo(d)); } } @@ -311,7 +314,8 @@ public class ChangeJson { if (changeControlUserFactory != null) { ctrl = changeControlUserFactory.controlFor(cd.change(db)); } else { - ctrl = changeControlGenericFactory.controlFor(cd.change(db), user); + ctrl = changeControlGenericFactory.controlFor(cd.change(db), + user.get()); } } catch (NoSuchChangeException e) { return null; @@ -776,7 +780,8 @@ public class ChangeJson { out.actions = Maps.newTreeMap(); for (UiAction.Description d : UiActions.from( revisions, - new RevisionResource(new ChangeResource(control(cd)), in))) { + new RevisionResource(new ChangeResource(control(cd)), in), + user)) { out.actions.put(d.getId(), new ActionInfo(d)); } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/extensions/webui/UiActions.java b/gerrit-server/src/main/java/com/google/gerrit/server/extensions/webui/UiActions.java index 9aae367a8e..fa64f4a484 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/extensions/webui/UiActions.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/extensions/webui/UiActions.java @@ -20,11 +20,15 @@ import com.google.common.base.Predicates; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.gerrit.extensions.registration.DynamicMap; +import com.google.gerrit.extensions.restapi.AuthException; import com.google.gerrit.extensions.restapi.RestCollection; import com.google.gerrit.extensions.restapi.RestResource; import com.google.gerrit.extensions.restapi.RestView; import com.google.gerrit.extensions.webui.PrivateInternals_UiActionDescription; import com.google.gerrit.extensions.webui.UiAction; +import com.google.gerrit.server.CurrentUser; +import com.google.gerrit.server.account.CapabilityUtils; +import com.google.inject.Provider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -70,13 +74,15 @@ public class UiActions { public static Iterable from( RestCollection collection, - R resource) { - return from(collection.views(), resource); + R resource, + Provider userProvider) { + return from(collection.views(), resource, userProvider); } public static Iterable from( DynamicMap> views, - final R resource) { + final R resource, + final Provider userProvider) { return Iterables.filter( Iterables.transform( views, @@ -103,6 +109,13 @@ public class UiActions { return null; } + try { + CapabilityUtils.checkRequiresCapability(userProvider, + e.getPluginName(), view.getClass()); + } catch (AuthException exc) { + return null; + } + UiAction.Description dsc = ((UiAction) view).getDescription(resource); if (dsc == null || !dsc.isVisible()) {