Use MODIFY_ACCOUNT instead of ACCESS_DATABASE for external id endpoints
With this change, we use MODIFY_ACCOUNT instead of ACCESS_DATABASE to
allow users to get/delete someone else's external IDs. The rational is
that this is the more narrow, better fitting permission.
We also document this possibility.
Change-Id: I90b5547326590ea9d3e5bcf5afcc9c803066598d
diff --git a/Documentation/rest-api-accounts.txt b/Documentation/rest-api-accounts.txt
index 28ecc97..10a2ff3 100644
--- a/Documentation/rest-api-accounts.txt
+++ b/Documentation/rest-api-accounts.txt
@@ -1728,6 +1728,10 @@
Retrieves the external ids of a user account.
+Only external ids belonging to the caller may be requested. Users that have
+link:access-control.html#capability_modifyAccount[Modify Account] can request
+external ids that belong to other accounts.
+
.Request
----
GET /a/accounts/self/external.ids HTTP/1.0
@@ -1761,7 +1765,9 @@
Delete a list of external ids for a user account. The target external ids must
be provided as a list in the request body.
-Only external ids belonging to the caller may be deleted.
+Only external ids belonging to the caller may be deleted. Users that have
+link:access-control.html#capability_modifyAccount[Modify Account] can delete
+external ids that belong to other accounts.
.Request
----
diff --git a/java/com/google/gerrit/server/restapi/account/DeleteExternalIds.java b/java/com/google/gerrit/server/restapi/account/DeleteExternalIds.java
index 80f0bb1..445a5d6 100644
--- a/java/com/google/gerrit/server/restapi/account/DeleteExternalIds.java
+++ b/java/com/google/gerrit/server/restapi/account/DeleteExternalIds.java
@@ -73,7 +73,7 @@
public Response<?> apply(AccountResource resource, List<String> extIds)
throws RestApiException, IOException, ConfigInvalidException, PermissionBackendException {
if (!self.get().hasSameAccountId(resource.getUser())) {
- permissionBackend.currentUser().check(GlobalPermission.ACCESS_DATABASE);
+ permissionBackend.currentUser().check(GlobalPermission.MODIFY_ACCOUNT);
}
if (extIds == null || extIds.isEmpty()) {
diff --git a/java/com/google/gerrit/server/restapi/account/GetExternalIds.java b/java/com/google/gerrit/server/restapi/account/GetExternalIds.java
index c5b4454..a3c48b9 100644
--- a/java/com/google/gerrit/server/restapi/account/GetExternalIds.java
+++ b/java/com/google/gerrit/server/restapi/account/GetExternalIds.java
@@ -67,7 +67,7 @@
public Response<List<AccountExternalIdInfo>> apply(AccountResource resource)
throws RestApiException, IOException, PermissionBackendException {
if (!self.get().hasSameAccountId(resource.getUser())) {
- permissionBackend.currentUser().check(GlobalPermission.ACCESS_DATABASE);
+ permissionBackend.currentUser().check(GlobalPermission.MODIFY_ACCOUNT);
}
Collection<ExternalId> ids = externalIds.byAccount(resource.getUser().getAccountId());
diff --git a/javatests/com/google/gerrit/acceptance/rest/account/ExternalIdIT.java b/javatests/com/google/gerrit/acceptance/rest/account/ExternalIdIT.java
index 6e16435..53e871f 100644
--- a/javatests/com/google/gerrit/acceptance/rest/account/ExternalIdIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/account/ExternalIdIT.java
@@ -132,14 +132,14 @@
AuthException thrown =
assertThrows(
AuthException.class, () -> gApi.accounts().id(admin.id().get()).getExternalIds());
- assertThat(thrown).hasMessageThat().contains("access database not permitted");
+ assertThat(thrown).hasMessageThat().contains("modify account not permitted");
}
@Test
- public void getExternalIdsOfOtherUserWithAccessDatabase() throws Exception {
+ public void getExternalIdsOfOtherUserWithModifyAccount() throws Exception {
projectOperations
.allProjectsForUpdate()
- .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .add(allowCapability(GlobalCapability.MODIFY_ACCOUNT).group(REGISTERED_USERS))
.update();
Collection<ExternalId> expectedIds = getAccountState(admin.id()).externalIds();
@@ -193,7 +193,7 @@
gApi.accounts()
.id(admin.id().get())
.deleteExternalIds(extIds.stream().map(e -> e.identity).collect(toList())));
- assertThat(thrown).hasMessageThat().contains("access database not permitted");
+ assertThat(thrown).hasMessageThat().contains("modify account not permitted");
}
@Test
@@ -213,10 +213,10 @@
}
@Test
- public void deleteExternalIdsOfOtherUserWithAccessDatabase() throws Exception {
+ public void deleteExternalIdsOfOtherUserWithModifyAccount() throws Exception {
projectOperations
.allProjectsForUpdate()
- .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .add(allowCapability(GlobalCapability.MODIFY_ACCOUNT).group(REGISTERED_USERS))
.update();
List<AccountExternalIdInfo> externalIds = gApi.accounts().self().getExternalIds();
@@ -464,7 +464,7 @@
public void readExternalIdsWhenInvalidExternalIdsExist() throws Exception {
projectOperations
.allProjectsForUpdate()
- .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .add(allowCapability(GlobalCapability.MODIFY_ACCOUNT).group(REGISTERED_USERS))
.update();
requestScopeOperations.resetCurrentApiUser();