]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9263 log warning once when OAuth URL is http but not https
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Thu, 5 Oct 2017 07:42:51 +0000 (09:42 +0200)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Mon, 16 Oct 2017 14:10:59 +0000 (16:10 +0200)
server/sonar-server/src/main/java/org/sonar/server/authentication/LogOAuthWarning.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/authentication/OAuth2ContextFactory.java
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
server/sonar-server/src/test/java/org/sonar/server/authentication/LogOAuthWarningTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/authentication/OAuth2ContextFactoryTest.java

diff --git a/server/sonar-server/src/main/java/org/sonar/server/authentication/LogOAuthWarning.java b/server/sonar-server/src/main/java/org/sonar/server/authentication/LogOAuthWarning.java
new file mode 100644 (file)
index 0000000..b536046
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.authentication;
+
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.Startable;
+import org.sonar.api.platform.Server;
+import org.sonar.api.server.authentication.OAuth2IdentityProvider;
+import org.sonar.api.utils.log.Loggers;
+
+public class LogOAuthWarning implements Startable {
+
+  private final Server server;
+  private final OAuth2IdentityProvider[] providers;
+
+  public LogOAuthWarning(Server server, OAuth2IdentityProvider[] providers) {
+    this.server = server;
+    this.providers = providers;
+  }
+
+  /**
+   * Used by default by picocontainer when no OAuth2IdentityProvider are present
+   */
+  public LogOAuthWarning(Server server) {
+    this(server, new OAuth2IdentityProvider[0]);
+  }
+
+  @Override
+  public void start() {
+    if (providers.length == 0) {
+      return;
+    }
+    String publicRootUrl = server.getPublicRootUrl();
+    if (StringUtils.startsWithIgnoreCase(publicRootUrl, "http:")) {
+      Loggers.get(getClass()).warn(
+        "For security reasons, OAuth authentication should use HTTPS. You should set the property 'Administration > Configuration > Server base URL' to a HTTPS URL.");
+    }
+  }
+
+  @Override
+  public void stop() {
+    // nothing to do
+  }
+}
index 368c3add037af9775f8fde11a304b3381f11db3b..d19d8a1fd2e80fd0c2613bf7dd790fa62784be0b 100644 (file)
@@ -23,18 +23,18 @@ import java.io.IOException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.sonar.api.platform.Server;
+import org.sonar.api.server.ServerSide;
 import org.sonar.api.server.authentication.OAuth2IdentityProvider;
 import org.sonar.api.server.authentication.UserIdentity;
-import org.sonar.api.utils.log.Loggers;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.authentication.event.AuthenticationEvent;
 import org.sonar.server.user.ThreadLocalUserSession;
 import org.sonar.server.user.UserSessionFactory;
 
 import static java.lang.String.format;
-import static org.sonar.api.CoreProperties.SERVER_BASE_URL;
 import static org.sonar.server.authentication.OAuth2CallbackFilter.CALLBACK_PATH;
 
+@ServerSide
 public class OAuth2ContextFactory {
 
   private final ThreadLocalUserSession threadLocalUserSession;
@@ -76,12 +76,7 @@ public class OAuth2ContextFactory {
 
     @Override
     public String getCallbackUrl() {
-      String publicRootUrl = server.getPublicRootUrl();
-      if (publicRootUrl.startsWith("http:")) {
-        Loggers.get(getClass()).warn(
-          "For security reasons, the server URL used for OAuth authentications should be https. Please update the property '{}'.", SERVER_BASE_URL);
-      }
-      return publicRootUrl + CALLBACK_PATH + identityProvider.getKey();
+      return server.getPublicRootUrl() + CALLBACK_PATH + identityProvider.getKey();
     }
 
     @Override
index 046a9fa2f36785b62333963d1c0cc2949a203e54..0b622830025bd433dbacb6f36a573e5086ff9155 100644 (file)
@@ -35,6 +35,7 @@ import org.sonar.ce.settings.ProjectConfigurationFactory;
 import org.sonar.core.component.DefaultResourceTypes;
 import org.sonar.core.timemachine.Periods;
 import org.sonar.server.authentication.AuthenticationModule;
+import org.sonar.server.authentication.LogOAuthWarning;
 import org.sonar.server.batch.BatchWsModule;
 import org.sonar.server.branch.BranchFeatureProxyImpl;
 import org.sonar.server.ce.ws.CeWsModule;
@@ -251,6 +252,7 @@ public class PlatformLevel4 extends PlatformLevel {
 
     add(
       LogServerId.class,
+      LogOAuthWarning.class,
       PluginDownloader.class,
       DeprecatedViews.class,
       PageRepository.class,
diff --git a/server/sonar-server/src/test/java/org/sonar/server/authentication/LogOAuthWarningTest.java b/server/sonar-server/src/test/java/org/sonar/server/authentication/LogOAuthWarningTest.java
new file mode 100644 (file)
index 0000000..7fe35db
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.authentication;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.platform.Server;
+import org.sonar.api.server.authentication.OAuth2IdentityProvider;
+import org.sonar.api.utils.log.LogTester;
+import org.sonar.api.utils.log.LoggerLevel;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+
+public class LogOAuthWarningTest {
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+  @Rule
+  public LogTester logTester = new LogTester();
+
+
+  private Server server = mock(Server.class);
+
+  @Test
+  public void log_warning_at_startup_if_non_secured_base_url_and_oauth_is_installed() throws Exception {
+    when(server.getPublicRootUrl()).thenReturn("http://mydomain.com");
+
+    LogOAuthWarning underTest = new LogOAuthWarning(server, new OAuth2IdentityProvider[1]);
+
+    underTest.start();
+
+    assertThat(logTester.logs(LoggerLevel.WARN)).containsOnly("For security reasons, OAuth authentication should use HTTPS. You should set the property 'Administration > Configuration > Server base URL' to a HTTPS URL.");
+
+    underTest.stop();
+  }
+
+  @Test
+  public void do_not_log_warning_at_startup_if_secured_base_url_and_oauth_is_installed() throws Exception {
+    when(server.getPublicRootUrl()).thenReturn("https://mydomain.com");
+
+    LogOAuthWarning underTest = new LogOAuthWarning(server, new OAuth2IdentityProvider[1]);
+
+    underTest.start();
+
+    assertThat(logTester.logs(LoggerLevel.WARN)).isEmpty();
+
+    underTest.stop();
+  }
+
+  @Test
+  public void do_not_log_warning_at_startup_if_non_secured_base_url_but_oauth_is_not_installed() throws Exception {
+    when(server.getPublicRootUrl()).thenReturn("http://mydomain.com");
+
+    LogOAuthWarning underTest = new LogOAuthWarning(server);
+
+    underTest.start();
+
+    assertThat(logTester.logs(LoggerLevel.WARN)).isEmpty();
+
+    underTest.stop();
+  }
+}
index d3961427255f1f11f53263ade67a717ced26aae3..16f0c16d6d427fd8fa4ec9d3c0a9844529f58760 100644 (file)
@@ -30,8 +30,6 @@ import org.sonar.api.platform.Server;
 import org.sonar.api.server.authentication.OAuth2IdentityProvider;
 import org.sonar.api.server.authentication.UserIdentity;
 import org.sonar.api.utils.System2;
-import org.sonar.api.utils.log.LogTester;
-import org.sonar.api.utils.log.LoggerLevel;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
@@ -55,11 +53,11 @@ public class OAuth2ContextFactoryTest {
   private static final String SECURED_PUBLIC_ROOT_URL = "https://mydomain.com";
   private static final String PROVIDER_NAME = "provider name";
   private static final UserIdentity USER_IDENTITY = UserIdentity.builder()
-      .setProviderLogin("johndoo")
-      .setLogin("id:johndoo")
-      .setName("John")
-      .setEmail("john@email.com")
-      .build();
+    .setProviderLogin("johndoo")
+    .setLogin("id:johndoo")
+    .setName("John")
+    .setEmail("john@email.com")
+    .build();
 
   @Rule
   public ExpectedException thrown = ExpectedException.none();
@@ -67,9 +65,6 @@ public class OAuth2ContextFactoryTest {
   @Rule
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
 
-  @Rule
-  public LogTester logTester = new LogTester();
-
   private DbClient dbClient = dbTester.getDbClient();
   private DbSession dbSession = dbTester.getSession();
   private ThreadLocalUserSession threadLocalUserSession = mock(ThreadLocalUserSession.class);
@@ -125,16 +120,6 @@ public class OAuth2ContextFactoryTest {
     verify(response).sendRedirect("/test");
   }
 
-  @Test
-  public void display_a_warning_if_not_https() throws Exception {
-    when(server.getPublicRootUrl()).thenReturn("http://mydomain.com");
-
-    OAuth2IdentityProvider.InitContext context = newInitContext();
-
-    assertThat(context.getCallbackUrl()).isEqualTo("http://mydomain.com/oauth2/callback/github");
-    assertThat(logTester.logs(LoggerLevel.WARN)).containsOnly("For security reasons, the server URL used for OAuth authentications should be https. Please update the property 'sonar.core.serverBaseURL'.");
-  }
-
   @Test
   public void create_callback() throws Exception {
     when(server.getPublicRootUrl()).thenReturn(SECURED_PUBLIC_ROOT_URL);