Add REST endpoints to get/set default edit preferences

For general and diff preferences defaults can already be configured
via REST. Support the same for edit preferences.

Change-Id: I325fe4f768ad9089f8cf598bd88c5b9b57af871d
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
Edwin Kempin 2018-01-17 11:01:00 +01:00
parent 4a28ca7a5a
commit 1e01692e79
9 changed files with 350 additions and 3 deletions

View File

@ -202,9 +202,8 @@ The parameter names match the names that are used in the preferences REST API:
If the value for a preference is the same as the default value for this
preference, it can be omitted in the `preference.config` file.
Defaults for general and diff preferences that apply for all accounts
can be configured in the `refs/users/default` branch in the `All-Users`
repository.
Defaults for preferences that apply for all accounts can be configured
in the `refs/users/default` branch in the `All-Users` repository.
[[project-watches]]
=== Project Watches

View File

@ -1223,6 +1223,103 @@ DiffPreferencesInfo] is returned.
}
----
[[get-edit-preferences]]
=== Get Default Edit Preferences
--
'GET /config/server/preferences.edit'
--
Returns the default edit preferences for the server.
.Request
----
GET /a/config/server/preferences.edit HTTP/1.0
----
As response a link:rest-api-accounts.html#edit-preferences-info[
EditPreferencesInfo] is returned.
.Response
----
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
)]}'
{
"tab_size": 8,
"line_length": 100,
"indent_unit": 2,
"cursor_blink_rate": 0,
"show_tabs": true,
"syntax_highlighting": true,
"match_brackets": true,
"auto_close_brackets": true,
"theme": "DEFAULT",
"key_map_type": "DEFAULT"
}
----
[[set-edit-preferences]]
=== Set Default Edit Preferences
--
'PUT /config/server/preferences.edit'
--
Sets the default edit preferences for the server.
The new edit preferences must be provided in the request body as a
link:rest-api-accounts.html#edit-preferences-input[
EditPreferencesInput] entity.
To be allowed to set default edit preferences, a user must be a member
of a group that is granted the
link:access-control.html#capability_administrateServer[
Administrate Server] capability.
.Request
----
PUT /a/config/server/preferences.edit HTTP/1.0
Content-Type: application/json; charset=UTF-8
{
"tab_size": 8,
"line_length": 80,
"indent_unit": 2,
"cursor_blink_rate": 0,
"show_tabs": true,
"syntax_highlighting": true,
"match_brackets": true,
"auto_close_brackets": true,
"theme": "DEFAULT",
"key_map_type": "DEFAULT"
}
----
As response a link:rest-api-accounts.html#edit-preferences-info[
EditPreferencesInfo] is returned.
.Response
----
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
)]}'
{
"tab_size": 8,
"line_length": 80,
"indent_unit": 2,
"cursor_blink_rate": 0,
"show_tabs": true,
"syntax_highlighting": true,
"match_brackets": true,
"auto_close_brackets": true,
"theme": "DEFAULT",
"key_map_type": "DEFAULT"
}
----
[[ids]]
== IDs

View File

@ -15,6 +15,7 @@
package com.google.gerrit.extensions.api.config;
import com.google.gerrit.extensions.client.DiffPreferencesInfo;
import com.google.gerrit.extensions.client.EditPreferencesInfo;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
import com.google.gerrit.extensions.common.ServerInfo;
import com.google.gerrit.extensions.restapi.NotImplementedException;
@ -34,6 +35,10 @@ public interface Server {
DiffPreferencesInfo setDefaultDiffPreferences(DiffPreferencesInfo in) throws RestApiException;
EditPreferencesInfo getDefaultEditPreferences() throws RestApiException;
EditPreferencesInfo setDefaultEditPreferences(EditPreferencesInfo in) throws RestApiException;
ConsistencyCheckInfo checkConsistency(ConsistencyCheckInput in) throws RestApiException;
/**
@ -73,6 +78,17 @@ public interface Server {
throw new NotImplementedException();
}
@Override
public EditPreferencesInfo getDefaultEditPreferences() throws RestApiException {
throw new NotImplementedException();
}
@Override
public EditPreferencesInfo setDefaultEditPreferences(EditPreferencesInfo in)
throws RestApiException {
throw new NotImplementedException();
}
@Override
public ConsistencyCheckInfo checkConsistency(ConsistencyCheckInput in) throws RestApiException {
throw new NotImplementedException();

View File

@ -397,6 +397,11 @@ public class PreferencesConfig {
return parseDiffPreferences(readDefaultConfig(allUsersRepo), null, null);
}
public static EditPreferencesInfo readDefaultEditPreferences(Repository allUsersRepo)
throws IOException, ConfigInvalidException {
return parseEditPreferences(readDefaultConfig(allUsersRepo), null, null);
}
static Config readDefaultConfig(Repository allUsersRepo)
throws IOException, ConfigInvalidException {
VersionedDefaultPreferences defaultPrefs = new VersionedDefaultPreferences();
@ -437,6 +442,21 @@ public class PreferencesConfig {
return parseDiffPreferences(defaultPrefs.getConfig(), null, null);
}
public static EditPreferencesInfo updateDefaultEditPreferences(
MetaDataUpdate md, EditPreferencesInfo input) throws IOException, ConfigInvalidException {
VersionedDefaultPreferences defaultPrefs = new VersionedDefaultPreferences();
defaultPrefs.load(md);
storeSection(
defaultPrefs.getConfig(),
UserConfigSections.EDIT,
null,
input,
EditPreferencesInfo.defaults());
defaultPrefs.commit(md);
return parseEditPreferences(defaultPrefs.getConfig(), null, null);
}
private static List<String> changeTable(Config cfg) {
return Lists.newArrayList(cfg.getStringList(CHANGE_TABLE, null, CHANGE_TABLE_COLUMN));
}

View File

@ -21,15 +21,18 @@ import com.google.gerrit.extensions.api.config.ConsistencyCheckInfo;
import com.google.gerrit.extensions.api.config.ConsistencyCheckInput;
import com.google.gerrit.extensions.api.config.Server;
import com.google.gerrit.extensions.client.DiffPreferencesInfo;
import com.google.gerrit.extensions.client.EditPreferencesInfo;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
import com.google.gerrit.extensions.common.ServerInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.server.config.ConfigResource;
import com.google.gerrit.server.restapi.config.CheckConsistency;
import com.google.gerrit.server.restapi.config.GetDiffPreferences;
import com.google.gerrit.server.restapi.config.GetEditPreferences;
import com.google.gerrit.server.restapi.config.GetPreferences;
import com.google.gerrit.server.restapi.config.GetServerInfo;
import com.google.gerrit.server.restapi.config.SetDiffPreferences;
import com.google.gerrit.server.restapi.config.SetEditPreferences;
import com.google.gerrit.server.restapi.config.SetPreferences;
import com.google.inject.Inject;
import com.google.inject.Provider;
@ -41,6 +44,8 @@ public class ServerImpl implements Server {
private final SetPreferences setPreferences;
private final GetDiffPreferences getDiffPreferences;
private final SetDiffPreferences setDiffPreferences;
private final GetEditPreferences getEditPreferences;
private final SetEditPreferences setEditPreferences;
private final GetServerInfo getServerInfo;
private final Provider<CheckConsistency> checkConsistency;
@ -50,12 +55,16 @@ public class ServerImpl implements Server {
SetPreferences setPreferences,
GetDiffPreferences getDiffPreferences,
SetDiffPreferences setDiffPreferences,
GetEditPreferences getEditPreferences,
SetEditPreferences setEditPreferences,
GetServerInfo getServerInfo,
Provider<CheckConsistency> checkConsistency) {
this.getPreferences = getPreferences;
this.setPreferences = setPreferences;
this.getDiffPreferences = getDiffPreferences;
this.setDiffPreferences = setDiffPreferences;
this.getEditPreferences = getEditPreferences;
this.setEditPreferences = setEditPreferences;
this.getServerInfo = getServerInfo;
this.checkConsistency = checkConsistency;
}
@ -112,6 +121,25 @@ public class ServerImpl implements Server {
}
}
@Override
public EditPreferencesInfo getDefaultEditPreferences() throws RestApiException {
try {
return getEditPreferences.apply(new ConfigResource());
} catch (Exception e) {
throw asRestApiException("Cannot get default edit preferences", e);
}
}
@Override
public EditPreferencesInfo setDefaultEditPreferences(EditPreferencesInfo in)
throws RestApiException {
try {
return setEditPreferences.apply(new ConfigResource(), in);
} catch (Exception e) {
throw asRestApiException("Cannot set default edit preferences", e);
}
}
@Override
public ConsistencyCheckInfo checkConsistency(ConsistencyCheckInput in) throws RestApiException {
try {

View File

@ -41,6 +41,8 @@ public class ConfigRestModule extends RestApiModule {
put(CONFIG_KIND, "preferences").to(SetPreferences.class);
get(CONFIG_KIND, "preferences.diff").to(GetDiffPreferences.class);
put(CONFIG_KIND, "preferences.diff").to(SetDiffPreferences.class);
get(CONFIG_KIND, "preferences.edit").to(GetEditPreferences.class);
put(CONFIG_KIND, "preferences.edit").to(SetEditPreferences.class);
put(CONFIG_KIND, "email.confirm").to(ConfirmEmail.class);
}
}

View File

@ -0,0 +1,49 @@
// Copyright (C) 2018 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.google.gerrit.server.restapi.config;
import com.google.gerrit.extensions.client.EditPreferencesInfo;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.server.account.PreferencesConfig;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.ConfigResource;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.IOException;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Repository;
@Singleton
public class GetEditPreferences implements RestReadView<ConfigResource> {
private final AllUsersName allUsersName;
private final GitRepositoryManager gitManager;
@Inject
GetEditPreferences(GitRepositoryManager gitManager, AllUsersName allUsersName) {
this.allUsersName = allUsersName;
this.gitManager = gitManager;
}
@Override
public EditPreferencesInfo apply(ConfigResource configResource)
throws BadRequestException, ResourceConflictException, IOException, ConfigInvalidException {
try (Repository git = gitManager.openRepository(allUsersName)) {
return PreferencesConfig.readDefaultEditPreferences(git);
}
}
}

View File

@ -0,0 +1,89 @@
// Copyright (C) 2018 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.google.gerrit.server.restapi.config;
import static com.google.gerrit.server.config.ConfigUtil.skipField;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.extensions.client.EditPreferencesInfo;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.PreferencesConfig;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.ConfigResource;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
import java.lang.reflect.Field;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
@Singleton
public class SetEditPreferences implements RestModifyView<ConfigResource, EditPreferencesInfo> {
private static final Logger log = LoggerFactory.getLogger(SetDiffPreferences.class);
private final Provider<MetaDataUpdate.User> metaDataUpdateFactory;
private final AllUsersName allUsersName;
private final AccountCache accountCache;
@Inject
SetEditPreferences(
Provider<MetaDataUpdate.User> metaDataUpdateFactory,
AllUsersName allUsersName,
AccountCache accountCache) {
this.metaDataUpdateFactory = metaDataUpdateFactory;
this.allUsersName = allUsersName;
this.accountCache = accountCache;
}
@Override
public EditPreferencesInfo apply(ConfigResource configResource, EditPreferencesInfo input)
throws BadRequestException, IOException, ConfigInvalidException {
if (input == null) {
throw new BadRequestException("input must be provided");
}
if (!hasSetFields(input)) {
throw new BadRequestException("unsupported option");
}
try (MetaDataUpdate md = metaDataUpdateFactory.get().create(allUsersName)) {
EditPreferencesInfo updatedPrefs = PreferencesConfig.updateDefaultEditPreferences(md, input);
accountCache.evictAllNoReindex();
return updatedPrefs;
}
}
private static boolean hasSetFields(EditPreferencesInfo in) {
try {
for (Field field : in.getClass().getDeclaredFields()) {
if (skipField(field)) {
continue;
}
if (field.get(in) != null) {
return true;
}
}
} catch (IllegalAccessException e) {
log.warn("Unable to verify input", e);
}
return false;
}
}

View File

@ -0,0 +1,47 @@
// Copyright (C) 2018 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.google.gerrit.acceptance.api.config;
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.AssertUtil.assertPrefs;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.extensions.client.EditPreferencesInfo;
import org.junit.Test;
@NoHttpd
public class EditPreferencesIT extends AbstractDaemonTest {
@Test
public void getEditPreferences() throws Exception {
EditPreferencesInfo result = gApi.config().server().getDefaultEditPreferences();
assertPrefs(result, EditPreferencesInfo.defaults());
}
@Test
public void setEditPreferences() throws Exception {
int newLineLength = EditPreferencesInfo.defaults().lineLength + 10;
EditPreferencesInfo update = new EditPreferencesInfo();
update.lineLength = newLineLength;
EditPreferencesInfo result = gApi.config().server().setDefaultEditPreferences(update);
assertThat(result.lineLength).named("lineLength").isEqualTo(newLineLength);
result = gApi.config().server().getDefaultEditPreferences();
EditPreferencesInfo expected = EditPreferencesInfo.defaults();
expected.lineLength = newLineLength;
assertPrefs(result, expected);
}
}