/*
* 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 util.user;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.sonar.orchestrator.Orchestrator;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.junit.rules.ExternalResource;
import org.sonarqube.ws.client.GetRequest;
import org.sonarqube.ws.client.PostRequest;
import org.sonarqube.ws.client.WsClient;
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;
public class UserRule extends ExternalResource implements GroupManagement {
public static final String ADMIN_LOGIN = "admin";
private final Orchestrator orchestrator;
private WsClient adminWsClient;
private final GroupManagement defaultOrganizationGroupManagement;
private UserRule(Orchestrator orchestrator) {
this.orchestrator = orchestrator;
this.defaultOrganizationGroupManagement = new GroupManagementImpl(null);
}
public static UserRule from(Orchestrator orchestrator) {
return new UserRule(requireNonNull(orchestrator, "Orchestrator instance cannot be null"));
}
// *****************
// Users
// *****************
public void resetUsers() {
for (Users.User user : getUsers().getUsers()) {
String userLogin = user.getLogin();
if (!userLogin.equals(ADMIN_LOGIN)) {
deactivateUsers(userLogin);
}
}
}
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();
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);
assertThat(user.isLocal()).isEqualTo(local);
}
public void verifyUserDoesNotExist(String login) {
assertThat(getUserByLogin(login)).as("Unexpected user with login '%s' has been found", login).isAbsent();
}
public void createUser(String login, String name, @Nullable String email, String password) {
adminWsClient().wsConnector().call(
new PostRequest("api/users/create")
.setParam("login", login)
.setParam("name", name)
.setParam("email", email)
.setParam("password", password))
.failIfNotSuccessful();
}
public void createUser(String login, String password) {
createUser(login, login, null, password);
}
public void setRoot(String login) {
adminWsClient().rootService().setRoot(login);
}
public void unsetRoot(String login) {
adminWsClient().rootService().unsetRoot(login);
}
public Optional<Users.User> getUserByLogin(String login) {
return FluentIterable.from(getUsers().getUsers()).firstMatch(new MatchUserLogin(login));
}
public Users getUsers() {
WsResponse response = adminWsClient().wsConnector().call(
new GetRequest("api/users/search"))
.failIfNotSuccessful();
return Users.parse(response.content());
}
public void deactivateUsers(List<String> userLogins) {
for (String userLogin : userLogins) {
if (getUserByLogin(userLogin).isPresent()) {
adminWsClient().wsConnector().call(new PostRequest("api/users/deactivate").setParam("login", userLogin)).failIfNotSuccessful();
}
}
}
public void deactivateUsers(String... userLogins) {
deactivateUsers(asList(userLogins));
}
// *****************
// User groups
// *****************
public GroupManagement forOrganization(String organizationKey) {
return new GroupManagementImpl(organizationKey);
}
private final class GroupManagementImpl implements GroupManagement {
@CheckForNull
private final String organizationKey;
private GroupManagementImpl(@Nullable String organizationKey) {
this.organizationKey = organizationKey;
}
@Override
public void createGroup(String name) {
createGroup(name, null);
}
@Override
public void createGroup(String name, @Nullable String description) {
PostRequest request = new PostRequest("api/user_groups/create")
.setParam("name", name)
.setParam("description", description);
addOrganizationParam(request);
adminWsClient().wsConnector().call(request).failIfNotSuccessful();
}
private void addOrganizationParam(PostRequest request) {
if (organizationKey != null) {
request.setParam("organization", organizationKey);
}
}
private void addOrganizationParam(GetRequest request) {
if (organizationKey != null) {
request.setParam("organization", organizationKey);
}
}
@Override
public void removeGroups(List<String> groupNames) {
for (String groupName : groupNames) {
if (getGroupByName(groupName).isPresent()) {
PostRequest request = new PostRequest("api/user_groups/delete")
.setParam("name", groupName);
addOrganizationParam(request);
adminWsClient().wsConnector().call(request).failIfNotSuccessful();
}
}
}
@Override
public void removeGroups(String... groupNames) {
removeGroups(asList(groupNames));
}
@Override
public java.util.Optional<Groups.Group> getGroupByName(String name) {
return getGroups().getGroups().stream().filter(new MatchGroupName(name)::apply).findFirst();
}
@Override
public Groups getGroups() {
GetRequest request = new GetRequest("api/user_groups/search");
addOrganizationParam(request);
WsResponse response = adminWsClient().wsConnector().call(request).failIfNotSuccessful();
return Groups.parse(response.content());
}
@Override
public void verifyUserGroupMembership(String userLogin, String... expectedGroups) {
Groups userGroup = getUserGroups(userLogin);
List<String> userGroupName = userGroup.getGroups().stream().map(Groups.Group::getName).collect(Collectors.toList());
assertThat(userGroupName).containsOnly(expectedGroups);
}
@Override
public Groups getUserGroups(String userLogin) {
GetRequest request = new GetRequest("api/users/groups")
.setParam("login", userLogin)
.setParam("selected", "selected");
addOrganizationParam(request);
WsResponse response = adminWsClient().wsConnector().call(request).failIfNotSuccessful();
return Groups.parse(response.content());
}
@Override
public void associateGroupsToUser(String userLogin, String... groups) {
for (String group : groups) {
PostRequest request = new PostRequest("api/user_groups/add_user")
.setParam("login", userLogin)
.setParam("name", group);
addOrganizationParam(request);
adminWsClient().wsConnector().call(request).failIfNotSuccessful();
}
}
}
@Override
public void createGroup(String name) {
defaultOrganizationGroupManagement.createGroup(name);
}
@Override
public void createGroup(String name, @Nullable String description) {
defaultOrganizationGroupManagement.createGroup(name, description);
}
@Override
public void removeGroups(List<String> groupNames) {
defaultOrganizationGroupManagement.removeGroups(groupNames);
}
@Override
public void removeGroups(String... groupNames) {
defaultOrganizationGroupManagement.removeGroups(groupNames);
}
@Override
public java.util.Optional<Groups.Group> getGroupByName(String name) {
return defaultOrganizationGroupManagement.getGroupByName(name);
}
@Override
public Groups getGroups() {
return defaultOrganizationGroupManagement.getGroups();
}
@Override
public void verifyUserGroupMembership(String userLogin, String... groups) {
defaultOrganizationGroupManagement.verifyUserGroupMembership(userLogin, groups);
}
@Override
public Groups getUserGroups(String userLogin) {
return defaultOrganizationGroupManagement.getUserGroups(userLogin);
}
@Override
public void associateGroupsToUser(String userLogin, String... groups) {
defaultOrganizationGroupManagement.associateGroupsToUser(userLogin, groups);
}
private WsClient adminWsClient() {
if (adminWsClient == null) {
adminWsClient = newAdminWsClient(orchestrator);
}
return adminWsClient;
}
private class MatchUserLogin implements Predicate<Users.User> {
private final String login;
private MatchUserLogin(String login) {
this.login = login;
}
@Override
public boolean apply(@Nonnull Users.User user) {
String login = user.getLogin();
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);
}
}
}