]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5430 Load SSO settings only at startup 1344/head
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 28 Oct 2016 09:46:25 +0000 (11:46 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 28 Oct 2016 10:59:02 +0000 (12:59 +0200)
server/sonar-server/src/main/java/org/sonar/server/authentication/SsoAuthenticator.java
server/sonar-server/src/test/java/org/sonar/server/authentication/SsoAuthenticatorTest.java

index 17aba9a45b4b75a19bd9d916072fa2bb1bf42b9f..3eafed1f6da284c1c60aaa888c76f5fc137d2718 100644 (file)
@@ -32,12 +32,15 @@ import java.util.Optional;
 import javax.annotation.CheckForNull;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import org.sonar.api.Startable;
 import org.sonar.api.config.Settings;
 import org.sonar.api.server.authentication.Display;
 import org.sonar.api.server.authentication.IdentityProvider;
 import org.sonar.api.server.authentication.UnauthorizedException;
 import org.sonar.api.server.authentication.UserIdentity;
 import org.sonar.api.utils.System2;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.exceptions.BadRequestException;
 
@@ -45,7 +48,9 @@ import static org.apache.commons.lang.StringUtils.defaultIfBlank;
 import static org.apache.commons.lang.time.DateUtils.addMinutes;
 import static org.sonar.server.user.UserUpdater.SQ_AUTHORITY;
 
-public class SsoAuthenticator {
+public class SsoAuthenticator implements Startable {
+
+  private static final Logger LOG = Loggers.get(SsoAuthenticator.class);
 
   private static final Splitter COMA_SPLITTER = Splitter.on(",").trimResults().omitEmptyStrings();
 
@@ -68,7 +73,7 @@ public class SsoAuthenticator {
 
   private static final String LAST_REFRESH_TIME_TOKEN_PARAM = "ssoLastRefreshTime";
 
-  private static final Map<String, String> DEFAULT_VALUES_BY_PARAMETERS = ImmutableMap.of(
+  private static final Map<String, String> DEFAULT_VALUES_BY_SETTING_KEYS = ImmutableMap.of(
     LOGIN_HEADER_PARAM, LOGIN_HEADER_DEFAULT_VALUE,
     NAME_HEADER_PARAM, NAME_HEADER_DEFAULT_VALUE,
     EMAIL_HEADER_PARAM, EMAIL_HEADER_DEFAULT_VALUE,
@@ -80,6 +85,9 @@ public class SsoAuthenticator {
   private final UserIdentityAuthenticator userIdentityAuthenticator;
   private final JwtHttpHandler jwtHttpHandler;
 
+  private boolean enabled = false;
+  private Map<String, String> settingsByKey = new HashMap<>();
+
   public SsoAuthenticator(System2 system2, Settings settings, UserIdentityAuthenticator userIdentityAuthenticator, JwtHttpHandler jwtHttpHandler) {
     this.system2 = system2;
     this.settings = settings;
@@ -87,6 +95,21 @@ public class SsoAuthenticator {
     this.jwtHttpHandler = jwtHttpHandler;
   }
 
+  @Override
+  public void start() {
+    if (settings.getBoolean(ENABLE_PARAM)) {
+      LOG.info("SSO Authentication enabled");
+      enabled = true;
+      DEFAULT_VALUES_BY_SETTING_KEYS.entrySet()
+        .forEach(entry -> settingsByKey.put(entry.getKey(), defaultIfBlank(settings.getString(entry.getKey()), DEFAULT_VALUES_BY_SETTING_KEYS.get(entry.getKey()))));
+    }
+  }
+
+  @Override
+  public void stop() {
+    // Nothing to do
+  }
+
   public Optional<UserDto> authenticate(HttpServletRequest request, HttpServletResponse response) {
     try {
       return doAuthenticate(request, response);
@@ -96,7 +119,7 @@ public class SsoAuthenticator {
   }
 
   private Optional<UserDto> doAuthenticate(HttpServletRequest request, HttpServletResponse response) {
-    if (!settings.getBoolean(ENABLE_PARAM)) {
+    if (!enabled) {
       return Optional.empty();
     }
     Map<String, String> headerValuesByNames = getHeaders(request);
@@ -120,7 +143,7 @@ public class SsoAuthenticator {
       return Optional.empty();
     }
     Date now = new Date(system2.now());
-    int refreshIntervalInMinutes = Integer.parseInt(getSettingValue(REFRESH_INTERVAL_PARAM));
+    int refreshIntervalInMinutes = Integer.parseInt(settingsByKey.get(REFRESH_INTERVAL_PARAM));
     Long lastFreshTime = (Long) token.get().getProperties().get(LAST_REFRESH_TIME_TOKEN_PARAM);
     if (lastFreshTime == null || now.after(addMinutes(new Date(lastFreshTime), refreshIntervalInMinutes))) {
       return Optional.empty();
@@ -145,7 +168,7 @@ public class SsoAuthenticator {
 
   @CheckForNull
   private String getHeaderValue(Map<String, String> headerValuesByNames, String settingKey) {
-    return headerValuesByNames.get(getSettingValue(settingKey).toLowerCase(Locale.ENGLISH));
+    return headerValuesByNames.get(settingsByKey.get(settingKey).toLowerCase(Locale.ENGLISH));
   }
 
   private static Map<String, String> getHeaders(HttpServletRequest request) {
@@ -155,11 +178,7 @@ public class SsoAuthenticator {
   }
 
   private boolean hasHeader(Map<String, String> headerValuesByNames, String settingKey) {
-    return headerValuesByNames.keySet().contains(getSettingValue(settingKey).toLowerCase(Locale.ENGLISH));
-  }
-
-  private String getSettingValue(String settingKey) {
-    return defaultIfBlank(settings.getString(settingKey), DEFAULT_VALUES_BY_PARAMETERS.get(settingKey));
+    return headerValuesByNames.keySet().contains(settingsByKey.get(settingKey).toLowerCase(Locale.ENGLISH));
   }
 
   private static class SsoIdentityProvider implements IdentityProvider {
index 310f9385d11af0f0b1dd3070fcfe75d1cebeb689..7e7ae6ec728d1d16664b96d5d99702cf98e3b3b3 100644 (file)
@@ -112,7 +112,7 @@ public class SsoAuthenticatorTest {
 
   @Test
   public void create_user_when_authenticating_new_user() throws Exception {
-    enableSso();
+    startWithSso();
     setNotUserInToken();
     HttpServletRequest request = createRequest(DEFAULT_LOGIN, DEFAULT_NAME, DEFAULT_EMAIL, GROUPS);
 
@@ -124,7 +124,7 @@ public class SsoAuthenticatorTest {
 
   @Test
   public void use_login_when_name_is_not_provided() throws Exception {
-    enableSso();
+    startWithSso();
     setNotUserInToken();
 
     underTest.authenticate(createRequest(DEFAULT_LOGIN, null, null, null), response);
@@ -134,7 +134,7 @@ public class SsoAuthenticatorTest {
 
   @Test
   public void update_user_when_authenticating_exiting_user() throws Exception {
-    enableSso();
+    startWithSso();
     setNotUserInToken();
     insertUser(newUserDto().setLogin(DEFAULT_LOGIN).setName("old name").setEmail("old email"), group1);
     // Name, email and groups are different
@@ -148,7 +148,7 @@ public class SsoAuthenticatorTest {
 
   @Test
   public void remove_groups_when_group_headers_is_empty() throws Exception {
-    enableSso();
+    startWithSso();
     setNotUserInToken();
     insertUser(DEFAULT_USER, group1);
 
@@ -159,7 +159,7 @@ public class SsoAuthenticatorTest {
 
   @Test
   public void remove_groups_when_group_headers_is_null() throws Exception {
-    enableSso();
+    startWithSso();
     setNotUserInToken();
     insertUser(DEFAULT_USER, group1);
     Map<String, String> headerValuesByName = new HashMap<>();
@@ -173,7 +173,7 @@ public class SsoAuthenticatorTest {
 
   @Test
   public void does_not_update_groups_when_no_group_headers() throws Exception {
-    enableSso();
+    startWithSso();
     setNotUserInToken();
     insertUser(DEFAULT_USER, group1);
 
@@ -184,7 +184,7 @@ public class SsoAuthenticatorTest {
 
   @Test
   public void does_not_update_user_when_user_is_in_token_and_refresh_time_is_close() throws Exception {
-    enableSso();
+    startWithSso();
     UserDto user = insertUser(DEFAULT_USER, group1);
     setUserInToken(user, CLOSE_REFRESH_TIME);
     HttpServletRequest request = createRequest(DEFAULT_LOGIN, "new name", "new email", GROUP2);
@@ -198,7 +198,7 @@ public class SsoAuthenticatorTest {
 
   @Test
   public void update_user_when_user_in_token_but_refresh_time_is_old() throws Exception {
-    enableSso();
+    startWithSso();
     UserDto user = insertUser(DEFAULT_USER, group1);
     // Refresh time was updated 6 minutes ago => more than 5 minutes
     setUserInToken(user, NOW - 6 * 60 * 1000L);
@@ -213,7 +213,7 @@ public class SsoAuthenticatorTest {
 
   @Test
   public void update_user_when_user_in_token_but_no_refresh_time() throws Exception {
-    enableSso();
+    startWithSso();
     UserDto user = insertUser(DEFAULT_USER, group1);
     setUserInToken(user, null);
     HttpServletRequest request = createRequest(DEFAULT_LOGIN, "new name", "new email", GROUP2);
@@ -227,8 +227,8 @@ public class SsoAuthenticatorTest {
 
   @Test
   public void use_refresh_time_from_settings() throws Exception {
-    enableSso();
     settings.setProperty("sonar.sso.refreshIntervalInMinutes", "10");
+    startWithSso();
     UserDto user = insertUser(DEFAULT_USER, group1);
     // Refresh time was updated 6 minutes ago => less than 10 minutes ago so not updated
     setUserInToken(user, NOW - 6 * 60 * 1000L);
@@ -243,7 +243,7 @@ public class SsoAuthenticatorTest {
 
   @Test
   public void update_user_when_login_from_token_is_different_than_login_from_request() throws Exception {
-    enableSso();
+    startWithSso();
     insertUser(DEFAULT_USER, group1);
     setUserInToken(DEFAULT_USER, CLOSE_REFRESH_TIME);
     HttpServletRequest request = createRequest("AnotherLogin", "Another name", "Another email", GROUP2);
@@ -256,12 +256,12 @@ public class SsoAuthenticatorTest {
 
   @Test
   public void use_headers_from_settings() throws Exception {
-    enableSso();
-    setNotUserInToken();
     settings.setProperty("sonar.sso.loginHeader", "head-login");
     settings.setProperty("sonar.sso.nameHeader", "head-name");
     settings.setProperty("sonar.sso.emailHeader", "head-email");
     settings.setProperty("sonar.sso.groupsHeader", "head-groups");
+    startWithSso();
+    setNotUserInToken();
     HttpServletRequest request = createRequest(ImmutableMap.of("head-login", DEFAULT_LOGIN, "head-name", DEFAULT_NAME, "head-email", DEFAULT_EMAIL, "head-groups", GROUPS));
 
     underTest.authenticate(request, response);
@@ -271,12 +271,12 @@ public class SsoAuthenticatorTest {
 
   @Test
   public void detect_group_header_even_with_wrong_case() throws Exception {
-    enableSso();
-    setNotUserInToken();
     settings.setProperty("sonar.sso.loginHeader", "login");
     settings.setProperty("sonar.sso.nameHeader", "name");
     settings.setProperty("sonar.sso.emailHeader", "email");
     settings.setProperty("sonar.sso.groupsHeader", "Groups");
+    startWithSso();
+    setNotUserInToken();
     HttpServletRequest request = createRequest(ImmutableMap.of("login", DEFAULT_LOGIN, "name", DEFAULT_NAME, "email", DEFAULT_EMAIL, "groups", GROUPS));
 
     underTest.authenticate(request, response);
@@ -286,7 +286,7 @@ public class SsoAuthenticatorTest {
 
   @Test
   public void trim_groups() throws Exception {
-    enableSso();
+    startWithSso();
     setNotUserInToken();
     HttpServletRequest request = createRequest(DEFAULT_LOGIN, null, null, "  dev ,    admin ");
 
@@ -297,7 +297,7 @@ public class SsoAuthenticatorTest {
 
   @Test
   public void does_not_authenticate_when_no_header() throws Exception {
-    enableSso();
+    startWithSso();
     setNotUserInToken();
 
     underTest.authenticate(createRequest(Collections.emptyMap()), response);
@@ -308,7 +308,7 @@ public class SsoAuthenticatorTest {
 
   @Test
   public void does_not_authenticate_when_not_enabled() throws Exception {
-    settings.setProperty("sonar.sso.enable", false);
+    startWithoutSso();
 
     underTest.authenticate(createRequest(DEFAULT_LOGIN, DEFAULT_NAME, DEFAULT_EMAIL, GROUPS), response);
 
@@ -318,7 +318,7 @@ public class SsoAuthenticatorTest {
 
   @Test
   public void throw_UnauthorizedException_when_BadRequestException_is_generated() throws Exception {
-    enableSso();
+    startWithSso();
     setNotUserInToken();
 
     expectedException.expect(UnauthorizedException.class);
@@ -326,8 +326,14 @@ public class SsoAuthenticatorTest {
     underTest.authenticate(createRequest("invalid login", DEFAULT_NAME, DEFAULT_EMAIL, GROUPS), response);
   }
 
-  private void enableSso() {
+  private void startWithSso() {
     settings.setProperty("sonar.sso.enable", true);
+    underTest.start();
+  }
+
+  private void startWithoutSso() {
+    settings.setProperty("sonar.sso.enable", false);
+    underTest.start();
   }
 
   private void setUserInToken(UserDto user, @Nullable Long lastRefreshTime) {