Merge "Remove CapabilityControl from CurrentUser"

This commit is contained in:
David Pursehouse 2017-06-21 23:41:42 +00:00 committed by Gerrit Code Review
commit f80e91155b
33 changed files with 222 additions and 217 deletions

View File

@ -20,6 +20,7 @@ import static java.util.concurrent.TimeUnit.MINUTES;
import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.git.QueueProvider; import com.google.gerrit.server.git.QueueProvider;
import com.google.gerrit.server.git.WorkQueue.CancelableRunnable; import com.google.gerrit.server.git.WorkQueue.CancelableRunnable;
@ -69,7 +70,6 @@ public class ProjectQoSFilter implements Filter {
private static final Pattern URI_PATTERN = Pattern.compile(FILTER_RE); private static final Pattern URI_PATTERN = Pattern.compile(FILTER_RE);
public static class Module extends ServletModule { public static class Module extends ServletModule {
@Override @Override
protected void configureServlets() { protected void configureServlets() {
bind(QueueProvider.class).to(CommandExecutorQueueProvider.class).in(SINGLETON); bind(QueueProvider.class).to(CommandExecutorQueueProvider.class).in(SINGLETON);
@ -77,18 +77,20 @@ public class ProjectQoSFilter implements Filter {
} }
} }
private final CapabilityControl.Factory capabilityFactory;
private final Provider<CurrentUser> user; private final Provider<CurrentUser> user;
private final QueueProvider queue; private final QueueProvider queue;
private final ServletContext context; private final ServletContext context;
private final long maxWait; private final long maxWait;
@Inject @Inject
ProjectQoSFilter( ProjectQoSFilter(
CapabilityControl.Factory capabilityFactory,
Provider<CurrentUser> user, Provider<CurrentUser> user,
QueueProvider queue, QueueProvider queue,
ServletContext context, ServletContext context,
@GerritServerConfig Config cfg) { @GerritServerConfig Config cfg) {
this.capabilityFactory = capabilityFactory;
this.user = user; this.user = user;
this.queue = queue; this.queue = queue;
this.context = context; this.context = context;
@ -137,7 +139,8 @@ public class ProjectQoSFilter implements Filter {
} }
private ScheduledThreadPoolExecutor getExecutor() { private ScheduledThreadPoolExecutor getExecutor() {
return queue.getQueue(user.get().getCapabilities().getQueueType()); QueueProvider.QueueType qt = capabilityFactory.create(user.get()).getQueueType();
return queue.getQueue(qt);
} }
@Override @Override

View File

@ -32,7 +32,6 @@ import com.google.gerrit.server.account.AccountCacheImpl;
import com.google.gerrit.server.account.AccountVisibility; import com.google.gerrit.server.account.AccountVisibility;
import com.google.gerrit.server.account.AccountVisibilityProvider; import com.google.gerrit.server.account.AccountVisibilityProvider;
import com.google.gerrit.server.account.CapabilityCollection; import com.google.gerrit.server.account.CapabilityCollection;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.account.FakeRealm; import com.google.gerrit.server.account.FakeRealm;
import com.google.gerrit.server.account.GroupCacheImpl; import com.google.gerrit.server.account.GroupCacheImpl;
import com.google.gerrit.server.account.GroupIncludeCacheImpl; import com.google.gerrit.server.account.GroupIncludeCacheImpl;
@ -164,7 +163,6 @@ public class BatchProgramModule extends FactoryModule {
install(MergeabilityCacheImpl.module()); install(MergeabilityCacheImpl.module());
install(TagCache.module()); install(TagCache.module());
factory(CapabilityCollection.Factory.class); factory(CapabilityCollection.Factory.class);
factory(CapabilityControl.Factory.class);
factory(ChangeData.Factory.class); factory(ChangeData.Factory.class);
factory(ProjectState.Factory.class); factory(ProjectState.Factory.class);

View File

@ -14,20 +14,13 @@
package com.google.gerrit.server; package com.google.gerrit.server;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.account.GroupMembership; import com.google.gerrit.server.account.GroupMembership;
import com.google.gerrit.server.account.ListGroupMembership; import com.google.gerrit.server.account.ListGroupMembership;
import com.google.gerrit.server.group.SystemGroupBackend; import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.inject.Inject;
import java.util.Collections; import java.util.Collections;
/** An anonymous user who has not yet authenticated. */ /** An anonymous user who has not yet authenticated. */
public class AnonymousUser extends CurrentUser { public class AnonymousUser extends CurrentUser {
@Inject
AnonymousUser(CapabilityControl.Factory capabilityControlFactory) {
super(capabilityControlFactory);
}
@Override @Override
public GroupMembership getEffectiveGroups() { public GroupMembership getEffectiveGroups() {
return new ListGroupMembership(Collections.singleton(SystemGroupBackend.ANONYMOUS_USERS)); return new ListGroupMembership(Collections.singleton(SystemGroupBackend.ANONYMOUS_USERS));

View File

@ -16,7 +16,6 @@ package com.google.gerrit.server;
import com.google.gerrit.common.Nullable; import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.account.GroupMembership; import com.google.gerrit.server.account.GroupMembership;
import com.google.gerrit.server.account.externalids.ExternalId; import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.inject.servlet.RequestScoped; import com.google.inject.servlet.RequestScoped;
@ -40,16 +39,9 @@ public abstract class CurrentUser {
private PropertyKey() {} private PropertyKey() {}
} }
private final CapabilityControl.Factory capabilityControlFactory;
private AccessPath accessPath = AccessPath.UNKNOWN; private AccessPath accessPath = AccessPath.UNKNOWN;
private CapabilityControl capabilities;
private PropertyKey<ExternalId.Key> lastLoginExternalIdPropertyKey = PropertyKey.create(); private PropertyKey<ExternalId.Key> lastLoginExternalIdPropertyKey = PropertyKey.create();
protected CurrentUser(CapabilityControl.Factory capabilityControlFactory) {
this.capabilityControlFactory = capabilityControlFactory;
}
/** How this user is accessing the Gerrit Code Review application. */ /** How this user is accessing the Gerrit Code Review application. */
public final AccessPath getAccessPath() { public final AccessPath getAccessPath() {
return accessPath; return accessPath;
@ -98,14 +90,6 @@ public abstract class CurrentUser {
return null; return null;
} }
/** Capabilities available to this user account. */
public CapabilityControl getCapabilities() {
if (capabilities == null) {
capabilities = capabilityControlFactory.create(this);
}
return capabilities;
}
/** Check if user is the IdentifiedUser */ /** Check if user is the IdentifiedUser */
public boolean isIdentifiedUser() { public boolean isIdentifiedUser() {
return false; return false;

View File

@ -21,7 +21,6 @@ import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.account.AccountCache; import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountState; import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.account.GroupBackend; import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.account.GroupMembership; import com.google.gerrit.server.account.GroupMembership;
import com.google.gerrit.server.account.ListGroupMembership; import com.google.gerrit.server.account.ListGroupMembership;
@ -55,7 +54,6 @@ public class IdentifiedUser extends CurrentUser {
/** Create an IdentifiedUser, ignoring any per-request state. */ /** Create an IdentifiedUser, ignoring any per-request state. */
@Singleton @Singleton
public static class GenericFactory { public static class GenericFactory {
private final CapabilityControl.Factory capabilityControlFactory;
private final AuthConfig authConfig; private final AuthConfig authConfig;
private final Realm realm; private final Realm realm;
private final String anonymousCowardName; private final String anonymousCowardName;
@ -66,7 +64,6 @@ public class IdentifiedUser extends CurrentUser {
@Inject @Inject
public GenericFactory( public GenericFactory(
@Nullable CapabilityControl.Factory capabilityControlFactory,
AuthConfig authConfig, AuthConfig authConfig,
Realm realm, Realm realm,
@AnonymousCowardName String anonymousCowardName, @AnonymousCowardName String anonymousCowardName,
@ -74,7 +71,6 @@ public class IdentifiedUser extends CurrentUser {
@DisableReverseDnsLookup Boolean disableReverseDnsLookup, @DisableReverseDnsLookup Boolean disableReverseDnsLookup,
AccountCache accountCache, AccountCache accountCache,
GroupBackend groupBackend) { GroupBackend groupBackend) {
this.capabilityControlFactory = capabilityControlFactory;
this.authConfig = authConfig; this.authConfig = authConfig;
this.realm = realm; this.realm = realm;
this.anonymousCowardName = anonymousCowardName; this.anonymousCowardName = anonymousCowardName;
@ -86,7 +82,6 @@ public class IdentifiedUser extends CurrentUser {
public IdentifiedUser create(AccountState state) { public IdentifiedUser create(AccountState state) {
return new IdentifiedUser( return new IdentifiedUser(
capabilityControlFactory,
authConfig, authConfig,
realm, realm,
anonymousCowardName, anonymousCowardName,
@ -110,7 +105,6 @@ public class IdentifiedUser extends CurrentUser {
public IdentifiedUser runAs( public IdentifiedUser runAs(
SocketAddress remotePeer, Account.Id id, @Nullable CurrentUser caller) { SocketAddress remotePeer, Account.Id id, @Nullable CurrentUser caller) {
return new IdentifiedUser( return new IdentifiedUser(
capabilityControlFactory,
authConfig, authConfig,
realm, realm,
anonymousCowardName, anonymousCowardName,
@ -132,7 +126,6 @@ public class IdentifiedUser extends CurrentUser {
*/ */
@Singleton @Singleton
public static class RequestFactory { public static class RequestFactory {
private final CapabilityControl.Factory capabilityControlFactory;
private final AuthConfig authConfig; private final AuthConfig authConfig;
private final Realm realm; private final Realm realm;
private final String anonymousCowardName; private final String anonymousCowardName;
@ -144,7 +137,6 @@ public class IdentifiedUser extends CurrentUser {
@Inject @Inject
RequestFactory( RequestFactory(
CapabilityControl.Factory capabilityControlFactory,
AuthConfig authConfig, AuthConfig authConfig,
Realm realm, Realm realm,
@AnonymousCowardName String anonymousCowardName, @AnonymousCowardName String anonymousCowardName,
@ -153,7 +145,6 @@ public class IdentifiedUser extends CurrentUser {
GroupBackend groupBackend, GroupBackend groupBackend,
@DisableReverseDnsLookup Boolean disableReverseDnsLookup, @DisableReverseDnsLookup Boolean disableReverseDnsLookup,
@RemotePeer Provider<SocketAddress> remotePeerProvider) { @RemotePeer Provider<SocketAddress> remotePeerProvider) {
this.capabilityControlFactory = capabilityControlFactory;
this.authConfig = authConfig; this.authConfig = authConfig;
this.realm = realm; this.realm = realm;
this.anonymousCowardName = anonymousCowardName; this.anonymousCowardName = anonymousCowardName;
@ -166,7 +157,6 @@ public class IdentifiedUser extends CurrentUser {
public IdentifiedUser create(Account.Id id) { public IdentifiedUser create(Account.Id id) {
return new IdentifiedUser( return new IdentifiedUser(
capabilityControlFactory,
authConfig, authConfig,
realm, realm,
anonymousCowardName, anonymousCowardName,
@ -181,7 +171,6 @@ public class IdentifiedUser extends CurrentUser {
public IdentifiedUser runAs(Account.Id id, CurrentUser caller) { public IdentifiedUser runAs(Account.Id id, CurrentUser caller) {
return new IdentifiedUser( return new IdentifiedUser(
capabilityControlFactory,
authConfig, authConfig,
realm, realm,
anonymousCowardName, anonymousCowardName,
@ -219,7 +208,6 @@ public class IdentifiedUser extends CurrentUser {
private Map<PropertyKey<Object>, Object> properties; private Map<PropertyKey<Object>, Object> properties;
private IdentifiedUser( private IdentifiedUser(
CapabilityControl.Factory capabilityControlFactory,
AuthConfig authConfig, AuthConfig authConfig,
Realm realm, Realm realm,
String anonymousCowardName, String anonymousCowardName,
@ -231,7 +219,6 @@ public class IdentifiedUser extends CurrentUser {
AccountState state, AccountState state,
@Nullable CurrentUser realUser) { @Nullable CurrentUser realUser) {
this( this(
capabilityControlFactory,
authConfig, authConfig,
realm, realm,
anonymousCowardName, anonymousCowardName,
@ -246,7 +233,6 @@ public class IdentifiedUser extends CurrentUser {
} }
private IdentifiedUser( private IdentifiedUser(
CapabilityControl.Factory capabilityControlFactory,
AuthConfig authConfig, AuthConfig authConfig,
Realm realm, Realm realm,
String anonymousCowardName, String anonymousCowardName,
@ -257,7 +243,6 @@ public class IdentifiedUser extends CurrentUser {
@Nullable Provider<SocketAddress> remotePeerProvider, @Nullable Provider<SocketAddress> remotePeerProvider,
Account.Id id, Account.Id id,
@Nullable CurrentUser realUser) { @Nullable CurrentUser realUser) {
super(capabilityControlFactory);
this.canonicalUrl = canonicalUrl; this.canonicalUrl = canonicalUrl;
this.accountCache = accountCache; this.accountCache = accountCache;
this.groupBackend = groupBackend; this.groupBackend = groupBackend;
@ -465,7 +450,6 @@ public class IdentifiedUser extends CurrentUser {
* @return copy of the identified user * @return copy of the identified user
*/ */
public IdentifiedUser materializedCopy() { public IdentifiedUser materializedCopy() {
CapabilityControl capabilities = getCapabilities();
Provider<SocketAddress> remotePeer; Provider<SocketAddress> remotePeer;
try { try {
remotePeer = Providers.of(remotePeerProvider.get()); remotePeer = Providers.of(remotePeerProvider.get());
@ -479,13 +463,6 @@ public class IdentifiedUser extends CurrentUser {
}; };
} }
return new IdentifiedUser( return new IdentifiedUser(
new CapabilityControl.Factory() {
@Override
public CapabilityControl create(CurrentUser user) {
return capabilities;
}
},
authConfig, authConfig,
realm, realm,
anonymousCowardName, anonymousCowardName,

View File

@ -14,10 +14,7 @@
package com.google.gerrit.server; package com.google.gerrit.server;
import com.google.common.annotations.VisibleForTesting;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.account.GroupMembership; import com.google.gerrit.server.account.GroupMembership;
import com.google.inject.Inject;
/** /**
* User identity for plugin code that needs an identity. * User identity for plugin code that needs an identity.
@ -33,12 +30,6 @@ public class InternalUser extends CurrentUser {
InternalUser create(); InternalUser create();
} }
@VisibleForTesting
@Inject
public InternalUser(CapabilityControl.Factory capabilityControlFactory) {
super(capabilityControlFactory);
}
@Override @Override
public GroupMembership getEffectiveGroups() { public GroupMembership getEffectiveGroups() {
return GroupMembership.EMPTY; return GroupMembership.EMPTY;

View File

@ -14,7 +14,6 @@
package com.google.gerrit.server; package com.google.gerrit.server;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.account.GroupMembership; import com.google.gerrit.server.account.GroupMembership;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
@ -32,9 +31,7 @@ public class PeerDaemonUser extends CurrentUser {
private final SocketAddress peer; private final SocketAddress peer;
@Inject @Inject
protected PeerDaemonUser( protected PeerDaemonUser(@Assisted SocketAddress peer) {
CapabilityControl.Factory capabilityControlFactory, @Assisted SocketAddress peer) {
super(capabilityControlFactory);
this.peer = peer; this.peer = peer;
} }

View File

@ -14,7 +14,6 @@
package com.google.gerrit.server; package com.google.gerrit.server;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
@ -27,9 +26,7 @@ public class PluginUser extends InternalUser {
private final String pluginName; private final String pluginName;
@Inject @Inject
protected PluginUser( protected PluginUser(@Assisted String pluginName) {
CapabilityControl.Factory capabilityControlFactory, @Assisted String pluginName) {
super(capabilityControlFactory);
this.pluginName = pluginName; this.pluginName = pluginName;
} }

View File

@ -18,12 +18,16 @@ import static java.util.stream.Collectors.toSet;
import com.google.gerrit.common.data.PermissionRule; import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.common.errors.NoSuchGroupException; import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.client.Account;
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.IdentifiedUser; import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.git.AccountsSection; import com.google.gerrit.server.git.AccountsSection;
import com.google.gerrit.server.group.SystemGroupBackend; import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
@ -32,6 +36,7 @@ import java.util.Set;
/** Access control management for one account's access to other accounts. */ /** Access control management for one account's access to other accounts. */
public class AccountControl { public class AccountControl {
public static class Factory { public static class Factory {
private final PermissionBackend permissionBackend;
private final ProjectCache projectCache; private final ProjectCache projectCache;
private final GroupControl.Factory groupControlFactory; private final GroupControl.Factory groupControlFactory;
private final Provider<CurrentUser> user; private final Provider<CurrentUser> user;
@ -40,11 +45,13 @@ public class AccountControl {
@Inject @Inject
Factory( Factory(
final ProjectCache projectCache, PermissionBackend permissionBackend,
final GroupControl.Factory groupControlFactory, ProjectCache projectCache,
final Provider<CurrentUser> user, GroupControl.Factory groupControlFactory,
final IdentifiedUser.GenericFactory userFactory, Provider<CurrentUser> user,
final AccountVisibility accountVisibility) { IdentifiedUser.GenericFactory userFactory,
AccountVisibility accountVisibility) {
this.permissionBackend = permissionBackend;
this.projectCache = projectCache; this.projectCache = projectCache;
this.groupControlFactory = groupControlFactory; this.groupControlFactory = groupControlFactory;
this.user = user; this.user = user;
@ -54,24 +61,34 @@ public class AccountControl {
public AccountControl get() { public AccountControl get() {
return new AccountControl( return new AccountControl(
projectCache, groupControlFactory, user.get(), userFactory, accountVisibility); permissionBackend,
projectCache,
groupControlFactory,
user.get(),
userFactory,
accountVisibility);
} }
} }
private final AccountsSection accountsSection; private final AccountsSection accountsSection;
private final GroupControl.Factory groupControlFactory; private final GroupControl.Factory groupControlFactory;
private final PermissionBackend.WithUser perm;
private final CurrentUser user; private final CurrentUser user;
private final IdentifiedUser.GenericFactory userFactory; private final IdentifiedUser.GenericFactory userFactory;
private final AccountVisibility accountVisibility; private final AccountVisibility accountVisibility;
private Boolean viewAll;
AccountControl( AccountControl(
final ProjectCache projectCache, PermissionBackend permissionBackend,
final GroupControl.Factory groupControlFactory, ProjectCache projectCache,
final CurrentUser user, GroupControl.Factory groupControlFactory,
final IdentifiedUser.GenericFactory userFactory, CurrentUser user,
final AccountVisibility accountVisibility) { IdentifiedUser.GenericFactory userFactory,
AccountVisibility accountVisibility) {
this.accountsSection = projectCache.getAllProjects().getConfig().getAccountsSection(); this.accountsSection = projectCache.getAllProjects().getConfig().getAccountsSection();
this.groupControlFactory = groupControlFactory; this.groupControlFactory = groupControlFactory;
this.perm = permissionBackend.user(user);
this.user = user; this.user = user;
this.userFactory = userFactory; this.userFactory = userFactory;
this.accountVisibility = accountVisibility; this.accountVisibility = accountVisibility;
@ -137,17 +154,16 @@ public class AccountControl {
} }
private boolean canSee(OtherUser otherUser) { private boolean canSee(OtherUser otherUser) {
// Special case: I can always see myself. if (accountVisibility == AccountVisibility.ALL) {
if (user.isIdentifiedUser() && user.getAccountId().equals(otherUser.getId())) {
return true; return true;
} } else if (user.isIdentifiedUser() && user.getAccountId().equals(otherUser.getId())) {
if (user.getCapabilities().canViewAllAccounts()) { // I can always see myself.
return true;
} else if (viewAll()) {
return true; return true;
} }
switch (accountVisibility) { switch (accountVisibility) {
case ALL:
return true;
case SAME_GROUP: case SAME_GROUP:
{ {
Set<AccountGroup.UUID> usersGroups = groupsOf(otherUser.getUser()); Set<AccountGroup.UUID> usersGroups = groupsOf(otherUser.getUser());
@ -178,12 +194,25 @@ public class AccountControl {
} }
case NONE: case NONE:
break; break;
case ALL:
default: default:
throw new IllegalStateException("Bad AccountVisibility " + accountVisibility); throw new IllegalStateException("Bad AccountVisibility " + accountVisibility);
} }
return false; return false;
} }
private boolean viewAll() {
if (viewAll == null) {
try {
perm.check(GlobalPermission.VIEW_ALL_ACCOUNTS);
viewAll = true;
} catch (AuthException | PermissionBackendException e) {
viewAll = false;
}
}
return viewAll;
}
private Set<AccountGroup.UUID> groupsOf(IdentifiedUser user) { private Set<AccountGroup.UUID> groupsOf(IdentifiedUser user) {
return user.getEffectiveGroups() return user.getEffectiveGroups()
.getKnownGroups() .getKnownGroups()

View File

@ -30,12 +30,9 @@ import com.google.gerrit.server.git.QueueProvider;
import com.google.gerrit.server.group.SystemGroupBackend; import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.gerrit.server.permissions.GlobalPermission; import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackendException; import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.RefControl;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted; import com.google.inject.Singleton;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -45,41 +42,40 @@ import java.util.Map;
/** Access control management for server-wide capabilities. */ /** Access control management for server-wide capabilities. */
public class CapabilityControl { public class CapabilityControl {
public interface Factory { private static final CurrentUser.PropertyKey<CapabilityControl> SELF =
CapabilityControl create(CurrentUser user); CurrentUser.PropertyKey.create();
@Singleton
public static class Factory {
private final ProjectCache projectCache;
@Inject
Factory(ProjectCache projectCache) {
this.projectCache = projectCache;
}
public CapabilityControl create(CurrentUser user) {
CapabilityControl ctl = user.get(SELF);
if (ctl == null) {
ctl = new CapabilityControl(projectCache, user);
user.put(SELF, ctl);
}
return ctl;
}
} }
private final CapabilityCollection capabilities; private final CapabilityCollection capabilities;
private final CurrentUser user; private final CurrentUser user;
private final Map<String, List<PermissionRule>> effective; private final Map<String, List<PermissionRule>> effective;
private Boolean canAdministrateServer; private Boolean canAdministrateServer;
private Boolean canEmailReviewers;
@Inject private CapabilityControl(ProjectCache projectCache, CurrentUser currentUser) {
CapabilityControl(ProjectCache projectCache, @Assisted CurrentUser currentUser) {
capabilities = projectCache.getAllProjects().getCapabilityCollection(); capabilities = projectCache.getAllProjects().getCapabilityCollection();
user = currentUser; user = currentUser;
effective = new HashMap<>(); effective = new HashMap<>();
} }
/** private boolean isAdmin() {
* <b>Do not use.</b> Determine if the user can administer this server.
*
* <p>This method is visible only for the benefit of the following transitional classes:
*
* <ul>
* <li>{@link ProjectControl}
* <li>{@link RefControl}
* <li>{@link ChangeControl}
* <li>{@link GroupControl}
* </ul>
*
* Other callers should not use this method, as it is slated to go away.
*
* @return true if the user can administer this server.
*/
public boolean isAdmin_DoNotUse() {
if (canAdministrateServer == null) { if (canAdministrateServer == null) {
if (user.getRealUser() != user) { if (user.getRealUser() != user) {
canAdministrateServer = false; canAdministrateServer = false;
@ -93,19 +89,10 @@ public class CapabilityControl {
} }
/** @return true if the user can email reviewers. */ /** @return true if the user can email reviewers. */
public boolean canEmailReviewers() { private boolean canEmailReviewers() {
if (canEmailReviewers == null) { return matchAny(capabilities.emailReviewers, ALLOWED_RULE)
canEmailReviewers =
matchAny(capabilities.emailReviewers, ALLOWED_RULE)
|| !matchAny(capabilities.emailReviewers, not(ALLOWED_RULE)); || !matchAny(capabilities.emailReviewers, not(ALLOWED_RULE));
} }
return canEmailReviewers;
}
/** @return true if the user can view all accounts. */
public boolean canViewAllAccounts() {
return canPerform(GlobalCapability.VIEW_ALL_ACCOUNTS) || isAdmin_DoNotUse();
}
/** @return which priority queue the user's tasks should be submitted to. */ /** @return which priority queue the user's tasks should be submitted to. */
public QueueProvider.QueueType getQueueType() { public QueueProvider.QueueType getQueueType() {
@ -226,7 +213,7 @@ public class CapabilityControl {
} else if (perm instanceof PluginPermission) { } else if (perm instanceof PluginPermission) {
PluginPermission pluginPermission = (PluginPermission) perm; PluginPermission pluginPermission = (PluginPermission) perm;
return canPerform(pluginPermission.permissionName()) return canPerform(pluginPermission.permissionName())
|| (pluginPermission.fallBackToAdmin() && isAdmin_DoNotUse()); || (pluginPermission.fallBackToAdmin() && isAdmin());
} }
throw new PermissionBackendException(perm + " unsupported"); throw new PermissionBackendException(perm + " unsupported");
} }
@ -234,11 +221,9 @@ public class CapabilityControl {
private boolean can(GlobalPermission perm) throws PermissionBackendException { private boolean can(GlobalPermission perm) throws PermissionBackendException {
switch (perm) { switch (perm) {
case ADMINISTRATE_SERVER: case ADMINISTRATE_SERVER:
return isAdmin_DoNotUse(); return isAdmin();
case EMAIL_REVIEWERS: case EMAIL_REVIEWERS:
return canEmailReviewers(); return canEmailReviewers();
case VIEW_ALL_ACCOUNTS:
return canViewAllAccounts();
case FLUSH_CACHES: case FLUSH_CACHES:
case KILL_TASK: case KILL_TASK:
@ -247,7 +232,7 @@ public class CapabilityControl {
case VIEW_QUEUE: case VIEW_QUEUE:
return canPerform(perm.permissionName()) return canPerform(perm.permissionName())
|| canPerform(GlobalCapability.MAINTAIN_SERVER) || canPerform(GlobalCapability.MAINTAIN_SERVER)
|| isAdmin_DoNotUse(); || isAdmin();
case CREATE_ACCOUNT: case CREATE_ACCOUNT:
case CREATE_GROUP: case CREATE_GROUP:
@ -255,9 +240,10 @@ public class CapabilityControl {
case MAINTAIN_SERVER: case MAINTAIN_SERVER:
case MODIFY_ACCOUNT: case MODIFY_ACCOUNT:
case STREAM_EVENTS: case STREAM_EVENTS:
case VIEW_ALL_ACCOUNTS:
case VIEW_CONNECTIONS: case VIEW_CONNECTIONS:
case VIEW_PLUGINS: case VIEW_PLUGINS:
return canPerform(perm.permissionName()) || isAdmin_DoNotUse(); return canPerform(perm.permissionName()) || isAdmin();
case ACCESS_DATABASE: case ACCESS_DATABASE:
case RUN_AS: case RUN_AS:

View File

@ -56,15 +56,18 @@ class GetCapabilities implements RestReadView<AccountResource> {
private Set<String> query; private Set<String> query;
private final PermissionBackend permissionBackend; private final PermissionBackend permissionBackend;
private final CapabilityControl.Factory capabilityFactory;
private final Provider<CurrentUser> self; private final Provider<CurrentUser> self;
private final DynamicMap<CapabilityDefinition> pluginCapabilities; private final DynamicMap<CapabilityDefinition> pluginCapabilities;
@Inject @Inject
GetCapabilities( GetCapabilities(
PermissionBackend permissionBackend, PermissionBackend permissionBackend,
CapabilityControl.Factory capabilityFactory,
Provider<CurrentUser> self, Provider<CurrentUser> self,
DynamicMap<CapabilityDefinition> pluginCapabilities) { DynamicMap<CapabilityDefinition> pluginCapabilities) {
this.permissionBackend = permissionBackend; this.permissionBackend = permissionBackend;
this.capabilityFactory = capabilityFactory;
this.self = self; this.self = self;
this.pluginCapabilities = pluginCapabilities; this.pluginCapabilities = pluginCapabilities;
} }
@ -81,8 +84,10 @@ class GetCapabilities implements RestReadView<AccountResource> {
for (GlobalOrPluginPermission p : perm.test(permissionsToTest())) { for (GlobalOrPluginPermission p : perm.test(permissionsToTest())) {
have.put(p.permissionName(), true); have.put(p.permissionName(), true);
} }
addRanges(have, rsrc);
addPriority(have, rsrc); CapabilityControl cc = capabilityFactory.create(rsrc.getUser());
addRanges(have, cc);
addPriority(have, cc);
return OutputFormat.JSON return OutputFormat.JSON
.newGson() .newGson()
@ -112,8 +117,7 @@ class GetCapabilities implements RestReadView<AccountResource> {
return query == null || query.contains(name.toLowerCase()); return query == null || query.contains(name.toLowerCase());
} }
private void addRanges(Map<String, Object> have, AccountResource rsrc) { private void addRanges(Map<String, Object> have, CapabilityControl cc) {
CapabilityControl cc = rsrc.getUser().getCapabilities();
for (String name : GlobalCapability.getRangeNames()) { for (String name : GlobalCapability.getRangeNames()) {
if (want(name) && cc.hasExplicitRange(name)) { if (want(name) && cc.hasExplicitRange(name)) {
have.put(name, new Range(cc.getRange(name))); have.put(name, new Range(cc.getRange(name)));
@ -121,8 +125,8 @@ class GetCapabilities implements RestReadView<AccountResource> {
} }
} }
private void addPriority(Map<String, Object> have, AccountResource rsrc) { private void addPriority(Map<String, Object> have, CapabilityControl cc) {
QueueProvider.QueueType queue = rsrc.getUser().getCapabilities().getQueueType(); QueueProvider.QueueType queue = cc.getQueueType();
if (queue != QueueProvider.QueueType.INTERACTIVE if (queue != QueueProvider.QueueType.INTERACTIVE
|| (query != null && query.contains(PRIORITY))) { || (query != null && query.contains(PRIORITY))) {
have.put(PRIORITY, queue); have.put(PRIORITY, queue);

View File

@ -17,9 +17,13 @@ package com.google.gerrit.server.account;
import com.google.gerrit.common.data.GroupDescription; import com.google.gerrit.common.data.GroupDescription;
import com.google.gerrit.common.data.GroupDescriptions; import com.google.gerrit.common.data.GroupDescriptions;
import com.google.gerrit.common.errors.NoSuchGroupException; import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.client.Account;
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.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
import com.google.inject.Singleton; import com.google.inject.Singleton;
@ -29,30 +33,38 @@ public class GroupControl {
@Singleton @Singleton
public static class GenericFactory { public static class GenericFactory {
private final PermissionBackend permissionBackend;
private final GroupBackend groupBackend; private final GroupBackend groupBackend;
@Inject @Inject
GenericFactory(GroupBackend gb) { GenericFactory(PermissionBackend permissionBackend, GroupBackend gb) {
this.permissionBackend = permissionBackend;
groupBackend = gb; groupBackend = gb;
} }
public GroupControl controlFor(CurrentUser who, AccountGroup.UUID groupId) public GroupControl controlFor(CurrentUser who, AccountGroup.UUID groupId)
throws NoSuchGroupException { throws NoSuchGroupException {
final GroupDescription.Basic group = groupBackend.get(groupId); GroupDescription.Basic group = groupBackend.get(groupId);
if (group == null) { if (group == null) {
throw new NoSuchGroupException(groupId); throw new NoSuchGroupException(groupId);
} }
return new GroupControl(who, group, groupBackend); return new GroupControl(who, group, permissionBackend, groupBackend);
} }
} }
public static class Factory { public static class Factory {
private final PermissionBackend permissionBackend;
private final GroupCache groupCache; private final GroupCache groupCache;
private final Provider<CurrentUser> user; private final Provider<CurrentUser> user;
private final GroupBackend groupBackend; private final GroupBackend groupBackend;
@Inject @Inject
Factory(GroupCache gc, Provider<CurrentUser> cu, GroupBackend gb) { Factory(
PermissionBackend permissionBackend,
GroupCache gc,
Provider<CurrentUser> cu,
GroupBackend gb) {
this.permissionBackend = permissionBackend;
groupCache = gc; groupCache = gc;
user = cu; user = cu;
groupBackend = gb; groupBackend = gb;
@ -79,7 +91,7 @@ public class GroupControl {
} }
public GroupControl controlFor(GroupDescription.Basic group) { public GroupControl controlFor(GroupDescription.Basic group) {
return new GroupControl(user.get(), group, groupBackend); return new GroupControl(user.get(), group, permissionBackend, groupBackend);
} }
public GroupControl validateFor(AccountGroup.Id groupId) throws NoSuchGroupException { public GroupControl validateFor(AccountGroup.Id groupId) throws NoSuchGroupException {
@ -102,11 +114,17 @@ public class GroupControl {
private final CurrentUser user; private final CurrentUser user;
private final GroupDescription.Basic group; private final GroupDescription.Basic group;
private Boolean isOwner; private Boolean isOwner;
private final PermissionBackend.WithUser perm;
private final GroupBackend groupBackend; private final GroupBackend groupBackend;
GroupControl(CurrentUser who, GroupDescription.Basic gd, GroupBackend gb) { GroupControl(
CurrentUser who,
GroupDescription.Basic gd,
PermissionBackend permissionBackend,
GroupBackend gb) {
user = who; user = who;
group = gd; group = gd;
this.perm = permissionBackend.user(user);
groupBackend = gb; groupBackend = gb;
} }
@ -127,8 +145,8 @@ public class GroupControl {
return user.isInternalUser() return user.isInternalUser()
|| groupBackend.isVisibleToAll(group.getGroupUUID()) || groupBackend.isVisibleToAll(group.getGroupUUID())
|| user.getEffectiveGroups().contains(group.getGroupUUID()) || user.getEffectiveGroups().contains(group.getGroupUUID())
|| user.getCapabilities().isAdmin_DoNotUse() || isOwner()
|| isOwner(); || canAdministrateServer();
} }
public boolean isOwner() { public boolean isOwner() {
@ -137,13 +155,20 @@ public class GroupControl {
isOwner = false; isOwner = false;
} else if (isOwner == null) { } else if (isOwner == null) {
AccountGroup.UUID ownerUUID = accountGroup.getOwnerGroupUUID(); AccountGroup.UUID ownerUUID = accountGroup.getOwnerGroupUUID();
isOwner = isOwner = getUser().getEffectiveGroups().contains(ownerUUID) || canAdministrateServer();
getUser().getEffectiveGroups().contains(ownerUUID)
|| getUser().getCapabilities().isAdmin_DoNotUse();
} }
return isOwner; return isOwner;
} }
private boolean canAdministrateServer() {
try {
perm.check(GlobalPermission.ADMINISTRATE_SERVER);
return true;
} catch (AuthException | PermissionBackendException denied) {
return false;
}
}
public boolean canAddMember() { public boolean canAddMember() {
return isOwner(); return isOwner();
} }

View File

@ -85,7 +85,6 @@ import com.google.gerrit.server.account.AccountResolver;
import com.google.gerrit.server.account.AccountVisibility; import com.google.gerrit.server.account.AccountVisibility;
import com.google.gerrit.server.account.AccountVisibilityProvider; import com.google.gerrit.server.account.AccountVisibilityProvider;
import com.google.gerrit.server.account.CapabilityCollection; import com.google.gerrit.server.account.CapabilityCollection;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.account.ChangeUserName; import com.google.gerrit.server.account.ChangeUserName;
import com.google.gerrit.server.account.EmailExpander; import com.google.gerrit.server.account.EmailExpander;
import com.google.gerrit.server.account.GroupCacheImpl; import com.google.gerrit.server.account.GroupCacheImpl;
@ -245,7 +244,6 @@ public class GerritGlobalModule extends FactoryModule {
factory(DeleteReviewerSender.Factory.class); factory(DeleteReviewerSender.Factory.class);
factory(AddKeySender.Factory.class); factory(AddKeySender.Factory.class);
factory(CapabilityCollection.Factory.class); factory(CapabilityCollection.Factory.class);
factory(CapabilityControl.Factory.class);
factory(ChangeData.Factory.class); factory(ChangeData.Factory.class);
factory(ChangeJson.AssistedFactory.class); factory(ChangeJson.AssistedFactory.class);
factory(CreateChangeSender.Factory.class); factory(CreateChangeSender.Factory.class);

View File

@ -29,18 +29,20 @@ class ReceiveConfig {
final boolean checkReferencedObjectsAreReachable; final boolean checkReferencedObjectsAreReachable;
final boolean allowDrafts; final boolean allowDrafts;
private final int systemMaxBatchChanges; private final int systemMaxBatchChanges;
private final CapabilityControl.Factory capabilityFactory;
@Inject @Inject
ReceiveConfig(@GerritServerConfig Config config) { ReceiveConfig(@GerritServerConfig Config config, CapabilityControl.Factory capabilityFactory) {
checkMagicRefs = config.getBoolean("receive", null, "checkMagicRefs", true); checkMagicRefs = config.getBoolean("receive", null, "checkMagicRefs", true);
checkReferencedObjectsAreReachable = checkReferencedObjectsAreReachable =
config.getBoolean("receive", null, "checkReferencedObjectsAreReachable", true); config.getBoolean("receive", null, "checkReferencedObjectsAreReachable", true);
allowDrafts = config.getBoolean("change", null, "allowDrafts", true); allowDrafts = config.getBoolean("change", null, "allowDrafts", true);
systemMaxBatchChanges = config.getInt("receive", "maxBatchChanges", 0); systemMaxBatchChanges = config.getInt("receive", "maxBatchChanges", 0);
this.capabilityFactory = capabilityFactory;
} }
public int getEffectiveMaxBatchChangesLimit(CurrentUser user) { public int getEffectiveMaxBatchChangesLimit(CurrentUser user) {
CapabilityControl cap = user.getCapabilities(); CapabilityControl cap = capabilityFactory.create(user);
if (cap.hasExplicitRange(BATCH_CHANGES_LIMIT)) { if (cap.hasExplicitRange(BATCH_CHANGES_LIMIT)) {
return cap.getRange(BATCH_CHANGES_LIMIT).getMax(); return cap.getRange(BATCH_CHANGES_LIMIT).getMax();
} }

View File

@ -19,6 +19,7 @@ import com.google.common.collect.ListMultimap;
import com.google.gerrit.common.errors.EmailException; import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.extensions.api.changes.NotifyHandling; import com.google.gerrit.extensions.api.changes.NotifyHandling;
import com.google.gerrit.extensions.api.changes.RecipientType; import com.google.gerrit.extensions.api.changes.RecipientType;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
@ -37,6 +38,8 @@ import com.google.gerrit.server.patch.PatchList;
import com.google.gerrit.server.patch.PatchListEntry; import com.google.gerrit.server.patch.PatchListEntry;
import com.google.gerrit.server.patch.PatchListNotAvailableException; import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException; import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ProjectState; import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeData;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
@ -94,8 +97,12 @@ public abstract class ChangeEmail extends NotificationEmail {
super.setFrom(id); super.setFrom(id);
/** 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); try {
emailOnlyAuthors = !user.getCapabilities().canEmailReviewers(); IdentifiedUser user = args.identifiedUserFactory.create(id);
args.permissionBackend.user(user).check(GlobalPermission.EMAIL_REVIEWERS);
} catch (AuthException | PermissionBackendException e) {
emailOnlyAuthors = true;
}
} }
public void setPatchSet(PatchSet ps) { public void setPatchSet(PatchSet ps) {

View File

@ -24,7 +24,6 @@ import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.IdentifiedUser.GenericFactory; import com.google.gerrit.server.IdentifiedUser.GenericFactory;
import com.google.gerrit.server.StarredChangesUtil; import com.google.gerrit.server.StarredChangesUtil;
import com.google.gerrit.server.account.AccountCache; import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.account.GroupBackend; import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.account.GroupIncludeCache; import com.google.gerrit.server.account.GroupIncludeCache;
import com.google.gerrit.server.config.AllProjectsName; import com.google.gerrit.server.config.AllProjectsName;
@ -36,6 +35,7 @@ import com.google.gerrit.server.mail.EmailSettings;
import com.google.gerrit.server.notedb.ChangeNotes; import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.patch.PatchListCache; import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.patch.PatchSetInfoFactory; import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.query.account.InternalAccountQuery; import com.google.gerrit.server.query.account.InternalAccountQuery;
import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeData;
@ -52,6 +52,7 @@ import org.eclipse.jgit.lib.PersonIdent;
public class EmailArguments { public class EmailArguments {
final GitRepositoryManager server; final GitRepositoryManager server;
final ProjectCache projectCache; final ProjectCache projectCache;
final PermissionBackend permissionBackend;
final GroupBackend groupBackend; final GroupBackend groupBackend;
final GroupIncludeCache groupIncludes; final GroupIncludeCache groupIncludes;
final AccountCache accountCache; final AccountCache accountCache;
@ -61,7 +62,6 @@ public class EmailArguments {
final EmailSender emailSender; final EmailSender emailSender;
final PatchSetInfoFactory patchSetInfoFactory; final PatchSetInfoFactory patchSetInfoFactory;
final IdentifiedUser.GenericFactory identifiedUserFactory; final IdentifiedUser.GenericFactory identifiedUserFactory;
final CapabilityControl.Factory capabilityControlFactory;
final ChangeNotes.Factory changeNotesFactory; final ChangeNotes.Factory changeNotesFactory;
final AnonymousUser anonymousUser; final AnonymousUser anonymousUser;
final String anonymousCowardName; final String anonymousCowardName;
@ -86,6 +86,7 @@ public class EmailArguments {
EmailArguments( EmailArguments(
GitRepositoryManager server, GitRepositoryManager server,
ProjectCache projectCache, ProjectCache projectCache,
PermissionBackend permissionBackend,
GroupBackend groupBackend, GroupBackend groupBackend,
GroupIncludeCache groupIncludes, GroupIncludeCache groupIncludes,
AccountCache accountCache, AccountCache accountCache,
@ -95,7 +96,6 @@ public class EmailArguments {
EmailSender emailSender, EmailSender emailSender,
PatchSetInfoFactory patchSetInfoFactory, PatchSetInfoFactory patchSetInfoFactory,
GenericFactory identifiedUserFactory, GenericFactory identifiedUserFactory,
CapabilityControl.Factory capabilityControlFactory,
ChangeNotes.Factory changeNotesFactory, ChangeNotes.Factory changeNotesFactory,
AnonymousUser anonymousUser, AnonymousUser anonymousUser,
@AnonymousCowardName String anonymousCowardName, @AnonymousCowardName String anonymousCowardName,
@ -116,6 +116,7 @@ public class EmailArguments {
OutgoingEmailValidator validator) { OutgoingEmailValidator validator) {
this.server = server; this.server = server;
this.projectCache = projectCache; this.projectCache = projectCache;
this.permissionBackend = permissionBackend;
this.groupBackend = groupBackend; this.groupBackend = groupBackend;
this.groupIncludes = groupIncludes; this.groupIncludes = groupIncludes;
this.accountCache = accountCache; this.accountCache = accountCache;
@ -125,7 +126,6 @@ public class EmailArguments {
this.emailSender = emailSender; this.emailSender = emailSender;
this.patchSetInfoFactory = patchSetInfoFactory; this.patchSetInfoFactory = patchSetInfoFactory;
this.identifiedUserFactory = identifiedUserFactory; this.identifiedUserFactory = identifiedUserFactory;
this.capabilityControlFactory = capabilityControlFactory;
this.changeNotesFactory = changeNotesFactory; this.changeNotesFactory = changeNotesFactory;
this.anonymousUser = anonymousUser; this.anonymousUser = anonymousUser;
this.anonymousCowardName = anonymousCowardName; this.anonymousCowardName = anonymousCowardName;

View File

@ -141,7 +141,7 @@ public class ProjectWatch {
private void add(Watchers matching, NotifyConfig nc) throws OrmException, QueryParseException { private void add(Watchers matching, NotifyConfig nc) throws OrmException, QueryParseException {
for (GroupReference ref : nc.getGroups()) { for (GroupReference ref : nc.getGroups()) {
CurrentUser user = new SingleGroupUser(args.capabilityControlFactory, ref.getUUID()); CurrentUser user = new SingleGroupUser(ref.getUUID());
if (filterMatch(user, nc.getFilter())) { if (filterMatch(user, nc.getFilter())) {
deliverToMembers(matching.list(nc.getHeader()), ref.getUUID()); deliverToMembers(matching.list(nc.getHeader()), ref.getUUID());
} }

View File

@ -247,9 +247,8 @@ public class ChangeControl {
return (isOwner() // owner (aka creator) of the change can abandon return (isOwner() // owner (aka creator) of the change can abandon
|| getRefControl().isOwner() // branch owner can abandon || getRefControl().isOwner() // branch owner can abandon
|| getProjectControl().isOwner() // project owner can abandon || getProjectControl().isOwner() // project owner can abandon
|| getUser().getCapabilities().isAdmin_DoNotUse() // site administers are god
|| getRefControl().canAbandon() // user can abandon a specific ref || getRefControl().canAbandon() // user can abandon a specific ref
) || getProjectControl().isAdmin())
&& !isPatchSetLocked(db); && !isPatchSetLocked(db);
} }
@ -266,13 +265,11 @@ public class ChangeControl {
switch (status) { switch (status) {
case DRAFT: case DRAFT:
return isOwner() return isOwner() || getRefControl().canDeleteDrafts() || getProjectControl().isAdmin();
|| getRefControl().canDeleteDrafts()
|| getUser().getCapabilities().isAdmin_DoNotUse();
case NEW: case NEW:
case ABANDONED: case ABANDONED:
return (isOwner() && getRefControl().canDeleteOwnChanges()) return (isOwner() && getRefControl().canDeleteOwnChanges())
|| getUser().getCapabilities().isAdmin_DoNotUse(); || getProjectControl().isAdmin();
case MERGED: case MERGED:
default: default:
return false; return false;
@ -410,7 +407,7 @@ public class ChangeControl {
if (getRefControl().canRemoveReviewer() // has removal permissions if (getRefControl().canRemoveReviewer() // has removal permissions
|| getRefControl().isOwner() // branch owner || getRefControl().isOwner() // branch owner
|| getProjectControl().isOwner() // project owner || getProjectControl().isOwner() // project owner
|| getUser().getCapabilities().isAdmin_DoNotUse()) { || getProjectControl().isAdmin()) {
return true; return true;
} }
} }
@ -424,9 +421,8 @@ public class ChangeControl {
return isOwner() // owner (aka creator) of the change can edit topic return isOwner() // owner (aka creator) of the change can edit topic
|| getRefControl().isOwner() // branch owner can edit topic || getRefControl().isOwner() // branch owner can edit topic
|| getProjectControl().isOwner() // project owner can edit topic || getProjectControl().isOwner() // project owner can edit topic
|| getUser().getCapabilities().isAdmin_DoNotUse() // site administers are god
|| getRefControl().canEditTopicName() // user can edit topic on a specific ref || getRefControl().canEditTopicName() // user can edit topic on a specific ref
; || getProjectControl().isAdmin();
} }
return getRefControl().canForceEditTopicName(); return getRefControl().canForceEditTopicName();
} }
@ -437,8 +433,7 @@ public class ChangeControl {
return isOwner() // owner (aka creator) of the change can edit desc return isOwner() // owner (aka creator) of the change can edit desc
|| getRefControl().isOwner() // branch owner can edit desc || getRefControl().isOwner() // branch owner can edit desc
|| getProjectControl().isOwner() // project owner can edit desc || getProjectControl().isOwner() // project owner can edit desc
|| getUser().getCapabilities().isAdmin_DoNotUse() // site administers are god || getProjectControl().isAdmin();
;
} }
return false; return false;
} }
@ -455,8 +450,8 @@ public class ChangeControl {
return isOwner() // owner (aka creator) of the change can edit hashtags return isOwner() // owner (aka creator) of the change can edit hashtags
|| getRefControl().isOwner() // branch owner can edit hashtags || getRefControl().isOwner() // branch owner can edit hashtags
|| getProjectControl().isOwner() // project owner can edit hashtags || getProjectControl().isOwner() // project owner can edit hashtags
|| getUser().getCapabilities().isAdmin_DoNotUse() // site administers are god || getRefControl().canEditHashtags() // user can edit hashtag on a specific ref
|| getRefControl().canEditHashtags(); // user can edit hashtag on a specific ref || getProjectControl().isAdmin();
} }
private boolean match(String destBranch, String refPattern) { private boolean match(String destBranch, String refPattern) {

View File

@ -21,6 +21,7 @@ import com.google.gerrit.extensions.api.access.GlobalOrPluginPermission;
import com.google.gerrit.extensions.restapi.AuthException; import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.permissions.FailedPermissionBackend; import com.google.gerrit.server.permissions.FailedPermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackend; import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException; import com.google.gerrit.server.permissions.PermissionBackendException;
@ -34,10 +35,12 @@ import java.util.Set;
@Singleton @Singleton
public class DefaultPermissionBackend extends PermissionBackend { public class DefaultPermissionBackend extends PermissionBackend {
private final ProjectCache projectCache; private final ProjectCache projectCache;
private final CapabilityControl.Factory capabilityFactory;
@Inject @Inject
DefaultPermissionBackend(ProjectCache projectCache) { DefaultPermissionBackend(ProjectCache projectCache, CapabilityControl.Factory capabilityFactory) {
this.projectCache = projectCache; this.projectCache = projectCache;
this.capabilityFactory = capabilityFactory;
} }
@Override @Override
@ -47,6 +50,7 @@ public class DefaultPermissionBackend extends PermissionBackend {
class WithUserImpl extends WithUser { class WithUserImpl extends WithUser {
private final CurrentUser user; private final CurrentUser user;
private CapabilityControl cap;
WithUserImpl(CurrentUser user) { WithUserImpl(CurrentUser user) {
this.user = checkNotNull(user, "user"); this.user = checkNotNull(user, "user");
@ -86,7 +90,10 @@ public class DefaultPermissionBackend extends PermissionBackend {
} }
private boolean can(GlobalOrPluginPermission perm) throws PermissionBackendException { private boolean can(GlobalOrPluginPermission perm) throws PermissionBackendException {
return user.getCapabilities().doCanForDefaultPermissionBackend(perm); if (cap == null) {
cap = capabilityFactory.create(user);
}
return cap.doCanForDefaultPermissionBackend(perm);
} }
} }

View File

@ -47,6 +47,8 @@ import com.google.gerrit.server.git.VisibleRefFilter;
import com.google.gerrit.server.group.SystemGroupBackend; import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.gerrit.server.notedb.ChangeNotes; import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.permissions.FailedPermissionBackend; import com.google.gerrit.server.permissions.FailedPermissionBackend;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackend.ForChange; import com.google.gerrit.server.permissions.PermissionBackend.ForChange;
import com.google.gerrit.server.permissions.PermissionBackend.ForProject; import com.google.gerrit.server.permissions.PermissionBackend.ForProject;
import com.google.gerrit.server.permissions.PermissionBackend.ForRef; import com.google.gerrit.server.permissions.PermissionBackend.ForRef;
@ -132,6 +134,7 @@ public class ProjectControl {
private final Set<AccountGroup.UUID> receiveGroups; private final Set<AccountGroup.UUID> receiveGroups;
private final String canonicalWebUrl; private final String canonicalWebUrl;
private final PermissionBackend.WithUser perm;
private final CurrentUser user; private final CurrentUser user;
private final ProjectState state; private final ProjectState state;
private final ChangeControl.Factory changeControlFactory; private final ChangeControl.Factory changeControlFactory;
@ -157,6 +160,7 @@ public class ProjectControl {
VisibleRefFilter.Factory refFilter, VisibleRefFilter.Factory refFilter,
Provider<InternalChangeQuery> queryProvider, Provider<InternalChangeQuery> queryProvider,
@CanonicalWebUrl @Nullable String canonicalWebUrl, @CanonicalWebUrl @Nullable String canonicalWebUrl,
PermissionBackend permissionBackend,
@Assisted CurrentUser who, @Assisted CurrentUser who,
@Assisted ProjectState ps, @Assisted ProjectState ps,
Metrics metrics) { Metrics metrics) {
@ -169,6 +173,7 @@ public class ProjectControl {
this.canonicalWebUrl = canonicalWebUrl; this.canonicalWebUrl = canonicalWebUrl;
this.queryProvider = queryProvider; this.queryProvider = queryProvider;
this.metrics = metrics; this.metrics = metrics;
this.perm = permissionBackend.user(who);
user = who; user = who;
state = ps; state = ps;
} }
@ -264,8 +269,16 @@ public class ProjectControl {
/** Is this user a project owner? */ /** Is this user a project owner? */
public boolean isOwner() { public boolean isOwner() {
return (isDeclaredOwner() && !controlForRef("refs/*").isBlocked(Permission.OWNER)) return (isDeclaredOwner() && !controlForRef("refs/*").isBlocked(Permission.OWNER)) || isAdmin();
|| user.getCapabilities().isAdmin_DoNotUse(); }
boolean isAdmin() {
try {
perm.check(GlobalPermission.ADMINISTRATE_SERVER);
return true;
} catch (AuthException | PermissionBackendException e) {
return false;
}
} }
private boolean isDeclaredOwner() { private boolean isDeclaredOwner() {
@ -278,7 +291,7 @@ public class ProjectControl {
/** Does this user have ownership on at least one reference name? */ /** Does this user have ownership on at least one reference name? */
public boolean isOwnerAnyRef() { public boolean isOwnerAnyRef() {
return canPerformOnAnyRef(Permission.OWNER) || user.getCapabilities().isAdmin_DoNotUse(); return canPerformOnAnyRef(Permission.OWNER) || isAdmin();
} }
/** @return true if the user can upload to at least one reference */ /** @return true if the user can upload to at least one reference */

View File

@ -201,8 +201,7 @@ public class RefControl {
// On the AllProjects project the owner access right cannot be assigned, // On the AllProjects project the owner access right cannot be assigned,
// this why for the AllProjects project we allow administrators to push // this why for the AllProjects project we allow administrators to push
// configuration changes if they have push without being project owner. // configuration changes if they have push without being project owner.
if (!(projectControl.getProjectState().isAllProjects() if (!(projectControl.getProjectState().isAllProjects() && projectControl.isAdmin())) {
&& getUser().getCapabilities().isAdmin_DoNotUse())) {
return false; return false;
} }
} }
@ -229,8 +228,7 @@ public class RefControl {
case UNKNOWN: case UNKNOWN:
case WEB_BROWSER: case WEB_BROWSER:
default: default:
return getUser().getCapabilities().isAdmin_DoNotUse() return (isOwner() && !isForceBlocked(Permission.PUSH)) || projectControl.isAdmin();
|| (isOwner() && !isForceBlocked(Permission.PUSH));
} }
} }
@ -376,10 +374,10 @@ public class RefControl {
case UNKNOWN: case UNKNOWN:
case WEB_BROWSER: case WEB_BROWSER:
default: default:
return getUser().getCapabilities().isAdmin_DoNotUse() return (isOwner() && !isForceBlocked(Permission.PUSH))
|| (isOwner() && !isForceBlocked(Permission.PUSH))
|| canPushWithForce() || canPushWithForce()
|| canPerform(Permission.DELETE); || canPerform(Permission.DELETE)
|| projectControl.isAdmin();
} }
} }

View File

@ -24,6 +24,7 @@ import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.MetricMaker; import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.metrics.Timer1; import com.google.gerrit.metrics.Timer1;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.index.Index; import com.google.gerrit.server.index.Index;
import com.google.gerrit.server.index.IndexCollection; import com.google.gerrit.server.index.IndexCollection;
import com.google.gerrit.server.index.IndexConfig; import com.google.gerrit.server.index.IndexConfig;
@ -61,6 +62,7 @@ public abstract class QueryProcessor<T> {
protected final Provider<CurrentUser> userProvider; protected final Provider<CurrentUser> userProvider;
private final CapabilityControl.Factory capabilityFactory;
private final Metrics metrics; private final Metrics metrics;
private final SchemaDefinitions<T> schemaDef; private final SchemaDefinitions<T> schemaDef;
private final IndexConfig indexConfig; private final IndexConfig indexConfig;
@ -76,6 +78,7 @@ public abstract class QueryProcessor<T> {
protected QueryProcessor( protected QueryProcessor(
Provider<CurrentUser> userProvider, Provider<CurrentUser> userProvider,
CapabilityControl.Factory capabilityFactory,
Metrics metrics, Metrics metrics,
SchemaDefinitions<T> schemaDef, SchemaDefinitions<T> schemaDef,
IndexConfig indexConfig, IndexConfig indexConfig,
@ -83,6 +86,7 @@ public abstract class QueryProcessor<T> {
IndexRewriter<T> rewriter, IndexRewriter<T> rewriter,
String limitField) { String limitField) {
this.userProvider = userProvider; this.userProvider = userProvider;
this.capabilityFactory = capabilityFactory;
this.metrics = metrics; this.metrics = metrics;
this.schemaDef = schemaDef; this.schemaDef = schemaDef;
this.indexConfig = indexConfig; this.indexConfig = indexConfig;
@ -231,7 +235,10 @@ public abstract class QueryProcessor<T> {
private int getPermittedLimit() { private int getPermittedLimit() {
if (enforceVisibility) { if (enforceVisibility) {
return userProvider.get().getCapabilities().getRange(GlobalCapability.QUERY_LIMIT).getMax(); return capabilityFactory
.create(userProvider.get())
.getRange(GlobalCapability.QUERY_LIMIT)
.getMax();
} }
return Integer.MAX_VALUE; return Integer.MAX_VALUE;
} }

View File

@ -20,6 +20,7 @@ import static com.google.gerrit.server.query.account.AccountQueryBuilder.FIELD_L
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.AccountControl; import com.google.gerrit.server.account.AccountControl;
import com.google.gerrit.server.account.AccountState; import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.index.IndexConfig; import com.google.gerrit.server.index.IndexConfig;
import com.google.gerrit.server.index.IndexPredicate; import com.google.gerrit.server.index.IndexPredicate;
import com.google.gerrit.server.index.account.AccountIndexCollection; import com.google.gerrit.server.index.account.AccountIndexCollection;
@ -44,6 +45,7 @@ public class AccountQueryProcessor extends QueryProcessor<AccountState> {
@Inject @Inject
protected AccountQueryProcessor( protected AccountQueryProcessor(
Provider<CurrentUser> userProvider, Provider<CurrentUser> userProvider,
CapabilityControl.Factory capabilityFactory,
Metrics metrics, Metrics metrics,
IndexConfig indexConfig, IndexConfig indexConfig,
AccountIndexCollection indexes, AccountIndexCollection indexes,
@ -51,6 +53,7 @@ public class AccountQueryProcessor extends QueryProcessor<AccountState> {
AccountControl.Factory accountControlFactory) { AccountControl.Factory accountControlFactory) {
super( super(
userProvider, userProvider,
capabilityFactory,
metrics, metrics,
AccountSchemaDefinitions.INSTANCE, AccountSchemaDefinitions.INSTANCE,
indexConfig, indexConfig,

View File

@ -41,7 +41,6 @@ import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.StarredChangesUtil; import com.google.gerrit.server.StarredChangesUtil;
import com.google.gerrit.server.account.AccountCache; import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountResolver; import com.google.gerrit.server.account.AccountResolver;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.account.GroupBackend; import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.account.GroupBackends; import com.google.gerrit.server.account.GroupBackends;
import com.google.gerrit.server.account.VersionedAccountDestinations; import com.google.gerrit.server.account.VersionedAccountDestinations;
@ -196,7 +195,6 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
final AllProjectsName allProjectsName; final AllProjectsName allProjectsName;
final AllUsersName allUsersName; final AllUsersName allUsersName;
final PermissionBackend permissionBackend; final PermissionBackend permissionBackend;
final CapabilityControl.Factory capabilityControlFactory;
final ChangeControl.GenericFactory changeControlGenericFactory; final ChangeControl.GenericFactory changeControlGenericFactory;
final ChangeData.Factory changeDataFactory; final ChangeData.Factory changeDataFactory;
final ChangeIndex index; final ChangeIndex index;
@ -236,7 +234,6 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
IdentifiedUser.GenericFactory userFactory, IdentifiedUser.GenericFactory userFactory,
Provider<CurrentUser> self, Provider<CurrentUser> self,
PermissionBackend permissionBackend, PermissionBackend permissionBackend,
CapabilityControl.Factory capabilityControlFactory,
ChangeControl.GenericFactory changeControlGenericFactory, ChangeControl.GenericFactory changeControlGenericFactory,
ChangeNotes.Factory notesFactory, ChangeNotes.Factory notesFactory,
ChangeData.Factory changeDataFactory, ChangeData.Factory changeDataFactory,
@ -269,7 +266,6 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
userFactory, userFactory,
self, self,
permissionBackend, permissionBackend,
capabilityControlFactory,
changeControlGenericFactory, changeControlGenericFactory,
notesFactory, notesFactory,
changeDataFactory, changeDataFactory,
@ -304,7 +300,6 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
IdentifiedUser.GenericFactory userFactory, IdentifiedUser.GenericFactory userFactory,
Provider<CurrentUser> self, Provider<CurrentUser> self,
PermissionBackend permissionBackend, PermissionBackend permissionBackend,
CapabilityControl.Factory capabilityControlFactory,
ChangeControl.GenericFactory changeControlGenericFactory, ChangeControl.GenericFactory changeControlGenericFactory,
ChangeNotes.Factory notesFactory, ChangeNotes.Factory notesFactory,
ChangeData.Factory changeDataFactory, ChangeData.Factory changeDataFactory,
@ -335,7 +330,6 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
this.userFactory = userFactory; this.userFactory = userFactory;
this.self = self; this.self = self;
this.permissionBackend = permissionBackend; this.permissionBackend = permissionBackend;
this.capabilityControlFactory = capabilityControlFactory;
this.notesFactory = notesFactory; this.notesFactory = notesFactory;
this.changeControlGenericFactory = changeControlGenericFactory; this.changeControlGenericFactory = changeControlGenericFactory;
this.changeDataFactory = changeDataFactory; this.changeDataFactory = changeDataFactory;
@ -372,7 +366,6 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
userFactory, userFactory,
Providers.of(otherUser), Providers.of(otherUser),
permissionBackend, permissionBackend,
capabilityControlFactory,
changeControlGenericFactory, changeControlGenericFactory,
notesFactory, notesFactory,
changeDataFactory, changeDataFactory,
@ -933,7 +926,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
for (GroupReference ref : suggestions) { for (GroupReference ref : suggestions) {
ids.add(ref.getUUID()); ids.add(ref.getUUID());
} }
return visibleto(new SingleGroupUser(args.capabilityControlFactory, ids)); return visibleto(new SingleGroupUser(ids));
} }
throw error("No user or group matches \"" + who + "\"."); throw error("No user or group matches \"" + who + "\".");

View File

@ -21,6 +21,7 @@ import com.google.gerrit.extensions.common.PluginDefinedInfo;
import com.google.gerrit.extensions.registration.DynamicMap; import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.index.IndexConfig; import com.google.gerrit.server.index.IndexConfig;
import com.google.gerrit.server.index.IndexPredicate; import com.google.gerrit.server.index.IndexPredicate;
import com.google.gerrit.server.index.QueryOptions; import com.google.gerrit.server.index.QueryOptions;
@ -65,6 +66,7 @@ public class ChangeQueryProcessor extends QueryProcessor<ChangeData>
@Inject @Inject
ChangeQueryProcessor( ChangeQueryProcessor(
Provider<CurrentUser> userProvider, Provider<CurrentUser> userProvider,
CapabilityControl.Factory capabilityFactory,
Metrics metrics, Metrics metrics,
IndexConfig indexConfig, IndexConfig indexConfig,
ChangeIndexCollection indexes, ChangeIndexCollection indexes,
@ -75,6 +77,7 @@ public class ChangeQueryProcessor extends QueryProcessor<ChangeData>
DynamicMap<ChangeAttributeFactory> attributeFactories) { DynamicMap<ChangeAttributeFactory> attributeFactories) {
super( super(
userProvider, userProvider,
capabilityFactory,
metrics, metrics,
ChangeSchemaDefinitions.INSTANCE, ChangeSchemaDefinitions.INSTANCE,
indexConfig, indexConfig,

View File

@ -14,25 +14,21 @@
package com.google.gerrit.server.query.change; package com.google.gerrit.server.query.change;
import com.google.common.collect.ImmutableSet;
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.account.CapabilityControl;
import com.google.gerrit.server.account.GroupMembership; import com.google.gerrit.server.account.GroupMembership;
import com.google.gerrit.server.account.ListGroupMembership; import com.google.gerrit.server.account.ListGroupMembership;
import java.util.Collections;
import java.util.Set; import java.util.Set;
public final class SingleGroupUser extends CurrentUser { public final class SingleGroupUser extends CurrentUser {
private final GroupMembership groups; private final GroupMembership groups;
public SingleGroupUser( public SingleGroupUser(AccountGroup.UUID groupId) {
CapabilityControl.Factory capabilityControlFactory, AccountGroup.UUID groupId) { this(ImmutableSet.of(groupId));
this(capabilityControlFactory, Collections.singleton(groupId));
} }
public SingleGroupUser( public SingleGroupUser(Set<AccountGroup.UUID> groups) {
CapabilityControl.Factory capabilityControlFactory, Set<AccountGroup.UUID> groups) {
super(capabilityControlFactory);
this.groups = new ListGroupMembership(groups); this.groups = new ListGroupMembership(groups);
} }

View File

@ -19,6 +19,7 @@ import static com.google.gerrit.server.query.group.GroupQueryBuilder.FIELD_LIMIT
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.account.CapabilityControl;
import com.google.gerrit.server.account.GroupControl; import com.google.gerrit.server.account.GroupControl;
import com.google.gerrit.server.index.IndexConfig; import com.google.gerrit.server.index.IndexConfig;
import com.google.gerrit.server.index.IndexPredicate; import com.google.gerrit.server.index.IndexPredicate;
@ -44,6 +45,7 @@ public class GroupQueryProcessor extends QueryProcessor<AccountGroup> {
@Inject @Inject
protected GroupQueryProcessor( protected GroupQueryProcessor(
Provider<CurrentUser> userProvider, Provider<CurrentUser> userProvider,
CapabilityControl.Factory capabilityFactory,
Metrics metrics, Metrics metrics,
IndexConfig indexConfig, IndexConfig indexConfig,
GroupIndexCollection indexes, GroupIndexCollection indexes,
@ -51,6 +53,7 @@ public class GroupQueryProcessor extends QueryProcessor<AccountGroup> {
GroupControl.GenericFactory groupControlFactory) { GroupControl.GenericFactory groupControlFactory) {
super( super(
userProvider, userProvider,
capabilityFactory,
metrics, metrics,
GroupSchemaDefinitions.INSTANCE, GroupSchemaDefinitions.INSTANCE,
indexConfig, indexConfig,

View File

@ -20,7 +20,6 @@ import static com.google.inject.Scopes.SINGLETON;
import com.google.gerrit.common.TimeUtil; import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.account.AccountCache; import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.account.FakeRealm; import com.google.gerrit.server.account.FakeRealm;
import com.google.gerrit.server.account.GroupBackend; import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.account.Realm; import com.google.gerrit.server.account.Realm;
@ -36,7 +35,6 @@ import com.google.inject.AbstractModule;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.util.Providers;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -93,8 +91,6 @@ public class IdentifiedUserTest {
.toInstance("http://localhost:8080/"); .toInstance("http://localhost:8080/");
bind(AccountCache.class).toInstance(accountCache); bind(AccountCache.class).toInstance(accountCache);
bind(GroupBackend.class).to(SystemGroupBackend.class).in(SINGLETON); bind(GroupBackend.class).to(SystemGroupBackend.class).in(SINGLETON);
bind(CapabilityControl.Factory.class)
.toProvider(Providers.<CapabilityControl.Factory>of(null));
bind(Realm.class).toInstance(mockRealm); bind(Realm.class).toInstance(mockRealm);
} }
}; };

View File

@ -27,8 +27,8 @@ public class FakeQueryBuilder extends ChangeQueryBuilder {
new FakeQueryBuilder.Definition<>(FakeQueryBuilder.class), new FakeQueryBuilder.Definition<>(FakeQueryBuilder.class),
new ChangeQueryBuilder.Arguments( new ChangeQueryBuilder.Arguments(
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, indexes, null, null, null, null, null, null, null, null, null, null, null, null, indexes, null, null, null, null, null, null,
null, null, null, null)); null, null, null));
} }
@Operator @Operator

View File

@ -35,7 +35,6 @@ import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.InternalUser; import com.google.gerrit.server.InternalUser;
import com.google.gerrit.server.account.AccountCache; import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.account.FakeRealm; import com.google.gerrit.server.account.FakeRealm;
import com.google.gerrit.server.account.GroupBackend; import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.account.Realm; import com.google.gerrit.server.account.Realm;
@ -158,8 +157,6 @@ public abstract class AbstractChangeNotesTest extends GerritBaseTests {
bind(NotesMigration.class).toInstance(MIGRATION); bind(NotesMigration.class).toInstance(MIGRATION);
bind(GitRepositoryManager.class).toInstance(repoManager); bind(GitRepositoryManager.class).toInstance(repoManager);
bind(ProjectCache.class).toProvider(Providers.<ProjectCache>of(null)); bind(ProjectCache.class).toProvider(Providers.<ProjectCache>of(null));
bind(CapabilityControl.Factory.class)
.toProvider(Providers.<CapabilityControl.Factory>of(null));
bind(Config.class).annotatedWith(GerritServerConfig.class).toInstance(testConfig); bind(Config.class).annotatedWith(GerritServerConfig.class).toInstance(testConfig);
bind(String.class) bind(String.class)
.annotatedWith(AnonymousCowardName.class) .annotatedWith(AnonymousCowardName.class)
@ -199,7 +196,7 @@ public abstract class AbstractChangeNotesTest extends GerritBaseTests {
changeOwner = userFactory.create(co.getId()); changeOwner = userFactory.create(co.getId());
otherUser = userFactory.create(ou.getId()); otherUser = userFactory.create(ou.getId());
otherUserId = otherUser.getAccountId(); otherUserId = otherUser.getAccountId();
internalUser = new InternalUser(null); internalUser = new InternalUser();
} }
private void setTimeForTesting() { private void setTimeForTesting() {

View File

@ -48,7 +48,6 @@ import com.google.gerrit.rules.PrologEnvironment;
import com.google.gerrit.rules.RulesCache; import com.google.gerrit.rules.RulesCache;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.CapabilityCollection; import com.google.gerrit.server.account.CapabilityCollection;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.account.GroupMembership; import com.google.gerrit.server.account.GroupMembership;
import com.google.gerrit.server.account.ListGroupMembership; import com.google.gerrit.server.account.ListGroupMembership;
import com.google.gerrit.server.config.AllProjectsName; import com.google.gerrit.server.config.AllProjectsName;
@ -58,6 +57,7 @@ import com.google.gerrit.server.config.AllUsersNameProvider;
import com.google.gerrit.server.config.SitePaths; import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.git.ProjectConfig; import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.index.SingleVersionModule.SingleVersionListener; import com.google.gerrit.server.index.SingleVersionModule.SingleVersionListener;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.ProjectPermission; import com.google.gerrit.server.permissions.ProjectPermission;
import com.google.gerrit.server.permissions.RefPermission; import com.google.gerrit.server.permissions.RefPermission;
import com.google.gerrit.server.query.change.InternalChangeQuery; import com.google.gerrit.server.query.change.InternalChangeQuery;
@ -206,8 +206,8 @@ public class RefControlTest {
private ChangeControl.Factory changeControlFactory; private ChangeControl.Factory changeControlFactory;
private ReviewDb db; private ReviewDb db;
@Inject private PermissionBackend permissionBackend;
@Inject private CapabilityCollection.Factory capabilityCollectionFactory; @Inject private CapabilityCollection.Factory capabilityCollectionFactory;
@Inject private CapabilityControl.Factory capabilityControlFactory;
@Inject private SchemaCreator schemaCreator; @Inject private SchemaCreator schemaCreator;
@Inject private SingleVersionListener singleVersionListener; @Inject private SingleVersionListener singleVersionListener;
@Inject private InMemoryDatabase schemaFactory; @Inject private InMemoryDatabase schemaFactory;
@ -910,6 +910,7 @@ public class RefControlTest {
null, // refFilter null, // refFilter
queryProvider, queryProvider,
canonicalWebUrl, canonicalWebUrl,
permissionBackend,
new MockUser(name, memberOf), new MockUser(name, memberOf),
newProjectState(local), newProjectState(local),
metrics); metrics);
@ -925,7 +926,6 @@ public class RefControlTest {
private final GroupMembership groups; private final GroupMembership groups;
MockUser(String name, AccountGroup.UUID[] groupId) { MockUser(String name, AccountGroup.UUID[] groupId) {
super(capabilityControlFactory);
username = name; username = name;
ArrayList<AccountGroup.UUID> groupIds = Lists.newArrayList(groupId); ArrayList<AccountGroup.UUID> groupIds = Lists.newArrayList(groupId);
groupIds.add(REGISTERED_USERS); groupIds.add(REGISTERED_USERS);

View File

@ -15,24 +15,27 @@
package com.google.gerrit.sshd; package com.google.gerrit.sshd;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.git.QueueProvider; import com.google.gerrit.server.git.QueueProvider;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ScheduledThreadPoolExecutor;
class CommandExecutorProvider implements Provider<ScheduledThreadPoolExecutor> { class CommandExecutorProvider implements Provider<ScheduledThreadPoolExecutor> {
private final CapabilityControl.Factory capabilityFactory;
private final QueueProvider queues; private final QueueProvider queues;
private final CurrentUser user; private final CurrentUser user;
@Inject @Inject
CommandExecutorProvider(QueueProvider queues, CurrentUser user) { CommandExecutorProvider(
CapabilityControl.Factory capabilityFactory, QueueProvider queues, CurrentUser user) {
this.capabilityFactory = capabilityFactory;
this.queues = queues; this.queues = queues;
this.user = user; this.user = user;
} }
@Override @Override
public ScheduledThreadPoolExecutor get() { public ScheduledThreadPoolExecutor get() {
return queues.getQueue(user.getCapabilities().getQueueType()); return queues.getQueue(capabilityFactory.create(user).getQueueType());
} }
} }

@ -1 +1 @@
Subproject commit 2a4d0bfe10c63c79ca0d47be21756377703e46c0 Subproject commit 1085b453039b0fe230c3584e0024a7965cc1e323