Move CapabilityControl onto CurrentUser

This makes it easier to ask what is the current user permitted to
perform, given the system's access controls. The limits are needed
not just for query size, but also other fine-grained permissions.

Change-Id: Ic767eb9184acce34e435629a00b037245e6ea607
This commit is contained in:
Shawn O. Pearce
2011-06-16 13:19:18 -07:00
parent dd273e0137
commit eda6e36af7
21 changed files with 128 additions and 115 deletions

View File

@@ -31,6 +31,7 @@ import com.google.gerrit.server.cache.EvictionPolicy;
import com.google.gerrit.server.config.AuthConfig; import com.google.gerrit.server.config.AuthConfig;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Module; import com.google.inject.Module;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
import com.google.inject.servlet.RequestScoped; import com.google.inject.servlet.RequestScoped;
@@ -64,7 +65,7 @@ public final class WebSession {
private final HttpServletResponse response; private final HttpServletResponse response;
private final WebSessionManager manager; private final WebSessionManager manager;
private final AuthConfig authConfig; private final AuthConfig authConfig;
private final AnonymousUser anonymous; private final Provider<AnonymousUser> anonymousProvider;
private final IdentifiedUser.RequestFactory identified; private final IdentifiedUser.RequestFactory identified;
private AccessPath accessPath = AccessPath.WEB_UI; private AccessPath accessPath = AccessPath.WEB_UI;
private Cookie outCookie; private Cookie outCookie;
@@ -75,13 +76,14 @@ public final class WebSession {
@Inject @Inject
WebSession(final HttpServletRequest request, WebSession(final HttpServletRequest request,
final HttpServletResponse response, final WebSessionManager manager, final HttpServletResponse response, final WebSessionManager manager,
final AuthConfig authConfig, final AnonymousUser anonymous, final AuthConfig authConfig,
final Provider<AnonymousUser> anonymousProvider,
final IdentifiedUser.RequestFactory identified) { final IdentifiedUser.RequestFactory identified) {
this.request = request; this.request = request;
this.response = response; this.response = response;
this.manager = manager; this.manager = manager;
this.authConfig = authConfig; this.authConfig = authConfig;
this.anonymous = anonymous; this.anonymousProvider = anonymousProvider;
this.identified = identified; this.identified = identified;
final String cookie = readCookie(); final String cookie = readCookie();
@@ -138,7 +140,7 @@ public final class WebSession {
if (isSignedIn()) { if (isSignedIn()) {
return identified.create(accessPath, val.getAccountId()); return identified.create(accessPath, val.getAccountId());
} }
return anonymous; return anonymousProvider.get();
} }
public void login(final AuthResult res, final boolean rememberMe) { public void login(final AuthResult res, final boolean rememberMe) {

View File

@@ -33,12 +33,14 @@ import com.google.gerrit.common.data.GerritConfig;
import com.google.gerrit.httpd.GitWebConfig; import com.google.gerrit.httpd.GitWebConfig;
import com.google.gerrit.launcher.GerritLauncher; import com.google.gerrit.launcher.GerritLauncher;
import com.google.gerrit.reviewdb.Project; import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.config.SitePaths; import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.git.LocalDiskRepositoryManager; import com.google.gerrit.server.git.LocalDiskRepositoryManager;
import com.google.gerrit.server.project.NoSuchProjectException; import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl; import com.google.gerrit.server.project.ProjectControl;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.errors.RepositoryNotFoundException;
@@ -83,15 +85,19 @@ class GitWebServlet extends HttpServlet {
private final URI gitwebUrl; private final URI gitwebUrl;
private final LocalDiskRepositoryManager repoManager; private final LocalDiskRepositoryManager repoManager;
private final ProjectControl.Factory projectControl; private final ProjectControl.Factory projectControl;
private final Provider<AnonymousUser> anonymousUserProvider;
private final EnvList _env; private final EnvList _env;
@Inject @Inject
GitWebServlet(final LocalDiskRepositoryManager repoManager, GitWebServlet(final LocalDiskRepositoryManager repoManager,
final ProjectControl.Factory projectControl, final SitePaths site, final ProjectControl.Factory projectControl,
final Provider<AnonymousUser> anonymousUserProvider,
final SitePaths site,
final GerritConfig gerritConfig, final GitWebConfig gitWebConfig) final GerritConfig gerritConfig, final GitWebConfig gitWebConfig)
throws IOException { throws IOException {
this.repoManager = repoManager; this.repoManager = repoManager;
this.projectControl = projectControl; this.projectControl = projectControl;
this.anonymousUserProvider = anonymousUserProvider;
this.gitwebCgi = gitWebConfig.getGitwebCGI(); this.gitwebCgi = gitWebConfig.getGitwebCGI();
this.deniedActions = new HashSet<String>(); this.deniedActions = new HashSet<String>();
@@ -507,7 +513,7 @@ class GitWebServlet extends HttpServlet {
env.set("GERRIT_CONTEXT_PATH", req.getContextPath() + "/"); env.set("GERRIT_CONTEXT_PATH", req.getContextPath() + "/");
env.set("GERRIT_PROJECT_NAME", project.getProject().getName()); env.set("GERRIT_PROJECT_NAME", project.getProject().getName());
if (project.forAnonymousUser().isVisible()) { if (project.forUser(anonymousUserProvider.get()).isVisible()) {
env.set("GERRIT_ANONYMOUS_READ", "1"); env.set("GERRIT_ANONYMOUS_READ", "1");
} }

View File

@@ -33,7 +33,6 @@ import com.google.gerrit.server.account.AccountInfoCacheFactory;
import com.google.gerrit.server.account.CapabilityControl; import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.project.ChangeControl; import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.query.Predicate; import com.google.gerrit.server.query.Predicate;
import com.google.gerrit.server.query.QueryParseException; import com.google.gerrit.server.query.QueryParseException;
import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeData;
@@ -85,7 +84,6 @@ public class ChangeListServiceImpl extends BaseServiceImplementation implements
private final Provider<CurrentUser> currentUser; private final Provider<CurrentUser> currentUser;
private final ChangeControl.Factory changeControlFactory; private final ChangeControl.Factory changeControlFactory;
private final AccountInfoCacheFactory.Factory accountInfoCacheFactory; private final AccountInfoCacheFactory.Factory accountInfoCacheFactory;
private final CapabilityControl.Factory capabilityControlFactory;
private final ChangeQueryBuilder.Factory queryBuilder; private final ChangeQueryBuilder.Factory queryBuilder;
private final Provider<ChangeQueryRewriter> queryRewriter; private final Provider<ChangeQueryRewriter> queryRewriter;
@@ -95,14 +93,12 @@ public class ChangeListServiceImpl extends BaseServiceImplementation implements
final Provider<CurrentUser> currentUser, final Provider<CurrentUser> currentUser,
final ChangeControl.Factory changeControlFactory, final ChangeControl.Factory changeControlFactory,
final AccountInfoCacheFactory.Factory accountInfoCacheFactory, final AccountInfoCacheFactory.Factory accountInfoCacheFactory,
final CapabilityControl.Factory capabilityControlFactory,
final ChangeQueryBuilder.Factory queryBuilder, final ChangeQueryBuilder.Factory queryBuilder,
final Provider<ChangeQueryRewriter> queryRewriter) { final Provider<ChangeQueryRewriter> queryRewriter) {
super(schema, currentUser); super(schema, currentUser);
this.currentUser = currentUser; this.currentUser = currentUser;
this.changeControlFactory = changeControlFactory; this.changeControlFactory = changeControlFactory;
this.accountInfoCacheFactory = accountInfoCacheFactory; this.accountInfoCacheFactory = accountInfoCacheFactory;
this.capabilityControlFactory = capabilityControlFactory;
this.queryBuilder = queryBuilder; this.queryBuilder = queryBuilder;
this.queryRewriter = queryRewriter; this.queryRewriter = queryRewriter;
} }
@@ -299,14 +295,9 @@ public class ChangeListServiceImpl extends BaseServiceImplementation implements
} }
private int safePageSize(final int pageSize) throws InvalidQueryException { private int safePageSize(final int pageSize) throws InvalidQueryException {
int maxLimit; int maxLimit = currentUser.get().getCapabilities()
try {
maxLimit = capabilityControlFactory.controlFor()
.getRange(GlobalCapability.QUERY_LIMIT) .getRange(GlobalCapability.QUERY_LIMIT)
.getMax(); .getMax();
} catch (NoSuchProjectException e) {
throw new InvalidQueryException("Search Disabled");
}
if (maxLimit == 0) { if (maxLimit == 0) {
throw new InvalidQueryException("Search Disabled"); throw new InvalidQueryException("Search Disabled");
} }

View File

@@ -30,6 +30,7 @@ import com.google.gerrit.reviewdb.PatchSetAncestor;
import com.google.gerrit.reviewdb.PatchSetApproval; import com.google.gerrit.reviewdb.PatchSetApproval;
import com.google.gerrit.reviewdb.RevId; import com.google.gerrit.reviewdb.RevId;
import com.google.gerrit.reviewdb.ReviewDb; import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountInfoCacheFactory; import com.google.gerrit.server.account.AccountInfoCacheFactory;
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException; import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
@@ -62,6 +63,7 @@ public class ChangeDetailFactory extends Handler<ChangeDetail> {
private final FunctionState.Factory functionState; private final FunctionState.Factory functionState;
private final PatchSetDetailFactory.Factory patchSetDetail; private final PatchSetDetailFactory.Factory patchSetDetail;
private final AccountInfoCacheFactory aic; private final AccountInfoCacheFactory aic;
private final AnonymousUser anonymousUser;
private final ReviewDb db; private final ReviewDb db;
private final Change.Id changeId; private final Change.Id changeId;
@@ -75,12 +77,14 @@ public class ChangeDetailFactory extends Handler<ChangeDetail> {
final PatchSetDetailFactory.Factory patchSetDetail, final ReviewDb db, final PatchSetDetailFactory.Factory patchSetDetail, final ReviewDb db,
final ChangeControl.Factory changeControlFactory, final ChangeControl.Factory changeControlFactory,
final AccountInfoCacheFactory.Factory accountInfoCacheFactory, final AccountInfoCacheFactory.Factory accountInfoCacheFactory,
final AnonymousUser anonymousUser,
@Assisted final Change.Id id) { @Assisted final Change.Id id) {
this.approvalTypes = approvalTypes; this.approvalTypes = approvalTypes;
this.functionState = functionState; this.functionState = functionState;
this.patchSetDetail = patchSetDetail; this.patchSetDetail = patchSetDetail;
this.db = db; this.db = db;
this.changeControlFactory = changeControlFactory; this.changeControlFactory = changeControlFactory;
this.anonymousUser = anonymousUser;
this.aic = accountInfoCacheFactory.create(); this.aic = accountInfoCacheFactory.create();
this.changeId = id; this.changeId = id;
@@ -101,7 +105,7 @@ public class ChangeDetailFactory extends Handler<ChangeDetail> {
detail = new ChangeDetail(); detail = new ChangeDetail();
detail.setChange(change); detail.setChange(change);
detail.setAllowsAnonymous(control.forAnonymousUser().isVisible()); detail.setAllowsAnonymous(control.forUser(anonymousUser).isVisible());
detail.setCanAbandon(change.getStatus().isOpen() && control.canAbandon()); detail.setCanAbandon(change.getStatus().isOpen() && control.canAbandon());
detail.setCanRestore(change.getStatus() == Change.Status.ABANDONED && control.canRestore()); detail.setCanRestore(change.getStatus() == Change.Status.ABANDONED && control.canRestore());

View File

@@ -17,20 +17,19 @@ package com.google.gerrit.server;
import com.google.gerrit.reviewdb.AccountGroup; import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.reviewdb.AccountProjectWatch; import com.google.gerrit.reviewdb.AccountProjectWatch;
import com.google.gerrit.reviewdb.Change; import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.config.AuthConfig; import com.google.gerrit.server.config.AuthConfig;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
/** An anonymous user who has not yet authenticated. */ /** An anonymous user who has not yet authenticated. */
@Singleton
public class AnonymousUser extends CurrentUser { public class AnonymousUser extends CurrentUser {
@Inject @Inject
AnonymousUser(final AuthConfig auth) { AnonymousUser(CapabilityControl.Factory capabilityControlFactory, AuthConfig auth) {
super(AccessPath.UNKNOWN, auth); super(capabilityControlFactory, AccessPath.UNKNOWN, auth);
} }
@Override @Override

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.server;
import com.google.gerrit.reviewdb.AccountGroup; import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.reviewdb.AccountProjectWatch; import com.google.gerrit.reviewdb.AccountProjectWatch;
import com.google.gerrit.reviewdb.Change; import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.config.AuthConfig; import com.google.gerrit.server.config.AuthConfig;
import com.google.inject.servlet.RequestScoped; import com.google.inject.servlet.RequestScoped;
@@ -32,10 +33,17 @@ import java.util.Set;
* @see IdentifiedUser * @see IdentifiedUser
*/ */
public abstract class CurrentUser { public abstract class CurrentUser {
private final CapabilityControl.Factory capabilityControlFactory;
private final AccessPath accessPath; private final AccessPath accessPath;
protected final AuthConfig authConfig; protected final AuthConfig authConfig;
protected CurrentUser(final AccessPath accessPath, final AuthConfig authConfig) { private CapabilityControl capabilities;
protected CurrentUser(
CapabilityControl.Factory capabilityControlFactory,
AccessPath accessPath,
AuthConfig authConfig) {
this.capabilityControlFactory = capabilityControlFactory;
this.accessPath = accessPath; this.accessPath = accessPath;
this.authConfig = authConfig; this.authConfig = authConfig;
} }
@@ -69,7 +77,17 @@ public abstract class CurrentUser {
return getEffectiveGroups().contains(authConfig.getBatchUsersGroup()); return getEffectiveGroups().contains(authConfig.getBatchUsersGroup());
} }
public final boolean isAdministrator() { public boolean isAdministrator() {
return getEffectiveGroups().contains(authConfig.getAdministratorsGroup()); return getEffectiveGroups().contains(authConfig.getAdministratorsGroup());
} }
/** Capabilities available to this user account. */
public CapabilityControl getCapabilities() {
CapabilityControl ctl = capabilities;
if (ctl == null) {
ctl = capabilityControlFactory.create(this);
capabilities = ctl;
}
return ctl;
}
} }

View File

@@ -23,6 +23,7 @@ import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gerrit.reviewdb.StarredChange; import com.google.gerrit.reviewdb.StarredChange;
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.GroupIncludeCache; import com.google.gerrit.server.account.GroupIncludeCache;
import com.google.gerrit.server.account.Realm; import com.google.gerrit.server.account.Realm;
import com.google.gerrit.server.config.AuthConfig; import com.google.gerrit.server.config.AuthConfig;
@@ -63,6 +64,7 @@ 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 Provider<String> canonicalUrl; private final Provider<String> canonicalUrl;
private final Realm realm; private final Realm realm;
@@ -70,10 +72,13 @@ public class IdentifiedUser extends CurrentUser {
private final GroupIncludeCache groupIncludeCache; private final GroupIncludeCache groupIncludeCache;
@Inject @Inject
GenericFactory(final AuthConfig authConfig, GenericFactory(
CapabilityControl.Factory capabilityControlFactory,
final AuthConfig authConfig,
final @CanonicalWebUrl Provider<String> canonicalUrl, final @CanonicalWebUrl Provider<String> canonicalUrl,
final Realm realm, final AccountCache accountCache, final Realm realm, final AccountCache accountCache,
final GroupIncludeCache groupIncludeCache) { final GroupIncludeCache groupIncludeCache) {
this.capabilityControlFactory = capabilityControlFactory;
this.authConfig = authConfig; this.authConfig = authConfig;
this.canonicalUrl = canonicalUrl; this.canonicalUrl = canonicalUrl;
this.realm = realm; this.realm = realm;
@@ -86,14 +91,16 @@ public class IdentifiedUser extends CurrentUser {
} }
public IdentifiedUser create(Provider<ReviewDb> db, Account.Id id) { public IdentifiedUser create(Provider<ReviewDb> db, Account.Id id) {
return new IdentifiedUser(AccessPath.UNKNOWN, authConfig, canonicalUrl, return new IdentifiedUser(capabilityControlFactory, AccessPath.UNKNOWN,
realm, accountCache, groupIncludeCache, null, db, id); authConfig, canonicalUrl, realm, accountCache, groupIncludeCache,
null, db, id);
} }
public IdentifiedUser create(AccessPath accessPath, public IdentifiedUser create(AccessPath accessPath,
Provider<SocketAddress> remotePeerProvider, Account.Id id) { Provider<SocketAddress> remotePeerProvider, Account.Id id) {
return new IdentifiedUser(accessPath, authConfig, canonicalUrl, realm, return new IdentifiedUser(capabilityControlFactory, accessPath,
accountCache, groupIncludeCache, remotePeerProvider, null, id); authConfig, canonicalUrl, realm, accountCache, groupIncludeCache,
remotePeerProvider, null, id);
} }
} }
@@ -105,6 +112,7 @@ 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 Provider<String> canonicalUrl; private final Provider<String> canonicalUrl;
private final Realm realm; private final Realm realm;
@@ -115,13 +123,16 @@ public class IdentifiedUser extends CurrentUser {
private final Provider<ReviewDb> dbProvider; private final Provider<ReviewDb> dbProvider;
@Inject @Inject
RequestFactory(final AuthConfig authConfig, RequestFactory(
CapabilityControl.Factory capabilityControlFactory,
final AuthConfig authConfig,
final @CanonicalWebUrl Provider<String> canonicalUrl, final @CanonicalWebUrl Provider<String> canonicalUrl,
final Realm realm, final AccountCache accountCache, final Realm realm, final AccountCache accountCache,
final GroupIncludeCache groupIncludeCache, final GroupIncludeCache groupIncludeCache,
final @RemotePeer Provider<SocketAddress> remotePeerProvider, final @RemotePeer Provider<SocketAddress> remotePeerProvider,
final Provider<ReviewDb> dbProvider) { final Provider<ReviewDb> dbProvider) {
this.capabilityControlFactory = capabilityControlFactory;
this.authConfig = authConfig; this.authConfig = authConfig;
this.canonicalUrl = canonicalUrl; this.canonicalUrl = canonicalUrl;
this.realm = realm; this.realm = realm;
@@ -134,8 +145,9 @@ public class IdentifiedUser extends CurrentUser {
public IdentifiedUser create(final AccessPath accessPath, public IdentifiedUser create(final AccessPath accessPath,
final Account.Id id) { final Account.Id id) {
return new IdentifiedUser(accessPath, authConfig, canonicalUrl, realm, return new IdentifiedUser(capabilityControlFactory, accessPath,
accountCache, groupIncludeCache, remotePeerProvider, dbProvider, id); authConfig, canonicalUrl, realm, accountCache, groupIncludeCache,
remotePeerProvider, dbProvider, id);
} }
} }
@@ -183,13 +195,15 @@ public class IdentifiedUser extends CurrentUser {
private Set<Change.Id> starredChanges; private Set<Change.Id> starredChanges;
private Collection<AccountProjectWatch> notificationFilters; private Collection<AccountProjectWatch> notificationFilters;
private IdentifiedUser(final AccessPath accessPath, private IdentifiedUser(
CapabilityControl.Factory capabilityControlFactory,
final AccessPath accessPath,
final AuthConfig authConfig, final Provider<String> canonicalUrl, final AuthConfig authConfig, final Provider<String> canonicalUrl,
final Realm realm, final AccountCache accountCache, final Realm realm, final AccountCache accountCache,
final GroupIncludeCache groupIncludeCache, final GroupIncludeCache groupIncludeCache,
@Nullable final Provider<SocketAddress> remotePeerProvider, @Nullable final Provider<SocketAddress> remotePeerProvider,
@Nullable final Provider<ReviewDb> dbProvider, final Account.Id id) { @Nullable final Provider<ReviewDb> dbProvider, final Account.Id id) {
super(accessPath, authConfig); super(capabilityControlFactory, accessPath, authConfig);
this.canonicalUrl = canonicalUrl; this.canonicalUrl = canonicalUrl;
this.realm = realm; this.realm = realm;
this.accountCache = accountCache; this.accountCache = accountCache;

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.server;
import com.google.gerrit.reviewdb.AccountGroup; import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.reviewdb.AccountProjectWatch; import com.google.gerrit.reviewdb.AccountProjectWatch;
import com.google.gerrit.reviewdb.Change; import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.config.AuthConfig; import com.google.gerrit.server.config.AuthConfig;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
@@ -40,8 +41,9 @@ public class PeerDaemonUser extends CurrentUser {
private final SocketAddress peer; private final SocketAddress peer;
@Inject @Inject
protected PeerDaemonUser(AuthConfig authConfig, @Assisted SocketAddress peer) { protected PeerDaemonUser(CapabilityControl.Factory capabilityControlFactory,
super(AccessPath.SSH_COMMAND, authConfig); AuthConfig authConfig, @Assisted SocketAddress peer) {
super(capabilityControlFactory, AccessPath.SSH_COMMAND, authConfig);
final HashSet<AccountGroup.UUID> g = new HashSet<AccountGroup.UUID>(); final HashSet<AccountGroup.UUID> g = new HashSet<AccountGroup.UUID>();
g.add(authConfig.getAdministratorsGroup()); g.add(authConfig.getAdministratorsGroup());

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.server;
import com.google.gerrit.reviewdb.AccountGroup; import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.reviewdb.AccountProjectWatch; import com.google.gerrit.reviewdb.AccountProjectWatch;
import com.google.gerrit.reviewdb.Change; import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.config.AuthConfig; import com.google.gerrit.server.config.AuthConfig;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
@@ -38,9 +39,9 @@ public class ReplicationUser extends CurrentUser {
private final Set<AccountGroup.UUID> effectiveGroups; private final Set<AccountGroup.UUID> effectiveGroups;
@Inject @Inject
protected ReplicationUser(AuthConfig authConfig, protected ReplicationUser(CapabilityControl.Factory capabilityControlFactory,
@Assisted Set<AccountGroup.UUID> authGroups) { AuthConfig authConfig, @Assisted Set<AccountGroup.UUID> authGroups) {
super(AccessPath.REPLICATION, authConfig); super(capabilityControlFactory, AccessPath.REPLICATION, authConfig);
if (authGroups == EVERYTHING_VISIBLE) { if (authGroups == EVERYTHING_VISIBLE) {
effectiveGroups = EVERYTHING_VISIBLE; effectiveGroups = EVERYTHING_VISIBLE;

View File

@@ -28,7 +28,7 @@ import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState; import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.assistedinject.Assisted;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -39,34 +39,23 @@ import java.util.Set;
/** Access control management for server-wide capabilities. */ /** Access control management for server-wide capabilities. */
public class CapabilityControl { public class CapabilityControl {
public static class Factory { public static interface Factory {
private final Project.NameKey wildProject; public CapabilityControl create(CurrentUser user);
private final ProjectCache projectCache;
private final Provider<CurrentUser> user;
@Inject
Factory(@WildProjectName Project.NameKey wp, ProjectCache pc,
Provider<CurrentUser> cu) {
wildProject = wp;
projectCache = pc;
user = cu;
}
public CapabilityControl controlFor() throws NoSuchProjectException {
final ProjectState p = projectCache.get(wildProject);
if (p == null) {
throw new NoSuchProjectException(wildProject);
}
return new CapabilityControl(p, user.get());
}
} }
private final ProjectState state; private final ProjectState state;
private final CurrentUser user; private final CurrentUser user;
private Map<String, List<PermissionRule>> permissions; private Map<String, List<PermissionRule>> permissions;
private CapabilityControl(ProjectState p, CurrentUser currentUser) { @Inject
state = p; CapabilityControl(
@WildProjectName Project.NameKey wp,
ProjectCache projectCache,
@Assisted CurrentUser currentUser) throws NoSuchProjectException {
state = projectCache.get(wp);
if (state == null) {
throw new NoSuchProjectException(wp);
}
user = currentUser; user = currentUser;
} }

View File

@@ -30,6 +30,7 @@ import com.google.gerrit.server.ReplicationUser;
import com.google.gerrit.server.account.AccountByEmailCacheImpl; import com.google.gerrit.server.account.AccountByEmailCacheImpl;
import com.google.gerrit.server.account.AccountCacheImpl; import com.google.gerrit.server.account.AccountCacheImpl;
import com.google.gerrit.server.account.AccountInfoCacheFactory; import com.google.gerrit.server.account.AccountInfoCacheFactory;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.account.DefaultRealm; import com.google.gerrit.server.account.DefaultRealm;
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;
@@ -138,7 +139,6 @@ public class GerritGlobalModule extends FactoryModule {
SINGLETON); SINGLETON);
bind(EmailExpander.class).toProvider(EmailExpanderProvider.class).in( bind(EmailExpander.class).toProvider(EmailExpanderProvider.class).in(
SINGLETON); SINGLETON);
bind(AnonymousUser.class);
bind(IdGenerator.class); bind(IdGenerator.class);
bind(CachePool.class); bind(CachePool.class);
@@ -153,6 +153,7 @@ public class GerritGlobalModule extends FactoryModule {
install(new PrologModule()); install(new PrologModule());
factory(AccountInfoCacheFactory.Factory.class); factory(AccountInfoCacheFactory.Factory.class);
factory(CapabilityControl.Factory.class);
factory(GroupInfoCacheFactory.Factory.class); factory(GroupInfoCacheFactory.Factory.class);
factory(ProjectState.Factory.class); factory(ProjectState.Factory.class);
factory(RefControl.Factory.class); factory(RefControl.Factory.class);

View File

@@ -17,10 +17,10 @@ package com.google.gerrit.server.config;
import static com.google.inject.Scopes.SINGLETON; import static com.google.inject.Scopes.SINGLETON;
import com.google.gerrit.reviewdb.ReviewDb; import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.RequestCleanup; import com.google.gerrit.server.RequestCleanup;
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.GroupControl; import com.google.gerrit.server.account.GroupControl;
import com.google.gerrit.server.account.PerformCreateGroup; import com.google.gerrit.server.account.PerformCreateGroup;
import com.google.gerrit.server.git.CreateCodeReviewNotes; import com.google.gerrit.server.git.CreateCodeReviewNotes;
@@ -57,7 +57,7 @@ public class GerritRequestModule extends FactoryModule {
bind(AccountResolver.class); bind(AccountResolver.class);
bind(ChangeQueryRewriter.class); bind(ChangeQueryRewriter.class);
bind(CapabilityControl.Factory.class).in(SINGLETON); bind(AnonymousUser.class).in(RequestScoped.class);
bind(ChangeControl.Factory.class).in(SINGLETON); bind(ChangeControl.Factory.class).in(SINGLETON);
bind(GroupControl.Factory.class).in(SINGLETON); bind(GroupControl.Factory.class).in(SINGLETON);
bind(ProjectControl.Factory.class).in(SINGLETON); bind(ProjectControl.Factory.class).in(SINGLETON);

View File

@@ -127,10 +127,6 @@ public class ChangeControl {
this.change = c; this.change = c;
} }
public ChangeControl forAnonymousUser() {
return new ChangeControl(getRefControl().forAnonymousUser(), getChange());
}
public ChangeControl forUser(final CurrentUser who) { public ChangeControl forUser(final CurrentUser who) {
return new ChangeControl(getRefControl().forUser(who), getChange()); return new ChangeControl(getRefControl().forUser(who), getChange());
} }

View File

@@ -126,10 +126,6 @@ public class ProjectControl {
state = ps; state = ps;
} }
public ProjectControl forAnonymousUser() {
return state.controlForAnonymousUser();
}
public ProjectControl forUser(final CurrentUser who) { public ProjectControl forUser(final CurrentUser who) {
return state.controlFor(who); return state.controlFor(who);
} }

View File

@@ -21,7 +21,6 @@ import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.reviewdb.AccountGroup; import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.reviewdb.Project; import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.rules.PrologEnvironment; import com.google.gerrit.rules.PrologEnvironment;
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.config.WildProjectName; import com.google.gerrit.server.config.WildProjectName;
import com.google.gerrit.server.git.GitRepositoryManager; import com.google.gerrit.server.git.GitRepositoryManager;
@@ -53,7 +52,6 @@ public class ProjectState {
ProjectState create(ProjectConfig config); ProjectState create(ProjectConfig config);
} }
private final AnonymousUser anonymousUser;
private final Project.NameKey wildProject; private final Project.NameKey wildProject;
private final ProjectCache projectCache; private final ProjectCache projectCache;
private final ProjectControl.AssistedFactory projectControlFactory; private final ProjectControl.AssistedFactory projectControlFactory;
@@ -67,14 +65,13 @@ public class ProjectState {
private transient long lastCheckTime; private transient long lastCheckTime;
@Inject @Inject
protected ProjectState(final AnonymousUser anonymousUser, protected ProjectState(
final ProjectCache projectCache, final ProjectCache projectCache,
@WildProjectName final Project.NameKey wildProject, @WildProjectName final Project.NameKey wildProject,
final ProjectControl.AssistedFactory projectControlFactory, final ProjectControl.AssistedFactory projectControlFactory,
final PrologEnvironment.Factory envFactory, final PrologEnvironment.Factory envFactory,
final GitRepositoryManager gitMgr, final GitRepositoryManager gitMgr,
@Assisted final ProjectConfig config) { @Assisted final ProjectConfig config) {
this.anonymousUser = anonymousUser;
this.projectCache = projectCache; this.projectCache = projectCache;
this.wildProject = wildProject; this.wildProject = wildProject;
this.projectControlFactory = projectControlFactory; this.projectControlFactory = projectControlFactory;
@@ -247,10 +244,6 @@ public class ProjectState {
return Collections.unmodifiableSet(owners); return Collections.unmodifiableSet(owners);
} }
public ProjectControl controlForAnonymousUser() {
return controlFor(anonymousUser);
}
public ProjectControl controlFor(final CurrentUser user) { public ProjectControl controlFor(final CurrentUser user) {
return projectControlFactory.create(user, this); return projectControlFactory.create(user, this);
} }

View File

@@ -90,10 +90,6 @@ public class RefControl {
return getProjectControl().getCurrentUser(); return getProjectControl().getCurrentUser();
} }
public RefControl forAnonymousUser() {
return getProjectControl().forAnonymousUser().controlForRef(getRefName());
}
public RefControl forUser(final CurrentUser who) { public RefControl forUser(final CurrentUser who) {
return getProjectControl().forUser(who).controlForRef(getRefName()); return getProjectControl().forUser(who).controlForRef(getRefName());
} }

View File

@@ -25,7 +25,6 @@ import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountResolver; import com.google.gerrit.server.account.AccountResolver;
import com.google.gerrit.server.account.GroupCache; import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.config.AuthConfig;
import com.google.gerrit.server.config.WildProjectName; import com.google.gerrit.server.config.WildProjectName;
import com.google.gerrit.server.git.GitRepositoryManager; import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.patch.PatchListCache; import com.google.gerrit.server.patch.PatchListCache;
@@ -103,7 +102,6 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
final ChangeControl.GenericFactory changeControlGenericFactory; final ChangeControl.GenericFactory changeControlGenericFactory;
final AccountResolver accountResolver; final AccountResolver accountResolver;
final GroupCache groupCache; final GroupCache groupCache;
final AuthConfig authConfig;
final ApprovalTypes approvalTypes; final ApprovalTypes approvalTypes;
final Project.NameKey wildProjectName; final Project.NameKey wildProjectName;
final PatchListCache patchListCache; final PatchListCache patchListCache;
@@ -117,7 +115,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
ChangeControl.Factory changeControlFactory, ChangeControl.Factory changeControlFactory,
ChangeControl.GenericFactory changeControlGenericFactory, ChangeControl.GenericFactory changeControlGenericFactory,
AccountResolver accountResolver, GroupCache groupCache, AccountResolver accountResolver, GroupCache groupCache,
AuthConfig authConfig, ApprovalTypes approvalTypes, ApprovalTypes approvalTypes,
@WildProjectName Project.NameKey wildProjectName, @WildProjectName Project.NameKey wildProjectName,
PatchListCache patchListCache, PatchListCache patchListCache,
GitRepositoryManager repoManager, GitRepositoryManager repoManager,
@@ -129,7 +127,6 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
this.changeControlGenericFactory = changeControlGenericFactory; this.changeControlGenericFactory = changeControlGenericFactory;
this.accountResolver = accountResolver; this.accountResolver = accountResolver;
this.groupCache = groupCache; this.groupCache = groupCache;
this.authConfig = authConfig;
this.approvalTypes = approvalTypes; this.approvalTypes = approvalTypes;
this.wildProjectName = wildProjectName; this.wildProjectName = wildProjectName;
this.patchListCache = patchListCache; this.patchListCache = patchListCache;
@@ -344,7 +341,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
// //
AccountGroup g = args.groupCache.get(new AccountGroup.NameKey(who)); AccountGroup g = args.groupCache.get(new AccountGroup.NameKey(who));
if (g != null) { if (g != null) {
return visibleto(new SingleGroupUser(args.authConfig, g.getGroupUUID())); return visibleto(new SingleGroupUser(g.getGroupUUID()));
} }
Collection<AccountGroup> matches = Collection<AccountGroup> matches =
@@ -354,7 +351,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
for (AccountGroup group : matches) { for (AccountGroup group : matches) {
ids.add(group.getGroupUUID()); ids.add(group.getGroupUUID());
} }
return visibleto(new SingleGroupUser(args.authConfig, ids)); return visibleto(new SingleGroupUser(ids));
} }
throw error("No user or group matches \"" + who + "\"."); throw error("No user or group matches \"" + who + "\".");

View File

@@ -39,7 +39,7 @@ public class ChangeQueryRewriter extends QueryRewriter<ChangeData> {
new InvalidProvider<ReviewDb>(), // new InvalidProvider<ReviewDb>(), //
new InvalidProvider<ChangeQueryRewriter>(), // new InvalidProvider<ChangeQueryRewriter>(), //
null, null, null, null, null, null, null, // null, null, null, null, null, null, null, //
null, null, null, null), null)); null, null, null), null));
private final Provider<ReviewDb> dbProvider; private final Provider<ReviewDb> dbProvider;

View File

@@ -19,11 +19,9 @@ import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.reviewdb.PatchSet; import com.google.gerrit.reviewdb.PatchSet;
import com.google.gerrit.reviewdb.ReviewDb; import com.google.gerrit.reviewdb.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.events.ChangeAttribute; import com.google.gerrit.server.events.ChangeAttribute;
import com.google.gerrit.server.events.EventFactory; import com.google.gerrit.server.events.EventFactory;
import com.google.gerrit.server.events.QueryStats; import com.google.gerrit.server.events.QueryStats;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.query.Predicate; import com.google.gerrit.server.query.Predicate;
import com.google.gerrit.server.query.QueryParseException; import com.google.gerrit.server.query.QueryParseException;
import com.google.gson.Gson; import com.google.gson.Gson;
@@ -67,8 +65,8 @@ public class QueryProcessor {
private final ChangeQueryBuilder queryBuilder; private final ChangeQueryBuilder queryBuilder;
private final ChangeQueryRewriter queryRewriter; private final ChangeQueryRewriter queryRewriter;
private final Provider<ReviewDb> db; private final Provider<ReviewDb> db;
private final int maxLimit;
private int defaultLimit;
private OutputFormat outputFormat = OutputFormat.TEXT; private OutputFormat outputFormat = OutputFormat.TEXT;
private boolean includePatchSets; private boolean includePatchSets;
private boolean includeCurrentPatchSet; private boolean includeCurrentPatchSet;
@@ -80,14 +78,14 @@ public class QueryProcessor {
@Inject @Inject
QueryProcessor(EventFactory eventFactory, QueryProcessor(EventFactory eventFactory,
ChangeQueryBuilder.Factory queryBuilder, CurrentUser currentUser, ChangeQueryBuilder.Factory queryBuilder, CurrentUser currentUser,
ChangeQueryRewriter queryRewriter, Provider<ReviewDb> db, ChangeQueryRewriter queryRewriter, Provider<ReviewDb> db) {
CapabilityControl.Factory ctl) throws NoSuchProjectException {
this.eventFactory = eventFactory; this.eventFactory = eventFactory;
this.queryBuilder = queryBuilder.create(currentUser); this.queryBuilder = queryBuilder.create(currentUser);
this.queryRewriter = queryRewriter; this.queryRewriter = queryRewriter;
this.db = db; this.db = db;
this.maxLimit = currentUser.getCapabilities()
defaultLimit = ctl.controlFor().getRange(GlobalCapability.QUERY_LIMIT).getMax(); .getRange(GlobalCapability.QUERY_LIMIT)
.getMax();
} }
public void setIncludePatchSets(boolean on) { public void setIncludePatchSets(boolean on) {
@@ -112,7 +110,7 @@ public class QueryProcessor {
new BufferedWriter( // new BufferedWriter( //
new OutputStreamWriter(outputStream, "UTF-8"))); new OutputStreamWriter(outputStream, "UTF-8")));
try { try {
if (defaultLimit == 0) { if (maxLimit == 0) {
ErrorMessage m = new ErrorMessage(); ErrorMessage m = new ErrorMessage();
m.message = "query disabled"; m.message = "query disabled";
show(m); show(m);
@@ -211,7 +209,7 @@ public class QueryProcessor {
} }
private int limit(Predicate<ChangeData> s) { private int limit(Predicate<ChangeData> s) {
return queryBuilder.hasLimit(s) ? queryBuilder.getLimit(s) : defaultLimit; return queryBuilder.hasLimit(s) ? queryBuilder.getLimit(s) : maxLimit;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -220,7 +218,7 @@ public class QueryProcessor {
Predicate<ChangeData> q = queryBuilder.parse(queryString); Predicate<ChangeData> q = queryBuilder.parse(queryString);
if (!queryBuilder.hasLimit(q)) { if (!queryBuilder.hasLimit(q)) {
q = Predicate.and(q, queryBuilder.limit(defaultLimit)); q = Predicate.and(q, queryBuilder.limit(maxLimit));
} }
if (!queryBuilder.hasSortKey(q)) { if (!queryBuilder.hasSortKey(q)) {
q = Predicate.and(q, queryBuilder.sortkey_before("z")); q = Predicate.and(q, queryBuilder.sortkey_before("z"));

View File

@@ -19,7 +19,6 @@ import com.google.gerrit.reviewdb.AccountProjectWatch;
import com.google.gerrit.reviewdb.Change; import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.server.AccessPath; import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.config.AuthConfig;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@@ -28,12 +27,12 @@ import java.util.Set;
final class SingleGroupUser extends CurrentUser { final class SingleGroupUser extends CurrentUser {
private final Set<AccountGroup.UUID> groups; private final Set<AccountGroup.UUID> groups;
SingleGroupUser(AuthConfig authConfig, AccountGroup.UUID groupId) { SingleGroupUser(AccountGroup.UUID groupId) {
this(authConfig, Collections.singleton(groupId)); this(Collections.singleton(groupId));
} }
SingleGroupUser(AuthConfig authConfig, Set<AccountGroup.UUID> groups) { SingleGroupUser(Set<AccountGroup.UUID> groups) {
super(AccessPath.UNKNOWN, authConfig); super(null, AccessPath.UNKNOWN, null);
this.groups = groups; this.groups = groups;
} }
@@ -51,4 +50,14 @@ final class SingleGroupUser extends CurrentUser {
public Collection<AccountProjectWatch> getNotificationFilters() { public Collection<AccountProjectWatch> getNotificationFilters() {
return Collections.emptySet(); return Collections.emptySet();
} }
@Override
public boolean isBatchUser() {
return false;
}
@Override
public boolean isAdministrator() {
return false;
}
} }

View File

@@ -28,7 +28,6 @@ import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.SystemConfig; import com.google.gerrit.reviewdb.SystemConfig;
import com.google.gerrit.rules.PrologEnvironment; import com.google.gerrit.rules.PrologEnvironment;
import com.google.gerrit.server.AccessPath; import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.config.AuthConfig; import com.google.gerrit.server.config.AuthConfig;
import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.GerritServerConfig;
@@ -206,7 +205,6 @@ public class RefControlTest extends TestCase {
private final SystemConfig systemConfig; private final SystemConfig systemConfig;
private final AuthConfig authConfig; private final AuthConfig authConfig;
private final AnonymousUser anonymousUser;
public RefControlTest() { public RefControlTest() {
systemConfig = SystemConfig.create(); systemConfig = SystemConfig.create();
@@ -228,11 +226,9 @@ public class RefControlTest extends TestCase {
bind(SystemConfig.class).toInstance(systemConfig); bind(SystemConfig.class).toInstance(systemConfig);
bind(AuthConfig.class); bind(AuthConfig.class);
bind(AnonymousUser.class);
} }
}); });
authConfig = injector.getInstance(AuthConfig.class); authConfig = injector.getInstance(AuthConfig.class);
anonymousUser = injector.getInstance(AnonymousUser.class);
} }
@Override @Override
@@ -322,10 +318,10 @@ public class RefControlTest extends TestCase {
GitRepositoryManager mgr = null; GitRepositoryManager mgr = null;
Project.NameKey wildProject = new Project.NameKey("All-Projects"); Project.NameKey wildProject = new Project.NameKey("All-Projects");
ProjectControl.AssistedFactory projectControlFactory = null; ProjectControl.AssistedFactory projectControlFactory = null;
all.put(local.getProject().getNameKey(), new ProjectState(anonymousUser, all.put(local.getProject().getNameKey(), new ProjectState(
projectCache, wildProject, projectControlFactory, projectCache, wildProject, projectControlFactory,
envFactory, mgr, local)); envFactory, mgr, local));
all.put(parent.getProject().getNameKey(), new ProjectState(anonymousUser, all.put(parent.getProject().getNameKey(), new ProjectState(
projectCache, wildProject, projectControlFactory, projectCache, wildProject, projectControlFactory,
envFactory, mgr, parent)); envFactory, mgr, parent));
return all.get(local.getProject().getNameKey()); return all.get(local.getProject().getNameKey());
@@ -335,7 +331,7 @@ public class RefControlTest extends TestCase {
private final Set<AccountGroup.UUID> groups; private final Set<AccountGroup.UUID> groups;
MockUser(AccountGroup.UUID[] groupId) { MockUser(AccountGroup.UUID[] groupId) {
super(AccessPath.UNKNOWN, RefControlTest.this.authConfig); super(null, AccessPath.UNKNOWN, RefControlTest.this.authConfig);
groups = new HashSet<AccountGroup.UUID>(Arrays.asList(groupId)); groups = new HashSet<AccountGroup.UUID>(Arrays.asList(groupId));
groups.add(registered); groups.add(registered);
groups.add(anonymous); groups.add(anonymous);
@@ -355,5 +351,10 @@ public class RefControlTest extends TestCase {
public Collection<AccountProjectWatch> getNotificationFilters() { public Collection<AccountProjectWatch> getNotificationFilters() {
return Collections.emptySet(); return Collections.emptySet();
} }
@Override
public boolean isAdministrator() {
return false;
}
} }
} }