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
This commit is contained in:
David Ostrovsky
2013-08-31 22:23:05 +02:00
committed by Shawn Pearce
parent c544351617
commit eb47db12fe
3 changed files with 31 additions and 11 deletions

View File

@@ -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<PatchSetDetail> {
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<UiAction.Description, UiCommandDetail>() {
@Override
public UiCommandDetail apply(UiAction.Description in) {

View File

@@ -123,7 +123,7 @@ public class ChangeJson {
private final Provider<ReviewDb> db;
private final LabelNormalizer labelNormalizer;
private final CurrentUser user;
private final Provider<CurrentUser> user;
private final AnonymousUser anonymous;
private final IdentifiedUser.GenericFactory userFactory;
private final ChangeControl.GenericFactory changeControlGenericFactory;
@@ -144,7 +144,7 @@ public class ChangeJson {
ChangeJson(
Provider<ReviewDb> db,
LabelNormalizer ln,
CurrentUser u,
Provider<CurrentUser> 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));
}
}

View File

@@ -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 <R extends RestResource> Iterable<UiAction.Description> from(
RestCollection<?, R> collection,
R resource) {
return from(collection.views(), resource);
R resource,
Provider<CurrentUser> userProvider) {
return from(collection.views(), resource, userProvider);
}
public static <R extends RestResource> Iterable<UiAction.Description> from(
DynamicMap<RestView<R>> views,
final R resource) {
final R resource,
final Provider<CurrentUser> 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<R>) view).getDescription(resource);
if (dsc == null || !dsc.isVisible()) {