Added the emailReviewers as a global capability
This adds functionality to deny the emailing of reviewers to certain
groups. This will replace the emailOnlyAuthors flag on the
AccountGroup.
Change-Id: If3697e88df50e0b0256b5b6a1ea810343124b96f
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/GlobalCapability.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GlobalCapability.java
index 2e46791..d3d2a4d 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/GlobalCapability.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/GlobalCapability.java
@@ -39,6 +39,16 @@
/** Can create any project on the server. */
public static final String CREATE_PROJECT = "createProject";
+ /**
+ * Denotes who may email change reviewers.
+ * <p>
+ * This can be used to deny build bots from emailing reviewers and people who
+ * have starred the changed. Instead, only the authors of the change will be
+ * emailed. The allow rules are evaluated before deny rules, however the
+ * default is to allow emailing, if no explicit rule is matched.
+ */
+ public static final String EMAIL_REVIEWERS = "emailReviewers";
+
/** Can flush any cache except the active web_sessions cache. */
public static final String FLUSH_CACHES = "flushCaches";
@@ -71,6 +81,7 @@
NAMES_LC.add(CREATE_ACCOUNT.toLowerCase());
NAMES_LC.add(CREATE_GROUP.toLowerCase());
NAMES_LC.add(CREATE_PROJECT.toLowerCase());
+ NAMES_LC.add(EMAIL_REVIEWERS.toLowerCase());
NAMES_LC.add(FLUSH_CACHES.toLowerCase());
NAMES_LC.add(KILL_TASK.toLowerCase());
NAMES_LC.add(PRIORITY.toLowerCase());
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
index f2a8ad6..14d25d2 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
@@ -128,6 +128,7 @@
createAccount, \
createGroup, \
createProject, \
+ emailReviewers, \
flushCaches, \
killTask, \
priority, \
@@ -140,6 +141,7 @@
createAccount = Create Account
createGroup = Create Group
createProject = Create Project
+emailReviewers = Email Reviewers
flushCaches = Flush Caches
killTask = Kill Task
priority = Priority
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityCollection.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityCollection.java
index 6cf4457..796b44e 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityCollection.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityCollection.java
@@ -34,6 +34,7 @@
private final Map<String, List<PermissionRule>> permissions;
public final List<PermissionRule> administrateServer;
+ public final List<PermissionRule> emailReviewers;
public final List<PermissionRule> priority;
public final List<PermissionRule> queryLimit;
@@ -46,14 +47,17 @@
new HashMap<String, List<PermissionRule>>();
for (Permission permission : section.getPermissions()) {
for (PermissionRule rule : permission.getRules()) {
- if (rule.getAction() != PermissionRule.Action.DENY) {
- List<PermissionRule> r = tmp.get(permission.getName());
- if (r == null) {
- r = new ArrayList<PermissionRule>(2);
- tmp.put(permission.getName(), r);
- }
- r.add(rule);
+ if (!permission.getName().equals(GlobalCapability.EMAIL_REVIEWERS)
+ && rule.getAction() == PermissionRule.Action.DENY) {
+ continue;
}
+
+ List<PermissionRule> r = tmp.get(permission.getName());
+ if (r == null) {
+ r = new ArrayList<PermissionRule>(2);
+ tmp.put(permission.getName(), r);
+ }
+ r.add(rule);
}
}
configureDefaults(tmp, section);
@@ -72,6 +76,7 @@
permissions = Collections.unmodifiableMap(res);
administrateServer = getPermission(GlobalCapability.ADMINISTRATE_SERVER);
+ emailReviewers = getPermission(GlobalCapability.EMAIL_REVIEWERS);
priority = getPermission(GlobalCapability.PRIORITY);
queryLimit = getPermission(GlobalCapability.QUERY_LIMIT);
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityControl.java
index 9f17671..eb42921 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityControl.java
@@ -15,11 +15,14 @@
package com.google.gerrit.server.account;
import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.common.data.PermissionRange;
import com.google.gerrit.common.data.PermissionRule;
+import com.google.gerrit.common.data.PermissionRule.Action;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.PeerDaemonUser;
@@ -45,6 +48,7 @@
private final Map<String, List<PermissionRule>> effective;
private Boolean canAdministrateServer;
+ private Boolean canEmailReviewers;
@Inject
CapabilityControl(ProjectCache projectCache, @Assisted CurrentUser currentUser) {
@@ -62,7 +66,7 @@
public boolean canAdministrateServer() {
if (canAdministrateServer == null) {
canAdministrateServer = user instanceof PeerDaemonUser
- || matchAny(capabilities.administrateServer);
+ || matchAny(capabilities.administrateServer, ALLOWED_RULE);
}
return canAdministrateServer;
}
@@ -85,6 +89,17 @@
|| canAdministrateServer();
}
+ /** @return true if the user can email reviewers. */
+ public boolean canEmailReviewers() {
+ if (canEmailReviewers == null) {
+ canEmailReviewers =
+ matchAny(capabilities.emailReviewers, ALLOWED_RULE)
+ || !matchAny(capabilities.emailReviewers, Predicates.not(ALLOWED_RULE));
+
+ }
+ return canEmailReviewers;
+ }
+
/** @return true if the user can kill any running task. */
public boolean canKillTask() {
return canPerform(GlobalCapability.KILL_TASK)
@@ -222,8 +237,16 @@
return mine;
}
- private boolean matchAny(List<PermissionRule> rules) {
- Iterable<AccountGroup.UUID> ids = Iterables.transform(rules,
+ private static final Predicate<PermissionRule> ALLOWED_RULE = new Predicate<PermissionRule>() {
+ @Override
+ public boolean apply(PermissionRule rule) {
+ return rule.getAction() == Action.ALLOW;
+ }
+ };
+
+ private boolean matchAny(Iterable<PermissionRule> rules, Predicate<PermissionRule> predicate) {
+ Iterable<AccountGroup.UUID> ids = Iterables.transform(
+ Iterables.filter(rules, predicate),
new Function<PermissionRule, AccountGroup.UUID>() {
@Override
public AccountGroup.UUID apply(PermissionRule rule) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/ChangeEmail.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/ChangeEmail.java
index a2bc483..faf586a 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/ChangeEmail.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/ChangeEmail.java
@@ -70,12 +70,17 @@
/** Is the from user in an email squelching group? */
final IdentifiedUser user = args.identifiedUserFactory.create(id);
- final Set<AccountGroup.UUID> gids = user.getEffectiveGroups().getKnownGroups();
- for (final AccountGroup.UUID gid : gids) {
- AccountGroup group = args.groupCache.get(gid);
- if (group != null && group.isEmailOnlyAuthors()) {
- emailOnlyAuthors = true;
- break;
+ if (!user.getCapabilities().canEmailReviewers()) {
+ emailOnlyAuthors = true;
+ } else {
+ // TODO(cranger): remove once the schema is migrated in the next patch.
+ final Set<AccountGroup.UUID> gids = user.getEffectiveGroups().getKnownGroups();
+ for (final AccountGroup.UUID gid : gids) {
+ AccountGroup group = args.groupCache.get(gid);
+ if (group != null && group.isEmailOnlyAuthors()) {
+ emailOnlyAuthors = true;
+ break;
+ }
}
}
}