Skip to content

Commit

Permalink
SONAR-6474 New WS to delete a group
Browse files Browse the repository at this point in the history
  • Loading branch information
jblievremont committed May 27, 2015
1 parent 98c5128 commit b24b0f1
Show file tree
Hide file tree
Showing 28 changed files with 538 additions and 79 deletions.
Expand Up @@ -19,10 +19,17 @@
*/
package org.sonar.server.db;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.IdentityHashMap;
import java.util.Map;
import org.sonar.api.server.ServerSide;
import org.sonar.core.issue.db.ActionPlanDao;
import org.sonar.core.issue.db.IssueChangeDao;
import org.sonar.core.issue.db.IssueFilterDao;
import org.sonar.core.permission.PermissionTemplateDao;
import org.sonar.core.persistence.DaoComponent;
import org.sonar.core.persistence.Database;
import org.sonar.core.persistence.DbSession;
Expand All @@ -36,6 +43,7 @@
import org.sonar.core.user.AuthorDao;
import org.sonar.core.user.AuthorizationDao;
import org.sonar.core.user.GroupMembershipDao;
import org.sonar.core.user.RoleDao;
import org.sonar.server.activity.db.ActivityDao;
import org.sonar.server.component.db.ComponentDao;
import org.sonar.server.component.db.ComponentIndexDao;
Expand All @@ -56,13 +64,6 @@
import org.sonar.server.user.db.UserDao;
import org.sonar.server.user.db.UserGroupDao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.IdentityHashMap;
import java.util.Map;

/**
* Facade for all db components, mainly DAOs
*/
Expand All @@ -88,6 +89,8 @@ public class DbClient {
private final GroupDao groupDao;
private final UserGroupDao userGroupDao;
private final GroupMembershipDao groupMembershipDao;
private final RoleDao roleDao;
private final PermissionTemplateDao permissionTemplateDao;
private final IssueDao issueDao;
private final IssueFilterDao issueFilterDao;
private final IssueChangeDao issueChangeDao;
Expand Down Expand Up @@ -128,6 +131,8 @@ public DbClient(Database db, MyBatis myBatis, DaoComponent... daoComponents) {
groupDao = getDao(map, GroupDao.class);
userGroupDao = getDao(map, UserGroupDao.class);
groupMembershipDao = getDao(map, GroupMembershipDao.class);
roleDao = getDao(map, RoleDao.class);
permissionTemplateDao = getDao(map, PermissionTemplateDao.class);
issueDao = getDao(map, IssueDao.class);
issueFilterDao = getDao(map, IssueFilterDao.class);
issueChangeDao = getDao(map, IssueChangeDao.class);
Expand Down Expand Up @@ -232,6 +237,14 @@ public GroupMembershipDao groupMembershipDao() {
return groupMembershipDao;
}

public RoleDao roleDao() {
return roleDao;
}

public PermissionTemplateDao permissionTemplateDao() {
return permissionTemplateDao;
}

public ActionPlanDao actionPlanDao() {
return actionPlanDao;
}
Expand Down
Expand Up @@ -19,6 +19,7 @@
*/
package org.sonar.server.platform.platformlevel;

import java.util.List;
import org.sonar.api.config.EmailSettings;
import org.sonar.api.issue.action.Actions;
import org.sonar.api.profiles.AnnotationProfileParser;
Expand Down Expand Up @@ -290,8 +291,6 @@
import org.sonar.server.ws.ListingWs;
import org.sonar.server.ws.WebServiceEngine;

import java.util.List;

public class PlatformLevel4 extends PlatformLevel {

private final List<Object> level4AddedComponents;
Expand Down Expand Up @@ -498,6 +497,7 @@ public PlatformLevel configure() {
UserGroupsWs.class,
org.sonar.server.usergroups.ws.SearchAction.class,
org.sonar.server.usergroups.ws.CreateAction.class,
org.sonar.server.usergroups.ws.DeleteAction.class,

// permissions
PermissionFacade.class,
Expand Down
Expand Up @@ -22,6 +22,7 @@

import java.util.Date;
import java.util.List;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.session.RowBounds;
Expand All @@ -30,6 +31,7 @@
import org.sonar.core.persistence.DbSession;
import org.sonar.core.user.GroupDto;
import org.sonar.core.user.GroupMapper;
import org.sonar.server.exceptions.NotFoundException;

/**
* @since 3.2
Expand All @@ -44,9 +46,27 @@ public GroupDao(System2 system) {
}

public GroupDto selectByKey(DbSession session, String key) {
GroupDto group = selectNullableByKey(session, key);
if (group == null) {
throw new NotFoundException(String.format("Could not find a group with name '%s'", key));
}
return group;
}

@CheckForNull
public GroupDto selectNullableByKey(DbSession session, String key) {
return mapper(session).selectByKey(key);
}

@CheckForNull
public GroupDto selectById(DbSession dbSession, long groupId) {
return mapper(dbSession).selectById(groupId);
}

public void deleteById(DbSession dbSession, long groupId) {
mapper(dbSession).deleteById(groupId);
}

public int countByQuery(DbSession session, @Nullable String query) {
return mapper(session).countByQuery(groupSearchToSql(query));
}
Expand Down
Expand Up @@ -32,6 +32,14 @@ public UserGroupDto insert(DbSession session, UserGroupDto dto) {
return dto;
}

public void delete(DbSession session, UserGroupDto dto) {
mapper(session).delete(dto);
}

public void deleteMembersByGroupId(DbSession session, long groupId) {
mapper(session).deleteMembersByGroup(groupId);
}

protected UserGroupMapper mapper(DbSession session) {
return session.getMapper(UserGroupMapper.class);
}
Expand Down
Expand Up @@ -121,7 +121,7 @@ private void checkNameIsUnique(String name, DbSession session) {
// There is no database constraint on column groups.name
// because MySQL cannot create a unique index
// on a UTF-8 VARCHAR larger than 255 characters on InnoDB
if (dbClient.groupDao().selectByKey(session, name) != null) {
if (dbClient.groupDao().selectNullableByKey(session, name) != null) {
throw new ServerException(HttpURLConnection.HTTP_CONFLICT, String.format("Name '%s' is already taken", name));
}
}
Expand Down
@@ -0,0 +1,107 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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.usergroups.ws;

import com.google.common.base.Preconditions;
import org.sonar.api.CoreProperties;
import org.sonar.api.config.Settings;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService.NewController;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.core.user.GroupDto;
import org.sonar.server.db.DbClient;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.user.UserSession;

public class DeleteAction implements UserGroupsWsAction {

private static final String PARAM_ID = "id";

private final DbClient dbClient;
private final UserSession userSession;
private final Settings settings;

public DeleteAction(DbClient dbClient, UserSession userSession, Settings settings) {
this.dbClient = dbClient;
this.userSession = userSession;
this.settings = settings;
}

@Override
public void define(NewController context) {
context.createAction("delete")
.setDescription("Delete a group. The default group cannot be deleted. Requires System Administrator permission.")
.setHandler(this)
.setSince("5.2")
.setPost(true)
.createParam(PARAM_ID)
.setDescription("ID of the group to delete.")
.setRequired(true);
}

@Override
public void handle(Request request, Response response) throws Exception {
userSession.checkLoggedIn().checkGlobalPermission(GlobalPermissions.SYSTEM_ADMIN);

long groupId = request.mandatoryParamAsLong(PARAM_ID);


DbSession dbSession = dbClient.openSession(false);
try {
if (dbClient.groupDao().selectById(dbSession, groupId) == null) {
throw new NotFoundException(String.format("Could not find a group with id=%d", groupId));
}

checkNotTryingToDeleteDefaultGroup(dbSession, groupId);

removeGroupMembers(groupId, dbSession);
removeGroupPermissions(groupId, dbSession);
removeFromPermissionTemplates(groupId, dbSession);
dbClient.groupDao().deleteById(dbSession, groupId);

dbSession.commit();
response.noContent();
} finally {
MyBatis.closeQuietly(dbSession);
}
}

private void checkNotTryingToDeleteDefaultGroup(DbSession dbSession, long groupId) {
String defaultGroupName = settings.getString(CoreProperties.CORE_DEFAULT_GROUP);
GroupDto defaultGroup = dbClient.groupDao().selectByKey(dbSession, defaultGroupName);
Preconditions.checkArgument(groupId != defaultGroup.getId(),
String.format("Default group '%s' cannot be deleted", defaultGroupName));
}

private void removeGroupMembers(long groupId, DbSession dbSession) {
dbClient.userGroupDao().deleteMembersByGroupId(dbSession, groupId);
}

private void removeGroupPermissions(long groupId, DbSession dbSession) {
dbClient.roleDao().deleteGroupRolesByGroupId(dbSession, groupId);
}

private void removeFromPermissionTemplates(long groupId, DbSession dbSession) {
dbClient.permissionTemplateDao().removeByGroup(groupId, dbSession);
}
}
Expand Up @@ -72,6 +72,19 @@ public void select_by_key() {
assertThat(group.getUpdatedAt()).isEqualTo(DateUtils.parseDate("2014-09-08"));
}

@Test
public void select_by_id() {
dbTester.prepareDbUnit(getClass(), "select_by_key.xml");

GroupDto group = new GroupDao(system2).selectById(session, 1L);
assertThat(group).isNotNull();
assertThat(group.getId()).isEqualTo(1L);
assertThat(group.getName()).isEqualTo("sonar-users");
assertThat(group.getDescription()).isEqualTo("Sonar Users");
assertThat(group.getCreatedAt()).isEqualTo(DateUtils.parseDate("2014-09-07"));
assertThat(group.getUpdatedAt()).isEqualTo(DateUtils.parseDate("2014-09-08"));
}

@Test
public void find_by_user_login() {
dbTester.prepareDbUnit(getClass(), "find_by_user_login.xml");
Expand Down Expand Up @@ -144,4 +157,16 @@ public void count_by_query() {
// Filter on name
assertThat(new GroupDao(system2).countByQuery(session, "sonar")).isEqualTo(2);
}

@Test
public void delete_by_id() {
dbTester.prepareDbUnit(getClass(), "select_by_key.xml");

GroupDao groupDao = new GroupDao(system2);
groupDao.deleteById(session, 1L);
session.commit();

assertThat(groupDao.countByQuery(session, null)).isZero();
}

}
Expand Up @@ -59,4 +59,12 @@ public void insert() {

db.assertDbUnit(getClass(), "insert-result.xml", "groups_users");
}

@Test
public void delete_members_by_group_id() {
db.prepareDbUnit(getClass(), "delete_members_by_group_id.xml");
dao.deleteMembersByGroupId(session, 1L);
session.commit();
db.assertDbUnit(getClass(), "delete_members_by_group_id-result.xml", "groups_users");
}
}

0 comments on commit b24b0f1

Please sign in to comment.