]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7981 Create WS settings/generate_secret_key to generate a secret key
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Mon, 5 Sep 2016 16:00:48 +0000 (18:00 +0200)
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Mon, 5 Sep 2016 16:01:21 +0000 (18:01 +0200)
server/sonar-server/src/main/java/org/sonar/server/setting/ws/GenerateSecretKeyAction.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/setting/ws/SettingsWsModule.java
server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
server/sonar-server/src/main/resources/org/sonar/server/setting/ws/generate_secret_key-example.json [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/setting/ws/GenerateSecretKeyActionTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/setting/ws/SettingsWsModuleTest.java
sonar-ws/src/main/protobuf/ws-settings.proto

diff --git a/server/sonar-server/src/main/java/org/sonar/server/setting/ws/GenerateSecretKeyAction.java b/server/sonar-server/src/main/java/org/sonar/server/setting/ws/GenerateSecretKeyAction.java
new file mode 100644 (file)
index 0000000..1d2caf4
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.setting.ws;
+
+import org.sonar.api.config.Settings;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.server.user.UserSession;
+import org.sonarqube.ws.Settings.GenerateSecretKeyWsResponse;
+
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
+import static org.sonar.server.ws.WsUtils.writeProtobuf;
+
+public class GenerateSecretKeyAction implements SettingsWsAction {
+  private final Settings settings;
+  private final UserSession userSession;
+
+  public GenerateSecretKeyAction(Settings settings, UserSession userSession) {
+    this.settings = settings;
+    this.userSession = userSession;
+  }
+
+  @Override
+  public void define(WebService.NewController context) {
+    context.createAction("generate_secret_key")
+      .setDescription("Generate a secret key")
+      .setSince("6.1")
+      .setInternal(true)
+      .setResponseExample(getClass().getResource("generate_secret_key-example.json"))
+      .setHandler(this);
+  }
+
+  @Override
+  public void handle(Request request, Response response) throws Exception {
+    userSession.checkPermission(SYSTEM_ADMIN);
+
+    writeProtobuf(GenerateSecretKeyWsResponse.newBuilder().setSecretKey(settings.getEncryption().generateRandomSecretKey()).build(), request, response);
+  }
+}
index 4a0a9755dec4c019d14ddae45f6515b3befbcb22..e8bbb1d78168f8e713472d499e1f550392b47091 100644 (file)
@@ -33,6 +33,7 @@ public class SettingsWsModule extends Module {
       SettingsFinder.class,
       ResetAction.class,
       EncryptAction.class,
+      GenerateSecretKeyAction.class,
       SettingsUpdater.class);
   }
 }
index 9cb9deb58c64f31bd84e81bd29ed0e1a90c625ad..1db6e6091bfe2606647d3a8f1c12c4131889efdb 100644 (file)
@@ -276,7 +276,7 @@ public final class JRubyFacade {
   }
 
   public String generateRandomSecretKey() {
-    return get(Settings.class).getEncryption().generateRandomSecretKey();
+    return  get(Settings.class).getEncryption().generateRandomSecretKey();
   }
 
   public License parseLicense(String base64) {
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/setting/ws/generate_secret_key-example.json b/server/sonar-server/src/main/resources/org/sonar/server/setting/ws/generate_secret_key-example.json
new file mode 100644 (file)
index 0000000..775c80c
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  "secretKey": "fCVFf/JHRi8Qwu5KLNva7g=="
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/setting/ws/GenerateSecretKeyActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/setting/ws/GenerateSecretKeyActionTest.java
new file mode 100644 (file)
index 0000000..3a91a9d
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.setting.ws;
+
+import com.google.common.base.Throwables;
+import java.io.File;
+import java.io.IOException;
+import org.apache.commons.io.FileUtils;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.config.Encryption;
+import org.sonar.api.config.Settings;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.TestRequest;
+import org.sonar.server.ws.WsActionTester;
+import org.sonarqube.ws.MediaTypes;
+import org.sonarqube.ws.Settings.GenerateSecretKeyWsResponse;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.core.permission.GlobalPermissions.QUALITY_PROFILE_ADMIN;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
+
+public class GenerateSecretKeyActionTest {
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+  @Rule
+  public UserSessionRule userSession = UserSessionRule.standalone().setGlobalPermissions(SYSTEM_ADMIN);
+  @Rule
+  public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  Settings settings = new Settings();
+  Encryption encryption = settings.getEncryption();
+
+  GenerateSecretKeyAction underTest = new GenerateSecretKeyAction(settings, userSession);
+
+  WsActionTester ws = new WsActionTester(underTest);
+
+  @Test
+  public void generate_valid_secret_key() throws IOException {
+    GenerateSecretKeyWsResponse result = call();
+
+    String secretKey = result.getSecretKey();
+    File file = temporaryFolder.newFile();
+    FileUtils.writeStringToFile(file, secretKey);
+    encryption.setPathToSecretKey(file.getAbsolutePath());
+    String encryptedValue = encryption.encrypt("my value");
+    String decryptedValue = encryption.decrypt(encryptedValue);
+    assertThat(decryptedValue).isEqualTo("my value");
+  }
+
+  @Test
+  public void definition() {
+    WebService.Action definition = ws.getDef();
+
+    assertThat(definition.key()).isEqualTo("generate_secret_key");
+    assertThat(definition.isPost()).isFalse();
+    assertThat(definition.isInternal()).isTrue();
+    assertThat(definition.responseExampleAsString()).isNotEmpty();
+    assertThat(definition.params()).hasSize(0);
+  }
+
+  @Test
+  public void fail_if_insufficient_permissions() {
+    expectedException.expect(ForbiddenException.class);
+
+    userSession.anonymous().setGlobalPermissions(QUALITY_PROFILE_ADMIN);
+
+    call();
+  }
+
+  private GenerateSecretKeyWsResponse call() {
+    TestRequest request = ws.newRequest()
+      .setMediaType(MediaTypes.PROTOBUF)
+      .setMethod("GET");
+
+    try {
+      return GenerateSecretKeyWsResponse.parseFrom(request.execute().getInputStream());
+    } catch (IOException e) {
+      throw Throwables.propagate(e);
+    }
+  }
+
+}
index 386ba30f9cc756bc332377261a282c5f39bd3260..627905526f9a925f76e9480c67f1ecc8340137ac 100644 (file)
@@ -29,6 +29,6 @@ public class SettingsWsModuleTest {
   public void verify_count_of_added_components() {
     ComponentContainer container = new ComponentContainer();
     new SettingsWsModule().configure(container);
-    assertThat(container.size()).isEqualTo(9 + 2);
+    assertThat(container.size()).isEqualTo(10 + 2);
   }
 }
index 519357e522cd9ced91a6082ec71835efc85bacac..910e57b57bd59f0aa9fce63961d72631b0b39d48 100644 (file)
@@ -34,6 +34,11 @@ message EncryptWsResponse {
   optional string encryptedValue = 1;
 }
 
+// Response of GET api/settings/generate_secret_key
+message GenerateSecretKeyWsResponse {
+  optional string secretKey = 1;
+}
+
 message Definition {
   optional string key = 1;
   optional string name = 2;