Add REST endpoint to list service users
The REST endpoint only returns service users which were created by the
caller. Administrators are able to see all service users.
Change-Id: I666295b772cf4fd475c68632c63a9f11485b71a9
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUser.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUser.java
index 06ce09b..80b3e2a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUser.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUser.java
@@ -57,9 +57,9 @@
@RequiresCapability(CreateServiceUserCapability.ID)
public class CreateServiceUser implements RestModifyView<ConfigResource, Input> {
- private static final String USER = "user";
- private static final String KEY_CREATED_BY = "createdBy";
- private static final String KEY_CREATED_AT = "createdAt";
+ public static final String USER = "user";
+ public static final String KEY_CREATED_BY = "createdBy";
+ public static final String KEY_CREATED_AT = "createdAt";
static class Input {
String username;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ListServiceUsers.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ListServiceUsers.java
new file mode 100644
index 0000000..d1d0cf0
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ListServiceUsers.java
@@ -0,0 +1,97 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.serviceuser;
+
+import static com.googlesource.gerrit.plugins.serviceuser.CreateServiceUser.KEY_CREATED_AT;
+import static com.googlesource.gerrit.plugins.serviceuser.CreateServiceUser.KEY_CREATED_BY;
+import static com.googlesource.gerrit.plugins.serviceuser.CreateServiceUser.USER;
+
+import com.google.common.collect.Maps;
+import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountCache;
+import com.google.gerrit.server.account.AccountInfo;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.AccountState;
+import com.google.gerrit.server.account.GetAccount;
+import com.google.gerrit.server.config.ConfigResource;
+import com.google.gerrit.server.git.ProjectLevelConfig;
+import com.google.gerrit.server.project.ProjectCache;
+import com.google.gwtorm.server.OrmException;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+import org.eclipse.jgit.lib.Config;
+
+import java.util.Map;
+
+public class ListServiceUsers implements RestReadView<ConfigResource> {
+ private final Provider<CurrentUser> userProvider;
+ private final IdentifiedUser.GenericFactory userFactory;
+ private final ProjectLevelConfig storage;
+ private final AccountCache accountCache;
+ private final Provider<GetAccount> getAccount;
+
+ @Inject
+ ListServiceUsers(Provider<CurrentUser> userProvider,
+ IdentifiedUser.GenericFactory userFactory, @PluginName String pluginName,
+ ProjectCache projectCache, AccountCache accountCache,
+ Provider<GetAccount> getAccount) {
+ this.userProvider = userProvider;
+ this.userFactory = userFactory;
+ this.storage = projectCache.getAllProjects().getConfig(pluginName + ".db");
+ this.accountCache = accountCache;
+ this.getAccount = getAccount;
+ }
+
+ @Override
+ public Map<String, ServiceUserInfo> apply(ConfigResource rscr) throws OrmException {
+ Map<String, ServiceUserInfo> accounts = Maps.newTreeMap();
+ Config db = storage.get();
+ boolean isAdmin = userProvider.get().getCapabilities().canAdministrateServer();
+ String currentUser = userProvider.get().getUserName();
+ for (String username : db.getSubsections(USER)) {
+ String createdBy = db.getString(USER, username, KEY_CREATED_BY);
+ if (isAdmin || currentUser.equals(createdBy)) {
+ AccountState account = accountCache.getByUsername(username);
+ if (account != null) {
+ ServiceUserInfo info = new ServiceUserInfo(getAccount.get().apply(
+ new AccountResource(userFactory.create(account.getAccount().getId()))));
+ info.username = null;
+ info.createdBy = createdBy;
+ info.createdAt = db.getString(USER, username, KEY_CREATED_AT);
+ accounts.put(username, info);
+ }
+ }
+ }
+ return accounts;
+ }
+
+ public static class ServiceUserInfo extends AccountInfo {
+ public String createdBy;
+ public String createdAt;
+
+ public ServiceUserInfo(AccountInfo info) {
+ super(info._id);
+ _accountId = info._accountId;
+ name = info.name;
+ email = info.email;
+ username = info.username;
+ avatars = info.avatars;
+ }
+ }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserCollection.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserCollection.java
index 4a95ed0..f04c1d4 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserCollection.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserCollection.java
@@ -23,6 +23,7 @@
import com.google.gerrit.server.account.AccountResource;
import com.google.gerrit.server.config.ConfigResource;
import com.google.inject.Inject;
+import com.google.inject.Provider;
public class ServiceUserCollection implements
ChildCollection<ConfigResource, AccountResource>,
@@ -30,12 +31,15 @@
private final DynamicMap<RestView<AccountResource>> views;
private final CreateServiceUser.Factory createServiceUserFactory;
+ private final Provider<ListServiceUsers> list;
@Inject
ServiceUserCollection(DynamicMap<RestView<AccountResource>> views,
- CreateServiceUser.Factory createServiceUserFactory) {
+ CreateServiceUser.Factory createServiceUserFactory,
+ Provider<ListServiceUsers> list) {
this.views = views;
this.createServiceUserFactory = createServiceUserFactory;
+ this.list = list;
}
@Override
@@ -45,8 +49,8 @@
}
@Override
- public RestView<ConfigResource> list() throws ResourceNotFoundException {
- throw new ResourceNotFoundException();
+ public RestView<ConfigResource> list() {
+ return list.get();
}
@Override
diff --git a/src/main/resources/Documentation/rest-api-config.md b/src/main/resources/Documentation/rest-api-config.md
index 56fae99..4273cad 100644
--- a/src/main/resources/Documentation/rest-api-config.md
+++ b/src/main/resources/Documentation/rest-api-config.md
@@ -51,6 +51,51 @@
}
```
+### <a id="list-service-users"> List Service Users
+GET /config/server/@PLUGIN@~serviceusers/_
+
+Lists service users.
+
+In order to see a service user the caller must have created that service
+user or be a member of a group that is granted the 'Administrate Server'
+capability.
+
+#### Request
+
+```
+ GET /config/server/@PLUGIN@~serviceusers/ HTTP/1.0
+```
+
+As response a map is returned that maps the username to a
+[ServiceUserInfo](#service-user-info) entity. The username in
+ServiceUserInfo is not set since it is already available as map key.
+
+#### Response
+
+```
+ HTTP/1.1 201 Created
+ Content-Disposition: attachment
+ Content-Type: application/json;charset=UTF-8
+
+ )]}'
+ {
+ "GlobalVerifier": {
+ "created_by": "jdoe",
+ "created_at": "Mon, 27 Jan 2014 21:00:12 +0100",
+ "_account_id": 1000107,
+ "name": "GlobalVerifier",
+ "avatars": []
+ },
+ "JenkinsVoter": {
+ "created_by": "jdoe",
+ "created_at": "Thu, 21 Nov 2013 15:00:55 +0100",
+ "_account_id": 1000195,
+ "name": "JenkinsVoter",
+ "avatars": []
+ }
+ }
+```
+
### <a id="get-config"> Get Config
_GET /config/server/@PLUGIN@~config_
@@ -113,6 +158,18 @@
* _allow\_email_: Whether it is allowed to provide an email address for
a service user (not set if `false`).
+### <a id="service-user-info"></a>ServiceUserInfo
+
+The `ServiceUserInfo` entity contains information about a service user.
+It has the same fields as a detailed
+[AccountInfo](../../../Documentation/rest-api-accounts.html#account-info)
+and in addition the following fields:
+
+* _created\_by_: The username of the user that created this service
+ user.
+* _created\_at_: The date when the service user was created in the
+ format 'EEE, dd MMM yyyy HH:mm:ss Z'.
+
### <a id="service-user-input"></a>ServiceUserInput
The `ServiceUserInput` entity contains options for creating a service