]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7448 Add ITs 848/head
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 22 Mar 2016 11:48:42 +0000 (12:48 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 22 Mar 2016 13:15:27 +0000 (14:15 +0100)
it/it-plugins/base-auth-plugin/pom.xml
it/it-plugins/base-auth-plugin/src/main/java/FakeBaseIdProvider.java
it/it-tests/src/test/java/it/user/BaseIdentityProviderTest.java
it/it-tests/src/test/java/util/user/Groups.java [new file with mode: 0644]
it/it-tests/src/test/java/util/user/UserRule.java

index 7c1077d65dac315529043aa03179a062354f5982..4e2f631194de44e516a958c4899922223f789232 100644 (file)
       <version>3.0.1</version>
       <scope>provided</scope>
     </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <version>17.0</version>
+      <exclusions>
+        <exclusion>
+          <!-- should be declared with scope provided -->
+          <groupId>com.google.code.findbugs</groupId>
+          <artifactId>jsr305</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
   </dependencies>
 
   <build>
index a7d897b137fbe67f91eeaeeb4bba922dec63c452..6a915d32b6527bb01c4485e83feaec2ae6d0a04c 100644 (file)
@@ -24,10 +24,15 @@ import org.sonar.api.server.authentication.Display;
 import org.sonar.api.server.authentication.UnauthorizedException;
 import org.sonar.api.server.authentication.UserIdentity;
 
+import static com.google.common.collect.Sets.newHashSet;
+
 public class FakeBaseIdProvider implements BaseIdentityProvider {
 
   private static final String ENABLED = "sonar.auth.fake-base-id-provider.enabled";
   private static final String ALLOWS_USERS_TO_SIGN_UP = "sonar.auth.fake-base-id-provider.allowsUsersToSignUp";
+  private static final String ENABLED_GROUPS_SYNC = "sonar.auth.fake-base-id-provider.enabledGroupsSync";
+  private static final String GROUPS = "sonar.auth.fake-base-id-provider.groups";
+
   private static final String USER_INFO = "sonar.auth.fake-base-id-provider.user";
 
   private static final String THROW_UNAUTHORIZED_EXCEPTION = "sonar.auth.fake-base-id-provider.throwUnauthorizedMessage";
@@ -50,13 +55,17 @@ public class FakeBaseIdProvider implements BaseIdentityProvider {
     }
 
     String[] userInfos = userInfoProperty.split(",");
-    context.authenticate(UserIdentity.builder()
+    UserIdentity.Builder builder = UserIdentity.builder()
       .setLogin(userInfos[0])
       .setProviderLogin(userInfos[1])
       .setName(userInfos[2])
-      .setEmail(userInfos[3])
-      .build());
+      .setEmail(userInfos[3]);
+
+    if (settings.getBoolean(ENABLED_GROUPS_SYNC)) {
+      builder.setGroups(newHashSet(settings.getStringArray(GROUPS)));
+    }
 
+    context.authenticate(builder.build());
     try {
       context.getResponse().sendRedirect("/");
     } catch (IOException e) {
index 734cda3c3a2d2e54ac5dcbd7385931a6829d8bca..0c30d4471b65a7e33386fd5b65d7b7f70eb3aabc 100644 (file)
@@ -19,6 +19,7 @@
  */
 package it.user;
 
+import com.google.common.base.Joiner;
 import com.google.common.base.Optional;
 import com.sonar.orchestrator.Orchestrator;
 import com.sonar.orchestrator.selenium.Selenese;
@@ -66,6 +67,10 @@ public class BaseIdentityProviderTest {
   static String USER_NAME_UPDATED = "John Doe";
   static String USER_EMAIL_UPDATED = "john.doe@email.com";
 
+  static String GROUP1 = "group1";
+  static String GROUP2 = "group2";
+  static String GROUP3 = "group3";
+
   static WsClient adminWsClient;
 
   @BeforeClass
@@ -75,11 +80,14 @@ public class BaseIdentityProviderTest {
   }
 
   @After
-  public void removeUserAndCleanPluginProperties() throws Exception {
+  public void cleanUpUsersAndGroupsAndProperties() throws Exception {
     userRule.deactivateUsers(USER_LOGIN);
+    userRule.removeGroups(GROUP1, GROUP2, GROUP3);
     setServerProperty(ORCHESTRATOR, "sonar.auth.fake-base-id-provider.enabled", null);
     setServerProperty(ORCHESTRATOR, "sonar.auth.fake-base-id-provider.user", null);
     setServerProperty(ORCHESTRATOR, "sonar.auth.fake-base-id-provider.throwUnauthorizedMessage", null);
+    setServerProperty(ORCHESTRATOR, "sonar.auth.fake-base-id-provider.enabledGroupsSync", null);
+    setServerProperty(ORCHESTRATOR, "sonar.auth.fake-base-id-provider.groups", null);
   }
 
   @Test
@@ -200,18 +208,70 @@ public class BaseIdentityProviderTest {
     userRule.verifyUserDoesNotExist(USER_LOGIN);
   }
 
+  @Test
+  public void synchronize_groups_for_new_user() throws Exception {
+    enablePlugin();
+    userRule.createGroup(GROUP1);
+    userRule.createGroup(GROUP2);
+    setUserCreatedByAuthPlugin(USER_LOGIN, USER_PROVIDER_ID, USER_NAME, USER_EMAIL);
+    // Group3 doesn't exist in DB, user won't belong to this group
+    setGroupsReturnedByAuthPlugin(GROUP1, GROUP2, GROUP3);
+
+    authenticateWithFakeAuthProvider();
+
+    userRule.verifyUserGroupMembership(USER_LOGIN, GROUP1, GROUP2);
+  }
+
+  @Test
+  public void synchronize_groups_for_existing_user() throws Exception {
+    enablePlugin();
+    userRule.createGroup(GROUP1);
+    userRule.createGroup(GROUP2);
+    userRule.createGroup(GROUP3);
+    userRule.createUser(USER_LOGIN, "password");
+    userRule.associateGroupsToUser(USER_LOGIN, GROUP1, GROUP2);
+    setUserCreatedByAuthPlugin(USER_LOGIN, USER_PROVIDER_ID, USER_NAME, USER_EMAIL);
+    // Group1 is not returned by the plugin, user won't belong anymore to this group
+    setGroupsReturnedByAuthPlugin(GROUP2, GROUP3);
+
+    authenticateWithFakeAuthProvider();
+
+    userRule.verifyUserGroupMembership(USER_LOGIN, GROUP2, GROUP3);
+  }
+
+  @Test
+  public void remove_user_groups_when_groups_provided_by_plugin_are_empty() throws Exception {
+    enablePlugin();
+    userRule.createGroup(GROUP1);
+    userRule.createUser(USER_LOGIN, "password");
+    userRule.associateGroupsToUser(USER_LOGIN, GROUP1);
+    setUserCreatedByAuthPlugin(USER_LOGIN, USER_PROVIDER_ID, USER_NAME, USER_EMAIL);
+    // No group is returned by the plugin
+    setGroupsReturnedByAuthPlugin();
+
+    authenticateWithFakeAuthProvider();
+
+    // User is not member to any group
+    userRule.verifyUserGroupMembership(USER_LOGIN);
+  }
+
+  private static void enablePlugin() {
+    setServerProperty(ORCHESTRATOR, "sonar.auth.fake-base-id-provider.enabled", "true");
+  }
+
   private static void setUserCreatedByAuthPlugin(String login, String providerId, String name, String email) {
     setServerProperty(ORCHESTRATOR, "sonar.auth.fake-base-id-provider.user", login + "," + providerId + "," + name + "," + email);
   }
 
+  private static void setGroupsReturnedByAuthPlugin(String... groups) {
+    setServerProperty(ORCHESTRATOR, "sonar.auth.fake-base-id-provider.enabledGroupsSync", "true");
+    setServerProperty(ORCHESTRATOR, "sonar.auth.fake-base-id-provider.groups", Joiner.on(",").join(groups));
+  }
+
   private static void authenticateWithFakeAuthProvider() {
     WsResponse response = adminWsClient.wsConnector().call(
       new GetRequest(("/sessions/init/" + FAKE_PROVIDER_KEY)));
     assertThat(response.code()).isEqualTo(200);
   }
 
-  private static void enablePlugin() {
-    setServerProperty(ORCHESTRATOR, "sonar.auth.fake-base-id-provider.enabled", "true");
-  }
-
 }
diff --git a/it/it-tests/src/test/java/util/user/Groups.java b/it/it-tests/src/test/java/util/user/Groups.java
new file mode 100644 (file)
index 0000000..34f64b9
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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 util.user;
+
+import com.google.gson.Gson;
+import java.util.List;
+
+public class Groups {
+
+  private List<Group> groups;
+
+  private Groups(List<Group> groups) {
+    this.groups = groups;
+  }
+
+  public List<Group> getGroups() {
+    return groups;
+  }
+
+  public static Groups parse(String json) {
+    Gson gson = new Gson();
+    return gson.fromJson(json, Groups.class);
+  }
+
+  public static class Group {
+    private final String name;
+
+    private Group(String name) {
+      this.name = name;
+    }
+
+    public String getName() {
+      return name;
+    }
+  }
+}
index c1560a2c0f4e37c5033f086a6ec1ad186a5e8eca..422863bc099b6c4e5465b3fe22b7427f3a493ae3 100644 (file)
@@ -19,6 +19,7 @@
  */
 package util.user;
 
+import com.google.common.base.Function;
 import com.google.common.base.Optional;
 import com.google.common.base.Predicate;
 import com.google.common.collect.FluentIterable;
@@ -26,7 +27,6 @@ import com.sonar.orchestrator.Orchestrator;
 import java.util.List;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
-import org.assertj.core.api.Assertions;
 import org.junit.rules.ExternalResource;
 import org.sonarqube.ws.client.GetRequest;
 import org.sonarqube.ws.client.PostRequest;
@@ -35,6 +35,7 @@ import org.sonarqube.ws.client.WsResponse;
 
 import static java.util.Arrays.asList;
 import static java.util.Objects.requireNonNull;
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.guava.api.Assertions.assertThat;
 import static util.ItUtils.newAdminWsClient;
 
@@ -52,6 +53,10 @@ public class UserRule extends ExternalResource {
     return new UserRule(requireNonNull(orchestrator, "Orchestrator instance can not be null"));
   }
 
+  // *****************
+  // Users
+  // *****************
+
   public void resetUsers() {
     for (Users.User user : getUsers().getUsers()) {
       String userLogin = user.getLogin();
@@ -61,25 +66,18 @@ public class UserRule extends ExternalResource {
     }
   }
 
-  private WsClient adminWsClient() {
-    if (adminWsClient == null) {
-      adminWsClient = newAdminWsClient(orchestrator);
-    }
-    return adminWsClient;
-  }
-
   public Users.User verifyUserExists(String login, String name, @Nullable String email) {
     Optional<Users.User> user = getUserByLogin(login);
     assertThat(user).as("User with login '%s' hasn't been found", login).isPresent();
-    Assertions.assertThat(user.get().getLogin()).isEqualTo(login);
-    Assertions.assertThat(user.get().getName()).isEqualTo(name);
-    Assertions.assertThat(user.get().getEmail()).isEqualTo(email);
+    assertThat(user.get().getLogin()).isEqualTo(login);
+    assertThat(user.get().getName()).isEqualTo(name);
+    assertThat(user.get().getEmail()).isEqualTo(email);
     return user.get();
   }
 
   public void verifyUserExists(String login, String name, @Nullable String email, boolean local) {
     Users.User user = verifyUserExists(login, name, email);
-    Assertions.assertThat(user.isLocal()).isEqualTo(local);
+    assertThat(user.isLocal()).isEqualTo(local);
   }
 
   public void verifyUserDoesNotExist(String login) {
@@ -106,7 +104,7 @@ public class UserRule extends ExternalResource {
   public Users getUsers() {
     WsResponse response = adminWsClient().wsConnector().call(
       new GetRequest("api/users/search"));
-    Assertions.assertThat(response.code()).isEqualTo(200);
+    assertThat(response.code()).isEqualTo(200);
     return Users.parse(response.content());
   }
 
@@ -124,6 +122,78 @@ public class UserRule extends ExternalResource {
     deactivateUsers(asList(userLogins));
   }
 
+  // *****************
+  // User groups
+  // *****************
+
+  public void createGroup(String name) {
+    createGroup(name, null);
+  }
+
+  public void createGroup(String name, @Nullable String description) {
+    adminWsClient().wsConnector().call(
+      new PostRequest("api/user_groups/create")
+        .setParam("name", name)
+        .setParam("description", description));
+  }
+
+  public void removeGroups(List<String> groupNames) {
+    for (String groupName : groupNames) {
+      if (getGroupByName(groupName).isPresent()) {
+        adminWsClient().wsConnector().call(
+          new PostRequest("api/user_groups/delete")
+            .setParam("name", groupName));
+      }
+    }
+  }
+
+  public void removeGroups(String... groupNames) {
+    removeGroups(asList(groupNames));
+  }
+
+  public Optional<Groups.Group> getGroupByName(String name) {
+    return FluentIterable.from(getGroups().getGroups()).firstMatch(new MatchGroupName(name));
+  }
+
+  public Groups getGroups() {
+    WsResponse response = adminWsClient().wsConnector().call(
+      new GetRequest("api/user_groups/search"));
+    assertThat(response.code()).isEqualTo(200);
+    return Groups.parse(response.content());
+  }
+
+  public void verifyUserGroupMembership(String userLogin, String... groups) {
+    Groups userGroup = getUserGroups(userLogin);
+    List<String> userGroupName = FluentIterable.from(userGroup.getGroups()).transform(ToGroupName.INSTANCE).toList();
+    assertThat(userGroupName).containsOnly(groups);
+  }
+
+  public Groups getUserGroups(String userLogin) {
+    WsResponse response = adminWsClient().wsConnector().call(
+      new GetRequest("api/users/groups")
+        .setParam("login", userLogin)
+        .setParam("selected", "selected"));
+    assertThat(response.code()).isEqualTo(200);
+    return Groups.parse(response.content());
+  }
+
+  public void associateGroupsToUser(String userLogin, String... groups) {
+    for (String group : groups) {
+      WsResponse response = adminWsClient().wsConnector().call(
+        new PostRequest("api/user_groups/add_user")
+          .setParam("login", userLogin)
+          .setParam("name", group));
+      assertThat(response.code()).isEqualTo(204);
+    }
+  }
+
+  private WsClient adminWsClient() {
+    if (adminWsClient == null) {
+      adminWsClient = newAdminWsClient(orchestrator);
+    }
+    return adminWsClient;
+  }
+
   private class MatchUserLogin implements Predicate<Users.User> {
     private final String login;
 
@@ -137,4 +207,27 @@ public class UserRule extends ExternalResource {
       return login != null && login.equals(this.login) && user.isActive();
     }
   }
+
+  private class MatchGroupName implements Predicate<Groups.Group> {
+    private final String groupName;
+
+    private MatchGroupName(String groupName) {
+      this.groupName = groupName;
+    }
+
+    @Override
+    public boolean apply(@Nonnull Groups.Group group) {
+      String groupName = group.getName();
+      return groupName != null && groupName.equals(this.groupName);
+    }
+  }
+
+  private enum ToGroupName implements Function<Groups.Group, String> {
+    INSTANCE;
+
+    @Override
+    public String apply(@Nonnull Groups.Group group) {
+      return group.getName();
+    }
+  }
 }