Convert administrateServer to PermissionBackend
Leave a poorly named backdoor in CapabilityControl for the existing
ProjectControl, RefControl, ChangeControl and GroupControl to test
administrator permission.
Update test expecting a failure when administateServer is not granted.
Change-Id: I0f523dbf26506ea53c38ffb02aeef74f3cf18ba6
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/AccessIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/AccessIT.java
index 839f166..8695498 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/AccessIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/AccessIT.java
@@ -218,7 +218,7 @@
setApiUser(user);
exception.expect(AuthException.class);
- exception.expectMessage("not administrator");
+ exception.expectMessage("administrate server not permitted");
gApi.projects().name(newProjectName).access(accessInput);
}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/HostPageServlet.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/HostPageServlet.java
index 84348d0..93673bc 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/HostPageServlet.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/HostPageServlet.java
@@ -37,6 +37,7 @@
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.notedb.NotesMigration;
+import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.gwtjsonrpc.server.JsonServlet;
import com.google.gwtjsonrpc.server.RPCServletUtils;
@@ -220,7 +221,7 @@
private DiffPreferencesInfo getDiffPreferences(IdentifiedUser user) {
try {
return getDiff.apply(new AccountResource(user));
- } catch (AuthException | ConfigInvalidException | IOException e) {
+ } catch (AuthException | ConfigInvalidException | IOException | PermissionBackendException e) {
log.warn("Cannot query account diff preferences", e);
}
return DiffPreferencesInfo.defaults();
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectAccessHandler.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectAccessHandler.java
index 0d90190..8d0947c 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectAccessHandler.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectAccessHandler.java
@@ -36,6 +36,7 @@
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
+import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.RefPattern;
@@ -95,7 +96,7 @@
public final T call()
throws NoSuchProjectException, IOException, ConfigInvalidException, InvalidNameException,
NoSuchGroupException, OrmException, UpdateParentFailedException,
- PermissionDeniedException {
+ PermissionDeniedException, PermissionBackendException {
final ProjectControl projectControl = projectControlFactory.controlFor(projectName);
Capable r = projectControl.canPushToAtLeastOneRef();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/AddSshKey.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/AddSshKey.java
index 8c10c73..1c5495f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/AddSshKey.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/AddSshKey.java
@@ -30,6 +30,9 @@
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AddSshKey.Input;
import com.google.gerrit.server.mail.send.AddKeySender;
+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.ssh.SshKeyCache;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
@@ -50,6 +53,7 @@
}
private final Provider<CurrentUser> self;
+ private final PermissionBackend permissionBackend;
private final VersionedAuthorizedKeys.Accessor authorizedKeys;
private final SshKeyCache sshKeyCache;
private final AddKeySender.Factory addKeyFactory;
@@ -57,10 +61,12 @@
@Inject
AddSshKey(
Provider<CurrentUser> self,
+ PermissionBackend permissionBackend,
VersionedAuthorizedKeys.Accessor authorizedKeys,
SshKeyCache sshKeyCache,
AddKeySender.Factory addKeyFactory) {
this.self = self;
+ this.permissionBackend = permissionBackend;
this.authorizedKeys = authorizedKeys;
this.sshKeyCache = sshKeyCache;
this.addKeyFactory = addKeyFactory;
@@ -68,9 +74,10 @@
@Override
public Response<SshKeyInfo> apply(AccountResource rsrc, Input input)
- throws AuthException, BadRequestException, OrmException, IOException, ConfigInvalidException {
- if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) {
- throw new AuthException("not allowed to add SSH keys");
+ throws AuthException, BadRequestException, OrmException, IOException, ConfigInvalidException,
+ PermissionBackendException {
+ if (self.get() != rsrc.getUser()) {
+ permissionBackend.user(self).check(GlobalPermission.ADMINISTRATE_SERVER);
}
return apply(rsrc.getUser(), input);
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityControl.java
index f38d019..2bba536 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityControl.java
@@ -30,7 +30,10 @@
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.PluginPermission;
+import com.google.gerrit.server.project.ChangeControl;
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.assistedinject.Assisted;
import java.util.ArrayList;
@@ -65,8 +68,23 @@
return user;
}
- /** @return true if the user can administer this server. */
- public boolean canAdministrateServer() {
+ /**
+ * <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 (user.getRealUser() != user) {
canAdministrateServer = false;
@@ -91,7 +109,7 @@
/** @return true if the user can view all accounts. */
public boolean canViewAllAccounts() {
- return canPerform(GlobalCapability.VIEW_ALL_ACCOUNTS) || canAdministrateServer();
+ return canPerform(GlobalCapability.VIEW_ALL_ACCOUNTS) || isAdmin_DoNotUse();
}
/** @return true if the user can access the database (with gsql). */
@@ -220,7 +238,7 @@
if (perm instanceof GlobalPermission) {
return can((GlobalPermission) perm);
} else if (perm instanceof PluginPermission) {
- return canPerform(perm.permissionName()) || canAdministrateServer();
+ return canPerform(perm.permissionName()) || isAdmin_DoNotUse();
}
throw new PermissionBackendException(perm + " unsupported");
}
@@ -228,7 +246,7 @@
private boolean can(GlobalPermission perm) throws PermissionBackendException {
switch (perm) {
case ADMINISTRATE_SERVER:
- return canAdministrateServer();
+ return isAdmin_DoNotUse();
case EMAIL_REVIEWERS:
return canEmailReviewers();
case VIEW_ALL_ACCOUNTS:
@@ -241,7 +259,7 @@
case VIEW_QUEUE:
return canPerform(perm.permissionName())
|| canPerform(GlobalCapability.MAINTAIN_SERVER)
- || canAdministrateServer();
+ || isAdmin_DoNotUse();
case CREATE_ACCOUNT:
case CREATE_GROUP:
@@ -251,7 +269,7 @@
case STREAM_EVENTS:
case VIEW_CONNECTIONS:
case VIEW_PLUGINS:
- return canPerform(perm.permissionName()) || canAdministrateServer();
+ return canPerform(perm.permissionName()) || isAdmin_DoNotUse();
case ACCESS_DATABASE:
case RUN_AS:
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteSshKey.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteSshKey.java
index 3d5d38e..f1ecd29 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteSshKey.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteSshKey.java
@@ -19,6 +19,9 @@
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.DeleteSshKey.Input;
+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.ssh.SshKeyCache;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
@@ -33,15 +36,18 @@
public static class Input {}
private final Provider<CurrentUser> self;
+ private final PermissionBackend permissionBackend;
private final VersionedAuthorizedKeys.Accessor authorizedKeys;
private final SshKeyCache sshKeyCache;
@Inject
DeleteSshKey(
Provider<CurrentUser> self,
+ PermissionBackend permissionBackend,
VersionedAuthorizedKeys.Accessor authorizedKeys,
SshKeyCache sshKeyCache) {
this.self = self;
+ this.permissionBackend = permissionBackend;
this.authorizedKeys = authorizedKeys;
this.sshKeyCache = sshKeyCache;
}
@@ -49,9 +55,9 @@
@Override
public Response<?> apply(AccountResource.SshKey rsrc, Input input)
throws AuthException, OrmException, RepositoryNotFoundException, IOException,
- ConfigInvalidException {
- if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) {
- throw new AuthException("not allowed to delete SSH keys");
+ ConfigInvalidException, PermissionBackendException {
+ if (self.get() != rsrc.getUser()) {
+ permissionBackend.user(self).check(GlobalPermission.ADMINISTRATE_SERVER);
}
authorizedKeys.deleteKey(rsrc.getUser().getAccountId(), rsrc.getSshKey().getKey().get());
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteWatchedProjects.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteWatchedProjects.java
index 97102a2..1666eb1 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteWatchedProjects.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteWatchedProjects.java
@@ -25,6 +25,9 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.WatchConfig.ProjectWatchKey;
+import com.google.gerrit.server.permissions.GlobalPermission;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -37,13 +40,18 @@
public class DeleteWatchedProjects
implements RestModifyView<AccountResource, List<ProjectWatchInfo>> {
private final Provider<IdentifiedUser> self;
+ private final PermissionBackend permissionBackend;
private final AccountCache accountCache;
private final WatchConfig.Accessor watchConfig;
@Inject
DeleteWatchedProjects(
- Provider<IdentifiedUser> self, AccountCache accountCache, WatchConfig.Accessor watchConfig) {
+ Provider<IdentifiedUser> self,
+ PermissionBackend permissionBackend,
+ AccountCache accountCache,
+ WatchConfig.Accessor watchConfig) {
this.self = self;
+ this.permissionBackend = permissionBackend;
this.accountCache = accountCache;
this.watchConfig = watchConfig;
}
@@ -51,9 +59,9 @@
@Override
public Response<?> apply(AccountResource rsrc, List<ProjectWatchInfo> input)
throws AuthException, UnprocessableEntityException, OrmException, IOException,
- ConfigInvalidException {
- if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) {
- throw new AuthException("It is not allowed to edit project watches of other users");
+ ConfigInvalidException, PermissionBackendException {
+ if (self.get() != rsrc.getUser()) {
+ permissionBackend.user(self).check(GlobalPermission.ADMINISTRATE_SERVER);
}
if (input == null) {
return Response.none();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/Emails.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/Emails.java
index b894f56..e31f481 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/Emails.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/Emails.java
@@ -17,12 +17,16 @@
import com.google.common.base.Strings;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.AcceptsCreate;
+import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ChildCollection;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.AccountResource.Email;
+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.Provider;
import com.google.inject.Singleton;
@@ -34,6 +38,7 @@
private final DynamicMap<RestView<AccountResource.Email>> views;
private final GetEmails list;
private final Provider<CurrentUser> self;
+ private final PermissionBackend permissionBackend;
private final CreateEmail.Factory createEmailFactory;
@Inject
@@ -41,10 +46,12 @@
DynamicMap<RestView<AccountResource.Email>> views,
GetEmails list,
Provider<CurrentUser> self,
+ PermissionBackend permissionBackend,
CreateEmail.Factory createEmailFactory) {
this.views = views;
this.list = list;
this.self = self;
+ this.permissionBackend = permissionBackend;
this.createEmailFactory = createEmailFactory;
}
@@ -55,21 +62,21 @@
@Override
public AccountResource.Email parse(AccountResource rsrc, IdString id)
- throws ResourceNotFoundException {
- if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) {
- throw new ResourceNotFoundException();
+ throws ResourceNotFoundException, PermissionBackendException, AuthException {
+ if (self.get() != rsrc.getUser()) {
+ permissionBackend.user(self).check(GlobalPermission.ADMINISTRATE_SERVER);
}
if ("preferred".equals(id.get())) {
String email = rsrc.getUser().getAccount().getPreferredEmail();
if (Strings.isNullOrEmpty(email)) {
- throw new ResourceNotFoundException();
+ throw new ResourceNotFoundException(id);
}
return new AccountResource.Email(rsrc.getUser(), email);
} else if (rsrc.getUser().hasEmailAddress(id.get())) {
return new AccountResource.Email(rsrc.getUser(), id.get());
} else {
- throw new ResourceNotFoundException();
+ throw new ResourceNotFoundException(id);
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/GetDiffPreferences.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/GetDiffPreferences.java
index 0edff4f..8215c6b 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/GetDiffPreferences.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/GetDiffPreferences.java
@@ -25,6 +25,9 @@
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.UserConfigSections;
+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.Provider;
import com.google.inject.Singleton;
@@ -42,23 +45,26 @@
private final Provider<CurrentUser> self;
private final Provider<AllUsersName> allUsersName;
+ private final PermissionBackend permissionBackend;
private final GitRepositoryManager gitMgr;
@Inject
GetDiffPreferences(
Provider<CurrentUser> self,
Provider<AllUsersName> allUsersName,
+ PermissionBackend permissionBackend,
GitRepositoryManager gitMgr) {
this.self = self;
this.allUsersName = allUsersName;
+ this.permissionBackend = permissionBackend;
this.gitMgr = gitMgr;
}
@Override
public DiffPreferencesInfo apply(AccountResource rsrc)
- throws AuthException, ConfigInvalidException, IOException {
- if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) {
- throw new AuthException("restricted to administrator");
+ throws AuthException, ConfigInvalidException, IOException, PermissionBackendException {
+ if (self.get() != rsrc.getUser()) {
+ permissionBackend.user(self).check(GlobalPermission.ADMINISTRATE_SERVER);
}
Account.Id id = rsrc.getUser().getAccountId();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/GetWatchedProjects.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/GetWatchedProjects.java
index e0aeee0..c2c0547 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/GetWatchedProjects.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/GetWatchedProjects.java
@@ -23,6 +23,9 @@
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.WatchConfig.NotifyType;
import com.google.gerrit.server.account.WatchConfig.ProjectWatchKey;
+import com.google.gerrit.server.permissions.GlobalPermission;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -38,22 +41,28 @@
@Singleton
public class GetWatchedProjects implements RestReadView<AccountResource> {
-
+ private final PermissionBackend permissionBackend;
private final Provider<IdentifiedUser> self;
private final WatchConfig.Accessor watchConfig;
@Inject
- public GetWatchedProjects(Provider<IdentifiedUser> self, WatchConfig.Accessor watchConfig) {
+ public GetWatchedProjects(
+ PermissionBackend permissionBackend,
+ Provider<IdentifiedUser> self,
+ WatchConfig.Accessor watchConfig) {
+ this.permissionBackend = permissionBackend;
this.self = self;
this.watchConfig = watchConfig;
}
@Override
public List<ProjectWatchInfo> apply(AccountResource rsrc)
- throws OrmException, AuthException, IOException, ConfigInvalidException {
- if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) {
- throw new AuthException("It is not allowed to list project watches of other users");
+ throws OrmException, AuthException, IOException, ConfigInvalidException,
+ PermissionBackendException {
+ if (self.get() != rsrc.getUser()) {
+ permissionBackend.user(self).check(GlobalPermission.ADMINISTRATE_SERVER);
}
+
Account.Id accountId = rsrc.getUser().getAccountId();
List<ProjectWatchInfo> projectWatchInfos = new ArrayList<>();
for (Map.Entry<ProjectWatchKey, Set<NotifyType>> e :
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/GroupControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/GroupControl.java
index ee788ec..e88e97e 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/GroupControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/GroupControl.java
@@ -127,7 +127,7 @@
return user.isInternalUser()
|| groupBackend.isVisibleToAll(group.getGroupUUID())
|| user.getEffectiveGroups().contains(group.getGroupUUID())
- || user.getCapabilities().canAdministrateServer()
+ || user.getCapabilities().isAdmin_DoNotUse()
|| isOwner();
}
@@ -139,7 +139,7 @@
AccountGroup.UUID ownerUUID = accountGroup.getOwnerGroupUUID();
isOwner =
getUser().getEffectiveGroups().contains(ownerUUID)
- || getUser().getCapabilities().canAdministrateServer();
+ || getUser().getCapabilities().isAdmin_DoNotUse();
}
return isOwner;
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/PostWatchedProjects.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/PostWatchedProjects.java
index 55ba912..d80c40b 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/PostWatchedProjects.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/PostWatchedProjects.java
@@ -15,7 +15,6 @@
package com.google.gerrit.server.account;
import com.google.gerrit.extensions.client.ProjectWatchInfo;
-import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestModifyView;
@@ -24,6 +23,9 @@
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.WatchConfig.NotifyType;
import com.google.gerrit.server.account.WatchConfig.ProjectWatchKey;
+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.ProjectsCollection;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
@@ -41,6 +43,7 @@
public class PostWatchedProjects
implements RestModifyView<AccountResource, List<ProjectWatchInfo>> {
private final Provider<IdentifiedUser> self;
+ private final PermissionBackend permissionBackend;
private final GetWatchedProjects getWatchedProjects;
private final ProjectsCollection projectsCollection;
private final AccountCache accountCache;
@@ -49,11 +52,13 @@
@Inject
public PostWatchedProjects(
Provider<IdentifiedUser> self,
+ PermissionBackend permissionBackend,
GetWatchedProjects getWatchedProjects,
ProjectsCollection projectsCollection,
AccountCache accountCache,
WatchConfig.Accessor watchConfig) {
this.self = self;
+ this.permissionBackend = permissionBackend;
this.getWatchedProjects = getWatchedProjects;
this.projectsCollection = projectsCollection;
this.accountCache = accountCache;
@@ -62,10 +67,12 @@
@Override
public List<ProjectWatchInfo> apply(AccountResource rsrc, List<ProjectWatchInfo> input)
- throws OrmException, RestApiException, IOException, ConfigInvalidException {
- if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) {
- throw new AuthException("not allowed to edit project watches");
+ throws OrmException, RestApiException, IOException, ConfigInvalidException,
+ PermissionBackendException {
+ if (self.get() != rsrc.getUser()) {
+ permissionBackend.user(self).check(GlobalPermission.ADMINISTRATE_SERVER);
}
+
Account.Id accountId = rsrc.getUser().getAccountId();
watchConfig.upsertProjectWatches(accountId, asMap(input));
accountCache.evict(accountId);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutHttpPassword.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutHttpPassword.java
index d8451bf..c06e5a3 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutHttpPassword.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutHttpPassword.java
@@ -29,6 +29,9 @@
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIds;
import com.google.gerrit.server.account.externalids.ExternalIdsUpdate;
+import com.google.gerrit.server.permissions.GlobalPermission;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -57,6 +60,7 @@
private final Provider<CurrentUser> self;
private final Provider<ReviewDb> dbProvider;
+ private final PermissionBackend permissionBackend;
private final AccountCache accountCache;
private final ExternalIds externalIds;
private final ExternalIdsUpdate.User externalIdsUpdate;
@@ -65,11 +69,13 @@
PutHttpPassword(
Provider<CurrentUser> self,
Provider<ReviewDb> dbProvider,
+ PermissionBackend permissionBackend,
AccountCache accountCache,
ExternalIds externalIds,
ExternalIdsUpdate.User externalIdsUpdate) {
this.self = self;
this.dbProvider = dbProvider;
+ this.permissionBackend = permissionBackend;
this.accountCache = accountCache;
this.externalIds = externalIds;
this.externalIdsUpdate = externalIdsUpdate;
@@ -78,7 +84,11 @@
@Override
public Response<String> apply(AccountResource rsrc, Input input)
throws AuthException, ResourceNotFoundException, ResourceConflictException, OrmException,
- IOException, ConfigInvalidException {
+ IOException, ConfigInvalidException, PermissionBackendException {
+ if (self.get() != rsrc.getUser()) {
+ permissionBackend.user(self).check(GlobalPermission.ADMINISTRATE_SERVER);
+ }
+
if (input == null) {
input = new Input();
}
@@ -86,22 +96,12 @@
String newPassword;
if (input.generate) {
- if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) {
- throw new AuthException("not allowed to generate HTTP password");
- }
newPassword = generate();
-
} else if (input.httpPassword == null) {
- if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) {
- throw new AuthException("not allowed to clear HTTP password");
- }
newPassword = null;
} else {
- if (!self.get().getCapabilities().canAdministrateServer()) {
- throw new AuthException(
- "not allowed to set HTTP password directly, "
- + "requires the Administrate Server permission");
- }
+ // Only administrators can explicitly set the password.
+ permissionBackend.user(self).check(GlobalPermission.ADMINISTRATE_SERVER);
newPassword = input.httpPassword;
}
return apply(rsrc.getUser(), newPassword);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutUsername.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutUsername.java
index e3a3c12..57bff65 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutUsername.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutUsername.java
@@ -25,6 +25,9 @@
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.PutUsername.Input;
+import com.google.gerrit.server.permissions.GlobalPermission;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -40,6 +43,7 @@
private final Provider<CurrentUser> self;
private final ChangeUserName.Factory changeUserNameFactory;
+ private final PermissionBackend permissionBackend;
private final Realm realm;
private final Provider<ReviewDb> db;
@@ -47,10 +51,12 @@
PutUsername(
Provider<CurrentUser> self,
ChangeUserName.Factory changeUserNameFactory,
+ PermissionBackend permissionBackend,
Realm realm,
Provider<ReviewDb> db) {
this.self = self;
this.changeUserNameFactory = changeUserNameFactory;
+ this.permissionBackend = permissionBackend;
this.realm = realm;
this.db = db;
}
@@ -58,9 +64,10 @@
@Override
public String apply(AccountResource rsrc, Input input)
throws AuthException, MethodNotAllowedException, UnprocessableEntityException,
- ResourceConflictException, OrmException, IOException, ConfigInvalidException {
- if (self.get() != rsrc.getUser() && !self.get().getCapabilities().canAdministrateServer()) {
- throw new AuthException("not allowed to set username");
+ ResourceConflictException, OrmException, IOException, ConfigInvalidException,
+ PermissionBackendException {
+ if (self.get() != rsrc.getUser()) {
+ permissionBackend.user(self).check(GlobalPermission.ADMINISTRATE_SERVER);
}
if (!realm.allowsEdit(AccountFieldName.USER_NAME)) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java
index dc5ea4c..6604496 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java
@@ -255,7 +255,7 @@
public DiffPreferencesInfo getDiffPreferences() throws RestApiException {
try {
return getDiffPreferences.apply(account);
- } catch (IOException | ConfigInvalidException e) {
+ } catch (IOException | ConfigInvalidException | PermissionBackendException e) {
throw new RestApiException("Cannot query diff preferences", e);
}
}
@@ -291,7 +291,7 @@
public List<ProjectWatchInfo> getWatchedProjects() throws RestApiException {
try {
return getWatchedProjects.apply(account);
- } catch (OrmException | IOException | ConfigInvalidException e) {
+ } catch (OrmException | IOException | ConfigInvalidException | PermissionBackendException e) {
throw new RestApiException("Cannot get watched projects", e);
}
}
@@ -301,7 +301,7 @@
throws RestApiException {
try {
return postWatchedProjects.apply(account, in);
- } catch (OrmException | IOException | ConfigInvalidException e) {
+ } catch (OrmException | IOException | ConfigInvalidException | PermissionBackendException e) {
throw new RestApiException("Cannot update watched projects", e);
}
}
@@ -310,7 +310,7 @@
public void deleteWatchedProjects(List<ProjectWatchInfo> in) throws RestApiException {
try {
deleteWatchedProjects.apply(account, in);
- } catch (OrmException | IOException | ConfigInvalidException e) {
+ } catch (OrmException | IOException | ConfigInvalidException | PermissionBackendException e) {
throw new RestApiException("Cannot delete watched projects", e);
}
}
@@ -421,7 +421,7 @@
in.raw = RawInputUtil.create(key);
try {
return addSshKey.apply(account, in).value();
- } catch (OrmException | IOException | ConfigInvalidException e) {
+ } catch (OrmException | IOException | ConfigInvalidException | PermissionBackendException e) {
throw new RestApiException("Cannot add SSH key", e);
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/projects/ProjectApiImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/projects/ProjectApiImpl.java
index 65673de..7d283ec 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/api/projects/ProjectApiImpl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/projects/ProjectApiImpl.java
@@ -300,7 +300,7 @@
public ProjectAccessInfo access(ProjectAccessInput p) throws RestApiException {
try {
return setAccess.apply(checkExists(), p);
- } catch (IOException e) {
+ } catch (IOException | PermissionBackendException e) {
throw new RestApiException("Cannot put access rights", e);
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
index b10cc71..86e55fe 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
@@ -105,6 +105,8 @@
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
+import com.google.gerrit.server.permissions.GlobalPermission;
+import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.ProjectCache;
@@ -292,6 +294,7 @@
private final Provider<InternalChangeQuery> queryProvider;
private final ChangeNotes.Factory notesFactory;
private final AccountResolver accountResolver;
+ private final PermissionBackend permissionBackend;
private final CmdLineParser.Factory optionParserFactory;
private final GitReferenceUpdated gitRefUpdated;
private final PatchSetInfoFactory patchSetInfoFactory;
@@ -357,6 +360,7 @@
Provider<InternalChangeQuery> queryProvider,
ChangeNotes.Factory notesFactory,
AccountResolver accountResolver,
+ PermissionBackend permissionBackend,
CmdLineParser.Factory optionParserFactory,
GitReferenceUpdated gitRefUpdated,
PatchSetInfoFactory patchSetInfoFactory,
@@ -396,6 +400,7 @@
this.queryProvider = queryProvider;
this.notesFactory = notesFactory;
this.accountResolver = accountResolver;
+ this.permissionBackend = permissionBackend;
this.optionParserFactory = optionParserFactory;
this.gitRefUpdated = gitRefUpdated;
this.patchSetInfoFactory = patchSetInfoFactory;
@@ -1042,10 +1047,13 @@
continue;
}
} else {
- if (!oldParent.equals(newParent)
- && !user.getCapabilities().canAdministrateServer()) {
- reject(cmd, "invalid project configuration: only Gerrit admin can set parent");
- continue;
+ if (!oldParent.equals(newParent)) {
+ try {
+ permissionBackend.user(user).check(GlobalPermission.ADMINISTRATE_SERVER);
+ } catch (AuthException e) {
+ reject(cmd, "invalid project configuration: only Gerrit admin can set parent");
+ continue;
+ }
}
if (projectCache.get(newParent) == null) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/MergeValidators.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/MergeValidators.java
index 150965c..298c650 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/MergeValidators.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/MergeValidators.java
@@ -19,6 +19,7 @@
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.registration.DynamicMap.Entry;
import com.google.gerrit.extensions.registration.DynamicSet;
+import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
@@ -29,6 +30,9 @@
import com.google.gerrit.server.config.ProjectConfigEntry;
import com.google.gerrit.server.git.CodeReviewCommit;
import com.google.gerrit.server.git.ProjectConfig;
+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.ProjectState;
import com.google.inject.Inject;
@@ -36,8 +40,12 @@
import java.util.List;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Repository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class MergeValidators {
+ private static final Logger log = LoggerFactory.getLogger(MergeValidators.class);
+
private final DynamicSet<MergeValidationListener> mergeValidationListeners;
private final ProjectConfigValidator.Factory projectConfigValidatorFactory;
@@ -93,6 +101,7 @@
private final AllProjectsName allProjectsName;
private final ProjectCache projectCache;
+ private final PermissionBackend permissionBackend;
private final DynamicMap<ProjectConfigEntry> pluginConfigEntries;
public interface Factory {
@@ -103,9 +112,11 @@
public ProjectConfigValidator(
AllProjectsName allProjectsName,
ProjectCache projectCache,
+ PermissionBackend permissionBackend,
DynamicMap<ProjectConfigEntry> pluginConfigEntries) {
this.allProjectsName = allProjectsName;
this.projectCache = projectCache;
+ this.permissionBackend = permissionBackend;
this.pluginConfigEntries = pluginConfigEntries;
}
@@ -132,8 +143,13 @@
}
} else {
if (!oldParent.equals(newParent)) {
- if (!caller.getCapabilities().canAdministrateServer()) {
+ try {
+ permissionBackend.user(caller).check(GlobalPermission.ADMINISTRATE_SERVER);
+ } catch (AuthException e) {
throw new MergeValidationException(SET_BY_ADMIN);
+ } catch (PermissionBackendException e) {
+ log.warn("Cannot check ADMINISTRATE_SERVER", e);
+ throw new MergeValidationException("validation unavailable");
}
if (projectCache.get(newParent) == null) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/ListGroups.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/ListGroups.java
index 9bf14e7..5e3110c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/group/ListGroups.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/ListGroups.java
@@ -356,7 +356,6 @@
private List<AccountGroup> filterGroups(Collection<AccountGroup> groups) {
List<AccountGroup> filteredGroups = new ArrayList<>(groups.size());
- boolean isAdmin = identifiedUser.get().getCapabilities().canAdministrateServer();
for (AccountGroup group : groups) {
if (!Strings.isNullOrEmpty(matchSubstring)) {
if (!group
@@ -372,13 +371,11 @@
if (!groupsToInspect.isEmpty() && !groupsToInspect.contains(group.getGroupUUID())) {
continue;
}
- if (!isAdmin) {
- GroupControl c = groupControlFactory.controlFor(group);
- if (!c.isVisible()) {
- continue;
- }
+
+ GroupControl c = groupControlFactory.controlFor(group);
+ if (c.isVisible()) {
+ filteredGroups.add(group);
}
- filteredGroups.add(group);
}
Collections.sort(filteredGroups, new GroupComparator());
return filteredGroups;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/send/AddKeySender.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/send/AddKeySender.java
index 0c09639..30938f1 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/send/AddKeySender.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/send/AddKeySender.java
@@ -17,9 +17,13 @@
import com.google.common.base.Joiner;
import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.extensions.api.changes.RecipientType;
+import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.reviewdb.client.AccountSshKey;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.mail.Address;
+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.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import java.util.List;
@@ -31,6 +35,7 @@
AddKeySender create(IdentifiedUser user, List<String> gpgKey);
}
+ private final PermissionBackend permissionBackend;
private final IdentifiedUser callingUser;
private final IdentifiedUser user;
private final AccountSshKey sshKey;
@@ -39,10 +44,12 @@
@AssistedInject
public AddKeySender(
EmailArguments ea,
+ PermissionBackend permissionBackend,
IdentifiedUser callingUser,
@Assisted IdentifiedUser user,
@Assisted AccountSshKey sshKey) {
super(ea, "addkey");
+ this.permissionBackend = permissionBackend;
this.callingUser = callingUser;
this.user = user;
this.sshKey = sshKey;
@@ -52,10 +59,12 @@
@AssistedInject
public AddKeySender(
EmailArguments ea,
+ PermissionBackend permissionBackend,
IdentifiedUser callingUser,
@Assisted IdentifiedUser user,
@Assisted List<String> gpgKeys) {
super(ea, "addkey");
+ this.permissionBackend = permissionBackend;
this.callingUser = callingUser;
this.user = user;
this.sshKey = null;
@@ -71,12 +80,25 @@
@Override
protected boolean shouldSendMessage() {
- /*
- * Don't send an email if no keys are added, or an admin is adding a key to
- * a user.
- */
- return (sshKey != null || gpgKeys.size() > 0)
- && (user.equals(callingUser) || !callingUser.getCapabilities().canAdministrateServer());
+ if (sshKey == null && (gpgKeys == null || gpgKeys.isEmpty())) {
+ // Don't email if no keys were added.
+ return false;
+ }
+
+ if (user.equals(callingUser)) {
+ // Send email if the user self-added a key; this notification is necessary to alert
+ // the user if their account was compromised and a key was unexpectedly added.
+ return true;
+ }
+
+ try {
+ // Don't email if an administrator added a key on behalf of the user.
+ permissionBackend.user(callingUser).check(GlobalPermission.ADMINISTRATE_SERVER);
+ return false;
+ } catch (AuthException | PermissionBackendException e) {
+ // Send email if a non-administrator modified the keys, e.g. by MODIFY_ACCOUNT.
+ return true;
+ }
}
@Override
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/permissions/PermissionBackend.java b/gerrit-server/src/main/java/com/google/gerrit/server/permissions/PermissionBackend.java
index 83b9182..180b67d 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/permissions/PermissionBackend.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/permissions/PermissionBackend.java
@@ -85,7 +85,7 @@
public abstract WithUser user(CurrentUser user);
/** @return lightweight factory scoped to answer for the specified user. */
- public WithUser user(Provider<CurrentUser> user) {
+ public <U extends CurrentUser> WithUser user(Provider<U> user) {
return user(checkNotNull(user, "Provider<CurrentUser>").get());
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java
index 1bb1103..8662e4a 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java
@@ -251,7 +251,7 @@
return (isOwner() // owner (aka creator) of the change can abandon
|| getRefControl().isOwner() // branch owner can abandon
|| getProjectControl().isOwner() // project owner can abandon
- || getUser().getCapabilities().canAdministrateServer() // site administers are god
+ || getUser().getCapabilities().isAdmin_DoNotUse() // site administers are god
|| getRefControl().canAbandon() // user can abandon a specific ref
)
&& !isPatchSetLocked(db);
@@ -275,10 +275,13 @@
switch (status) {
case DRAFT:
- return isOwner() || getRefControl().canDeleteDrafts() || isAdmin();
+ return isOwner()
+ || getRefControl().canDeleteDrafts()
+ || getUser().getCapabilities().isAdmin_DoNotUse();
case NEW:
case ABANDONED:
- return (isAdmin() || (isOwner() && getRefControl().canDeleteOwnChanges()));
+ return (isOwner() && getRefControl().canDeleteOwnChanges())
+ || getUser().getCapabilities().isAdmin_DoNotUse();
case MERGED:
default:
return false;
@@ -394,10 +397,6 @@
return false;
}
- public boolean isAdmin() {
- return getUser().getCapabilities().canAdministrateServer();
- }
-
/** @return true if the user is allowed to remove this reviewer. */
public boolean canRemoveReviewer(PatchSetApproval approval) {
return canRemoveReviewer(approval.getAccountId(), approval.getValue());
@@ -424,7 +423,7 @@
if (getRefControl().canRemoveReviewer() // has removal permissions
|| getRefControl().isOwner() // branch owner
|| getProjectControl().isOwner() // project owner
- || getUser().getCapabilities().canAdministrateServer()) {
+ || getUser().getCapabilities().isAdmin_DoNotUse()) {
return true;
}
}
@@ -438,7 +437,7 @@
return isOwner() // owner (aka creator) of the change can edit topic
|| getRefControl().isOwner() // branch owner can edit topic
|| getProjectControl().isOwner() // project owner can edit topic
- || getUser().getCapabilities().canAdministrateServer() // site administers are god
+ || getUser().getCapabilities().isAdmin_DoNotUse() // site administers are god
|| getRefControl().canEditTopicName() // user can edit topic on a specific ref
;
}
@@ -451,7 +450,7 @@
return isOwner() // owner (aka creator) of the change can edit desc
|| getRefControl().isOwner() // branch owner can edit desc
|| getProjectControl().isOwner() // project owner can edit desc
- || getUser().getCapabilities().canAdministrateServer() // site administers are god
+ || getUser().getCapabilities().isAdmin_DoNotUse() // site administers are god
;
}
return false;
@@ -469,7 +468,7 @@
return isOwner() // owner (aka creator) of the change can edit hashtags
|| getRefControl().isOwner() // branch owner can edit hashtags
|| getProjectControl().isOwner() // project owner can edit hashtags
- || getUser().getCapabilities().canAdministrateServer() // site administers are god
+ || getUser().getCapabilities().isAdmin_DoNotUse() // site administers are god
|| getRefControl().canEditHashtags(); // user can edit hashtag on a specific ref
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectControl.java
index b188ee4..241d266 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectControl.java
@@ -324,7 +324,7 @@
/** Is this user a project owner? Ownership does not imply {@link #isVisible()} */
public boolean isOwner() {
return (isDeclaredOwner() && !controlForRef("refs/*").isBlocked(Permission.OWNER))
- || user.getCapabilities().canAdministrateServer();
+ || user.getCapabilities().isAdmin_DoNotUse();
}
private boolean isDeclaredOwner() {
@@ -337,7 +337,7 @@
/** Does this user have ownership on at least one reference name? */
public boolean isOwnerAnyRef() {
- return canPerformOnAnyRef(Permission.OWNER) || user.getCapabilities().canAdministrateServer();
+ return canPerformOnAnyRef(Permission.OWNER) || user.getCapabilities().isAdmin_DoNotUse();
}
/** @return true if the user can upload to at least one reference */
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java
index 50c024e..f9a4b1b 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java
@@ -200,7 +200,7 @@
// this why for the AllProjects project we allow administrators to push
// configuration changes if they have push without being project owner.
if (!(projectControl.getProjectState().isAllProjects()
- && getUser().getCapabilities().canAdministrateServer())) {
+ && getUser().getCapabilities().isAdmin_DoNotUse())) {
return false;
}
}
@@ -227,7 +227,7 @@
case UNKNOWN:
case WEB_BROWSER:
default:
- return getUser().getCapabilities().canAdministrateServer()
+ return getUser().getCapabilities().isAdmin_DoNotUse()
|| (isOwner() && !isForceBlocked(Permission.PUSH));
}
}
@@ -373,7 +373,7 @@
case UNKNOWN:
case WEB_BROWSER:
default:
- return getUser().getCapabilities().canAdministrateServer()
+ return getUser().getCapabilities().isAdmin_DoNotUse()
|| (isOwner() && !isForceBlocked(Permission.PUSH))
|| canPushWithForce()
|| canPerform(Permission.DELETE);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/SetAccess.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/SetAccess.java
index c74efc6..6c55c37 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/SetAccess.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/SetAccess.java
@@ -41,6 +41,9 @@
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.group.GroupsCollection;
+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.Provider;
import com.google.inject.Singleton;
@@ -54,6 +57,7 @@
@Singleton
public class SetAccess implements RestModifyView<ProjectResource, ProjectAccessInput> {
protected final GroupBackend groupBackend;
+ private final PermissionBackend permissionBackend;
private final GroupsCollection groupsCollection;
private final Provider<MetaDataUpdate.User> metaDataUpdateFactory;
private final AllProjectsName allProjects;
@@ -65,6 +69,7 @@
@Inject
private SetAccess(
GroupBackend groupBackend,
+ PermissionBackend permissionBackend,
Provider<MetaDataUpdate.User> metaDataUpdateFactory,
AllProjectsName allProjects,
Provider<SetParent> setParent,
@@ -73,6 +78,7 @@
GetAccess getAccess,
Provider<IdentifiedUser> identifiedUser) {
this.groupBackend = groupBackend;
+ this.permissionBackend = permissionBackend;
this.metaDataUpdateFactory = metaDataUpdateFactory;
this.allProjects = allProjects;
this.setParent = setParent;
@@ -85,7 +91,7 @@
@Override
public ProjectAccessInfo apply(ProjectResource rsrc, ProjectAccessInput input)
throws ResourceNotFoundException, ResourceConflictException, IOException, AuthException,
- BadRequestException, UnprocessableEntityException {
+ BadRequestException, UnprocessableEntityException, PermissionBackendException {
List<AccessSection> removals = getAccessSections(input.remove);
List<AccessSection> additions = getAccessSections(input.add);
MetaDataUpdate.User metaDataUpdateUser = metaDataUpdateFactory.get();
@@ -269,16 +275,11 @@
}
private void checkGlobalCapabilityPermissions(Project.NameKey projectName)
- throws BadRequestException, AuthException {
-
+ throws BadRequestException, AuthException, PermissionBackendException {
if (!allProjects.equals(projectName)) {
throw new BadRequestException(
"Cannot edit global capabilities for projects other than " + allProjects.get());
}
-
- if (!identifiedUser.get().getCapabilities().canAdministrateServer()) {
- throw new AuthException(
- "Editing global capabilities requires " + GlobalCapability.ADMINISTRATE_SERVER);
- }
+ permissionBackend.user(identifiedUser).check(GlobalPermission.ADMINISTRATE_SERVER);
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/SetParent.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/SetParent.java
index f8d649b..7ec8706 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/SetParent.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/SetParent.java
@@ -30,6 +30,9 @@
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
+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.SetParent.Input;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -45,12 +48,18 @@
}
private final ProjectCache cache;
+ private final PermissionBackend permissionBackend;
private final MetaDataUpdate.Server updateFactory;
private final AllProjectsName allProjects;
@Inject
- SetParent(ProjectCache cache, MetaDataUpdate.Server updateFactory, AllProjectsName allProjects) {
+ SetParent(
+ ProjectCache cache,
+ PermissionBackend permissionBackend,
+ MetaDataUpdate.Server updateFactory,
+ AllProjectsName allProjects) {
this.cache = cache;
+ this.permissionBackend = permissionBackend;
this.updateFactory = updateFactory;
this.allProjects = allProjects;
}
@@ -58,13 +67,13 @@
@Override
public String apply(ProjectResource rsrc, Input input)
throws AuthException, ResourceConflictException, ResourceNotFoundException,
- UnprocessableEntityException, IOException {
+ UnprocessableEntityException, IOException, PermissionBackendException {
return apply(rsrc, input, true);
}
public String apply(ProjectResource rsrc, Input input, boolean checkIfAdmin)
throws AuthException, ResourceConflictException, ResourceNotFoundException,
- UnprocessableEntityException, IOException {
+ UnprocessableEntityException, IOException, PermissionBackendException {
ProjectControl ctl = rsrc.getControl();
String parentName =
MoreObjects.firstNonNull(Strings.emptyToNull(input.parent), allProjects.get());
@@ -97,10 +106,11 @@
}
public void validateParentUpdate(final ProjectControl ctl, String newParent, boolean checkIfAdmin)
- throws AuthException, ResourceConflictException, UnprocessableEntityException {
+ throws AuthException, ResourceConflictException, UnprocessableEntityException,
+ PermissionBackendException {
IdentifiedUser user = ctl.getUser().asIdentifiedUser();
- if (checkIfAdmin && !user.getCapabilities().canAdministrateServer()) {
- throw new AuthException("not administrator");
+ if (checkIfAdmin) {
+ permissionBackend.user(user).check(GlobalPermission.ADMINISTRATE_SERVER);
}
if (ctl.getProject().getNameKey().equals(allProjects)) {
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/BaseCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/BaseCommand.java
index 9971b0c..dbf5b10 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/BaseCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/BaseCommand.java
@@ -21,6 +21,7 @@
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.registration.DynamicMap;
+import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.DynamicOptions;
@@ -29,6 +30,9 @@
import com.google.gerrit.server.git.ProjectRunnable;
import com.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.git.WorkQueue.CancelableRunnable;
+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.NoSuchChangeException;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.sshd.SshScope.Context;
@@ -83,6 +87,7 @@
@Inject @CommandExecutor private WorkQueue.Executor executor;
+ @Inject private PermissionBackend permissionBackend;
@Inject private CurrentUser user;
@Inject private SshScope.Context context;
@@ -251,7 +256,7 @@
protected void startThread(final CommandRunnable thunk) {
final TaskThunk tt = new TaskThunk(thunk);
- if (isAdminHighPriorityCommand() && user.getCapabilities().canAdministrateServer()) {
+ if (isAdminHighPriorityCommand()) {
// Admin commands should not block the main work threads (there
// might be an interactive shell there), nor should they wait
// for the main work threads.
@@ -263,7 +268,15 @@
}
private boolean isAdminHighPriorityCommand() {
- return getClass().getAnnotation(AdminHighPriorityCommand.class) != null;
+ if (getClass().getAnnotation(AdminHighPriorityCommand.class) != null) {
+ try {
+ permissionBackend.user(user).check(GlobalPermission.ADMINISTRATE_SERVER);
+ return true;
+ } catch (AuthException | PermissionBackendException e) {
+ return false;
+ }
+ }
+ return false;
}
/**
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetAccountCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetAccountCommand.java
index bfa1a81..8c6db83 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetAccountCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetAccountCommand.java
@@ -229,7 +229,8 @@
}
private void addSshKeys(List<String> sshKeys)
- throws RestApiException, OrmException, IOException, ConfigInvalidException {
+ throws RestApiException, OrmException, IOException, ConfigInvalidException,
+ PermissionBackendException {
for (final String sshKey : sshKeys) {
AddSshKey.Input in = new AddSshKey.Input();
in.raw = RawInputUtil.create(sshKey.getBytes(UTF_8), "plain/text");
@@ -258,7 +259,7 @@
private void deleteSshKey(SshKeyInfo i)
throws AuthException, OrmException, RepositoryNotFoundException, IOException,
- ConfigInvalidException {
+ ConfigInvalidException, PermissionBackendException {
AccountSshKey sshKey =
new AccountSshKey(new AccountSshKey.Id(user.getAccountId(), i.seq), i.sshPublicKey);
deleteSshKey.apply(new AccountResource.SshKey(user, sshKey), null);