aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2016-10-05 13:57:56 +0200
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2016-10-12 12:24:31 +0200
commitc7c271638798905934be58f81365feba904a954f (patch)
tree220f168a73079d6e3c01324c5291e434a291d190
parent9a2a008ff6fd46a758ed408f2957ac41ca5df5f0 (diff)
downloadsonarqube-c7c271638798905934be58f81365feba904a954f.tar.gz
sonarqube-c7c271638798905934be58f81365feba904a954f.zip
SONAR-8191 last root can't be unset via /api/root/unset_root
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/root/ws/UnsetRootWsAction.java4
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/root/ws/UnsetRootWsActionTest.java72
-rw-r--r--sonar-db/src/main/java/org/sonar/db/user/UserDao.java4
-rw-r--r--sonar-db/src/main/java/org/sonar/db/user/UserMapper.java6
-rw-r--r--sonar-db/src/main/resources/org/sonar/db/user/UserMapper.xml11
-rw-r--r--sonar-db/src/test/java/org/sonar/db/user/UserDaoTest.java95
6 files changed, 172 insertions, 20 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/root/ws/UnsetRootWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/root/ws/UnsetRootWsAction.java
index 1dcf2b7b5f8..880bcaeae1c 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/root/ws/UnsetRootWsAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/root/ws/UnsetRootWsAction.java
@@ -24,6 +24,7 @@ import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
+import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.user.UserSession;
public class UnsetRootWsAction implements RootWsAction {
@@ -60,6 +61,9 @@ public class UnsetRootWsAction implements RootWsAction {
String login = request.mandatoryParam(PARAM_LOGIN);
try (DbSession dbSession = dbClient.openSession(false)) {
+ if (dbClient.userDao().countRootUsersButLogin(dbSession, login) == 0) {
+ throw new BadRequestException("Last root can't be unset");
+ }
dbClient.userDao().setRoot(dbSession, login, false);
dbSession.commit();
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/root/ws/UnsetRootWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/root/ws/UnsetRootWsActionTest.java
index 140460f14c3..43c81df782a 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/root/ws/UnsetRootWsActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/root/ws/UnsetRootWsActionTest.java
@@ -29,13 +29,14 @@ import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.user.UserDao;
import org.sonar.db.user.UserDto;
-import org.sonar.db.user.UserTesting;
+import org.sonar.server.exceptions.BadRequestException;
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 static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.db.user.UserTesting.newUserDto;
public class UnsetRootWsActionTest {
private static final String SOME_LOGIN = "johndoe";
@@ -60,7 +61,7 @@ public class UnsetRootWsActionTest {
assertThat(action.isPost()).isTrue();
assertThat(action.since()).isEqualTo("6.2");
assertThat(action.description()).isEqualTo("Make the specified user not root.<br/>" +
- "Requires to be root.");
+ "Requires to be root.");
assertThat(action.responseExample()).isNull();
assertThat(action.deprecatedKey()).isNull();
assertThat(action.deprecatedSince()).isNull();
@@ -94,7 +95,7 @@ public class UnsetRootWsActionTest {
@Test
public void execute_fails_with_IAE_when_login_param_is_not_provided() {
- userSessionRule.login().setRoot();
+ makeAuthenticatedUserRoot();
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("The 'login' parameter is missing");
@@ -104,13 +105,9 @@ public class UnsetRootWsActionTest {
@Test
public void execute_makes_user_with_specified_login_not_root_when_it_is() {
- UserDto otherUser = UserTesting.newUserDto();
- userDao.insert(dbSession, otherUser);
- userDao.setRoot(dbSession, otherUser.getLogin(), true);
- userDao.insert(dbSession, UserTesting.newUserDto(SOME_LOGIN, "name", "email"));
- userDao.setRoot(dbSession, SOME_LOGIN, true);
- dbSession.commit();
- userSessionRule.login().setRoot();
+ UserDto otherUser = insertRootUser(newUserDto());
+ insertRootUser(newUserDto(SOME_LOGIN, "name", "email"));
+ makeAuthenticatedUserRoot();
executeRequest(SOME_LOGIN);
@@ -120,13 +117,9 @@ public class UnsetRootWsActionTest {
@Test
public void execute_has_no_effect_when_user_is_already_not_root() {
- UserDto otherUser = UserTesting.newUserDto();
- userDao.insert(dbSession, otherUser);
- userDao.setRoot(dbSession, otherUser.getLogin(), true);
- userDao.insert(dbSession, UserTesting.newUserDto(SOME_LOGIN, "name", "email"));
- userDao.setRoot(dbSession, SOME_LOGIN, true);
- dbSession.commit();
- userSessionRule.login().setRoot();
+ UserDto otherUser = insertRootUser(newUserDto());
+ insertNonRootUser(newUserDto(SOME_LOGIN, "name", "email"));
+ makeAuthenticatedUserRoot();
executeRequest(SOME_LOGIN);
@@ -134,6 +127,47 @@ public class UnsetRootWsActionTest {
assertThat(userDao.selectByLogin(dbSession, otherUser.getLogin()).isRoot()).isTrue();
}
+ @Test
+ public void execute_fails_with_BadRequestException_when_attempting_to_unset_root_on_last_root_user() {
+ insertRootUser(newUserDto(SOME_LOGIN, "name", "email"));
+ insertNonRootUser(newUserDto());
+ makeAuthenticatedUserRoot();
+
+ expectedException.expect(BadRequestException.class);
+ expectedException.expectMessage("Last root can't be unset");
+
+ executeRequest(SOME_LOGIN);
+ }
+
+ @Test
+ public void execute_fails_with_BadRequestException_when_attempting_to_unset_non_root_and_there_is_no_root_at_all() {
+ insertNonRootUser(newUserDto(SOME_LOGIN, "name", "email"));
+ insertNonRootUser(newUserDto());
+ makeAuthenticatedUserRoot();
+
+ expectedException.expect(BadRequestException.class);
+ expectedException.expectMessage("Last root can't be unset");
+
+ executeRequest("non_existing_user");
+ }
+
+ private UserDto insertNonRootUser(UserDto dto) {
+ userDao.insert(dbSession, dto);
+ dbSession.commit();
+ return dto;
+ }
+
+ private UserDto insertRootUser(UserDto dto) {
+ insertNonRootUser(dto);
+ userDao.setRoot(dbSession, dto.getLogin(), true);
+ dbSession.commit();
+ return dto;
+ }
+
+ private void makeAuthenticatedUserRoot() {
+ userSessionRule.login().setRoot();
+ }
+
private void expectInsufficientPrivilegesForbiddenException() {
expectedException.expect(ForbiddenException.class);
expectedException.expectMessage("Insufficient privileges");
@@ -145,8 +179,8 @@ public class UnsetRootWsActionTest {
request.setParam("login", login);
}
return request
- .execute()
- .getStatus();
+ .execute()
+ .getStatus();
}
}
diff --git a/sonar-db/src/main/java/org/sonar/db/user/UserDao.java b/sonar-db/src/main/java/org/sonar/db/user/UserDao.java
index f844726616a..5e1fe961e72 100644
--- a/sonar-db/src/main/java/org/sonar/db/user/UserDao.java
+++ b/sonar-db/src/main/java/org/sonar/db/user/UserDao.java
@@ -140,6 +140,10 @@ public class UserDao implements Dao {
return mapper.selectUsers(query);
}
+ public long countRootUsersButLogin(DbSession dbSession, String login) {
+ return getMapper(dbSession).countRootUsersButLogin(login);
+ }
+
public UserDto insert(DbSession session, UserDto dto) {
getMapper(session).insert(dto);
return dto;
diff --git a/sonar-db/src/main/java/org/sonar/db/user/UserMapper.java b/sonar-db/src/main/java/org/sonar/db/user/UserMapper.java
index b053b1f2e8b..517dc24d76d 100644
--- a/sonar-db/src/main/java/org/sonar/db/user/UserMapper.java
+++ b/sonar-db/src/main/java/org/sonar/db/user/UserMapper.java
@@ -53,6 +53,11 @@ public interface UserMapper {
long countByEmail(String email);
+ /**
+ * Count actives users which are root and which login is not the specified one.
+ */
+ long countRootUsersButLogin(@Param("login") String login);
+
void insert(UserDto userDto);
void update(UserDto userDto);
@@ -80,5 +85,4 @@ public interface UserMapper {
void deletePropertiesMatchingLogin(@Param("propertyKeys") List<String> propertyKeys, @Param("login") String login);
void deactivateUser(@Param("id") long userId, @Param("now") long now);
-
}
diff --git a/sonar-db/src/main/resources/org/sonar/db/user/UserMapper.xml b/sonar-db/src/main/resources/org/sonar/db/user/UserMapper.xml
index 66e370697b6..6de7be4b580 100644
--- a/sonar-db/src/main/resources/org/sonar/db/user/UserMapper.xml
+++ b/sonar-db/src/main/resources/org/sonar/db/user/UserMapper.xml
@@ -98,6 +98,17 @@
where lower(u.email)=#{email} AND u.active=${_true}
</select>
+ <select id="countRootUsersButLogin" parameterType="String" resultType="long">
+ select
+ count(1)
+ from
+ users u
+ where
+ u.active = ${_true}
+ and u.is_root = ${_true}
+ and u.login &lt;&gt; #{login}
+ </select>
+
<delete id="removeUserFromGroups" parameterType="long">
DELETE FROM groups_users WHERE user_id=#{id}
</delete>
diff --git a/sonar-db/src/test/java/org/sonar/db/user/UserDaoTest.java b/sonar-db/src/test/java/org/sonar/db/user/UserDaoTest.java
index fd57b852a9c..dec3ce93999 100644
--- a/sonar-db/src/test/java/org/sonar/db/user/UserDaoTest.java
+++ b/sonar-db/src/test/java/org/sonar/db/user/UserDaoTest.java
@@ -193,6 +193,101 @@ public class UserDaoTest {
}
@Test
+ public void countRootUsersButLogin_returns_0_when_there_is_no_user_at_all() {
+ assertThat(underTest.countRootUsersButLogin(session, "bla")).isEqualTo(0);
+ }
+
+ @Test
+ public void countRootUsersButLogin_returns_0_when_there_is_no_root() {
+ underTest.insert(session, newUserDto());
+ session.commit();
+
+ assertThat(underTest.countRootUsersButLogin(session, "bla")).isEqualTo(0);
+ }
+
+ @Test
+ public void countRootUsersButLogin_returns_0_when_there_is_no_active_root() {
+ insertNonRootUser(newUserDto());
+ insertInactiveRootUser(newUserDto());
+ session.commit();
+
+ assertThat(underTest.countRootUsersButLogin(session, "bla")).isEqualTo(0);
+ }
+
+ @Test
+ public void countRootUsersButLogin_returns_count_of_all_active_roots_when_there_specified_login_does_not_exist() {
+ insertRootUser(newUserDto());
+ insertNonRootUser(newUserDto());
+ insertRootUser(newUserDto());
+ insertRootUser(newUserDto());
+ insertInactiveRootUser(newUserDto());
+ insertInactiveRootUser(newUserDto());
+ session.commit();
+
+ assertThat(underTest.countRootUsersButLogin(session, "bla")).isEqualTo(3);
+ }
+
+ @Test
+ public void countRootUsersButLogin_returns_count_of_all_active_roots_when_specified_login_is_not_root() {
+ insertRootUser(newUserDto());
+ String login = insertNonRootUser(newUserDto()).getLogin();
+ insertRootUser(newUserDto());
+ insertRootUser(newUserDto());
+ insertInactiveRootUser(newUserDto());
+ insertInactiveRootUser(newUserDto());
+ session.commit();
+
+ assertThat(underTest.countRootUsersButLogin(session, login)).isEqualTo(3);
+ }
+
+ @Test
+ public void countRootUsersButLogin_returns_count_of_all_active_roots_when_specified_login_is_inactive_root() {
+ insertRootUser(newUserDto());
+ insertNonRootUser(newUserDto());
+ insertRootUser(newUserDto());
+ insertRootUser(newUserDto());
+ String inactiveRootLogin = insertInactiveRootUser(newUserDto()).getLogin();
+ insertInactiveRootUser(newUserDto());
+ session.commit();
+
+ assertThat(underTest.countRootUsersButLogin(session, inactiveRootLogin)).isEqualTo(3);
+ }
+
+ @Test
+ public void countRootUsersButLogin_returns_count_of_all_active_roots_minus_one_when_specified_login_is_active_root() {
+ insertRootUser(newUserDto());
+ insertNonRootUser(newUserDto());
+ insertRootUser(newUserDto());
+ String rootLogin = insertRootUser(newUserDto()).getLogin();
+ insertInactiveRootUser(newUserDto());
+ insertInactiveRootUser(newUserDto());
+ session.commit();
+
+ assertThat(underTest.countRootUsersButLogin(session, rootLogin)).isEqualTo(2);
+ }
+
+ private UserDto insertInactiveRootUser(UserDto dto) {
+ insertRootUser(dto);
+ dto.setActive(false);
+ underTest.update(session, dto);
+ session.commit();
+ return dto;
+ }
+
+ private UserDto insertRootUser(UserDto dto) {
+ underTest.insert(session, dto);
+ underTest.setRoot(session, dto.getLogin(), true);
+ session.commit();
+ return dto;
+ }
+
+ private UserDto insertNonRootUser(UserDto dto) {
+ underTest.insert(session, dto);
+ session.commit();
+ return dto;
+ }
+
+ @Test
public void insert_user() {
Long date = DateUtils.parseDate("2014-06-20").getTime();