import org.sonar.server.user.UserSession;
import static com.google.common.base.Preconditions.checkArgument;
+import static java.lang.String.format;
import static org.sonar.server.exceptions.BadRequestException.checkRequest;
import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_COMPONENT;
import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_FIELD_VALUES;
private static final Collector<CharSequence, ?, String> COMMA_JOINER = Collectors.joining(",");
private static final String MSG_NO_EMPTY_VALUE = "A non empty value must be provided";
private static final int VALUE_MAXIMUM_LENGTH = 4000;
+ static final Map<String, String> KEY_CONSTRAINTS = Map.of(
+ "sonar.auth.gitlab.url", "sonar.auth.gitlab.secret.secured"
+ );
private final PropertyDefinitions propertyDefinitions;
private final DbClient dbClient;
public void handle(Request request, Response response) throws Exception {
try (DbSession dbSession = dbClient.openSession(false)) {
SetRequest wsRequest = toWsRequest(request);
+ throwIfUnmatchedConstraintOnGlobalKey(wsRequest.getKey());
SettingsWsSupport.validateKey(wsRequest.getKey());
doHandle(dbSession, wsRequest);
}
response.noContent();
}
+ private void throwIfUnmatchedConstraintOnGlobalKey(String key) {
+ if (KEY_CONSTRAINTS.containsKey(key)) {
+ String keyConstrained = KEY_CONSTRAINTS.get(key);
+ checkRequest(!isGlobalKeySet(keyConstrained), format("Setting '%s' must be empty to set '%s'", keyConstrained, key));
+ }
+ }
+
+ private boolean isGlobalKeySet(String keyConstrained) {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ PropertyDto propertyDto = dbClient.propertiesDao().selectGlobalProperty(dbSession, keyConstrained);
+ return propertyDto != null && !StringUtils.isBlank(propertyDto.getValue());
+ }
+ }
+
private void doHandle(DbSession dbSession, SetRequest request) {
Optional<ComponentDto> component = searchComponent(dbSession, request);
String projectKey = component.isPresent() ? component.get().getKey() : null;
.hasMessage(format("Setting '%s' can only be used in sonar.properties", settingKey));
}
+ @Test
+ public void fail_when_key_constraints_are_not_met() {
+ propertyDb.insertProperty(newGlobalPropertyDto("sonar.auth.gitlab.secret.secured", "secret"), null, null, null, null);
+
+ assertThatThrownBy(() -> {
+ callForGlobalSetting("sonar.auth.gitlab.url", "http://new.url");
+ })
+ .isInstanceOf(BadRequestException.class)
+ .hasMessage("Setting 'sonar.auth.gitlab.secret.secured' must be empty to set 'sonar.auth.gitlab.url'");
+ }
+
+ @Test
+ public void succeed_when_key_constraints_are_met() {
+ assertGlobalSettingIsNotSet("sonar.auth.gitlab.secret.secured");
+
+ callForGlobalSetting("sonar.auth.gitlab.url", "http://new.url");
+
+ assertGlobalSetting("sonar.auth.gitlab.url", "http://new.url");
+ }
+
@Test
public void definition() {
WebService.Action definition = ws.getDef();
.containsExactly(key, value, null);
}
+ private void assertGlobalSettingIsNotSet(String key) {
+ PropertyDto result = dbClient.propertiesDao().selectGlobalProperty(key);
+
+ assertThat(result).isNull();
+ }
+
private void assertUserSetting(String key, String value, String userUuid) {
List<PropertyDto> result = dbClient.propertiesDao().selectByQuery(PropertyQuery.builder().setKey(key).setUserUuid(userUuid).build(), dbSession);