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
This commit is contained in:
Colby Ranger
2012-04-10 13:41:19 -07:00
parent 7a9bb6adc8
commit d9488f0c37
5 changed files with 62 additions and 16 deletions

View File

@@ -39,6 +39,16 @@ public class GlobalCapability {
/** Can create any project on the server. */ /** Can create any project on the server. */
public static final String CREATE_PROJECT = "createProject"; 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. */ /** Can flush any cache except the active web_sessions cache. */
public static final String FLUSH_CACHES = "flushCaches"; public static final String FLUSH_CACHES = "flushCaches";
@@ -71,6 +81,7 @@ public class GlobalCapability {
NAMES_LC.add(CREATE_ACCOUNT.toLowerCase()); NAMES_LC.add(CREATE_ACCOUNT.toLowerCase());
NAMES_LC.add(CREATE_GROUP.toLowerCase()); NAMES_LC.add(CREATE_GROUP.toLowerCase());
NAMES_LC.add(CREATE_PROJECT.toLowerCase()); NAMES_LC.add(CREATE_PROJECT.toLowerCase());
NAMES_LC.add(EMAIL_REVIEWERS.toLowerCase());
NAMES_LC.add(FLUSH_CACHES.toLowerCase()); NAMES_LC.add(FLUSH_CACHES.toLowerCase());
NAMES_LC.add(KILL_TASK.toLowerCase()); NAMES_LC.add(KILL_TASK.toLowerCase());
NAMES_LC.add(PRIORITY.toLowerCase()); NAMES_LC.add(PRIORITY.toLowerCase());

View File

@@ -128,6 +128,7 @@ capabilityNames = \
createAccount, \ createAccount, \
createGroup, \ createGroup, \
createProject, \ createProject, \
emailReviewers, \
flushCaches, \ flushCaches, \
killTask, \ killTask, \
priority, \ priority, \
@@ -140,6 +141,7 @@ administrateServer = Administrate Server
createAccount = Create Account createAccount = Create Account
createGroup = Create Group createGroup = Create Group
createProject = Create Project createProject = Create Project
emailReviewers = Email Reviewers
flushCaches = Flush Caches flushCaches = Flush Caches
killTask = Kill Task killTask = Kill Task
priority = Priority priority = Priority

View File

@@ -34,6 +34,7 @@ public class CapabilityCollection {
private final Map<String, List<PermissionRule>> permissions; private final Map<String, List<PermissionRule>> permissions;
public final List<PermissionRule> administrateServer; public final List<PermissionRule> administrateServer;
public final List<PermissionRule> emailReviewers;
public final List<PermissionRule> priority; public final List<PermissionRule> priority;
public final List<PermissionRule> queryLimit; public final List<PermissionRule> queryLimit;
@@ -46,7 +47,11 @@ public class CapabilityCollection {
new HashMap<String, List<PermissionRule>>(); new HashMap<String, List<PermissionRule>>();
for (Permission permission : section.getPermissions()) { for (Permission permission : section.getPermissions()) {
for (PermissionRule rule : permission.getRules()) { for (PermissionRule rule : permission.getRules()) {
if (rule.getAction() != PermissionRule.Action.DENY) { if (!permission.getName().equals(GlobalCapability.EMAIL_REVIEWERS)
&& rule.getAction() == PermissionRule.Action.DENY) {
continue;
}
List<PermissionRule> r = tmp.get(permission.getName()); List<PermissionRule> r = tmp.get(permission.getName());
if (r == null) { if (r == null) {
r = new ArrayList<PermissionRule>(2); r = new ArrayList<PermissionRule>(2);
@@ -55,7 +60,6 @@ public class CapabilityCollection {
r.add(rule); r.add(rule);
} }
} }
}
configureDefaults(tmp, section); configureDefaults(tmp, section);
Map<String, List<PermissionRule>> res = Map<String, List<PermissionRule>> res =
@@ -72,6 +76,7 @@ public class CapabilityCollection {
permissions = Collections.unmodifiableMap(res); permissions = Collections.unmodifiableMap(res);
administrateServer = getPermission(GlobalCapability.ADMINISTRATE_SERVER); administrateServer = getPermission(GlobalCapability.ADMINISTRATE_SERVER);
emailReviewers = getPermission(GlobalCapability.EMAIL_REVIEWERS);
priority = getPermission(GlobalCapability.PRIORITY); priority = getPermission(GlobalCapability.PRIORITY);
queryLimit = getPermission(GlobalCapability.QUERY_LIMIT); queryLimit = getPermission(GlobalCapability.QUERY_LIMIT);
} }

View File

@@ -15,11 +15,14 @@
package com.google.gerrit.server.account; package com.google.gerrit.server.account;
import com.google.common.base.Function; 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.common.collect.Iterables;
import com.google.gerrit.common.data.GlobalCapability; import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.common.data.GroupReference; import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.common.data.PermissionRange; import com.google.gerrit.common.data.PermissionRange;
import com.google.gerrit.common.data.PermissionRule; 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.reviewdb.client.AccountGroup;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.PeerDaemonUser; import com.google.gerrit.server.PeerDaemonUser;
@@ -45,6 +48,7 @@ public class CapabilityControl {
private final Map<String, List<PermissionRule>> effective; private final Map<String, List<PermissionRule>> effective;
private Boolean canAdministrateServer; private Boolean canAdministrateServer;
private Boolean canEmailReviewers;
@Inject @Inject
CapabilityControl(ProjectCache projectCache, @Assisted CurrentUser currentUser) { CapabilityControl(ProjectCache projectCache, @Assisted CurrentUser currentUser) {
@@ -62,7 +66,7 @@ public class CapabilityControl {
public boolean canAdministrateServer() { public boolean canAdministrateServer() {
if (canAdministrateServer == null) { if (canAdministrateServer == null) {
canAdministrateServer = user instanceof PeerDaemonUser canAdministrateServer = user instanceof PeerDaemonUser
|| matchAny(capabilities.administrateServer); || matchAny(capabilities.administrateServer, ALLOWED_RULE);
} }
return canAdministrateServer; return canAdministrateServer;
} }
@@ -85,6 +89,17 @@ public class CapabilityControl {
|| canAdministrateServer(); || 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. */ /** @return true if the user can kill any running task. */
public boolean canKillTask() { public boolean canKillTask() {
return canPerform(GlobalCapability.KILL_TASK) return canPerform(GlobalCapability.KILL_TASK)
@@ -222,8 +237,16 @@ public class CapabilityControl {
return mine; return mine;
} }
private boolean matchAny(List<PermissionRule> rules) { private static final Predicate<PermissionRule> ALLOWED_RULE = new Predicate<PermissionRule>() {
Iterable<AccountGroup.UUID> ids = Iterables.transform(rules, @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>() { new Function<PermissionRule, AccountGroup.UUID>() {
@Override @Override
public AccountGroup.UUID apply(PermissionRule rule) { public AccountGroup.UUID apply(PermissionRule rule) {

View File

@@ -70,6 +70,10 @@ public abstract class ChangeEmail extends OutgoingEmail {
/** Is the from user in an email squelching group? */ /** Is the from user in an email squelching group? */
final IdentifiedUser user = args.identifiedUserFactory.create(id); final IdentifiedUser user = args.identifiedUserFactory.create(id);
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(); final Set<AccountGroup.UUID> gids = user.getEffectiveGroups().getKnownGroups();
for (final AccountGroup.UUID gid : gids) { for (final AccountGroup.UUID gid : gids) {
AccountGroup group = args.groupCache.get(gid); AccountGroup group = args.groupCache.get(gid);
@@ -79,6 +83,7 @@ public abstract class ChangeEmail extends OutgoingEmail {
} }
} }
} }
}
public void setPatchSet(final PatchSet ps) { public void setPatchSet(final PatchSet ps) {
patchSet = ps; patchSet = ps;